import { makeAutoObservable, toJS, } from 'mobx';
import API from '../api/index';
import { Toast } from "@grace/ui";
import { initWx, IWxShareInfo } from "@/built-in/share/weixin/weixin.ts";
import { _asyncThrottle, _debounce, getTimeStamp, getUrlParam } from '@/utils/utils';
import { PageCtrl } from '@/core/ctrls/PageCtrl';
import { ModalCtrl } from '@/core/ctrls/ModalCtrl';
import { getDomain } from '@spark/dbdomain';
import { showShareGuide } from '@spark/share';
import Loginpop from '@/panels/loginpop/loginpop';
import InvalidPop from '@/panels/invalidPop/invalidPop';
import FirstPop from '@/panels/firstPop/firstPop';
import Tipspop from '@/panels/tipspop/tipspop';
import { IS_OTHER_APP, isWeiXin, queryAppFundDetail } from '@/AppTools';
import { CHANNEL } from '@/AppTools';
import { NewbieModal } from '@/panels/newbieModal/newbieModal';
import RedPackRainModal from '@/panels/redPackRainModal/redPackRainModal';
import { errMessageMap } from '@/utils/errorHandler';

class Store {

  constructor() {
    makeAutoObservable(this);
  }

  baseInfo: any = {};

  /** 前端开发配置 */
  frontVariable: {
    homeTip: any;
    shareInfo: any,
    ruleImg?: string,
  } = {
      shareInfo: {
        title: "",
        desc: "",
        imgUrl: "",
      },
      homeTip: ''
    };

  ruleInfo = '';

  /** 积分门票 */
  ticketNum = null;

  /** 获取活动规则 */
  async initRule() {
    // 模拟获取远程的数据
    const { data } = await API.getRule();
    this.ruleInfo = data;
  }

  /** 获取前端配置项 */
  async getFrontVariable() {
    // 获取前端开发配置
    const { data } = await API.getFrontVariable();
    const resData = data || {};
    if (resData.shareInfo) resData.shareInfo = JSON.parse(resData.shareInfo);
    this.frontVariable = resData;
    console.log('前端开发配置', data)
  }

  indexData: {
    redRainConfig?: any,
    actStartTime?: number,
    actEndTime?: number,
    currentTime?: number, // 前端自定义
    // 终点倒计时时间戳
    endPoint?: number,
    ruleText?: string,
    uid?: string,
    giftPop?: {
      type?: string,
      actPrizeVO?: Array<{
        prizeName?: string,
        prizeImg?: string,
        prizeId?: string,
      }>
    }
    // 大明星配置
    bigStartConfig?: Array<{
      prizeImg?: string,
      titleImg?: string,
      min?: number,
      max?: number,
      unlockedPrizeImg?: string,
    }>,
    // 首次体验金弹窗
    firstMoneyPop?: {
      notifyText?: string,
      experienceNum?: number,
    },
    // 模拟资产
    virtualAssets?: {
      preDayIncome?: string,
      availableFunds?: string,
      totalMoney?: string,
      realBuyJumpUrl?: string,
      totalIncome?: number,
    },
    // 签到模块
    checkIn?: {
      totalCheckIn?: number,
      todayCheckIn?: boolean, // 今日是否签到(true签到)
      totalExperienceNum?: number, // 累计可获得最高体验金数量
      checkInConfig?: Array<{
        id?: number,
        days?: number,
        experienceNum?: number,
        status?: boolean, // true已领奖
      }>,
    },
    // 推荐产品配置
    recommendProductConfig?: Array<{
      name?: string,
      shenShuGuiZei?: string,
      touZiQiXianText?: string,
      qigouText?: string,
      baiFenBiText?: string,
      fengXian?: string,
      code?: string,
      status?: string, // 0推荐,1不推荐
      realBuyJumpUrl?: string,
      mineProduct?: boolean, // 我的产品(true是)
      rate?: number, // 利率（需要除100展示）
      type?: string, // 产品类型(0-非现金，1-现金)
      totalProfit?: number, // 累计收益，mineProduct为true时有值，单位：分	
      positionMoney?: number, // 持仓金额，mineProduct为true时有值，单位：分	
    }>,
    // 待存储产品code
    codeList?: Array<{
      code?: string,
      type?: number, // 产品类型(0-非现金，1-现金)
    }>,
    endPop?: boolean,
    productEnd?: boolean, // 理财到达终点，true-是
  } = {};
  percent = 0;

  async judgeIsWhiteUser() {
    const { success, data, code, message } = await API.isWhiteUser({
      "redirectUrl": CFG.domain + CFG.index
    });
    if (success) {
      if (data) {
        location.replace(data);
      } else {
        await this.updateIndex();
      }
    } else if (code == 60001) {
      // 非白名单用户
      ModalCtrl.showModal(InvalidPop);
    } else if (code == 60002) {
      // 请绑定手机号
      ModalCtrl.showModal(Loginpop)
    } else if ((CFG.channel == CHANNEL.KUNLUN) && (code == 100001 || code == 100007 || code == 100009)) {
      // 只有昆仑银行 需要绑定手机号 其他渠道拦截登录直接出未登录toast，防止奖品被刷
      ModalCtrl.showModal(Loginpop);
    } else {
      Toast.show(errMessageMap[code] || message || '网络异常，请稍后再试')
    }
  }

  homeRoot = null;
  /*
  leftOpenTime = 0;
  leftOpenId = null;
  */
  async updateIndex() {
    const { success, data, timeStamp } = await API.index();
    if (!success) {
      return;
    }
    const resData = data || {}
    resData.currentTime = timeStamp;
    this.indexData = resData;

    const { firstMoneyPop, endPop, checkIn, codeList, giftPop, redRainConfig } = resData

    // 计算进度条百分比
    if (checkIn?.checkInConfig && checkIn?.totalCheckIn !== undefined) {
      this.percent = this.calculateProgressPercent(checkIn.checkInConfig, checkIn.totalCheckIn);
      console.log(`当前签到${checkIn.totalCheckIn}天，进度条百分比: ${this.percent.toFixed(1)}%`);
    } else {
      this.percent = 0;
    }

    // 防止奖品被刷 禁止微信端访问了 这个弹窗不会出了 配置项控制
    if (endPop) {
      ModalCtrl.showModal(Tipspop);
    }

    // 更新产品信息
    if (codeList?.length && CFG.channel == CHANNEL.HXLC) {
      this.updateFundInfo(codeList)
    }

    if (giftPop && giftPop?.todayPopFlag) {
      ModalCtrl.showModal(NewbieModal, { type: giftPop?.type, actPrizeVO: giftPop?.actPrizeVO })
    }

    if (redRainConfig?.canJoin) {
      // 在时间段内，显示红包雨弹窗
      ModalCtrl.showModal(RedPackRainModal, { redRainId: redRainConfig?.redRainId });
    }

    if (firstMoneyPop) {
      ModalCtrl.showModal(FirstPop, firstMoneyPop);
    }
  }

  /*
  judgeRedModal() {
    const redRainConfig = this.indexData?.redRainConfig
    // 红包雨时间段判断
    const everyJoinStatus = redRainConfig?.some(item => !item?.joinStatus);
    if (everyJoinStatus) {
      const len = redRainConfig?.length;
      for (let i = 0; i < len; i++) {
        const redItem = redRainConfig?.[i];
        const redStart = getTimeStamp(redItem?.startTime);
        const redEnd = getTimeStamp(redItem?.endTime);

        // 看看是不是在开始的场次之前 那就直接等最开始的倒计时就行了
        if (this.indexData.currentTime < redStart) {
          this.leftOpenTime = redStart - this.indexData.currentTime;
          break;
        }

        if (this.indexData.currentTime >= redStart && this.indexData.currentTime <= redEnd && !redItem?.joinStatus) {
          // 在时间段内，显示红包雨弹窗
          ModalCtrl.showModal(RedPackRainModal, { redRainId: redItem?.rainId });
          break;
        }

        // 看看是不是最后一场之后 那就直接等第二天的时间
        if (this.indexData.currentTime > redEnd && i == len - 1) {
          const firstStart = getTimeStamp(redRainConfig?.[0]?.startTime);
          this.leftOpenTime = firstStart + 24 * 60 * 60 * 1000 - this.indexData.currentTime;
          break;
        }
      }

      if (this.leftOpenTime > 0) {
        this.leftOpenId = setTimeout(async () => {
          await this.updateIndex();
          this.judgeRedModal();
          clearTimeout(this.leftOpenId);
          this.leftOpenId = null;
          this.leftOpenTime = 0;
        }, this.leftOpenTime)
      }
    }
  }
  */

  /**
   * 更新某些基金信息
   * @param fundcodeList 需要查询的基金code列表
   */
  async updateFundInfo(fundcodeList) {
    console.info('需要查询的基金code列表, ', fundcodeList.map(item => item.code))
    // 调客户端方法 查询产品的收益率等信息
    const adInfos = []
    for (let len = fundcodeList.length, i = 0; i < len; i++) {
      const res = await queryAppFundDetail(fundcodeList[i])
      if (res) adInfos.push(res)
    }
    // 本地自测代码
    // adInfos[0] = {
    //   fundcode: '23112008P',
    //   incomeRate: '1.78%',
    //   pernetValue: '1.0690',
    // }

    // 将客户端查到的收益率 更新到产品列表中
    const _temp = JSON.parse(JSON.stringify(this.indexData))
    _temp.recommendProductConfig = _temp.recommendProductConfig?.map(item => {
      const _adInfo = adInfos.find(adInfo => adInfo.fundcode == item.code)
      if (_adInfo) {
        item.rate = (_adInfo.incomeRate.replace('%', '') || 0) * 10000 / 100
        return item
      }
      return item
    })
    this.indexData = _temp;
    console.info('基金产品收益率信息(客户端更新后的), ', toJS(this.indexData))

    if (!adInfos?.length) return
    // 将客户端查到的收益率 更新我们后端
    const _codeList = adInfos.map(item => {
      return {
        code: item.fundcode, // 产品code
        incomeRate: (item.incomeRate.replace('%', '') || 0) * 10000 / 100, // 年化率(单位：分),例如：1.78%传递178
        netValue: (item.pernetValue || 0) * 1000000 / 100, // 净值(单位：分),例如:1.66传递16600
      }
    })
    const params = {
      codeList: _codeList,
    }
    console.info('coop_codeUpdate入参，', params)
    API.coop_codeUpdate(params)
  }

  /**
   * 计算不均匀进度条百分比
   * 进度条一共固定4个节点，每个节点的百分比为：0-13 24-38 49-63 74-90
   * 节点之间的空白间隔不计入进度范围
   * @param checkInConfig 签到配置数组
   * @param totalCheckIn 总签到天数
   * @returns 进度条百分比
   */
  calculateProgressPercent(checkInConfig: Array<{ days: number }>, totalCheckIn: number): number {
    if (!checkInConfig || checkInConfig.length === 0 || totalCheckIn === 0) {
      return 0;
    }

    // 进度条节点配置：每个节点的起始和结束百分比
    const progressNodes = [
      { start: 0, end: 13 },   // 节点1: 0-13%
      { start: 24, end: 38 },  // 节点2: 24-38%
      { start: 49, end: 63 },  // 节点3: 49-63%
      { start: 74, end: 90 }   // 节点4: 74-90%
    ];

    // 找到当前签到天数对应的节点
    let currentNode = 0;
    for (let i = 0; i < checkInConfig.length; i++) {
      if (totalCheckIn >= checkInConfig[i].days) {
        currentNode = i;
      } else {
        break;
      }
    }

    // 如果已经完成所有节点
    if (currentNode >= progressNodes.length - 1) {
      return progressNodes[progressNodes.length - 1].end;
    }

    // 获取当前节点的配置
    const currentNodeConfig = progressNodes[currentNode];
    const currentDays = checkInConfig[currentNode].days;

    // 如果当前签到天数等于当前节点要求的天数，返回节点结束百分比
    if (totalCheckIn === currentDays) {
      return currentNodeConfig.end;
    }

    // 如果当前签到天数大于当前节点要求的天数，计算在下一个节点内的进度
    if (totalCheckIn > currentDays) {
      const nextDays = currentNode + 1 < checkInConfig.length ? checkInConfig[currentNode + 1].days : currentDays;
      const nextNodeConfig = progressNodes[currentNode + 1];

      const daysDiff = nextDays - currentDays;
      const progressDiff = nextNodeConfig.end - nextNodeConfig.start;
      const extraDays = totalCheckIn - currentDays;
      const extraProgress = (extraDays / daysDiff) * progressDiff;
      const result = Math.min(nextNodeConfig.start + extraProgress, nextNodeConfig.end);

      return result;
    }

    // 如果当前签到天数小于第一个节点要求的天数，计算在第一个节点内的进度
    if (currentNode === 0 && totalCheckIn < currentDays) {
      const progressRatio = totalCheckIn / currentDays;
      const nodeProgress = currentNodeConfig.end - currentNodeConfig.start;
      const result = currentNodeConfig.start + (progressRatio * nodeProgress);

      return result;
    }

    // 默认返回当前节点的起始百分比
    return currentNodeConfig.start;
  }

  judgeActTime(brakeStart = true, brakeEnd = true) {
    if (brakeStart && this.indexData.currentTime < this.indexData.actStartTime) {
      Toast.show("活动未开始");
      return false
    } else if (brakeEnd && this.indexData.currentTime > this.indexData.actEndTime) {
      Toast.show("活动已结束");
      return false
    }
    return true;
  }


  /** 普通分享 */
  async initShare() {
    const domain = await getDomain();
    console.error('看下域名', domain);
    let url = `${domain || location.origin}${CFG.index}`;

    const shareInfo = this.frontVariable?.shareInfo?.[0]
    let option = {
      title: shareInfo?.title,
      // 标题
      desc: shareInfo?.desc || '',
      // 描述
      imgUrl: shareInfo?.imgUrl,
      link: url
    };

    initWx(option);
  }

  /** 邀请好友 */
  async doInvite(taskCode) {
    const domain = await getDomain();
    console.error('看下域名', domain);
    let url = `${domain || location.origin}${CFG.index}`;

    const shareInfo = this.frontVariable?.shareInfo?.[1]
    let option = {
      title: shareInfo?.title,
      // 标题
      desc: shareInfo?.desc || '',
      // 描述
      imgUrl: shareInfo?.imgUrl,
      link: url
    };

    showShareGuide();

    const res = await API.getInviteCode({ taskCode: taskCode })
    url += `&inviteCode=${res.data.inviteCode}`;

    initWx(option);
  }

  async doAssist() {
    let inviteCode = getUrlParam('inviteCode')
    if (!inviteCode || inviteCode == 'null' || inviteCode == 'undefined') return false;
    const { success, message, code } = await API.doAssist({ inviteCode: inviteCode });
    history.replaceState({}, '', location.href.replace(new RegExp(`[?&]inviteCode=[^&]*`), ''));
  }

}

export default (new Store());
