import type { ModifyProfileParams, SelfInfo, User, UserDetailInfoByUin, UserDetailInfoByUinV2 } from '@/core/entities';
import { NodeIKernelProfileListener, ProfileListener } from '@/core/listeners';
import { RequestUtil } from '@/common/utils/request';
import { NodeIKernelProfileService, ProfileBizType, UserDetailSource } from '@/core/services';
import { InstanceContext, NapCatCore } from '..';

export class NTQQUserApi {
  context: InstanceContext;
  core: NapCatCore;
  constructor(context: InstanceContext, core: NapCatCore) {
    this.context = context;
    this.core = core;
  }
   async getProfileLike(uid: string) {
    return this.context.session.getProfileLikeService().getBuddyProfileLike({
      friendUids: [
        uid
      ],
      basic: 1,
      vote: 1,
      favorite: 0,
      userProfile: 1,
      type: 2,
      start: 0,
      limit: 20
    });
  }
   async setLongNick(longNick: string) {
    return this.context.session.getProfileService().setLongNick(longNick);
  }
   async setSelfOnlineStatus(status: number, extStatus: number, batteryStatus: number) {
    return this.context.session.getMsgService().setStatus({ status: status, extStatus: extStatus, batteryStatus: batteryStatus });
  }
   async getBuddyRecommendContactArkJson(uin: string, sencenID = '') {
    return this.context.session.getBuddyService().getBuddyRecommendContactArkJson(uin, sencenID);
  }
   async like(uid: string, count = 1): Promise<{ result: number, errMsg: string, succCounts: number }> {
    return this.context.session.getProfileLikeService().setBuddyProfileLike({
      friendUid: uid,
      sourceId: 71,
      doLikeCount: count,
      doLikeTollCount: 0
    });
  }

   async setQQAvatar(filePath: string) {
    type setQQAvatarRet = { result: number, errMsg: string };
    const ret = await this.context.session.getProfileService().setHeader(filePath) as setQQAvatarRet;
    return { result: ret?.result, errMsg: ret?.errMsg };
  }
   async setGroupAvatar(gc: string, filePath: string) {
    return this.context.session.getGroupService().setHeader(gc, filePath);
  }

   async fetchUserDetailInfos(uids: string[]) {
    //26702 以上使用新接口 .Dev Mlikiowa
    type EventService = NodeIKernelProfileService['fetchUserDetailInfo'];
    type EventListener = NodeIKernelProfileListener['onUserDetailInfoChanged'];
    let retData: User[] = [];
    let [_retData, _retListener] = await this.core.eventWrapper.CallNormalEvent
      <EventService, EventListener>
      (
        'NodeIKernelProfileService/fetchUserDetailInfo',
        'NodeIKernelProfileListener/onUserDetailInfoChanged',
        uids.length,
        5000,
        (profile) => {
          if (uids.includes(profile.uid)) {
            let RetUser: User = {
              ...profile.simpleInfo.coreInfo,
              ...profile.simpleInfo.status,
              ...profile.simpleInfo.vasInfo,
              ...profile.commonExt,
              ...profile.simpleInfo.baseInfo,
              qqLevel: profile.commonExt.qqLevel,
              pendantId: ""
            };
            retData.push(RetUser);
            return true;
          }
          return false;
        },
        "BuddyProfileStore",
        uids,
        UserDetailSource.KSERVER,
        [
          ProfileBizType.KALL
        ]
      );

    return retData;
  }
   async fetchUserDetailInfo(uid: string) {
    type EventService = NodeIKernelProfileService['fetchUserDetailInfo'];
    type EventListener = NodeIKernelProfileListener['onUserDetailInfoChanged'];
    let [_retData, profile] = await this.core.eventWrapper.CallNormalEvent
      <EventService, EventListener>
      (
        'NodeIKernelProfileService/fetchUserDetailInfo',
        'NodeIKernelProfileListener/onUserDetailInfoChanged',
        1,
        5000,
        (profile) => {
          if (profile.uid === uid) {
            return true;
          }
          return false;
        },
        "BuddyProfileStore",
        [
          uid
        ],
        UserDetailSource.KSERVER,
        [
          ProfileBizType.KALL
        ]
      );
    let RetUser: User = {
      ...profile.simpleInfo.coreInfo,
      ...profile.simpleInfo.status,
      ...profile.simpleInfo.vasInfo,
      ...profile.commonExt,
      ...profile.simpleInfo.baseInfo,
      qqLevel: profile.commonExt.qqLevel,
      pendantId: ""
    };
    return RetUser;
  }
   async getUserDetailInfo(uid: string) {
    if (this.context.basicInfoWrapper.requireMinNTQQBuild('26702')) {
      return this.fetchUserDetailInfo(uid);
    }
    return this.getUserDetailInfoOld(uid);
  }
   async getUserDetailInfoOld(uid: string) {
    type EventService = NodeIKernelProfileService['getUserDetailInfoWithBizInfo'];
    type EventListener = NodeIKernelProfileListener['onProfileDetailInfoChanged'];
    let [_retData, profile] = await this.core.eventWrapper.CallNormalEvent
      <EventService, EventListener>
      (
        'NodeIKernelProfileService/getUserDetailInfoWithBizInfo',
        'NodeIKernelProfileListener/onProfileDetailInfoChanged',
        2,
        5000,
        (profile: User) => {
          if (profile.uid === uid) {
            return true;
          }
          return false;
        },
        uid,
        [0]
      );
    return profile;
  }
   async modifySelfProfile(param: ModifyProfileParams) {
    return napCatCore.session.getProfileService().modifyDesktopMiniProfile(param);
  }
  //需要异常处理
   async getCookies(domain: string) {
    const ClientKeyData = await this.forceFetchClientKey();
    const requestUrl = 'https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=' + selfInfo.uin + '&clientkey=' + ClientKeyData.clientKey + '&u1=https%3A%2F%2F' + domain + '%2F' + selfInfo.uin + '%2Finfocenter&keyindex=19%27'
    let cookies: { [key: string]: string; } = await RequestUtil.HttpsGetCookies(requestUrl);
    return cookies;
  }
   async getPSkey(domainList: string[]) {
    return await this.context.session.getTipOffService().getPskey(domainList, true);
  }
   async getRobotUinRange(): Promise<Array<any>> {
    const robotUinRanges = await this.context.session.getRobotService().getRobotUinRange({
      justFetchMsgConfig: '1',
      type: 1,
      version: 0,
      aioKeywordVersion: 0
    });
    // console.log(robotUinRanges?.response?.robotUinRanges);
    return robotUinRanges?.response?.robotUinRanges;
  }
  //需要异常处理
  
   async getQzoneCookies() {
    const ClientKeyData = await this.forceFetchClientKey();
    const requestUrl = 'https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=' + selfInfo.uin + '&clientkey=' + ClientKeyData.clientKey + '&u1=https%3A%2F%2Fuser.qzone.qq.com%2F' + selfInfo.uin + '%2Finfocenter&keyindex=19%27'
    let cookies: { [key: string]: string; } = await RequestUtil.HttpsGetCookies(requestUrl);
    return cookies;
  }
  //需要异常处理
  
   async getSkey(): Promise<string | undefined> {
    const ClientKeyData = await this.forceFetchClientKey();
    if (ClientKeyData.result !== 0) {
      throw new Error('getClientKey Error');
    }
    const clientKey = ClientKeyData.clientKey;
    const keyIndex = ClientKeyData.keyIndex;
    const requestUrl = 'https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=' + selfInfo.uin + '&clientkey=' + clientKey + '&u1=https%3A%2F%2Fh5.qzone.qq.com%2Fqqnt%2Fqzoneinpcqq%2Ffriend%3Frefresh%3D0%26clientuin%3D0%26darkMode%3D0&keyindex=19%27';
    let cookies: { [key: string]: string; } = await RequestUtil.HttpsGetCookies(requestUrl);
    const skey = cookies['skey'];
    if (!skey) {
      throw new Error('getSkey Skey is Empty');
    }
    return skey;
  }
   async getUidByUin(Uin: string) {
    //此代码仅临时使用,后期会被废弃
    if (this.context.basicInfoWrapper.requireMinNTQQBuild('26702')) {
      return await this..getUidByUinV2(Uin);
    }
    return await this.getUidByUinV1(Uin);
  }
   async getUinByUid(Uid: string) {
    //此代码仅临时使用,后期会被废弃
    if (this.context.basicInfoWrapper.requireMinNTQQBuild('26702')) {
      return await this.getUinByUidV2(Uid);
    }
    return await this.getUinByUidV1(Uid);
  }

  //后期改成流水线处理
   async getUidByUinV2(Uin: string) {
    let uid = (await this.context.session.getProfileService().getUidByUin('FriendsServiceImpl', [Uin])).get(Uin);
    if (uid) return uid;
    uid = (await this.context.session.getGroupService().getUidByUins([Uin])).uids.get(Uin);
    if (uid) return uid;
    uid = (await this.context.session.getUixConvertService().getUid([Uin])).uidInfo.get(Uin);
    if (uid) return uid;
    console.log((await NTQQFriendApi.getBuddyIdMapCache(true)));
    uid = (await NTQQFriendApi.getBuddyIdMapCache(true)).getValue(Uin);//从Buddy缓存获取Uid
    if (uid) return uid;
    uid = (await NTQQFriendApi.getBuddyIdMap(true)).getValue(Uin);
    if (uid) return uid;
    let unveifyUid = (await this.getUserDetailInfoByUinV2(Uin)).detail.uid;//从QQ Native 特殊转换
    if (unveifyUid.indexOf("*") == -1) uid = unveifyUid;
    //if (uid) return uid;
    return uid;
  }
  //后期改成流水线处理
   async getUinByUidV2(Uid: string) {
    let uin = (await this.context.session.getProfileService().getUinByUid('FriendsServiceImpl', [Uid])).get(Uid);
    if (uin) return uin;
    uin = (await this.context.session.getGroupService().getUinByUids([Uid])).uins.get(Uid);
    if (uin) return uin;
    uin = (await this.context.session.getUixConvertService().getUin([Uid])).uinInfo.get(Uid);
    if (uin) return uin;
    uin = (await NTQQFriendApi.getBuddyIdMapCache(true)).getKey(Uid);//从Buddy缓存获取Uin
    if (uin) return uin;
    uin = (await NTQQFriendApi.getBuddyIdMap(true)).getKey(Uid);
    if (uin) return uin;
    uin = (await this.getUserDetailInfo(Uid)).uin; //从QQ Native 转换
    return uin;
  }

   async getUidByUinV1(Uin: string) {
    // 通用转换开始尝试
    let uid = (await this.context.session.getUixConvertService().getUid([Uin])).uidInfo.get(Uin);
    // Uid 好友转
    if (!uid) {
      Array.from(friends.values()).forEach((t) => {
        if (t.uin == Uin) {
          uid = t.uid;
        }
      });
    }
    //Uid 群友列表转
    if (!uid) {
      for (let groupMembersList of groupMembers.values()) {
        for (let GroupMember of groupMembersList.values()) {
          if (GroupMember.uin == Uin) {
            uid = GroupMember.uid;
          }
        }
      }
    }
    if (!uid) {
      let unveifyUid = (await this.getUserDetailInfoByUin(Uin)).info.uid;//从QQ Native 特殊转换 方法三
      if (unveifyUid.indexOf("*") == -1) {
        uid = unveifyUid;
      }
    }
    return uid;
  }
   async getUinByUidV1(Uid: string) {
    let ret = await this.core.eventWrapper.callNoListenerEvent
      <(Uin: string[]) => Promise<{ uinInfo: Map<string, string> }>>(
        'NodeIKernelUixConvertService/getUin',
        5000,
        [Uid]
      );
    let uin = ret.uinInfo.get(Uid);
    if (!uin) {
      //从Buddy缓存获取Uin
      Array.from(friends.values()).forEach((t) => {
        if (t.uid == Uid) {
          uin = t.uin;
        }
      })
    }
    if (!uin) {
      uin = (await this.getUserDetailInfo(Uid)).uin; //从QQ Native 转换
    }

    // if (!uin) {
    //   uin = (await NTQQFriendApi.getFriends(false)).find((t) => { t.uid == Uid })?.uin;  //从QQ Native 缓存转换
    // }
    // if (!uin) {
    //   uin = (await NTQQFriendApi.getFriends(true)).find((t) => { t.uid == Uid })?.uin;  //从QQ Native 非缓存转换
    // }
    return uin;
  }
   async getRecentContactListSnapShot(count: number) {
    return await this.context.session.getRecentContactService().getRecentContactListSnapShot(count);
  }
   async getRecentContactListSyncLimit(count: number) {
    return await this.context.session.getRecentContactService().getRecentContactListSyncLimit(count);
  }
   async getRecentContactListSync() {
    return await this.context.session.getRecentContactService().getRecentContactListSync();
  }
   async getRecentContactList() {
    return await this.context.session.getRecentContactService().getRecentContactList();
  }
   async getUserDetailInfoByUinV2(Uin: string) {
    return await this.core.eventWrapper.callNoListenerEvent
      <(Uin: string) => Promise<UserDetailInfoByUinV2>>(
        'NodeIKernelProfileService/getUserDetailInfoByUin',
        5000,
        Uin
      );
  }
   async getUserDetailInfoByUin(Uin: string) {
    return this.core.eventWrapper.callNoListenerEvent
      <(Uin: string) => Promise<UserDetailInfoByUin>>(
        'NodeIKernelProfileService/getUserDetailInfoByUin',
        5000,
        Uin
      );
  }
   async forceFetchClientKey() {
    return await this.context.session.getTicketService().forceFetchClientKey('');
  }
}