import { useEffect, useState } from "react";
import { api, Persona, StylePreset } from "../api/haixun";
import { Badge, Button, Card, ErrorText, Field, Input, PageTitle, Textarea } from "../components/ui";
import { shortText } from "../lib/format";
import { notifyJobCreated } from "../lib/jobEvents";
import { AcIcon } from "../components/AcIcon";

export function PersonasPage() {
  const [personas, setPersonas] = useState<Persona[]>([]);
  const [selected, setSelected] = useState<Persona>();
  const [presets, setPresets] = useState<StylePreset[]>([]);
  const [name, setName] = useState("");
  const [displayName, setDisplayName] = useState("");
  const [benchmark, setBenchmark] = useState("");
  const [brief, setBrief] = useState("");
  const [styleMode, setStyleMode] = useState<"benchmark" | "manual">("benchmark");
  const [referenceText, setReferenceText] = useState("");
  const [sourceLabel, setSourceLabel] = useState("");
  const [personaDraftEdit, setPersonaDraftEdit] = useState("");
  const [error, setError] = useState<unknown>();
  const [message, setMessage] = useState("");
  const [styleAnalyzing, setStyleAnalyzing] = useState(false);
  const [textStyleAnalyzing, setTextStyleAnalyzing] = useState(false);

  async function load(nextId?: string) {
    setError(undefined);
    try {
      const data = await api.personas();
      setPersonas(data.list || []);
      const persona = data.list.find((item) => item.id === (nextId || selected?.id)) || data.list[0];
      setSelected(persona);
      setDisplayName(persona?.display_name || "");
      setBrief(persona?.brief || "");
      setPersonaDraftEdit(extractPersonaDraft(persona?.style_profile));
      if (persona) {
        const presetData = await api.stylePresets(persona.id);
        setPresets(presetData.list || []);
      }
    } catch (err) {
      setError(err);
    }
  }

  useEffect(() => {
    void load();
  }, []);

  // 切換人設時同步名稱與摘要
  useEffect(() => {
    if (selected) {
      setDisplayName(selected.display_name || "");
      setBrief(selected.brief || "");
      setPersonaDraftEdit(extractPersonaDraft(selected.style_profile));
    }
  }, [selected?.id]);

  async function createPersona() {
    const created = await api.createPersona({ display_name: name || "新島民人設" });
    setName("");
    await load(created.id);
  }

  async function savePersona() {
    if (!selected) return;
    const updated = await api.updatePersona(selected.id, {
      display_name: displayName || undefined,
      brief
    });
    setSelected(updated);
    setDisplayName(updated.display_name || "");
    setBrief(updated.brief || "");
    setMessage("人設已更新");

    // 樂觀更新列表中的名稱
    setPersonas((prev) => prev.map((p) => p.id === updated.id ? { ...p, display_name: updated.display_name, brief: updated.brief } : p));

    await load(updated.id);
  }

  async function savePersonaDraft() {
    if (!selected?.style_profile) return;
    try {
      const nextProfile = replacePersonaDraft(selected.style_profile, personaDraftEdit);
      const updated = await api.updatePersona(selected.id, { style_profile: nextProfile });
      setSelected(updated);
      setPersonaDraftEdit(extractPersonaDraft(updated.style_profile));
      setPersonas((prev) => prev.map((p) => p.id === updated.id ? { ...p, style_profile: updated.style_profile } : p));
      setMessage("人設語言指紋已更新");
    } catch (err) {
      setError(err);
    }
  }

  async function deletePersona(id: string) {
    if (!window.confirm("確定要刪除此人設嗎？\n刪除後將從列表消失（相關草稿與設定會保留但無法再以此人設發文）。")) return;
    try {
      await api.deletePersona(id);
      const wasCurrent = selected?.id === id;
      setMessage("人設已刪除");
      // 重新載入；若刪的是目前選取的，load 會自動挑第一個
      await load(wasCurrent ? undefined : selected?.id);
    } catch (err) {
      setError(err);
    }
  }

  async function startStyle() {
    if (!selected || !benchmark || styleAnalyzing) return;
    setStyleAnalyzing(true);
    setError(undefined);
    try {
      const data = await api.startStyleAnalysis(selected.id, benchmark);
      notifyJobCreated({ jobId: data.job_id, label: "8D 語調分析" });
      setMessage(`8D 任務已建立：${data.job_id}`);
    } catch (err) {
      setError(err);
    } finally {
      setStyleAnalyzing(false);
    }
  }

  async function startStyleFromText() {
    if (!selected || !referenceText.trim() || textStyleAnalyzing) return;
    if (selected.style_profile && !window.confirm("目前已有 8D 風格檔案，重新分析會覆寫現有結果。要繼續嗎？")) {
      return;
    }
    setTextStyleAnalyzing(true);
    setError(undefined);
    try {
      const data = await api.startStyleAnalysisFromText(selected.id, {
        raw_text: referenceText.trim(),
        source_label: sourceLabel.trim() || undefined
      });
      setSelected(data.persona);
      setPersonas((prev) => prev.map((p) => (p.id === data.persona.id ? data.persona : p)));
      setMessage(data.message || `8D 分析完成（${data.post_count} 段樣本）`);
    } catch (err) {
      setError(err);
    } finally {
      setTextStyleAnalyzing(false);
    }
  }

  async function deletePreset(presetId: string) {
    if (!selected) return;
    if (!window.confirm("確定要刪除此語調預設嗎？")) return;
    try {
      await api.deleteStylePreset(selected.id, presetId);
      setMessage("語調預設已刪除");
      await load(selected.id);
    } catch (err) {
      setError(err);
    }
  }



  return (
    <div className="page-grid" style={{ gap: "1.15rem" }}>
      <PageTitle
        title="人設"
        subtitle="管理人設與 8D 風格分析。主要語調與口吻來自 8D 分析的人設語音摘要。"
        action={<Button onClick={() => void load()}>重新載入</Button>}
      />
      <ErrorText error={error} />
      {message ? <Card><p>{message}</p></Card> : null}

      <div className="grid-2" style={{ gap: "1.25rem" }}>
        <Card title="人設列表">
          <div className="page-grid" style={{ gap: "0.9rem" }}>
            <div className="button-row">
              <Input value={name} onChange={(e) => setName(e.target.value)} placeholder="人設名稱" style={{ fontSize: "15px" }} />
              <Button variant="primary" onClick={() => void createPersona()}>建立人設</Button>
            </div>
            {personas.length === 0 && <p className="muted" style={{ fontSize: "14px" }}>尚未建立任何人設。輸入名稱後按「建立人設」。</p>}
            {personas.map((persona) => {
              const isActive = persona.id === selected?.id;
              return (
                <div
                  key={persona.id}
                  className={`persona-item ${isActive ? "active" : ""}`}
                  style={{ padding: "0.85rem 0.95rem" }}
                  onClick={() => { setSelected(persona); setDisplayName(persona.display_name || ""); setBrief(persona.brief || ""); void load(persona.id); }}
                  role="button"
                  tabIndex={0}
                  onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { setSelected(persona); setDisplayName(persona.display_name || ""); setBrief(persona.brief || ""); void load(persona.id); } }}
                >
                  <div className="title-row" style={{ alignItems: "center" }}>
                    <span style={{ display: "flex", alignItems: "center", gap: "0.5rem", flex: 1, fontSize: "15px", fontWeight: 700 }}>
                      <AcIcon name="persona" size={18} />
                      {persona.display_name || persona.id}
                    </span>
                    <Badge variant={isActive ? "brand" : (persona.style_profile ? "success" : "neutral")}>
                      {persona.style_profile ? "8D 已就緒" : "待分析"}
                    </Badge>
                    <button
                      type="button"
                      onClick={(e) => { e.stopPropagation(); void deletePersona(persona.id); }}
                      className="ac-btn ac-btn-danger"
                      style={{ padding: "0.25rem 0.6rem", fontSize: "0.75rem", minHeight: "auto", lineHeight: 1 }}
                      title="刪除人設"
                    >
                      刪除
                    </button>
                  </div>
                  <p className="brief muted" style={{ fontSize: "13.5px", marginTop: "0.35rem" }}>{shortText(persona.brief || persona.persona || "尚未填寫人設摘要", 90)}</p>
                </div>
              );
            })}
          </div>
        </Card>

        <Card title="人設設定">
          {selected ? (
            <div className="page-grid" style={{ gap: "1.1rem" }}>
              <div style={{ display: "flex", alignItems: "center", gap: "0.6rem" }}>
                {selected.style_profile ? <Badge variant="success">8D 就緒</Badge> : <Badge variant="warning">尚未分析</Badge>}
              </div>

              <Field label="人設名稱">
                <Input
                  value={displayName}
                  onChange={(e) => setDisplayName(e.target.value)}
                  placeholder="例如：溫柔島民"
                  style={{ fontSize: "15px" }}
                />
              </Field>

              <Field label="人設摘要（brief）">
                <Textarea
                  value={brief}
                  onChange={(e) => setBrief(e.target.value)}
                  placeholder="描述這個人設的定位、產品、目標受眾與核心訊息..."
                  style={{ minHeight: "11rem", fontSize: "15px" }}
                />
              </Field>

              <div className="button-row">
                <Button variant="primary" onClick={() => void savePersona()}>儲存人設設定</Button>
              </div>

              <div style={{ height: 4 }} />

              <div className="page-grid" style={{ gap: "0.75rem" }}>
                <div className="button-row" style={{ flexWrap: "wrap" }}>
                  <Button
                    variant={styleMode === "benchmark" ? "primary" : "soft"}
                    onClick={() => setStyleMode("benchmark")}
                  >
                    對標帳號
                  </Button>
                  <Button
                    variant={styleMode === "manual" ? "primary" : "soft"}
                    onClick={() => setStyleMode("manual")}
                  >
                    貼參考文字
                  </Button>
                </div>

                {styleMode === "benchmark" ? (
                  <Field label="對標 Threads username（抓樣本做 8D）">
                    <div className="button-row">
                      <Input value={benchmark} onChange={(e) => setBenchmark(e.target.value)} placeholder="例如 ultralab_tw" style={{ flex: 1, maxWidth: 280, fontSize: "15px" }} />
                      <Button loading={styleAnalyzing} onClick={() => void startStyle()} disabled={!benchmark.trim()}>開始 8D 分析</Button>
                    </div>
                    <p className="subtle" style={{ fontSize: "0.85rem", marginTop: "0.3rem", lineHeight: 1.5 }}>
                      由背景任務爬取公開貼文後分析。需啟動 Node style-8d worker。
                    </p>
                  </Field>
                ) : (
                  <>
                    <Field label="參考文字（1–12 段，用 --- 分隔多篇）">
                      <Textarea
                        value={referenceText}
                        onChange={(e) => setReferenceText(e.target.value)}
                        placeholder={"貼上你想模仿的貼文或代表文…\n\n---\n\n第二篇參考文…"}
                        style={{ minHeight: "10rem", fontSize: "15px" }}
                      />
                    </Field>
                    <Field label="來源說明（選填）">
                      <Input
                        value={sourceLabel}
                        onChange={(e) => setSourceLabel(e.target.value)}
                        placeholder="例如：我自己的舊文"
                        style={{ fontSize: "15px" }}
                      />
                    </Field>
                    <div className="button-row">
                      <Button
                        variant="primary"
                        loading={textStyleAnalyzing}
                        onClick={() => void startStyleFromText()}
                        disabled={!referenceText.trim()}
                      >
                        產生 8D 分析
                      </Button>
                    </div>
                    <p className="subtle" style={{ fontSize: "0.85rem", lineHeight: 1.5 }}>
                      建議 2–6 篇、每篇至少 10 字。會使用設定頁的研究用 AI，完成後直接寫入下方 8D 風格檔案。
                    </p>
                  </>
                )}
              </div>

              <div style={{ borderTop: "1px solid var(--hx-line)", paddingTop: "0.75rem", marginTop: "0.3rem" }}>
                <div className="button-row" style={{ justifyContent: "space-between", alignItems: "center" }}>
                  <span className="subtle" style={{ fontSize: "0.85rem" }}>危險操作</span>
                  <Button
                    variant="danger"
                    onClick={() => void deletePersona(selected.id)}
                  >
                    刪除這個人設
                  </Button>
                </div>
              </div>
            </div>
          ) : (
            <p className="muted">請先從左側建立或選擇一人設。</p>
          )}
        </Card>
      </div>

      {selected && selected.style_profile && (
        <Card title="8D 風格檔案與語調（來自分析）">
          <div className="page-grid" style={{ gap: "1rem", fontSize: "14.5px" }}>
            <Field
              label="可編輯的人設語言指紋"
              hint="這段會直接餵給產文流程。可以改口頭禪、標點換行、知識轉譯、CTA、禁忌。"
            >
              <Textarea
                value={personaDraftEdit}
                onChange={(e) => setPersonaDraftEdit(e.target.value)}
                rows={14}
                style={{ fontSize: "15px", lineHeight: 1.7 }}
              />
            </Field>
            <div className="button-row">
              <Button variant="primary" onClick={() => void savePersonaDraft()} disabled={!personaDraftEdit.trim()}>
                儲存語言指紋
              </Button>
              <Button variant="soft" onClick={() => setPersonaDraftEdit(extractPersonaDraft(selected.style_profile))}>
                還原目前版本
              </Button>
            </div>
            <Style8DView raw={selected.style_profile} />
          </div>
        </Card>
      )}

      {/* 其他語調預設（選用） - 主要語調已整合在 8D 分析的「人設語音摘要」中，可在此刪除 */}
      {presets.length > 0 && (
        <Card title={`其他語調預設（${selected ? (selected.display_name || '目前人設') : ''}）`}>
          <div style={{ fontSize: "14px", marginBottom: "0.5rem", color: "var(--hx-muted)" }}>
            主要語調與口吻來自上方的 8D 分析結果。下方為額外儲存的預設（可刪除）。
          </div>
          <div style={{ display: "grid", gap: "0.7rem" }}>
            {presets.map((preset) => (
              <div key={preset.id} className="card" style={{ padding: "0.95rem 1.1rem", background: "var(--hx-surface)" }}>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: "0.3rem" }}>
                  <div style={{ fontWeight: 800, fontSize: "15px" }}>{preset.name}</div>
                  <Button
                    variant="danger"
                    onClick={() => void deletePreset(preset.id)}
                    style={{ fontSize: "0.7rem", padding: "0.15rem 0.45rem", minHeight: "1.7rem" }}
                  >
                    刪除
                  </Button>
                </div>
                <p className="muted" style={{ margin: "0.4rem 0 0.55rem", fontSize: "14.5px", lineHeight: 1.6 }}>
                  {shortText(preset.tone || preset.notes || "（無口吻描述）", 160)}
                </p>
                <div className="button-row">
                  {(preset.cta || []).slice(0, 5).map((item) => <Badge key={item} variant="brand">{item}</Badge>)}
                  {(preset.banned_words || []).slice(0, 5).map((item) => <Badge key={item} variant="warning">{item}</Badge>)}
                </div>
              </div>
            ))}
          </div>
        </Card>
      )}
    </div>
  );
}


// 8D 結構解析與美觀呈現
interface Dim {
  summary: string;
  evidence?: string[];
}
interface Stored8D {
  username?: string;
  sourceType?: string;
  sourceLabel?: string;
  analyzedAt?: string;
  postCount?: number;
  analysis?: Record<string, Dim>;
  personaDraft?: string;
  engagement?: { medianInteractions?: number; verdict?: string };
}

const DIM_ORDER = ["d1Tone","d2Structure","d3Interaction","d4Topics","d5Rhythm","d6Visual","d7Conversion","d8Risk"] as const;
const DIM_LABELS: Record<string, string> = {
  d1Tone: "D1 語氣人格",
  d2Structure: "D2 結構模板",
  d3Interaction: "D3 互動方式",
  d4Topics: "D4 主題分布",
  d5Rhythm: "D5 發文節奏",
  d6Visual: "D6 視覺語法",
  d7Conversion: "D7 轉換方式",
  d8Risk: "D8 風險紅線",
};

function parse8D(raw?: string): Stored8D | null {
  if (!raw) return null;
  try {
    const p = JSON.parse(raw);
    if (!p || (Object.keys(p.analysis || {}).length === 0 && !p.personaDraft)) return null;
    return p as Stored8D;
  } catch {
    return null;
  }
}

function extractPersonaDraft(raw?: string) {
  return parse8D(raw)?.personaDraft?.trim() || "";
}

function replacePersonaDraft(raw: string, personaDraft: string) {
  const parsed = JSON.parse(raw) as Stored8D;
  parsed.personaDraft = personaDraft.trim();
  return JSON.stringify(parsed);
}

function Style8DView({ raw }: { raw: string }) {
  const profile = parse8D(raw);
  if (!profile) return <pre style={{ whiteSpace: "pre-wrap", fontSize: "12px", opacity: 0.7 }}>{raw}</pre>;

  const analysis = profile.analysis || {};
  const draft = (profile.personaDraft || "").trim();

  return (
    <div className="page-grid" style={{ gap: "0.85rem" }}>
      {/* meta row */}
      <div className="button-row" style={{ justifyContent: "space-between", flexWrap: "wrap" }}>
        <div>
          {profile.sourceType === "manual" ? (
            <Badge variant="brand">{profile.sourceLabel || "手動貼文"}</Badge>
          ) : profile.username ? (
            <Badge variant="brand">@{profile.username}</Badge>
          ) : null}
          {profile.postCount != null ? <Badge variant="neutral">樣本 {profile.postCount} 篇</Badge> : null}
          {profile.analyzedAt ? <span className="subtle" style={{ fontSize: "0.82rem", marginLeft: 6 }}>{profile.analyzedAt.slice(0,10)}</span> : null}
        </div>
        {profile.engagement?.verdict && profile.engagement.verdict !== "not_applicable" ? (
          <Badge variant={profile.engagement.verdict === "strong" ? "success" : "warning"}>互動 {profile.engagement.verdict}</Badge>
        ) : null}
      </div>

      {/* 8 維度卡片 */}
      <div className="dim-grid">
        {DIM_ORDER.map((key) => {
          const d = analysis[key] || { summary: "" };
          if (!d.summary) return null;
          return (
            <div key={key} className="dim-card" style={{ padding: "0.75rem 0.85rem" }}>
              <div className="dim-head">
                <span className="dim-badge">{key.slice(0,2).toUpperCase()}</span>
                <span className="dim-title" style={{ fontSize: "0.88rem" }}>{DIM_LABELS[key]}</span>
              </div>
              <div className="dim-summary" style={{ fontSize: "0.95rem", lineHeight: 1.6 }}>{d.summary}</div>
              {d.evidence && d.evidence.length > 0 && (
                <ul className="evidence" style={{ fontSize: "0.82rem" }}>
                  {d.evidence.slice(0, 3).map((e, i) => <li key={i}>「{e}」</li>)}
                </ul>
              )}
            </div>
          );
        })}
      </div>

      {/* 人設語音卡（PersonaDraft） - TA 目標客群特別突出 */}
      {draft && (
        <div className="voice-card" style={{ padding: "0.95rem 1.1rem" }}>
          <h4 style={{ fontSize: "0.9rem" }}><AcIcon name="persona" size={17} /> 人設語音摘要（TA 目標客群）</h4>
          <div className="voice-section">
            <p style={{ whiteSpace: "pre-wrap", fontSize: "0.95rem", lineHeight: 1.65 }}>{draft}</p>
          </div>
          {/* 快速提取 TA 區塊 */}
          {draft.includes("【對誰說】") && (
            <div style={{ marginTop: "0.5rem", paddingTop: "0.5rem", borderTop: "1px dashed var(--hx-line)" }}>
              <div style={{ fontSize: "0.8rem", color: "var(--hx-brand)", fontWeight: 600 }}>目標客群 TA</div>
              <div style={{ fontSize: "0.92rem", whiteSpace: "pre-wrap" }}>
                {draft.split("【對誰說】")[1]?.split("【")[0]?.trim() || ""}
              </div>
            </div>
          )}
        </div>
      )}
    </div>
  );
}
