/* global React, html2canvas, jspdf */
const { useState: useStateO } = React;

function CopyBlock({ text }) {
  const [copied, setCopied] = useStateO(false);
  const doCopy = () => {
    const fn = navigator.clipboard && navigator.clipboard.writeText
      ? navigator.clipboard.writeText(text)
      : Promise.reject();
    fn.then(() => { setCopied(true); setTimeout(() => setCopied(false), 1600); })
      .catch(() => {
        // fallback
        const ta = document.createElement("textarea");
        ta.value = text; document.body.appendChild(ta); ta.select();
        try { document.execCommand("copy"); setCopied(true); setTimeout(() => setCopied(false), 1600); } catch (e) {}
        document.body.removeChild(ta);
      });
  };
  return (
    <div className="copyblock">
      <button className={"copy-btn" + (copied ? " copied" : "")} onClick={doCopy}>
        {copied ? "✓ コピー済み" : "⧉ コピー"}
      </button>
      {text}
    </div>
  );
}

function Section({ num, title, children }) {
  return (
    <div className="doc-section">
      <div className="ds-label">
        <div className="ds-num">{num}</div>
        <div className="ds-title">{title}</div>
      </div>
      <div className="ds-body">{children}</div>
    </div>
  );
}

function StrategyField({ label, value, strong }) {
  return (
    <div className={"strategy-field" + (strong ? " is-strong" : "")}>
      <div className="strategy-field__label">{label}</div>
      <div className="strategy-field__value">{value}</div>
    </div>
  );
}

function StoryBlock({ story }) {
  const blocks = Array.isArray(story)
    ? story.filter(Boolean)
    : (story ? [story] : []);
  if (!blocks.length) return null;
  return (
    <div className="story">
      {blocks.map((paragraph, i) => <p key={i}>{paragraph}</p>)}
    </div>
  );
}

function Output({ result, status, onRestart, onEdit, onRegenerate }) {
  const allVariants = Array.isArray(result.variants) && result.variants.length ? result.variants : [result];
  const variants = result.source === "gemini-experiment"
    ? allVariants.filter((variant) => variant.angle === "gemini")
    : allVariants;
  const [selectedIndex, setSelectedIndex] = useStateO(0);
  const r = variants[Math.min(selectedIndex, variants.length - 1)] || result;
  const [saving, setSaving] = useStateO(false);
  const safeName = (r.name || "branding").replace(/[\\/:*?"<>|\s]+/g, "-").replace(/^-+|-+$/g, "") || "branding";
  const forcedGate = result.qualityGate?.forcedCount ? ` forced=${result.qualityGate.forcedCount}` : "";
  const sourceMeta = result.source === "gemini-experiment"
    ? `Gemini実験生成・${result.model || "gemini"}${result.qualityGate ? ` / 品質ゲート accepted=${result.qualityGate.acceptedCount} rejected=${result.qualityGate.rejectedCount}${forcedGate}` : ""}`
    : result.source === "workers-ai-experiment"
      ? `Workers AI実験生成・${result.model || "workers-ai"}`
      : result.qualityFallback?.provider === "gemini"
        ? `Writer/Criticローカル生成・Gemini品質ゲートfallback rejected=${result.qualityFallback.rejectedCount}`
      : result.source === "local-writer-critic"
          ? "Writer/Criticローカル生成・外部API不要"
          : "テンプレートフォールバックで生成";
  const gateMeta = result.source === "gemini-experiment"
    ? (result.qualityGate?.forcedCount ? "Gemini品質ゲート: rescued / Gemini品質ゲート救済採用" : "Gemini品質ゲート: passed")
    : result.qualityFallback?.provider === "gemini"
      ? `Gemini品質ゲート: failed / local fallback / rejected=${result.qualityFallback.rejectedCount}`
      : "Gemini品質ゲート: not used / local generation";
  const onSavePdf = async () => {
    if (saving) return;
    if (!window.html2canvas || !window.jspdf) {
      alert("PDF保存の準備が完了していません。少し待ってからもう一度お試しください。");
      return;
    }

    setSaving(true);
    try {
      const docNode = document.querySelector(".doc");
      const actionButtons = Array.from(document.querySelectorAll(".copy-btn, .doc-foot"));
      actionButtons.forEach((node) => node.classList.add("pdf-hidden"));

      const canvas = await html2canvas(docNode, {
        scale: Math.min(window.devicePixelRatio || 1, 2),
        backgroundColor: "#EEF5FA",
        useCORS: true,
      });
      actionButtons.forEach((node) => node.classList.remove("pdf-hidden"));

      const pdf = new jspdf.jsPDF("p", "mm", "a4");
      const pageWidth = pdf.internal.pageSize.getWidth();
      const pageHeight = pdf.internal.pageSize.getHeight();
      const margin = 10;
      const imgWidth = pageWidth - margin * 2;
      const imgHeight = (canvas.height * imgWidth) / canvas.width;
      const imgData = canvas.toDataURL("image/jpeg", 0.96);

      let y = margin;
      let remainingHeight = imgHeight;
      pdf.addImage(imgData, "JPEG", margin, y, imgWidth, imgHeight);
      remainingHeight -= pageHeight - margin * 2;

      while (remainingHeight > 0) {
        pdf.addPage();
        y = margin - (imgHeight - remainingHeight);
        pdf.addImage(imgData, "JPEG", margin, y, imgWidth, imgHeight);
        remainingHeight -= pageHeight - margin * 2;
      }

      pdf.save(`${safeName}-brand-message.pdf`);
    } catch (e) {
      alert("PDFの保存に失敗しました。時間を置いてもう一度お試しください。");
    } finally {
      document.querySelectorAll(".pdf-hidden").forEach((node) => node.classList.remove("pdf-hidden"));
      setSaving(false);
    }
  };
  return (
    <div className="output fade-in">
      <div className="output-bar">
        <div className="output-bar-inner">
          <div className="ob-left">
            <div className="mark">B</div>
            <span>ブランド出力</span>
          </div>
          <div className="ob-actions">
            <button className="btn btn-ghost" onClick={onEdit} style={{ padding: "11px 18px", fontSize: 14 }}>入力を修正</button>
            <button className="btn btn-ghost" onClick={onRegenerate} style={{ padding: "11px 18px", fontSize: 14 }}>再生成</button>
            <button className="btn btn-gold" onClick={onSavePdf} disabled={saving} style={{ padding: "12px 22px", fontSize: 14 }}>
              {saving ? "PDF作成中..." : "⤓ PDFを直接保存"}
            </button>
          </div>
        </div>
      </div>

      <div className="doc">
        <div className="variant-panel">
          <div>
            <div className="variant-panel__label">生成案</div>
            <div className="variant-panel__meta">{sourceMeta}</div>
          </div>
          <div className="variant-tabs" role="tablist" aria-label="生成案を選択">
            {variants.map((variant, i) => (
              <button
                key={i}
                className={"variant-tab" + (i === selectedIndex ? " is-active" : "")}
                onClick={() => setSelectedIndex(i)}
                type="button"
              >
                {variant.label || `案${i + 1}`}
              </button>
            ))}
          </div>
          {status && <div className="variant-warning">{status}</div>}
        </div>

        <div className="variant-compare" aria-label="生成案の比較">
          {variants.map((variant, i) => (
            <button
              key={i}
              className={"variant-card" + (i === selectedIndex ? " is-active" : "")}
              type="button"
              onClick={() => setSelectedIndex(i)}
            >
              <div className="variant-card__top">
                <span>{variant.label || `案${i + 1}`}</span>
                {typeof variant.score === "number" && <b>{variant.score}</b>}
              </div>
              <div className="variant-card__catch">{variant.dsi || variant.catch}</div>
              <div className="variant-card__tag">{variant.enemy ? `敵: ${variant.enemy}` : variant.tagline}</div>
              {Array.isArray(variant.critique) && variant.critique.length > 0 && (
                <div className="variant-card__note">{variant.critique.slice(0, 2).join(" / ")}</div>
              )}
            </button>
          ))}
        </div>

        <div className="doc-hero">
          <div className="dh-type-badge">{r.typeLabel}</div>
          <div className="dh-kicker">Titan Strategy</div>
          <div className="dh-name">{r.name}</div>
          <div className="dh-catch">{r.dsi || r.catch}</div>
          <div className="dh-tag">{r.shortPitch || r.tagline}</div>
          <div className="provenance-strip">{gateMeta}</div>
        </div>

        <Section num="01" title="DSI / Binary Frame">
          <div className="strategy-grid">
            <StrategyField label="DSI" value={r.dsi || r.statement} strong />
            <StrategyField label="Binary Frame / Enemy" value={r.binaryFrame || r.enemy || ""} strong />
          </div>
        </Section>

        <Section num="02" title="Target / Pain Cost / Promise">
          <div className="strategy-grid is-three">
            <StrategyField label="Target" value={r.target || r.targetText} />
            <StrategyField label="Pain-Cost" value={r.painCost || ""} />
            <StrategyField label="Promise" value={r.promise || r.valueText} />
          </div>
        </Section>

        <Section num="03" title="Proof / Difference">
          <div className="strategy-grid">
            <StrategyField label="Proof" value={r.proof || (Array.isArray(r.points) ? r.points[0] : "")} />
            <StrategyField label="Difference" value={r.difference || (Array.isArray(r.points) ? r.points[1] : "")} />
          </div>
        </Section>

        <Section num="04" title="Taboo / Operating Rule">
          <div className="strategy-grid">
            <StrategyField label="Taboo: what we refuse" value={r.taboo || ""} />
            <StrategyField label="System enforcement" value={r.operatingRule || ""} />
          </div>
        </Section>

        <Section num="05" title="Story">
          <StoryBlock story={r.story} />
        </Section>

        <Section num="06" title="Short Pitch">
          <CopyBlock text={r.shortPitch || r.pitch} />
        </Section>

        <div className="doc-foot">
          <div>このブランド出力は、あなたの入力をもとに自動で整理されたものです。案を切り替えながら、使いやすい文面を選べます。</div>
          <div className="restart">
            <button className="btn btn-ghost" onClick={onRegenerate} style={{ fontSize: 14 }}>もう一度生成する</button>
            <button className="btn btn-ghost" onClick={onEdit} style={{ fontSize: 14 }}>入力を見直す</button>
            <button className="btn-quiet" onClick={onRestart}>最初からやり直す</button>
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Output, CopyBlock, Section, StoryBlock });
