import { Injectable } from '@angular/core';
import { FmodeParse, FmodeObject } from 'fmode-ng/parse';
import * as ww from '@wecom/jssdk';
import { WxworkCorp } from 'fmode-ng/core';

const Parse = FmodeParse.with('nova');

export interface WxworkCurrentChat {
  type: 'chatId' | 'userId';
  id?: string;
  contact?: any;
  follow_user?: any;
  group?: any;
}

/**
 * 企微SDK服务
 * 封装企业微信JSSDK功能
 */
@Injectable({
  providedIn: 'root'
})
export class WxworkSDKService {
  // 企业配置映射
  private companyMap: any = {
    'cDL6R1hgSi': { // 映三色
      corpResId: 'SpL6gyD1Gu'
    }
  };

  // 应用套件映射
  private suiteMap: any = {
    'crm': {
      suiteId: 'dk2559ba758f33d8f5'
    }
  };

  cid: string = '';
  appId: string = '';
  corpId: string = '';
  wecorp: WxworkCorp | null = null;
  ww = ww;
  registerUrl: string = '';

  constructor() {}

  /**
   * 初始化SDK
   */
  async initialize(cid: string, appId: string): Promise<void> {
    this.cid = cid;
    this.appId = appId;
    this.wecorp = new WxworkCorp(cid);
    await this.registerCorpWithSuite();
  }

  /**
   * 注册企业微信JSAPI
   */
  async registerCorpWithSuite(apiList?: string[]): Promise<boolean> {
    if (this.platform() !== 'wxwork') return false;

    // 如果URL未变化且已注册，直接返回
    if (!apiList?.length && this.registerUrl === location.href) {
      return true;
    }

    apiList = apiList || this.getDefaultApiList();

    try {
      const corpConfig = await this.getCorpByCid(this.cid);
      const suiteId = this.suiteMap[this.appId]?.suiteId;

      const now = new Date();

      return new Promise((resolve) => {
        ww.register({
          corpId: corpConfig.corpId,
          suiteId: suiteId,
          agentId: corpConfig.agentId,
          jsApiList: apiList!,
          getAgentConfigSignature: async () => {
            const jsapiTicket = await this.wecorp!.ticket.get();
            return ww.getSignature({
              ticket: jsapiTicket,
              nonceStr: '666',
              timestamp: (now.getTime() / 1000).toFixed(0),
              url: location.href
            });
          },
          onAgentConfigSuccess: () => {
            this.registerUrl = location.href;
            resolve(true);
          },
          onAgentConfigFail: (err: any) => {
            console.error('Agent config failed:', err);
            resolve(false);
          },
          onConfigFail: (err: any) => {
            console.error('Config failed:', err);
            resolve(false);
          }
        });
      });
    } catch (error) {
      console.error('Register failed:', error);
      return false;
    }
  }

  /**
   * 获取当前聊天对象
   */
  async getCurrentChatObject(): Promise<{
    GroupChat?: FmodeObject;
    Contact?: FmodeObject;
    currentChat: WxworkCurrentChat | null;
  }> {
    const currentChat = await this.getCurrentChat();

    if (!currentChat) {
      return { currentChat: null };
    }

    let GroupChat: FmodeObject | undefined;
    let Contact: FmodeObject | undefined;

    try {
      if (currentChat.type === 'chatId' && currentChat.group) {
        GroupChat = await this.syncGroupChat(currentChat.group);
      } else if (currentChat.type === 'userId' && currentChat.id) {
        const contactInfo = await this.wecorp!.externalContact.get(currentChat.id);
        Contact = await this.syncContact(contactInfo);
      }
    } catch (error) {
      console.error('getCurrentChatObject error:', error);
    }

    return { GroupChat, Contact, currentChat };
  }

  /**
   * 获取当前聊天场景
   */
  async getCurrentChat(): Promise<WxworkCurrentChat | null> {
    const isRegister = await this.registerCorpWithSuite();
    if (!isRegister) return null;

    try {
      const context = await ww.getContext();
      const entry = context?.entry;

      let type: 'chatId' | 'userId';
      let id: string | undefined;
      let contact: any;
      let chat: any;

      if (entry === 'group_chat_tools') {
        type = 'chatId';
        id = (await ww.getCurExternalChat())?.chatId;
        chat = await this.wecorp!.externalContact.groupChat.get(id!);
      } else if (entry === 'contact_profile' || entry === 'single_chat_tools') {
        type = 'userId';
        id = (await ww.getCurExternalContact())?.userId;
        contact = await this.wecorp!.externalContact.get(id!);
      } else {
        return null;
      }

      return {
        type,
        id,
        group: chat?.group_chat,
        contact: contact?.external_contact,
        follow_user: contact?.follow_user
      };
    } catch (error) {
      console.error('getCurrentChat error:', error);
      return null;
    }
  }

  /**
   * 获取当前用户信息
   */
  async getCurrentUser(): Promise<FmodeObject | null> {
    const userInfo = await this.getUserinfo();
    if (!userInfo) return null;

    return await this.getContactOrProfile(userInfo);
  }

  /**
   * 获取用户信息
   */
  async getUserinfo(code?: string): Promise<any> {
    // 优先检查缓存
    if (!code) {
      const userInfoStr = localStorage.getItem(`${this.cid}/USERINFO`);
      if (userInfoStr) {
        const userInfo = JSON.parse(userInfoStr);
        userInfo.cid = this.cid;
        return userInfo;
      }
    }

    // 从URL获取code
    const url = new URL(location.href);
    code = url.searchParams.get('code') || code;
    if (!code) return null;

    const result = await this.wecorp!.auth.getuserinfo(code);
    if (result?.errcode) {
      console.error(result?.errmsg);
      return null;
    }

    // 补全外部用户信息
    if (result?.external_userid) {
      const euser = await this.wecorp!.externalContact.get(result.external_userid);
      if (euser?.external_contact) {
        Object.assign(result, euser.external_contact);
      }
    }

    result.cid = this.cid;

    // 缓存用户信息
    localStorage.setItem(`${this.cid}/USERINFO`, JSON.stringify(result));

    return result;
  }

  /**
   * 同步群聊信息
   */
  async syncGroupChat(groupInfo: any): Promise<FmodeObject> {
    let query = new Parse.Query('GroupChat');
    query.equalTo('chat_id', groupInfo?.chat_id);
    let group = await query.first();

    if (!group?.id) {
      group = new Parse.Object('GroupChat');
    }

    // 生成入群方式
    if (!group?.get('joinUrl')) {
      const config_id1 = (await this.wecorp!.externalContact.groupChat.addJoinWay({
        scene: 1,
        chat_id_list: [groupInfo.chat_id]
      }))?.config_id;
      const joinUrl = (await this.wecorp!.externalContact.groupChat.getJoinWay(config_id1))?.join_way;
      group.set('joinUrl', joinUrl);
    }

    if (!group?.get('joinQrcode')) {
      const config_id2 = (await this.wecorp!.externalContact.groupChat.addJoinWay({
        scene: 2,
        chat_id_list: [groupInfo.chat_id]
      }))?.config_id;
      const joinQrcode = (await this.wecorp!.externalContact.groupChat.getJoinWay(config_id2))?.join_way;
      group.set('joinQrcode', joinQrcode);
    }

    // 更新群聊数据
    let needSave = false;

    if (group.get('chat_id') !== groupInfo.chat_id) needSave = true;
    if (group.get('name') !== groupInfo.name) needSave = true;
    if (group.get('owner') !== groupInfo.owner) needSave = true;
    if (group.get('notice') !== groupInfo.notice) needSave = true;
    if (group.get('member_version') !== groupInfo.member_version) {
      needSave = true;
      group.set('member_list', groupInfo.member_list);
      group.set('member_version', groupInfo.member_version);
    }

    group.set({
      chat_id: groupInfo.chat_id,
      name: groupInfo.name,
      owner: groupInfo.owner,
      notice: groupInfo.notice
    });

    if (this.cid) {
      group.set('company', { __type: 'Pointer', className: 'Company', objectId: this.cid });
    }

    if (needSave) {
      group = await group.save();
    }

    return group;
  }

  /**
   * 同步联系人信息
   */
  async syncContact(contactInfo: any): Promise<FmodeObject> {
    const externalContact = contactInfo.external_contact || contactInfo;
    const externalUserId = externalContact.external_userid;

    let query = new Parse.Query('ContactInfo');
    query.equalTo('external_userid', externalUserId);

    const Company = new Parse.Object('Company');
    Company.id = this.cid;
    query.equalTo('company', Company);

    let contact = await query.first();

    if (!contact?.id) {
      contact = new Parse.Object('ContactInfo');
      if (Company?.id) {
        contact.set('company', Company.toPointer());
      }
    }

    const name = externalContact.name || '';
    const mobile = externalContact.mobile || '';

    const data: any = {
      ...externalContact,
      follow_user: contactInfo.follow_user || externalContact.follow_user || []
    };

    let needSave = false;

    if (contact.get('external_userid') !== externalUserId) needSave = true;
    if (contact.get('name') !== name && name) needSave = true;
    if (contact.get('mobile') !== mobile && mobile) needSave = true;

    const oldData = contact.get('data');
    if (JSON.stringify(oldData) !== JSON.stringify(data)) needSave = true;

    contact.set('external_userid', externalUserId);
    contact.set('name', name);
    contact.set('mobile', mobile);
    contact.set('data', data);

    if (needSave) {
      contact = await contact.save();
    }

    return contact;
  }

  /**
   * 获取Profile或UserSocial
   */
  async getContactOrProfile(userInfo: any): Promise<FmodeObject> {
    let UserType: string;

    if (userInfo.openid || userInfo.external_userid) {
      UserType = 'UserSocial';
    } else if (userInfo.userid) {
      UserType = 'Profile';
    } else {
      throw new Error('Invalid user info');
    }

    // 构建查询条件
    const userCondition: any[] = [];
    const prefix = UserType === 'UserSocial' ? 'data.' : '';

    if (userInfo.openid) userCondition.push({ [`${prefix}openid`]: { $regex: userInfo.openid } });
    if (userInfo.userid) userCondition.push({ [`${prefix}userid`]: { $regex: userInfo.userid } });
    if (userInfo.mobile) userCondition.push({ [`${prefix}mobile`]: { $regex: userInfo.mobile } });
    if (userInfo.email) userCondition.push({ [`${prefix}email`]: { $regex: userInfo.email } });
    if (userInfo.external_userid) {
      userCondition.push({ [`${prefix}external_userid`]: { $regex: userInfo.external_userid } });
    }

    const query = Parse.Query.fromJSON(UserType, {
      where: {
        $or: userCondition
      }
    });
    query.equalTo('company', this.cid);

    let thisUser = await query.first();

    if (!thisUser?.id) {
      thisUser = new Parse.Object(UserType);
    }

    // 关联当前登录用户
    const current = Parse.User.current();
    if (current?.id && !thisUser?.get('user')?.id) {
      thisUser.set('user', current.toPointer());
    }

    return thisUser;
  }

  /**
   * 创建群聊
   */
  async createGroupChat(options: {
    groupName: string;
    userIds?: string[];
    externalUserIds?: string[];
  }): Promise<any> {
    const isRegister = await this.registerCorpWithSuite();
    if (!isRegister) return null;

    return new Promise((resolve, reject) => {
      ww.createCorpGroupChat({
        groupName: options.groupName,
        userIds: options.userIds,
        externalUserIds: options.externalUserIds,
        success: (data: any) => {
          resolve(data);
        },
        fail: (err: any) => {
          reject(err);
        }
      });
    });
  }

  /**
   * 添加成员到群聊
   */
  async addUserToGroup(options: {
    chatId: string;
    userIds?: string[];
    externalUserIds?: string[];
  }): Promise<any> {
    const isRegister = await this.registerCorpWithSuite();
    if (!isRegister) return null;

    return new Promise((resolve, reject) => {
      (ww as any).updateCorpGroupChat({
        chatId: options.chatId,
        userIds: options.userIds,
        externalUserIds: options.externalUserIds,
        success: (data:any) => {
          resolve(data);
        },
        fail: (err:any) => {
          reject(err);
        }
      });
    });
  }

  /**
   * 打开指定群聊
   */
  async openChat(chatId: string): Promise<void> {
    const isRegister = await this.registerCorpWithSuite();
    if (!isRegister) return;

    return new Promise((resolve, reject) => {
      ww.openEnterpriseChat({
        externalUserIds: [],
        groupName: '',
        chatId: chatId,
        success: () => {
          resolve();
        },
        fail: (err: any) => {
          reject(err);
        }
      });
    });
  }

  /**
   * 选择企业联系人
   */
  async selectEnterpriseContact(options?: {
    mode?: 'single' | 'multi';
    type?: Array<'department' | 'user'>;
  }): Promise<any> {
    const isRegister = await this.registerCorpWithSuite();
    if (!isRegister) return null;

    return new Promise((resolve, reject) => {
      (ww as any).selectEnterpriseContact({
        fromDepartmentId: -1,
        mode: options?.mode || 'multi',
        type: options?.type || ['department', 'user'],
        success: (data:any) => {
          resolve(data);
        },
        fail: (err:any) => {
          reject(err);
        }
      });
    });
  }

  /**
   * 获取企业配置
   */
  private async getCorpByCid(cid: string): Promise<any> {
    if (this.corpId) return { corpId: this.corpId };

    const query = new Parse.Query('CloudResource');
    const res = await query.get(this.companyMap[cid]?.corpResId);
    const config: any = res.get('config');
    return config;
  }

  /**
   * 判断平台
   */
  private platform(): string {
    const ua = navigator.userAgent.toLowerCase();
    if (ua.indexOf('wxwork') > -1) return 'wxwork';
    if (ua.indexOf('wechat') > -1) return 'wechat';
    return 'h5';
  }

  /**
   * 获取默认API列表
   */
  private getDefaultApiList(): string[] {
    return [
      'getContext',
      'getCurExternalChat',
      'getCurExternalContact',
      'createCorpGroupChat',
      'updateCorpGroupChat',
      'openEnterpriseChat',
      'selectEnterpriseContact',
      'checkJsApi',
      'chooseImage',
      'previewImage',
      'uploadImage',
      'downloadImage',
      'getLocation',
      'openLocation',
      'scanQRCode',
      'closeWindow'
    ];
  }
}
