import { defineStore } from 'pinia';
import consola from 'consola';
import { genTestUserSig } from '/@/utils/generateTestUserSig';
import type { RemoteStream } from 'trtc-js-sdk';
import sortBy from 'lodash-es/sortBy';

interface RtcState {
  socket: Nullable<SocketIOClient.Socket>;
  socketId: string;
  showDaoGou: boolean;
  sdkAppId: string;
  userId: string;
  roomId: string;
  role: 'leader' | 'customer';
  secretKey: string;
  userSig: string;
  audioDeviceId: string;
  videoDeviceId: string;
  cameraList: MediaDeviceInfo[];
  microphoneList: MediaDeviceInfo[];
  logs: any[];
  isJoined: boolean;
  isRTCJoined: boolean;
  isPublished: boolean;
  isShared: boolean;
  remoteStreams: RemoteStream[];
  // invitedRemoteStreams: any[],
  avatar: Nullable<string>;
  nickname: string;
  mode: string;
  chatList: ChatContentType[];
  memberList: UserInfoType[];
  // audioMuted: boolean;
  inputStatus: boolean;
  currentSession: Nullable<UserInfoType>;
  baseDialog: BaseDialog;
  ifBaseDialog: boolean;
  baseDiaLogCallback?: () => void;
  connectStatus: number;
  isHosterOnline: boolean;
}

interface DeviceListParams {
  cameraItems: MediaDeviceInfo[];
  microphoneItems: MediaDeviceInfo[];
}

export interface ChatContentType {
  role: RoleType;
  mode: string;
  Nickname: Nullable<string>;
  UserId: string;
  text: string;
}

export interface UserInfoType {
  Avatar: string;
  Id: string;
  InTime: string;
  IsClient: boolean;
  IsMuted: boolean;
  IsWords: boolean;
  JoinTime: string;
  Nickname: string;
  Role: RoleType;
  RoomId: string;
  UserId: string;
  text?: string;
  Order: number;
  IsOnline?: boolean;
  IsAssistant?: boolean;
}
export type RoleType = 'leader' | 'customer';

interface RoomConfigType {
  limit: number;
  masterId: string;
  ttl?: number;
}

// type Enumerate<N extends number, Acc extends number[] = []> = Acc['length'] extends N
//   ? Acc[number]
//   : Enumerate<N, [...Acc, Acc['length']]>;

// type IntRange<F extends number, T extends number> = Exclude<Enumerate<T>, Enumerate<F>>;

export interface SocketParams {
  userId: string;
  roomId: string;
  role: RoleType;
  avatar: string;
  nickname: string;
  mode?: string;
  roomConfig?: RoomConfigType;
  isClient?: boolean;
}

interface BaseDialog {
  title: string;
  desc: string;
  okTxt: string;
  closeTxt: string;
  isSingle?: boolean;
}
const defaultBaseDialog: BaseDialog = {
  title: '温馨提示',
  desc: '',
  okTxt: '确定',
  closeTxt: '取消',
};

export const useRtcStore = defineStore({
  id: 'rtc',
  state: (): RtcState => ({
    socket: null,
    socketId: '',
    showDaoGou: false,
    sdkAppId: '1400685498',
    nickname: '',
    userId: '',
    roomId: '',
    role: 'customer',
    secretKey: '7500f8938c46c5d3c64621ae7826905eec9723bf218fbcf121242e056a4ee14f',
    userSig:
      'eJwtzcsOgjAQBdB-6RaDU2jLI3EhsrHRBdGNK2Po0IyvNAWJxvjvEmA5597c*bLj7hD26FnOohDYYrzJ4LOjhkZ*tejPd7wY9EJwnsV8brXmdnGODMu5AEggExBNSUcPHFQpnkopIJkU34784ApECjBvkB1e8MLJfWyLOAis06Wut4b0tVdL77RVTb35dGXby6o6rVfs9wdhLDRy',
    audioDeviceId: '',
    videoDeviceId: '',
    cameraList: [],
    microphoneList: [],
    logs: [],
    isJoined: false,
    isRTCJoined: false,
    isPublished: false,
    isShared: false,
    remoteStreams: [],
    // invitedRemoteStreams: [],
    avatar: null,
    mode: '',
    chatList: [],
    memberList: [],
    // audioMuted: true,
    inputStatus: true,
    currentSession: null,
    baseDialog: defaultBaseDialog,
    ifBaseDialog: false,
    connectStatus: 0,
    isHosterOnline: true,
  }),
  persist: [
    {
      storage: localStorage,
      paths: ['memberList'],
    },
    {
      storage: sessionStorage,
      paths: ['userId'],
    },
  ],
  getters: {
    checkUserInMemberList() {
      return (userId: string) => this.memberList.find((item) => item.UserId === userId);
    },
    isLeader(): boolean {
      return this.role === 'leader';
    },
    isMe() {
      return (userId: string) => this.userId === userId;
    },
    genUserSig() {
      const { userSig } = genTestUserSig({
        sdkAppId: parseInt(this.sdkAppId, 10),
        userId: this.userId,
        secretKey: this.secretKey,
      });
      return userSig;
    },
    isIdInRemoteStream() {
      return (userId: string) => {
        return this.remoteStreams.some((item) => item.getId() === userId);
      };
    },
    isUserInRemoteStream() {
      return (userId: string) => {
        return this.remoteStreams.some((item) => item.getUserId() === userId);
      };
    },
    getSelfRoomStatus() {
      return () => this.memberList.find((item) => item.UserId === this.userId);
    },
    getRoomLeader() {
      return () => this.memberList.find((item) => item.Role === 'leader');
    },
  },
  actions: {
    showBaseDialog(dialog: BaseDialog, callback?: () => void): void {
      this.ifBaseDialog = true;
      this.baseDialog = dialog;
      this.baseDiaLogCallback = callback;
    },
    hideBaseDialog() {
      this.ifBaseDialog = false;
      this.baseDialog = defaultBaseDialog;
    },
    setSocketParams(params: SocketParams): void {
      this.avatar = params.avatar;
      this.roomId = params.roomId;
      this.userId = params.userId;
      this.nickname = params.nickname;
      this.role = params.role;
      if (!['leader', 'customer'].includes(params.role)) {
        consola.info({
          message: '角色参数有误',
          level: 0,
          tag: 'role',
        });
        this.role = 'customer';
      }
    },
    setNickName(nickname: string) {
      this.nickname = nickname;
    },

    setAvatar(payload: string) {
      this.avatar = payload;
      localStorage.setItem('leaderAvatar', payload || '');
    },
    setSocket(payload: SocketIOClient.Socket) {
      this.socket = payload;
    },
    setShowDaoGou(payload: boolean) {
      this.showDaoGou = payload;
    },

    setUserId(payload: string) {
      this.userId = payload;
    },

    setRoomId(payload: string) {
      this.roomId = payload;
    },
    setRole(payload: RoleType) {
      this.role = payload;
    },

    setDeviceList(payload: DeviceListParams) {
      this.cameraList = payload.cameraItems;
      this.microphoneList = payload.microphoneItems;
    },

    setVideoDeviceId(payload: string) {
      this.videoDeviceId = payload;
    },

    setAudioDeviceId(payload: string) {
      this.audioDeviceId = payload;
    },

    setIsJoined(payload: boolean) {
      this.isJoined = payload;
      console.log('setIsJoined', payload);
    },
    setIsRTCJoined(payload: boolean) {
      this.isRTCJoined = payload;
    },
    setIsPublished(payload: boolean) {
      this.isPublished = payload;
    },

    addToChatList(content: ChatContentType) {
      this.chatList.push(content);
    },
    setMemberList(members: UserInfoType[]) {
      const memberList = members.reduce((prev: UserInfoType[], current: UserInfoType, index) => {
        if (prev.findIndex((ele: UserInfoType) => ele.UserId === current.UserId) === -1) {
          // console.log(current);
          current.Order = index > 1 ? index : 2;
          if (current.Role === 'leader') {
            current.Order = 0;
          } else {
            if (current.IsAssistant) {
              current.Order = 1;
            }
            if (current.UserId === this.userId) {
              current.Order = 2;
              this.currentSession = current;
            }
          }

          prev.push(current);
        }
        return prev;
      }, []);
      const sortList = sortBy(memberList, ['Order', 'UserId'], ['asc', 'asc']);
      console.log('sortList', sortList);
      this.memberList = sortList;
    },

    clearMemberList(): void {
      this.memberList = [];
      this.userId = '';
    },
    updateMemberDatabyId(UserId: string, data: Partial<UserInfoType>) {
      const updateIndex = this.memberList.findIndex((member) => member.UserId === UserId);
      if (updateIndex > -1) {
        this.memberList[updateIndex] = Object.assign({}, this.memberList[updateIndex], data);
        //单点更新并是当事人也更一份数据
        if (UserId === this.userId) {
          this.currentSession = this.memberList[updateIndex];
        }
      }
    },
    mute() {
      this.setMute(false);
    },
    unmute() {
      this.setMute(true);
    },
    setMute(mute: boolean) {
      // this.audioMuted = mute;
      this.updateMemberDatabyId(this.userId, {
        IsMuted: mute,
      });
    },

    setinputStatus(status: boolean) {
      this.inputStatus = status;
    },

    pushRemoteStreams(stream: RemoteStream) {
      this.remoteStreams.push(stream);
    },
    removeRemoteStreams(id: string) {
      const existStreamIndex = this.remoteStreams.findIndex((stream) => stream.getId() === id);
      if (existStreamIndex > -1) {
        consola.info({
          message: `handleRemoveIdByRemoteStream: index->${existStreamIndex}`,
          tag: 'rtc:audio',
        });
        this.remoteStreams.splice(existStreamIndex, 1);
      }
    },
    setConnectStatus(status: number) {
      this.connectStatus = status;
    },
    setHosterOnline(status: boolean) {
      this.isHosterOnline = status;
    },
  },
});
