import { useState, useEffect, useRef, useId } from "react";
import { View, Text, Image, Button, Canvas } from "@tarojs/components";
import Taro, { useRouter, useShareAppMessage } from "@tarojs/taro";
import dayjs from "dayjs";
import classnames from "classnames";
import { withAuth, RadarChart } from "@/components";
import evaluateService, {
  LastTimeTestResult,
  Question,
  TestResultData,
} from "@/services/evaluateService";
import { useUserInfo, useUserActions } from "@/store/userStore";
import { useEvaluate, EvaluateScene } from "@/store/evaluateStore";
import { delay, getCurrentFullPath } from "@/utils";
import CloseIcon from "@/static/ntrp/ntrp_close_icon.svg";
import DocCopy from "@/static/ntrp/ntrp_doc_copy.svg";
import ArrowRight from "@/static/ntrp/ntrp_arrow_right.svg";
import ArrowBack from "@/static/ntrp/ntrp_arrow_back.svg";
import CircleChecked from "@/static/ntrp/ntrp_circle_checked.svg";
import CircleUnChecked from "@/static/ntrp/ntrp_circle_unchecked.svg";
import WechatIcon from "@/static/ntrp/ntrp_wechat.svg";
import DownloadIcon from "@/static/ntrp/ntrp_download.svg";
import ReTestIcon from "@/static/ntrp/ntrp_re-action.svg";
import styles from "./index.module.scss";

enum StageType {
  INTRO = "intro",
  TEST = "test",
  RESULT = "result",
}

const sourceTypeToTextMap = new Map([
  [EvaluateScene.detail, "继续加入球局"],
  [EvaluateScene.publish, "继续发布球局"],
]);

function adjustRadarLabels(
  source: [string, number][],
  topK: number = 4 // 默认挑前4个最长的标签保护
): [string, number][] {
  if (source.length === 0) return source;

  // 复制并按长度排序（降序）
  let sorted = [...source].sort((a, b) => b[0].length - a[0].length);

  // 取出前 K 个最长标签
  let protectedLabels = sorted.slice(0, topK);
  // 其他标签（保持原始顺序，但排除掉 protected）
  let protectedSet = new Set(protectedLabels.map(([l]) => l));
  let others = source.filter(([l]) => !protectedSet.has(l));

  let n = source.length;
  let result: ([string, number] | undefined)[] = new Array(n);

  // 放首尾
  result[0] = protectedLabels.shift() || others.shift();
  result[n - 1] = protectedLabels.shift() || others.shift();

  // 放中间（支持偶数两个位置）
  if (n % 2 === 0) {
    let mid1 = n / 2 - 1;
    let mid2 = n / 2;
    result[mid1] = protectedLabels.shift() || others.shift();
    result[mid2] = protectedLabels.shift() || others.shift();
  } else {
    let mid = Math.floor(n / 2);
    result[mid] = protectedLabels.shift() || others.shift();
  }

  // 把剩余标签按顺序塞进空位
  let pool = [...protectedLabels, ...others];
  for (let i = 0; i < n; i++) {
    if (!result[i]) result[i] = pool.shift();
  }

  return result as [string, number][];
}

function isEmptyArrowFunction(fn) {
  return (
    typeof fn === "function" &&
    !fn.hasOwnProperty("prototype") && // 排除普通函数
    fn.toString().replace(/\s+/g, "") === "()=>{}"
  );
}

function CommonGuideBar(props) {
  const { title, confirm } = props;
  const { onCancel } = useEvaluate();
  // const userInfo = useUserInfo()

  function handleClose() {
    //TODO: 二次确认
    if (confirm) {
    }
    try {
      if (isEmptyArrowFunction(onCancel)) {
        Taro.redirectTo({ url: "/game_pages/list/index" });
      }
      onCancel();
    } catch {
      Taro.redirectTo({ url: "/game_pages/list/index" });
    }
  }

  return (
    <View className={styles.header}>
      <View className={styles.closeIcon} onClick={handleClose}>
        <Image className={styles.closeImg} src={CloseIcon} />
      </View>
      <View className={styles.title}>
        <Text>{title}</Text>
      </View>
    </View>
  );
}

function Intro() {
  const [ntrpData, setNtrpData] = useState<LastTimeTestResult>();
  const userInfo = useUserInfo();
  const { fetchUserInfo } = useUserActions();
  const [ready, setReady] = useState(false);
  const { setCallback } = useEvaluate();

  const { last_test_result: { ntrp_level, create_time, id } = {} } =
    ntrpData || {};
  const lastTestTime = dayjs(create_time).format("YYYY年M月D日");

  useEffect(() => {
    getLastResult();
  }, []);

  async function getLastResult() {
    const res = await evaluateService.getLastResult();
    if (res.code === 0) {
      setNtrpData(res.data);
      if (res.data.has_ntrp_level) {
        fetchUserInfo();
      }
      setReady(true);
    }
  }
  if (!ready) {
    return "";
  }

  function handleNext(type) {
    setCallback({
      type: EvaluateScene.share,
      next: () => {
        Taro.redirectTo({ url: "/game_pages/list/index" });
      },
      onCancel: () => {
        Taro.redirectTo({ url: "/game_pages/list/index" });
        // if (userInfo.id) {
        //   Taro.redirectTo({ url: "/game_pages/list/index" });
        // } else {
        //   Taro.exitMiniProgram();
        // }
      },
    });
    Taro.redirectTo({
      url: `/other_pages/ntrp-evaluate/index?stage=${type}${
        type === StageType.RESULT ? `&id=${id}` : ""
      }`,
    });
  }

  return (
    <View className={styles.introContainer}>
      <CommonGuideBar />
      {ntrpData?.has_ntrp_level ? (
        <View className={styles.result}>
          <View className={styles.avatarWrap}>
            <View className={styles.avatar}>
              <Image
                className={styles.avatarUrl}
                src={userInfo.avatar_url}
                mode="aspectFill"
              />
            </View>
            {/* avatar side */}
            <View className={styles.addonImage}>
              <Image
                className={styles.docImage}
                src={DocCopy}
                mode="aspectFill"
              />
            </View>
          </View>
          {/* tip */}
          <View className={styles.tip}>
            <Image
              className={styles.tipImage}
              src="http://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/b7cb47aa-b609-4112-899f-3fde02ed2431.png"
              mode="aspectFit"
            />
          </View>
          <View className={styles.lastResult}>
            <View className={styles.tipAndTime}>
              <Text>上次测试结果</Text>
              <Text>{lastTestTime}</Text>
            </View>
            <View className={styles.levelWrap}>
              <Text>NTRP</Text>
              <Text className={styles.level}>{ntrp_level}</Text>
            </View>
            <View className={styles.slogan}>
              <Text>变线+网前，下一步就是赢比赛！</Text>
            </View>
          </View>
          <View className={styles.actions}>
            <View className={styles.buttonWrap}>
              <Button
                className={classnames(styles.button, styles.primary)}
                type="primary"
                onClick={() => handleNext(StageType.TEST)}
              >
                <Text>再次测试</Text>
                <Image className={styles.arrowImage} src={ArrowRight} />
              </Button>
            </View>
            <View className={styles.buttonWrap}>
              <Button
                className={styles.button}
                onClick={() => handleNext(StageType.RESULT)}
              >
                <Text>继续使用上次测试结果</Text>
              </Button>
            </View>
          </View>
        </View>
      ) : (
        <View className={styles.guide}>
          {/* tip */}
          <View className={styles.tip}>
            <Image
              className={styles.tipImage}
              src="http://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/b7cb47aa-b609-4112-899f-3fde02ed2431.png"
              mode="aspectFit"
            />
          </View>
          {/* radar */}
          <View className={styles.radar}>
            <Image
              className={styles.radarImage}
              src="http://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/a2e1b639-82a9-4ab8-b767-8605556eafcb.png"
              mode="aspectFit"
            />
          </View>
          <View className={styles.desc}>
            <Text>
              NTRP（National Tennis Rating
              Program）是一种常用的网球水平分级系统，这不是绝对精准的“分数”，而是一个参考标准，能够帮助你更清晰地了解自己的网球水平，从而在训练、比赛或娱乐活动中找到「难度合适」的球友，避免过度碾压或被碾压。
            </Text>
          </View>
          <View className={styles.actions}>
            <View className={styles.buttonWrap}>
              <Button
                className={classnames(styles.button, styles.primary)}
                type="primary"
                onClick={() => handleNext(StageType.TEST)}
              >
                <Text>开始测试</Text>
                <Image className={styles.arrowImage} src={ArrowRight} />
              </Button>
            </View>
          </View>
        </View>
      )}
    </View>
  );
}

function Test() {
  const [disabled, setDisabled] = useState(false);
  const [index, setIndex] = useState(0);
  const [questions, setQuestions] = useState<
    (Question & { choosen: number })[]
  >([]);
  const startTimeRef = useRef<number>(0);

  useEffect(() => {
    startTimeRef.current = Date.now();
    getQUestions();
  }, []);

  useEffect(() => {
    setDisabled(questions[index]?.choosen === -1);
  }, [index, questions]);

  async function getQUestions() {
    const res = await evaluateService.getQuestions();
    if (res.code === 0) {
      setQuestions(res.data.map((item) => ({ ...item, choosen: 3 })));
    }
  }

  function handleSelect(i) {
    setQuestions((prev) =>
      prev.map((item, pIndex) => ({
        ...item,
        ...(pIndex === index ? { choosen: i } : {}),
      }))
    );
  }

  async function handleSubmit() {
    setDisabled(true);
    try {
      const res = await evaluateService.submit({
        answers: questions.map((item) => ({
          question_id: item.id,
          answer_index: item.choosen,
        })),
        test_duration: (Date.now() - startTimeRef.current) / 1000,
      });
      if (res.code === 0) {
        Taro.redirectTo({
          url: `/other_pages/ntrp-evaluate/index?stage=${StageType.RESULT}&id=${res.data.record_id}`,
        });
      }
    } catch (e) {
      Taro.showToast({ title: e.message, icon: "error" });
    } finally {
      setDisabled(false);
    }
  }

  function handIndexChange(direction) {
    console.log(disabled, direction);
    if (disabled && direction > 0) {
      return;
    }
    if (index === questions.length - 1 && direction > 0) {
      handleSubmit();
      return;
    }
    setIndex((prev) => prev + direction);
  }

  const question = questions[index];
  if (!question) {
    return "";
  }
  return (
    <View className={styles.testContainer}>
      <CommonGuideBar confirm title={`${index + 1} / ${questions.length}`} />
      <View className={styles.bar}>
        <View
          className={styles.progressBar}
          style={{ width: `${100 * ((index + 1) / questions.length)}%` }}
        />
      </View>
      <View className={styles.notice}>
        <Text>根据近3个月实际表现勾选最符合项</Text>
      </View>
      <View className={styles.question}>
        <View className={styles.content}>{question.question_content}</View>
        <View className={styles.options}>
          {question.options.map((item, i) => {
            const checked = question.choosen === i;
            return (
              <View
                key={i}
                className={styles.optionItem}
                onClick={() => handleSelect(i)}
              >
                <View className={styles.optionText}>{item.text}</View>
                <View className={styles.optionIcon}>
                  <Image
                    className={styles.icon}
                    src={checked ? CircleChecked : CircleUnChecked}
                  />
                </View>
              </View>
            );
          })}
        </View>
      </View>
      <View className={styles.actions}>
        <View
          className={classnames(styles.next, disabled ? styles.disabled : "")}
          onClick={() => handIndexChange(1)}
        >
          <Button className={styles.nextBtn} type="primary">
            {index === questions.length - 1 ? "完成测试" : "继续"}
          </Button>
        </View>
        {index !== 0 && (
          <View className={styles.prev} onClick={() => handIndexChange(-1)}>
            <Image className={styles.backIcon} src={ArrowBack} />
            <Text>返回</Text>
          </View>
        )}
      </View>
    </View>
  );
}

function Result() {
  const { params } = useRouter();
  const { id } = params;
  const userInfo = useUserInfo();
  const { fetchUserInfo } = useUserActions();
  const { type, next, clear } = useEvaluate();
  const radarRef = useRef();

  const [result, setResult] = useState<TestResultData>();
  const [radarData, setRadarData] = useState<
    [propName: string, prop: number][]
  >([]);

  useEffect(() => {
    getResultById();
    fetchUserInfo();
  }, []);

  async function getResultById() {
    const res = await evaluateService.getTestResult({ record_id: Number(id) });
    if (res.code === 0) {
      setResult(res.data);
      setRadarData(
        adjustRadarLabels(
          Object.entries(res.data.radar_data.abilities).map(([key, value]) => [
            key,
            value.current_score,
          ])
        )
      );
      updateUserLevel(res.data.record_id, res.data.ntrp_level);
    }
  }

  function updateUserLevel(record_id, ntrp_level) {
    try {
      evaluateService.updateNtrp({
        record_id,
        ntrp_level,
        update_type: "test_result",
      });
    } catch (e) {
      Taro.showToast({ title: e.message, icon: "none" });
    }
  }

  function handleReTest() {
    Taro.redirectTo({
      url: `/other_pages/ntrp-evaluate/index?stage=${StageType.TEST}`,
    });
  }

  function handleViewGames() {
    Taro.redirectTo({
      url: "/game_pages/list/index",
    });
  }

  async function handleGoon() {
    if (type) {
      next();
      await delay(1500);
      clear();
    } else {
      handleViewGames();
    }
  }

  async function genCardImage() {
    return new Promise(async (resolve, reject) => {
      const url = await radarRef.current.generateImage();
      const query = Taro.createSelectorQuery();
      query
        .select("#exportCanvas")
        .fields({ node: true, size: true })
        .exec((res2) => {
          const canvas = res2[0].node;
          const ctx = canvas.getContext("2d");
          const dpr = Taro.getSystemInfoSync().pixelRatio;
          const width = 300;
          const height = 400;
          canvas.width = width * dpr;
          canvas.height = height * dpr;
          ctx.scale(dpr, dpr);

          // 背景
          ctx.fillStyle = "#e9fdf8";
          ctx.fillRect(0, 0, width, height);

          // 标题文字
          ctx.fillStyle = "#000";
          ctx.font = "16px sans-serif";
          ctx.fillText("你的 NTRP 测试结果为", 20, 40);
          ctx.fillStyle = "#00E5AD";
          ctx.font = "bold 22px sans-serif";
          ctx.fillText(`NTRP ${result?.ntrp_level}`, 20, 70);

          // 绘制雷达图
          const img = canvas.createImage();
          img.src = url;
          img.onload = () => {
            ctx.drawImage(img, 20, 100, 260, 260);

            // 第三步：导出最终卡片
            Taro.canvasToTempFilePath({
              canvas,
              success: (res3) => {
                console.log("导出成功:", res3.tempFilePath);
                resolve(res3.tempFilePath);
              },
            });
          };
        });
    });
  }

  async function handleSaveImage() {
    if (!userInfo.id) {
      return;
    }
    const url = await genCardImage();
    Taro.saveImageToPhotosAlbum({ filePath: url });
  }

  useShareAppMessage(async (res) => {
    const url = await genCardImage();
    console.log(res, "res");
    return {
      title: "分享",
      imageUrl: url,
      path: `/other_pages/ntrp-evaluate/index?stage=${StageType.INTRO}`,
    };
  });

  function handleAuth() {
    if (userInfo.id) {
      return true;
    }
    const currentPage = getCurrentFullPath();
    Taro.redirectTo({
      url: `/login_pages/index/index${
        currentPage ? `?redirect=${encodeURIComponent(currentPage)}` : ""
      }`,
    });
  }

  return (
    <View className={styles.resultContainer}>
      <CommonGuideBar />
      <View className={styles.card}>
        <View className={styles.avatarWrap}>
          <View className={styles.avatar}>
            <Image
              className={styles.avatarUrl}
              src={userInfo.avatar_url}
              mode="aspectFit"
            />
          </View>
          {/* avatar side */}
          <View className={styles.addonImage}>
            <Image
              className={styles.docImage}
              src={DocCopy}
              mode="aspectFill"
            />
          </View>
        </View>
        <View className={styles.desc}>
          <View className={styles.tip}>
            <Text>你的 NTRP 测试结果为</Text>
          </View>
          <View className={styles.levelWrap}>
            <Text>NTRP</Text>
            <Text className={styles.level}>{result?.ntrp_level}</Text>
          </View>
          <View className={styles.slogan}>
            <Text>变线+网前，下一步就是赢比赛！</Text>
          </View>
        </View>
        <View>
          <RadarChart ref={radarRef} data={radarData} />
        </View>
        <View className={styles.retest} onClick={handleReTest}>
          <Image className={styles.re_actIcon} src={ReTestIcon} />
          <Text>重新测试</Text>
        </View>
      </View>
      {userInfo.id ? (
        <View className={styles.updateTip}>
          <Text>你的 NTRP 水平已更新为 {result?.ntrp_level} </Text>
          <Text className={styles.grayTip}>(可在个人信息中修改)</Text>
        </View>
      ) : (
        <View className={styles.updateTip}>
          <Text>登录「有场」小程序，查看匹配你的球局</Text>
        </View>
      )}
      <View className={styles.actions}>
        <View className={styles.viewGame} onClick={handleGoon}>
          <Button className={styles.viewGameBtn}>
            {sourceTypeToTextMap.get(type) || "去看看球局"}
          </Button>
        </View>
        <View className={styles.otherActions}>
          <View className={styles.share}>
            <Button
              className={styles.shareBtn}
              openType={userInfo.id ? "share" : undefined}
              onClick={handleAuth}
            >
              <Image className={styles.wechatIcon} src={WechatIcon} />
              <Text>邀请好友测试</Text>
            </Button>
          </View>
          <View className={styles.saveImage} onClick={handleSaveImage}>
            <Button className={styles.saveImageBtn}>
              <Image className={styles.downloadIcon} src={DownloadIcon} />
              <Text>保存图片</Text>
            </Button>
          </View>
        </View>
      </View>
      <Canvas
        type="2d"
        id="exportCanvas"
        style={{
          width: "0px",
          height: "0px",
          position: "absolute",
          left: "-9999px",
        }}
      />
    </View>
  );
}

const ComponentsMap = {
  [StageType.INTRO]: Intro,
  [StageType.TEST]: Test,
  [StageType.RESULT]: Result,
};

function NtrpEvaluate() {
  // const { updateUserInfo } = useUserActions();
  const { params } = useRouter();
  // const { redirect } = params;

  const stage = params.stage as StageType;

  // async function handleUpdateNtrp() {
  //   await updateUserInfo({
  //     ntrp_level: "4.0",
  //   });
  //   Taro.showToast({
  //     title: "更新成功",
  //     icon: "success",
  //     duration: 2000,
  //   });
  //   await delay(2000);
  //   if (redirect) {
  //     Taro.redirectTo({ url: decodeURIComponent(redirect) });
  //   }
  // }

  const Component = ComponentsMap[stage];

  return <Component />;
}

export default withAuth(NtrpEvaluate);
