import { toPng } from "html-to-image";
import type { ChangeEvent } from "react";
import { useEffect, useMemo, useRef, useState } from "react";
import type {
  CertificateFieldKey,
  CertificateFormData,
  CertificateTemplateDefinition,
} from "@/lib/certificate";
import {
  certificateFieldLabels,
  certificateFieldOrder,
  certificateTemplates,
  customTemplateUploadEnabled,
  getQrSource,
} from "@/lib/certificate";
import { fetchStats, incrementGenerationCount, type StatsResponse } from "@/lib/stats";
import { TemplateScaleFrame } from "@/templates/template-primitives";

const defaultFormData: CertificateFormData = {
  childName: "",
  familyAddress: "",
  parentName: "",
  birthDate: "",
  birthAddress: "",
};

const emptyStats: StatsResponse = {
  total: 0,
  byTemplate: {},
  updatedAt: null,
};

const previewWidth = 760;
const statsUnavailableMessage =
  "统计服务未连接，当前数量不会持久化。请同时运行 npm run dev 和 npm run dev:server，或直接运行 npm run dev:all。";
const statsIncrementFailedMessage =
  "图片已下载，但统计服务没有记录这次生成。请同时运行 npm run dev 和 npm run dev:server，或直接运行 npm run dev:all。";

function TemplateThumbnail({
  template,
  formData,
  qrSource,
  currentCount,
}: {
  template: CertificateTemplateDefinition;
  formData: CertificateFormData;
  qrSource: string;
  currentCount: number;
}) {
  const scale = 220 / template.width;
  const Component = template.Component;

  return (
    <div className="template-card__preview-shell" style={{ height: `${template.height * scale}px` }}>
      <TemplateScaleFrame width={template.width} height={template.height} scale={scale}>
        <Component formData={formData} qrSrc={qrSource} currentCount={currentCount} />
      </TemplateScaleFrame>
    </div>
  );
}

export function CertificateGenerator() {
  const [selectedTemplateId, setSelectedTemplateId] = useState(
    certificateTemplates[0]?.id ?? "",
  );
  const [formData, setFormData] = useState<CertificateFormData>(defaultFormData);
  const [stats, setStats] = useState<StatsResponse>(emptyStats);
  const [isExporting, setIsExporting] = useState(false);
  const [errorMessage, setErrorMessage] = useState("");
  const [statsMessage, setStatsMessage] = useState("");
  const exportRef = useRef<HTMLDivElement>(null);

  const selectedTemplate = useMemo(
    () =>
      certificateTemplates.find((template) => template.id === selectedTemplateId) ??
      certificateTemplates[0],
    [selectedTemplateId],
  );

  const qrSource = useMemo(() => getQrSource(), []);
  const currentCount = stats.total + 1;
  const SelectedTemplateComponent = selectedTemplate.Component;

  useEffect(() => {
    let active = true;

    fetchStats()
      .then((nextStats) => {
        if (!active) return;
        setStats(nextStats);
        setStatsMessage("");
      })
      .catch(() => {
        if (!active) return;
        setStatsMessage(statsUnavailableMessage);
      });

    return () => {
      active = false;
    };
  }, []);

  const handleChange =
    (key: CertificateFieldKey) =>
    (event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
      setFormData((current) => ({
        ...current,
        [key]: event.target.value,
      }));
    };

  const handleExport = async () => {
    if (!exportRef.current) {
      setErrorMessage("导出节点尚未准备好，请稍后重试。");
      return;
    }

    setIsExporting(true);
    setErrorMessage("");

    try {
      const dataUrl = await toPng(exportRef.current, {
        cacheBust: true,
        pixelRatio: 1,
        canvasWidth: selectedTemplate.width,
        canvasHeight: selectedTemplate.height,
        backgroundColor: "#ffffff",
      });

      const link = document.createElement("a");
      link.href = dataUrl;
      link.download = `${selectedTemplate.name}.png`;
      link.click();

      try {
        const nextStats = await incrementGenerationCount(selectedTemplate.id);
        setStats(nextStats);
        setStatsMessage("");
      } catch {
        setStatsMessage(statsIncrementFailedMessage);
      }
    } catch (error) {
      setErrorMessage(error instanceof Error ? error.message : "导出失败，请稍后重试。");
    } finally {
      setIsExporting(false);
    }
  };

  return (
    <main className="app-shell">
      <div className="page page--studio">
        <section className="panel panel--templates panel--soft">
          <div className="panel-head panel-head--inline">
            <div>
              <h2>模板切换</h2>
            </div>
          </div>
          <div className="template-strip">
            {certificateTemplates.map((template) => {
              const active = template.id === selectedTemplate.id;

              return (
                <button
                  key={template.id}
                  type="button"
                  onClick={() => setSelectedTemplateId(template.id)}
                  className={`template-card ${active ? "is-active" : ""}`}
                >
                  <div className="template-card__preview template-card__preview--component">
                    <TemplateThumbnail
                      template={template}
                      formData={formData}
                      qrSource={qrSource}
                      currentCount={currentCount}
                    />
                  </div>
                  <div className="template-card__body">
                    <div>
                      <p className="template-card__title">{template.name}</p>
                      <p className="template-card__meta">{template.width} x {template.height}</p>
                    </div>
                    <span className="template-card__tag">{active ? "当前模板" : "点击切换"}</span>
                  </div>
                </button>
              );
            })}
          </div>
        </section>

        <section className="workspace workspace--studio">
          <aside className="panel panel--fields panel--soft">
            <div className="panel-head">
              <h2>龙虾信息填写</h2>
            </div>
            <div className="form-grid">
              {certificateFieldOrder.map((key) => (
                <label key={key} className="field">
                  <span>{certificateFieldLabels[key]}</span>
                  {key === "familyAddress" || key === "birthAddress" ? (
                    <textarea
                      rows={2}
                      value={formData[key]}
                      onChange={handleChange(key)}
                      placeholder={`请输入${certificateFieldLabels[key]}`}
                    />
                  ) : (
                    <input
                      value={formData[key]}
                      onChange={handleChange(key)}
                      placeholder={`请输入${certificateFieldLabels[key]}`}
                    />
                  )}
                </label>
              ))}
            </div>

            {customTemplateUploadEnabled ? (
              <div className="panel-note">
                已开启 <code>VITE_ENABLE_CUSTOM_TEMPLATE_UPLOAD</code>，当前版本仅预留入口。
              </div>
            ) : null}
          </aside>

          <section className="panel panel--preview-shell panel--soft">
            <div className="panel-head panel-head--inline panel-head--preview">
              <div>
                <h2>图片预览</h2>
              </div>
            </div>

            {errorMessage ? <div className="error-box">{errorMessage}</div> : null}
            {statsMessage ? <div className="error-box">{statsMessage}</div> : null}

            <div className="preview-frame preview-frame--studio">
              <TemplateScaleFrame
                width={selectedTemplate.width}
                height={selectedTemplate.height}
                scale={previewWidth / selectedTemplate.width}
              >
                <SelectedTemplateComponent
                  formData={formData}
                  qrSrc={qrSource}
                  currentCount={currentCount}
                />
              </TemplateScaleFrame>
            </div>

            <div className="download-row">
              <button type="button" onClick={handleExport} disabled={isExporting}>
                {isExporting ? "导出中..." : "下载图片"}
              </button>
            </div>
          </section>
        </section>

        <div className="export-stage" aria-hidden="true">
          <div ref={exportRef}>
            <SelectedTemplateComponent
              formData={formData}
              qrSrc={qrSource}
              currentCount={currentCount}
            />
          </div>
        </div>
      </div>
    </main>
  );
}
