import { Injectable } from '@angular/core';
import { HttpService } from './http.service';
import * as Parse from 'parse';
import { AlertController, ToastController } from '@ionic/angular';
// import AgoraRTM from 'agora-rtmClient';
import { Subject } from 'rxjs';
import { Router } from '@angular/router';
import { AiChatService } from './aichart.service';
declare const AgoraRTM: any;
import { VapInit } from '../lib/vap-player/index';

@Injectable({
  providedIn: 'root',
})
export class MessageService {
  private eventSource = new Subject<any>();
  event$ = this.eventSource.asObservable();
  private eventplay = new Subject<any>();
  eventplay$ = this.eventplay.asObservable();

  company: string = 'Qje9D4bqol';
  rtmClient: any; // RTM实例
  // rtmClientMap: any = {};
  channelNameList: any = {}; //订阅频道状态
  msChannelName: string = 'global_room'; // 全球频道
  options: any = {
    connectState: false,
  };
  appid?: string;
  userId: string = Parse.User.current()?.id!;

  pageFun?: Function; //页面传入的方法
  alert: any; // 弹窗
  messageMapList: any = {};
  giftLogMap: any = [];
  giftList: Array<any> = []; //礼物列表
  timeg: any;
  isPlayer: boolean = false;
  newNoticeMap = new Set(); //新消息提示
  private audioPlayer: HTMLAudioElement | null = null;
  private loopPlayAudio(audioUrl: string, rep?: boolean) {
    if (this.audioPlayer) {
      this.audioPlayer.pause();
      this.audioPlayer.currentTime = 0;
    }

    this.audioPlayer = new Audio(audioUrl);
    this.audioPlayer.loop = rep; // 设置循环播放
    this.audioPlayer.play().catch((error) => {
      console.error('播放音频失败:', error);
    });
  }
  reset() {
    this.options = { connectState: false };
    this.rtmClient = null;
    this.channelNameList = {};
    this.messageMapList = {};
    this.newNoticeMap = new Set();
  }
  constructor(
    private alertController: AlertController,
    private router: Router,
    private toastController: ToastController,
    private http: HttpService,
    private aiServ: AiChatService
  ) {
    this.aiServ.getGift().then((data) => (this.giftList = data));
  }

  /* 获取token */
  async getToken() {
    this.userId = Parse.User.current()?.id!;
    //获取频道token记录
    let uid = Parse.User.current()?.id;
    let baseurl = 'https://server.fmode.cn/api/webrtc/build_token';
    let reqBody = {
      company: this.company,
      channelName: this.msChannelName,
      type: 'withrtm',
      account: uid,
    };
    let data: any = await this.http.httpRequst(baseurl, reqBody, 'POST');
    console.log(data);
    if (data.code == 200) {
      // this.options[channel] = {
      //   token: data.data.token,
      // };
      this.options.token = data.data.token;
      this.appid = data.data.appid;
    }
  }

  async initRTM() {
    // let states = ['CONNECTED', 'CONNECTING'];
    if (this.options.connectState) return;
    await this.getToken();
    const rtmConfig = { logLevel: 'error', logUpload: false };
    this.rtmClient = new AgoraRTM.RTM(this.appid, this.userId, rtmConfig);
    this.joinReady();
    await this.loginRTM();
    // this.subscribeMessage(channelName);
    // this.publishMessage('user-online', channelName, 'USER'); //用户上线通知
  }
  /**@监听频道消息
   *@'USERCALLINVITATION': 用户通话邀请
   *@'CLOASEINVITATION': 取消通话邀请
   *@'REFUSEINVITATION_' + uid: 拒绝通话邀请
   *@'RESPONSEINVITOIN_' + uid: 接受邀请
   *@'USERGREETING_' + '': 问候
   */
  joinReady() {
    this.rtmClient?.addEventListener('message', async (event: any) => {
      console.log('接收到一条消息：', event);
      let states = [
        'USERCALLINVITATION',
        'REFUSEINVITATION_' + this.userId,
        'REFUSEINVITATION_' + event.publisher,
        'CLOASEINVITATION',
        'RESPONSEINVITOIN_' + this.userId,
        'RESPONSEINVITOIN_' + event.publisher,
      ];
      const message = JSON.parse(event.message);
      let is_self = event.publisher == this.userId;
      console.log('自己发出的消息：', is_self, message.text);
      if (
        states.includes(message.text) ||
        message.text.indexOf('ONUSERSENDGIFT_') > -1 ||
        message.text.indexOf('USERGREETING_') > -1
      ) {
        if (!is_self) {
          this.callPresence(message.text, event.publisher, event.channelName);
        }
        //呼出播放声音
        if (message.text == 'USERCALLINVITATION') {
          this.loopPlayAudio('mp3/call.mp3', true);
        } else if (message.text == 'CLOASEINVITATION') {
          if (this.audioPlayer) {
            this.audioPlayer.pause();
            this.audioPlayer.currentTime = 0;
          }
        }
        return;
      }
      this.showMessage(event);
    });
    this.rtmClient?.addEventListener('presence', (event: any) => {
      console.log('频道人员状态变化 ', event);
      let is_self = event.publisher == this.userId;
      //远端用户离开频道，主播在线状态
      if (
        !is_self &&
        event.eventType === 'REMOTE_LEAVE' &&
        event.channelName === this.userId
      ) {
        this.setConnectState(this.userId, 'ONLINE');
      }
    });
    this.rtmClient?.addEventListener('linkState', (event: any) => {
      console.log('连接状态: ', event);
    });
  }

  /* 设置频道状态 */
  async setConnectState(channelName: string, mode: string) {
    const channelType = 'MESSAGE';
    const states = {
      Mode: mode,
    };
    try {
      await this.rtmClient?.presence.setState(channelName, channelType, states);
      console.log('频道状态发生更改：', mode);
    } catch (err: any) {
      console.log(err);
    }
  }

  /* 呼叫事件 */
  async callPresence(message: string, publisher: string, channelName: string) {
    let userData = await this.getUserMetadata(publisher);
    console.log('向我发出事件用户：', userData);
    let toast;
    if (message.indexOf('ONUSERSENDGIFT_') > -1) {
      let arr = message.split('_');
      let gift = this.giftList.find((item: any) => item.id == arr[1]);
      // let r = await this.aiServ.getGift(undefined,arr[1])
      // let gift = r[0]
      this.giftLogMap.push({
        gift,
        count: arr?.[2],
        user: userData,
      });
      !this.isPlayer &&
        setTimeout(() => {
          // this.playGift(this.giftLogMap.slice(-1)[0]);
          let obj = this.giftLogMap.slice(-1)[0];
          this.eventplay.next({
            video: obj.gift.video,
            config: obj.gift.config,
          });
        }, 0);
      return;
    }
    if (message.indexOf('USERGREETING_') > -1) {
      this.loopPlayAudio('mp3/message.mp3');
      let arr = message.split('_');
      this.alert = await this.alertController.create({
        cssClass: 'my-custom-class',
        header: '收到打招呼消息',
        message: `${userData?.nickname?.value ?? '未知用户'}：${arr[1]}`,
        backdropDismiss: false,
        buttons: [
          {
            text: '关闭',
            role: 'cancel',
            handler: async (blah) => {},
          },
          {
            text: '查看主页',
            cssClass: 'secondary',
            handler: async () => {
              this.router.navigate(['user/profile/' + publisher]);
            },
          },
        ],
      });
      await this.alert.present();
      return;
    }
    switch (message) {
      case 'USERCALLINVITATION':
        this.loopPlayAudio('mp3/call.mp3', true);
        await this.setConnectState(this.userId, 'CONNECTING');
        // console.log(`收到${userData?.nickname?.value ?? '未知用户'}通话邀请`);
        this.alert = await this.alertController.create({
          cssClass: 'my-custom-class',
          header: '通话邀请',
          message: `收到${userData?.nickname?.value ?? '未知用户'}通话邀请`,
          backdropDismiss: false,
          buttons: [
            {
              text: '拒绝',
              role: 'cancel',
              handler: async (blah) => {
                await this.setConnectState(this.userId, 'ONLINE');
                this.publishMessage(
                  'REFUSEINVITATION_' + publisher,
                  channelName
                );
                // 停止播放音频
                if (this.audioPlayer) {
                  this.audioPlayer.pause();
                  this.audioPlayer.currentTime = 0;
                }
              },
            },
            {
              text: '接受',
              cssClass: 'secondary',
              handler: async () => {
                this.publishMessage(
                  'RESPONSEINVITOIN_' + publisher,
                  channelName
                );
                let rid = await this.getRoom(this.userId);
                this.router.navigate(['live/link-room/' + rid]);
                // 停止播放音频
                if (this.audioPlayer) {
                  this.audioPlayer.pause();
                  this.audioPlayer.currentTime = 0;
                }
              },
            },
          ],
        });
        await this.alert.present();
        break;
      case 'CLOASEINVITATION':
        await this.setConnectState(this.userId, 'ONLINE');
        // console.log(`${userData?.nickname?.value ?? '未知用户'}取消通话`);
        this.alert?.dismiss();
        toast = await this.toastController.create({
          message: '对方已取消通话邀请',
          color: 'warning',
          duration: 1500,
        });
        toast.present();
        // 停止播放音频
        if (this.audioPlayer) {
          this.audioPlayer.pause();
          this.audioPlayer.currentTime = 0;
        }
        break;
      case 'REFUSEINVITATION_' + this.userId:
        // console.log(`${userData?.nickname?.value ?? '未知用户'}拒绝通话`);
        this.alert?.dismiss();
        this.eventSource.next(false);
        // 停止播放音频
        if (this.audioPlayer) {
          this.audioPlayer.pause();
          this.audioPlayer.currentTime = 0;
        }
        break;
      case 'RESPONSEINVITOIN_' + this.userId:
        // console.log(`${userData?.nickname?.value ?? '未知用户'}同意通话，进入视频通话`);
        this.alert?.dismiss();
        this.eventSource.next(true);
        // 停止播放音频
        if (this.audioPlayer) {
          this.audioPlayer.pause();
          this.audioPlayer.currentTime = 0;
        }
        break;
    }
  }

  // 礼物消息
  // showGiftDecrement() {
  //   this.timeg = setTimeout(() => {
  //     this.giftLogMap.shift();
  //     if (this.giftLogMap.length > 0) {
  //       this.showGiftDecrement();
  //     } else {
  //       clearTimeout(this.timeg);
  //       this.timeg = null;
  //     }
  //   }, 5000);
  // }

  playGift(giftModule: any) {
    console.log(giftModule);
    this.isPlayer = true;
    let dom = document.getElementById('vap-gift');
    console.log(dom);
    let vapPlayer = VapInit({
      container: dom, // 要渲染的载体，dom元素
      src: giftModule.gift?.video, // vap动画地址
      config: giftModule.gift?.config, // 播放vap动画需要的 json文件。必填
      width: window.innerWidth, // 容器宽度
      height: window.innerHeight, // 容器高度
      fps: 30, // 帧数，json文件中有这个视频的帧数的，可以看一下，
      mute: false, // 静音
      type: 1, // 组件基于type字段做了实例化缓存，不同的VAP实例应该使用不同的type值（如0、1、2等）
      loop: false, // 循环
      precache: true, // 预加载视频，下载完再播。小动画建议边下边播，大动画还是先下后播吧，因为太大了或者网络不好，会一卡一卡的。
      beginPoint: 0, // 起始播放时间点(单位秒),在一些浏览器中可能无效
      accurate: true, // 是否启用精准模式（使用requestVideoFrameCallback提升融合效果，浏览器不兼容时自动降级）
    });
    vapPlayer.play(); // 开始播放
    vapPlayer.on('ended', () => {
      // 监听播放完成的事件
      vapPlayer.destroy();
      vapPlayer = null;
      console.log('播放结束');
      this.giftLogMap.pop();
      if (this.giftLogMap.length > 0) {
        this.playGift(this.giftLogMap.slice(-1)[0]);
      } else {
        this.isPlayer = false;
      }
    });
    vapPlayer.on('playering', function () {
      console.log('playering');
    });
  }

  async getRoom(uid: string): Promise<string | undefined> {
    let query = new Parse.Query('Room');
    query.equalTo('company', this.company);
    query.equalTo('user', uid);
    query.notEqualTo('isDeleted', true);
    query.select('objectId');
    let r = await query.first();
    return r?.id;
  }
  /* 加入频道 */
  // async join(channelName: string) {
  //   const options = {
  //     token: this.options[channelName].token,
  //     withPresence: true,
  //     withLock: true,
  //     withMetadata: true,
  //   };
  //   try {
  //     const streamChannel =
  //       this.rtmClientMap[channelName].rtmClient.createStreamChannel(
  //         channelName
  //       );
  //     const result = await streamChannel.join(options);
  //   } catch (status) {
  //     console.error('join channel failed: ', status);
  //   }
  // }
  async loginRTM() {
    try {
      await this.rtmClient?.login({
        token: this.options.token,
      });
      this.options.connectState = true; // 登录成功
      let userMateData = await this.getUserMetadata(this.userId);
      if (!userMateData?.nickname?.value || !userMateData?.avatar?.value) {
        let user = Parse.User.current();
        const metadata = [
          {
            key: 'nickname',
            value: user?.get('nickname') || '',
          },
          {
            key: 'avatar',
            value:
              user?.get('avatar') ??
              'https://file-cloud.fmode.cn/DXNgcD6zo6/20221202/j6p8kb034039.png',
          },
        ];
        const options = {
          userId: this.userId,
          addTimeStamp: true,
          addUserId: true,
        };
        let result = await this.rtmClient?.storage.setUserMetadata(
          metadata,
          options
        );
        console.log(JSON.stringify(result));
      }
    } catch (status) {
      console.log(status);
    }
  }
  logOutRTM() {
    this.rtmClient?.logout().then(() => {
      console.log('logout success');
      this.options.connectState = false;
    });
  }
  /* 订阅消息 */
  subscribeMessage(channelName: string, param?: any, deadline?: number): any {
    if (this.channelNameList[channelName]) {
      return;
    }

    return new Promise((resolve, reject) => {
      const options = {
        withMessage: param?.message ?? false, // message 事件
        withPresence: param?.presence ?? false, // presence 事件
        beQuiet: false, // quiet 事件
        withMetadata: false, // metadata 事件
        withLock: false, // lock 事件
      };
      this.rtmClient
        ?.subscribe(channelName, options)
        .then((res: any) => {
          console.log('subscribeMessage', res);
          //订阅成功
          this.channelNameList[channelName] = true;
          if (!this.messageMapList[channelName]) {
            this.messageMapList[channelName] = [];
            if (channelName.indexOf('-') > -1 || channelName == 'global_room') {
              let noticeMap = localStorage.getItem('noticeMap') || '{}';
              noticeMap = JSON.parse(noticeMap);
              if(!noticeMap[channelName]){
                noticeMap[channelName] = 0;
                localStorage.setItem('noticeMap', JSON.stringify(noticeMap));
              }
              this.getHistoryMessage(channelName, deadline);
            }
          }
          this.pageFun?.();
          resolve(true);
        })
        .catch((err: any) => {
          console.error('subscribeMessageErr', err);
          resolve(false);
        });
    });
  }

  async getHistoryMessage(channelName: string, deadline?: number) {
    let query = new Parse.Query('MessageLog');
    query.equalTo('channel', channelName);
    query.descending('createdAt');
    query.skip(this.messageMapList[channelName].length);
    query.limit(50);
    query.select('content', 'from_id');
    deadline && query.greaterThanOrEqualTo('createdAt', new Date(deadline));
    let msgList = await query.find();
    console.log('历史消息：', msgList);
    msgList.forEach((item: any) => {
      let is_self = item?.get('from_id') == this.userId;
      let data: any = item?.get('content');
      data['is_self'] = is_self;
      data['timestamp'] = new Date(data.timestamp);
      this.messageMapList[channelName].unshift(data);
    });
    //处理未读信息红点
    let noticeMap = localStorage.getItem('noticeMap') || '{}';
    noticeMap = JSON.parse(noticeMap);
    if (this.router.url.indexOf('/live/chat/' + channelName) == 0) {
      noticeMap[channelName] = new Date().getTime();
      localStorage.setItem('noticeMap', JSON.stringify(noticeMap));
      this.newNoticeMap.delete(channelName);
    } else if (msgList.length > 0 && !this.newNoticeMap.has(channelName)) {
      let lastMsg = this.messageMapList[channelName]?.at(-1);
      if (!lastMsg.is_self && lastMsg.timestamp > noticeMap[channelName]) {
        this.newNoticeMap.add(channelName);
      }
    }
    // this.messageMapList[channelName].unshift(...msgList);
  }
  /* 取消订阅 */
  unsubscribeMessage(channelName: string) {
    this.rtmClient
      ?.unsubscribe(channelName)
      .then((res: any) => {
        console.log('unsubscribeMessage', res);
        //订阅成功
        this.channelNameList[channelName] = false;
      })
      .catch((err: any) => {
        console.error('unsubscribeMessage', err);
      });
  }

  async showMessage(param: any) {
    let userData = await this.getUserMetadata(param.publisher);
    let is_self = param.publisher == this.userId;
    // console.log(userData);
    let message = JSON.parse(param.message);
    if (!this.messageMapList[param.channelName])
      this.messageMapList[param.channelName] = [];
    if (is_self) {
      this.saveMeesage({
        from_id: this.userId,
        from_username: Parse.User.current()?.get('nickname') ?? '未知用户',
        target_id: param.channelName,
        // target_name: userData?.nickname?.value ?? '未知用户',
        channel: param.channelName,
        content: {
          avatar:
            userData?.avatar?.value ??
            'https://file-cloud.fmode.cn/DXNgcD6zo6/20221202/j6p8kb034039.png',
          msg_type: 1,
          name: userData?.nickname?.value ?? '未知用户',
          content: message?.text ?? '',
          publisher: param.publisher,
          timestamp: param.timestamp,
        },
      });
    } else if (param.channelName.indexOf('-') > -1) {
      let noticeMap: any = localStorage.getItem('noticeMap') || '{}';
      noticeMap = JSON.parse(noticeMap);
      if (
        this.router.url.indexOf('/live/chat/' + param.channelName) == 0
      ) {
        noticeMap[param.channelName] = new Date().getTime();
        localStorage.setItem('noticeMap', JSON.stringify(noticeMap));
        this.newNoticeMap.delete(param.channelName);
      } else if (param.timestamp > noticeMap[param.channelName]) {
        this.newNoticeMap.add(param.channelName);
      }
    }
    let data: any = {
      is_self: is_self,
      avatar:
        userData?.avatar?.value ??
        'https://file-cloud.fmode.cn/DXNgcD6zo6/20221202/j6p8kb034039.png',
      msg_type: 1,
      name: userData?.nickname?.value ?? '未知用户',
      content: message?.text ?? '',
      publisher: param.publisher,
      timestamp: new Date(param.timestamp),
    };
    this.messageMapList[param.channelName].push(data);
    this.pageFun?.();
  }

  async saveMeesage(parse: {
    from_id: string;
    from_username: string;
    target_id: string;
    // target_name: string;
    channel: string;
    content: Object;
  }) {
    console.log(parse);
    let obj = Parse.Object.extend('MessageLog');
    let message = new obj();
    message.set('from_id', parse.from_id);
    message.set('from_username', parse.from_username);
    message.set('target_id', parse.target_id);
    // message.set('target_name', parse.target_name);
    message.set('channel', parse.channel);
    message.set('content', parse.content);
    message.set('company', {
      __type: 'Pointer',
      className: 'Company',
      objectId: this.company,
    });
    await message.save();
  }

  async getUserMetadata(uid: string) {
    try {
      const result = await this.rtmClient?.storage.getUserMetadata({
        userId: uid,
      });
      return result.metadata;
    } catch (status) {
      console.log(JSON.stringify(status));
    }
  }

  async publishMessage(
    message: string,
    channelName: string,
    channelType?: string
  ) {
    const payload = { type: 'text', text: message };
    const publishMessage = JSON.stringify(payload);
    const publishOptions = { channelType: channelType ?? 'MESSAGE' };
    try {
      const result = await this.rtmClient?.publish(
        channelName,
        publishMessage,
        publishOptions
      );
      console.log('发出消息：', result);
    } catch (status) {
      console.log('发出消息失败：', status);
    }
  }

  delMsg(channelName: string, index?: number, limit?: number) {
    this.messageMapList[channelName].splice(
      index ?? 0,
      limit ?? this.messageMapList[channelName].length
    );
    console.log(this.messageMapList[channelName]);
  }
}
