import { useEffect, useImperativeHandle, forwardRef } from "react";
import { Canvas } from "@tarojs/components";
import Taro from "@tarojs/taro";

function getImageWh(src): Promise<{ width: number; height: number }> {
  return new Promise((resolve) => {
    Taro.getImageInfo({
      src,
      success: ({ width, height }) => resolve({ width, height }),
    });
  });
}

const qrCodeUrl =
  "https://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/5e013195-fc79-4082-bf06-9aa79aea65ae.png";

const ringUrl =
  "https://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/b635164f-ecec-434a-a00b-69614a918f2f.png";

const dateIcon =
  "https://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/1b49476e-0eda-42ff-b08c-002ce510df82.jpg";

const mapIcon =
  "https://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/06b994fa-9227-4708-8555-8a07af8d0c3b.jpg";

// const logo = "http://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/fb732da6-11b9-4022-a524-a377b17635eb.jpg"

const logoText =
  "https://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/9d8cbc9d-9601-4e2d-ab23-76420a4537d6.png";

const Poster = (props, ref) => {
  const { data } = props;
  const {
    playType,
    ntrp,
    mainCoursal,
    nickname,
    avatarUrl,
    title,
    locationName,
    date,
    time,
  } = data;
  useEffect(() => {
    drawCard();
  }, []);

  useImperativeHandle(ref, () => ({
    generateImage: () =>
      new Promise((resolve, reject) => {
        const query = Taro.createSelectorQuery();
        query
          .select("#cardCanvas")
          .fields({ node: true, size: true })
          .exec((res) => {
            const canvas = res[0].node;
            // ⚠️ 关键：传 canvas，而不是 canvasId
            Taro.canvasToTempFilePath({
              canvas,
              success: (res) => resolve(res.tempFilePath),
              fail: (err) => reject(err),
            });
          });
      }),
  }));

  const drawCard = async () => {
    const query = Taro.createSelectorQuery();
    query
      .select("#cardCanvas")
      .fields({ node: true, size: true })
      .exec(async (res) => {
        const canvas = res[0].node;
        const ctx = canvas.getContext("2d");
        const dpr = Taro.getWindowInfo().pixelRatio;
        const width = 600; // px
        const height = 1000;

        canvas.width = width * dpr;
        canvas.height = height * dpr;
        ctx.scale(dpr, dpr);

        // 背景卡片
        // roundRect(ctx, 0, 0, width, height, 20, "#fff");

        // 整体背景
        roundRectGradient(ctx, 0, 0, width, height, 24, "#BFFFEF", "#F2FFFC");

        // 顶部图片
        const img = await loadImage(canvas, mainCoursal);
        // roundRect(ctx, 20, 20, width - 40, width - 40, 20, "#fff");
        await drawCoverImage(
          ctx,
          mainCoursal,
          img,
          10,
          10,
          width - 20,
          width - 20,
          20
        );

        // 标签
        let left = drawTag(ctx, playType, 18, 18);
        drawTag(ctx, ntrp, left + 4, 18);

        let top = width - 10;
        left = 16;

        top += 16;

        // 用户头像（圆形）
        const avatar = await loadImage(canvas, avatarUrl);
        ctx.save();
        ctx.beginPath();
        ctx.arc(left + 30, top + 30, 30, 0, Math.PI * 2);
        ctx.clip();
        ctx.drawImage(avatar, left, top, 60, 60);
        ctx.restore();

        // 头像右边 6
        left += 66;

        top += 40;

        // 用户名 + 邀请
        ctx.fillStyle = "#333";
        ctx.font = "bold 28px sans-serif";
        // ctx.fillText("华巴轮卡 邀你加入球局", 100, 370);
        const nickNameText = `${nickname} 邀你加入`;
        ctx.fillText(nickNameText, left, top);
        let textW = ctx.measureText(nickNameText).width;
        left += textW;
        ctx.fillStyle = "#00B578";
        ctx.fillText("球局", left, top);
        const ringImg = await loadImage(canvas, ringUrl);
        ctx.drawImage(ringImg, left - 10, top - 30, 80, 36);

        left = 16;
        top += 60;

        // 活动标题
        ctx.fillStyle = "#333";
        ctx.font = "bold 34px sans-serif";
        let r = drawTextWrap(ctx, title, left, top, width - 32, 40);

        top = r.top + 40;
        left = 16;
        const dateImg = await loadImage(canvas, dateIcon);
        await drawCoverImage(ctx, dateIcon, dateImg, left, top, 40, 40, 8);

        left += 40 + 8;

        top += 30;

        // 时间
        ctx.font = "26px sans-serif";
        ctx.fillStyle = "#00B578";
        ctx.fillText(date, left, top);
        textW = ctx.measureText(date).width;
        left += 8 + textW;
        ctx.fillStyle = "#333";
        ctx.fillText(time, left, top);

        left = 16;
        top += 24;
        const mapImg = await loadImage(canvas, mapIcon);
        await drawCoverImage(ctx, dateIcon, mapImg, left, top, 40, 40, 8);

        left += 40 + 8;
        top += 30;

        // 地址
        ctx.fillStyle = "#666";
        ctx.font = "26px sans-serif";
        r = drawTextWrap(ctx, locationName, left, top, width - 32 - left, 34);

        left = 16;
        top = r.top + 60;

        const logoWh = await getImageWh(logoText);
        console.log(logoWh);
        const logoTextImg = await loadImage(canvas, logoText);
        ctx.drawImage(
          logoTextImg,
          left,
          top,
          400,
          // 56
          400 / (logoWh.width / logoWh.height)
        );

        const qrImg = await loadImage(canvas, qrCodeUrl);
        ctx.drawImage(qrImg, width - 12 - 150, top - 50, 160, 160);

        left = 16;
        top += 400 / (logoWh.width / logoWh.height) + 30;

        // 底部文字
        ctx.fillStyle = "#333";
        ctx.font = "20px sans-serif";
        ctx.fillText("长按识别二维码，快来加入，有你就有场！", left, top);

        // 小程序码
        // const qrcode = await loadImage(canvas, "小程序码路径");
        // ctx.drawImage(qrcode, 480, 880, 100, 100);

        // 导出图片
        // Taro.canvasToTempFilePath({
        //   canvas,
        //   success: (res) => {
        //     console.log("导出路径", res.tempFilePath);
        //   },
        //   fail: (err) => console.error(err),
        // });
      });
  };

  const roundRectGradient = (ctx, x, y, w, h, r, color1, color2) => {
    const gradient = ctx.createLinearGradient(x, y, x, y + h);
    gradient.addColorStop(0, color1);
    gradient.addColorStop(1, color2);

    ctx.beginPath();
    ctx.moveTo(x + r, y);
    ctx.lineTo(x + w - r, y);
    ctx.arcTo(x + w, y, x + w, y + r, r);
    ctx.lineTo(x + w, y + h - r);
    ctx.arcTo(x + w, y + h, x + w - r, y + h, r);
    ctx.lineTo(x + r, y + h);
    ctx.arcTo(x, y + h, x, y + h - r, r);
    ctx.lineTo(x, y + r);
    ctx.arcTo(x, y, x + r, y, r);
    ctx.closePath();

    ctx.fillStyle = gradient;
    ctx.fill();
  };

  const drawCoverImage = async (ctx, src, img, x, y, w, h, r = 0) => {
    const { width, height } = await getImageWh(src);
    const imgW = width;
    const imgH = height;

    // 计算缩放比例，取较大值，保证完全覆盖
    const scale = Math.max(w / imgW, h / imgH);

    // 缩放后的宽高
    const newW = imgW * scale;
    const newH = imgH * scale;

    // 居中偏移
    const offsetX = x + (w - newW) / 2;
    const offsetY = y + (h - newH) / 2;

    ctx.save();

    // 如果需要圆角
    if (r > 0) {
      ctx.beginPath();
      ctx.moveTo(x + r, y);
      ctx.lineTo(x + w - r, y);
      ctx.arcTo(x + w, y, x + w, y + r, r);
      ctx.lineTo(x + w, y + h - r);
      ctx.arcTo(x + w, y + h, x + w - r, y + h, r);
      ctx.lineTo(x + r, y + h);
      ctx.arcTo(x, y + h, x, y + h - r, r);
      ctx.lineTo(x, y + r);
      ctx.arcTo(x, y, x + r, y, r);
      ctx.closePath();
      ctx.clip();
    }

    // 绘制图片 (cover 效果)
    ctx.drawImage(img, offsetX, offsetY, newW, newH);

    ctx.restore();
  };

  /** 加载图片 */
  const loadImage = (canvas, src) => {
    return new Promise((resolve) => {
      const img = canvas.createImage();
      img.onload = () => resolve(img);
      img.src = src;
    });
  };

  /** 圆角矩形 */
  const roundRect = (ctx, x, y, w, h, r, fillStyle) => {
    ctx.beginPath();
    ctx.moveTo(x + r, y);
    ctx.lineTo(x + w - r, y);
    ctx.arcTo(x + w, y, x + w, y + r, r);
    ctx.lineTo(x + w, y + h - r);
    ctx.arcTo(x + w, y + h, x + w - r, y + h, r);
    ctx.lineTo(x + r, y + h);
    ctx.arcTo(x, y + h, x, y + h - r, r);
    ctx.lineTo(x, y + r);
    ctx.arcTo(x, y, x + r, y, r);
    ctx.closePath();
    ctx.fillStyle = fillStyle;
    ctx.fill();
  };

  /** 绘制标签 */
  const drawTag = (ctx, text, x, y) => {
    ctx.font = "22px sans-serif";
    const padding = 12;
    const textWidth = ctx.measureText(text).width;
    roundRect(ctx, x, y, textWidth + padding * 2, 40, 20, "#fff");
    ctx.fillStyle = "#333";
    ctx.fillText(text, x + padding, y + 28);
    return x + textWidth + padding * 2;
  };

  /** 文本换行 */
  const drawTextWrap = (ctx, text, x, y, maxWidth, lineHeight) => {
    let line = "";
    const lines = [];
    for (let char of text) {
      const testLine = line + char;
      if (ctx.measureText(testLine).width > maxWidth) {
        lines.push(line);
        line = char;
      } else {
        line = testLine;
      }
    }
    if (line) lines.push(line);
    lines.forEach((l, i) => {
      ctx.fillText(l, x, y + i * lineHeight);
    });
    const lastLineText = lines.at(-1);
    return {
      left: x + ctx.measureText(lastLineText),
      top: y + (lines.length - 1) * lineHeight,
    };
  };

  return (
    <Canvas
      type="2d"
      id="cardCanvas"
      style={{
        width: "600rpx",
        height: "1000rpx",
        // position: "absolute",
        // left: "-9999px",
      }}
    />
  );
};

export default forwardRef(Poster);
