import { useEffect, useMemo, useState } from "react";
import { api, OwnPostFormulaReview, OwnPostPerformanceItem, PostPerformance, ThreadsReply } from "../../api/haixun";
import { isStrongPost } from "../../lib/postScore";
import { Badge, Button, Card, Field, Input, Select, Textarea } from "../../components/ui";
import {
  formatFormulaAge,
  formulaDisplayStatus
} from "../../lib/formulaCache";
import { shortText } from "../../lib/format";
import { MentionProfileLookup } from "../../components/MentionProfileLookup";
import { ReplyInboxPanel } from "./ReplyInboxPanel";
import { notifyJobCreated } from "../../lib/jobEvents";

type Props = {
  accountId: string;
  performance?: PostPerformance;
  refreshTick?: number;
  selectedPersonaId: string;
  onRefresh: () => Promise<void>;
  onMessage: (msg: string) => void;
  onFormulasLoadingChange?: (loading: boolean) => void;
  onFormulasLoaded?: (count: number) => void;
};

type Filter = "all" | "image" | "tagged";

export function OwnPostsHub({
  accountId,
  performance,
  refreshTick = 0,
  selectedPersonaId,
  onRefresh,
  onMessage,
  onFormulasLoadingChange,
  onFormulasLoaded
}: Props) {
  const [filter, setFilter] = useState<Filter>("all");
  const [expandedMediaId, setExpandedMediaId] = useState("");
  const [repliesByMedia, setRepliesByMedia] = useState<Record<string, ThreadsReply[]>>({});
  const [replyTextByKey, setReplyTextByKey] = useState<Record<string, string>>({});
  const [loadingReplies, setLoadingReplies] = useState("");
  const [generatingKey, setGeneratingKey] = useState("");
  const [publishingKey, setPublishingKey] = useState("");
  const [formulaByMedia, setFormulaByMedia] = useState<Record<string, OwnPostFormulaReview>>({});
  const [generatingFormula, setGeneratingFormula] = useState("");
  const [generatingDraftFromFormula, setGeneratingDraftFromFormula] = useState("");
  const [loadingFormulas, setLoadingFormulas] = useState(false);
  const [syncingPosts, setSyncingPosts] = useState(false);

  const posts = useMemo(() => {
    const list = performance?.posts || [];
    return list.filter((post) => {
      if (filter === "image") {
        return (post.media_type || "").toUpperCase() === "IMAGE" || Boolean(post.media_url || post.thumbnail_url);
      }
      if (filter === "tagged") {
        return Boolean(post.topic_tag?.trim());
      }
      return true;
    });
  }, [filter, performance?.posts]);

  async function loadSavedFormulas(nextAccountId = accountId) {
    if (!nextAccountId) {
      setFormulaByMedia({});
      return;
    }
    setLoadingFormulas(true);
    onFormulasLoadingChange?.(true);
    try {
      const data = await api.listOwnPostFormulas(nextAccountId);
      const map: Record<string, OwnPostFormulaReview> = {};
      for (const item of data.list || []) {
        const mediaID = (item.media_id || "").trim();
        if (mediaID) map[mediaID] = item;
      }
      setFormulaByMedia(map);
      onFormulasLoaded?.(Object.keys(map).length);
    } catch (err) {
      onMessage(err instanceof Error ? err.message : "載入已儲存覆盤失敗");
    } finally {
      setLoadingFormulas(false);
      onFormulasLoadingChange?.(false);
    }
  }

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

  useEffect(() => {
    if (!refreshTick) return;
    void loadSavedFormulas();
  }, [refreshTick]);

  async function syncPostsAndFormulas() {
    setSyncingPosts(true);
    try {
      await onRefresh();
      await loadSavedFormulas();
      onMessage(`已重新同步貼文與覆盤庫 · ${new Date().toLocaleTimeString("zh-TW")}`);
    } catch (err) {
      onMessage(err instanceof Error ? err.message : "重新同步失敗");
    } finally {
      setSyncingPosts(false);
    }
  }

  const imagePosts = useMemo(
    () =>
      (performance?.posts || []).filter(
        (post) => post.media_url || post.thumbnail_url || (post.media_type || "").toUpperCase() === "IMAGE"
      ),
    [performance?.posts]
  );

  async function loadReplies(mediaID: string) {
    if (!accountId) return;
    setLoadingReplies(mediaID);
    try {
      const result = await api.threadsPlayground(accountId, { action: "media_conversation", media_id: mediaID, limit: 50 });
      if (!result.ok) {
        onMessage(result.message);
        return;
      }
      const list = parseJSON<ThreadsReply[]>(result.data, []);
      setExpandedMediaId(mediaID);
      setRepliesByMedia((current) => ({ ...current, [mediaID]: list }));
    } finally {
      setLoadingReplies("");
    }
  }

  async function generateReply(key: string, post: OwnPostPerformanceItem, reply?: ThreadsReply) {
    if (!accountId) return;
    if (!selectedPersonaId) {
      onMessage("請先選擇回覆人設，AI 才會用你的人設語氣生成");
      return;
    }
    setGeneratingKey(key);
    try {
      const data = await api.generateOwnPostReplyDraft(accountId, {
        media_id: post.media_id,
        persona_id: selectedPersonaId,
        reply_to_id: reply?.id,
        post_text: post.text,
        reply_text: reply?.text
      });
      setReplyTextByKey((current) => ({ ...current, [key]: data.text }));
      onMessage("AI 回覆草稿已生成，可編輯後發送");
    } catch (err) {
      onMessage(err instanceof Error ? err.message : "AI 草稿生成失敗");
    } finally {
      setGeneratingKey("");
    }
  }

  async function generateFormula(
    post: OwnPostPerformanceItem,
    options?: { force?: boolean; silent?: boolean }
  ) {
    if (!accountId) return;
    const cached = formulaByMedia[post.media_id];
    if (!options?.force && cached) {
      if (!options?.silent) {
        onMessage("已載入儲存的覆盤；只有按重新分析才會重打 AI");
      }
      return;
    }

    setGeneratingFormula(post.media_id);
    try {
      const data = await api.generateOwnPostFormula(accountId, {
        media_id: post.media_id,
        persona_id: selectedPersonaId || undefined,
        post_text: post.text,
        topic_tag: post.topic_tag,
        media_type: post.media_type,
        timestamp: post.timestamp,
        like_count: post.like_count,
        reply_count: post.reply_count,
        views: post.views,
        repost_count: post.repost_count,
        quote_count: post.quote_count,
        shares: post.shares,
        force: options?.force === true
      });
      setFormulaByMedia((current) => ({ ...current, [post.media_id]: { ...data, media_id: data.media_id || post.media_id } }));
      if (!options?.silent) {
        if (data.from_cache) {
          onMessage(`顯示儲存覆盤（${formatFormulaAge(data)} · 未重打 AI）`);
        } else if (options?.force) {
          onMessage(`已重新向 AI 取得覆盤 · ${formatReviewedAt(data.reviewed_at) || "剛剛"}`);
        } else {
          onMessage(`AI 覆盤完成並已儲存 · ${formatReviewedAt(data.reviewed_at) || "剛剛"}`);
        }
      }
    } catch (err) {
      if (!options?.silent) {
        onMessage(err instanceof Error ? err.message : "AI 覆盤失敗");
      }
    } finally {
      setGeneratingFormula("");
    }
  }

  async function publishReply(key: string, replyToId: string, mediaID: string) {
    const text = replyTextByKey[key]?.trim();
    if (!accountId || !text) return;
    setPublishingKey(key);
    try {
      const result = await api.threadsPlayground(accountId, {
        action: "publish_reply",
        reply_to_id: replyToId,
        text
      });
      onMessage(result.ok ? "已透過 Threads API 發送回覆" : result.message);
      if (result.ok) {
        setReplyTextByKey((current) => ({ ...current, [key]: "" }));
        await onRefresh();
        if (expandedMediaId === mediaID) {
          await loadReplies(mediaID);
        }
      }
    } finally {
      setPublishingKey("");
    }
  }

  async function generateDraftFromReview(
    post: OwnPostPerformanceItem,
    input: { topic: string; brief: string; count: number; useWebSearch: boolean }
  ) {
    if (!accountId || !selectedPersonaId || !post.media_id || !input.topic.trim()) return;
    setGeneratingDraftFromFormula(post.media_id);
    try {
      const imported = await api.importOwnPostToFormula(accountId, {
        media_id: post.media_id,
        label: `已發貼文覆盤 ${post.topic_tag || post.media_id}`
      });
      const formulaID = imported.formula?.id;
      if (!formulaID) throw new Error("覆盤無法轉成寫法公式，請先重新產生覆盤再試。");
      const data = await api.startFormulaDraftJob(selectedPersonaId, {
        account_id: accountId,
        formula_id: formulaID,
        topic: input.topic.trim(),
        brief: input.brief.trim() || undefined,
        use_web_search: input.useWebSearch,
        draft_count: input.count
      });
      notifyJobCreated({ jobId: data.job_id, label: "用覆盤產文", templateType: "generate-formula-draft" });
      onMessage(data.message || `已用這篇覆盤產生 ${input.count} 篇草稿，完成後到文案任務草稿區查看。`);
    } catch (err) {
      onMessage(err instanceof Error ? err.message : "用覆盤產文失敗");
    } finally {
      setGeneratingDraftFromFormula("");
    }
  }

  return (
    <div className="page-grid">
      <div className="grid-3">
        <StatMini label="已同步貼文" value={String(performance?.posts?.length || 0)} hint={performance?.username ? `@${performance.username}` : "Threads API"} />
        <StatMini
          label="帳號洞察"
          value={performance?.account_insights?.status === "ok" ? "已載入" : "—"}
          hint={performance?.account_insights?.message || "需 threads_manage_insights"}
        />
        <StatMini label="含圖貼文" value={String(imagePosts.length)} hint="media_url / thumbnail" />
      </div>

      {performance?.account_insights?.metrics?.length ? (
        <Card title="帳號成效（API）">
          <div className="hx-metric-grid">
            {performance.account_insights.metrics.map((metric) => (
              <div key={metric.name} className="hx-metric-chip">
                <span className="hx-metric-chip__label">{metric.name}</span>
                <strong>{metric.value}</strong>
              </div>
            ))}
          </div>
        </Card>
      ) : null}

      {imagePosts.length > 0 ? (
        <Card title="圖片牆（自己的貼文）">
          <div className="hx-media-wall">
            {imagePosts.map((post) => {
              const src = post.media_url || post.thumbnail_url;
              if (!src) return null;
              return (
                <a
                  key={post.media_id}
                  href={post.permalink || src}
                  target="_blank"
                  rel="noreferrer"
                  className="hx-media-wall__item"
                  title={shortText(post.text, 80)}
                >
                  <img src={src} alt="" loading="lazy" />
                  {post.topic_tag ? <span className="hx-media-wall__tag">#{post.topic_tag}</span> : null}
                </a>
              );
            })}
          </div>
        </Card>
      ) : null}

      <Card
        title="我的貼文管理"
        action={
          <div className="button-row">
            <Select value={filter} onChange={(e) => setFilter(e.target.value as Filter)}>
              <option value="all">全部</option>
              <option value="image">有圖片</option>
              <option value="tagged">有標籤</option>
            </Select>
            <Button variant="soft" loading={syncingPosts} onClick={() => void syncPostsAndFormulas()}>
              重新同步
            </Button>
          </div>
        }
      >
        {loadingFormulas ? (
          <div className="hx-formula-status hx-formula-status--loading" role="status" style={{ marginBottom: "0.75rem" }}>
            <span className="hx-formula-status__spinner" aria-hidden="true" />
            <strong>正在從資料庫載入儲存覆盤…</strong>
            <span>GET /own-post-formulas（不會重打 AI）</span>
          </div>
        ) : null}
        <div className={`page-grid${loadingFormulas ? " hx-own-posts--loading" : ""}`}>
          {posts.map((post) => {
            const strong = isStrongPost(post, performance?.posts || []);
            const formula = formulaByMedia[post.media_id];
            return (
            <article key={post.media_id} className="hx-own-post-card">
              <header className="hx-own-post-card__head">
                <div>
                  <div className="button-row" style={{ flexWrap: "wrap" }}>
                    {post.topic_tag ? <Badge variant="brand">#{post.topic_tag}</Badge> : null}
                    {post.media_type ? <Badge variant="neutral">{post.media_type}</Badge> : null}
                    {strong ? <Badge variant="success">成效佳</Badge> : null}
                    {loadingFormulas ? (
                      <Badge variant="neutral">覆盤載入中</Badge>
                    ) : generatingFormula === post.media_id ? (
                      <Badge variant="warning">覆盤更新中</Badge>
                    ) : formula ? (
                      <Badge variant="success">已儲存覆盤</Badge>
                    ) : null}
                    {post.insights_status === "error" ? <Badge variant="warning">洞察受限</Badge> : null}
                  </div>
                  <p className="hx-own-post-card__text">{post.text || post.media_id}</p>
                  <p className="muted hx-text-sm">{post.timestamp || ""}</p>
                </div>
                {(post.thumbnail_url || post.media_url) && (post.media_type || "").toUpperCase() !== "TEXT_POST" ? (
                  <a href={post.permalink || post.media_url} target="_blank" rel="noreferrer" className="hx-own-post-card__thumb">
                    <img src={post.thumbnail_url || post.media_url} alt="" />
                  </a>
                ) : null}
              </header>

              <div className="hx-metric-grid">
                <Metric label="讚" value={post.like_count} />
                <Metric label="回覆" value={post.reply_count} />
                <Metric label="瀏覽" value={post.views ?? 0} />
                <Metric label="轉發" value={post.repost_count ?? 0} />
                <Metric label="引用" value={post.quote_count ?? 0} />
                <Metric label="分享" value={post.shares ?? 0} />
              </div>

              <div className="button-row">
                {post.permalink ? (
                  <a href={post.permalink} target="_blank" rel="noreferrer" className="hx-link-chip">
                    開啟 Threads
                  </a>
                ) : null}
                <Button variant="soft" loading={loadingReplies === post.media_id} onClick={() => void loadReplies(post.media_id)}>
                  {expandedMediaId === post.media_id ? "重新載入留言" : "看留言收件匣"}
                </Button>
                {!formula ? (
                  <Button
                    variant="soft"
                    loading={generatingFormula === post.media_id}
                    onClick={() => void generateFormula(post)}
                  >
                    產生洞察覆盤
                  </Button>
                ) : null}
              </div>

              {formula ? (
                <>
                  <FormulaReviewPanel
                    formula={formula}
                    refreshing={generatingFormula === post.media_id}
                  />
                  <ReviewDraftGenerator
                    loading={generatingDraftFromFormula === post.media_id}
                    disabled={!selectedPersonaId}
                    defaultTopic={post.topic_tag || ""}
                    onSubmit={(input) => void generateDraftFromReview(post, input)}
                  />
                  <div className="button-row">
                    <Button
                      variant="primary"
                      loading={generatingFormula === post.media_id}
                      onClick={() => void generateFormula(post, { force: true })}
                    >
                      重新打覆盤（強制向 AI 索取）
                    </Button>
                  </div>
                </>
              ) : null}

              <Field label="回覆這篇貼文（Threads API）">
                <Textarea
                  value={replyTextByKey[`post:${post.media_id}`] || ""}
                  onChange={(e) => setReplyTextByKey((current) => ({ ...current, [`post:${post.media_id}`]: e.target.value }))}
                  placeholder="輸入回覆內容，或用 AI 生成（可輸入 @帳號 查詢對方）"
                />
                <MentionProfileLookup
                  accountId={accountId}
                  text={replyTextByKey[`post:${post.media_id}`] || ""}
                  label="留言中的 @ 提及"
                />
                <div className="button-row" style={{ marginTop: 8 }}>
                  <Button
                    variant="soft"
                    loading={generatingKey === `post:${post.media_id}`}
                    disabled={!selectedPersonaId}
                    onClick={() => void generateReply(`post:${post.media_id}`, post)}
                  >
                    AI 生成回覆
                  </Button>
                  <Button
                    variant="primary"
                    loading={publishingKey === `post:${post.media_id}`}
                    disabled={!replyTextByKey[`post:${post.media_id}`]?.trim()}
                    onClick={() => void publishReply(`post:${post.media_id}`, post.media_id, post.media_id)}
                  >
                    API 發送
                  </Button>
                </div>
              </Field>

              {expandedMediaId === post.media_id ? (
                <ReplyInboxPanel
                  accountId={accountId}
                  post={post}
                  replies={repliesByMedia[post.media_id] || []}
                  accountUsername={performance?.username}
                  replyTextByKey={replyTextByKey}
                  generatingKey={generatingKey}
                  publishingKey={publishingKey}
                  selectedPersonaId={selectedPersonaId}
                  onReplyTextChange={(key, value) => setReplyTextByKey((current) => ({ ...current, [key]: value }))}
                  onGenerate={(key, reply) => void generateReply(key, post, reply)}
                  onPublish={(key, replyToId) => void publishReply(key, replyToId, post.media_id)}
                />
              ) : null}
            </article>
          );
          })}
          {!posts.length ? <p className="muted">尚無可管理的貼文。請確認 Threads API 已連線，並按「重新同步」。</p> : null}
        </div>
      </Card>
    </div>
  );
}

function Metric({ label, value }: { label: string; value: number }) {
  return (
    <div className="hx-metric-chip">
      <span className="hx-metric-chip__label">{label}</span>
      <strong>{value}</strong>
    </div>
  );
}

function StatMini({ label, value, hint }: { label: string; value: string; hint?: string }) {
  return (
    <div className="hx-stat-mini">
      <span className="muted hx-text-sm">{label}</span>
      <strong>{value}</strong>
      {hint ? <span className="muted hx-text-xs">{hint}</span> : null}
    </div>
  );
}

function formulaHasContent(formula: OwnPostFormulaReview): boolean {
  return Boolean(
    formula.summary?.trim() ||
      formula.formula?.trim() ||
      formula.post_template?.trim() ||
      formula.wins?.length ||
      formula.improvements?.length ||
      formula.replication_tips?.length ||
      formula.avoid?.length
  );
}

function formatReviewedAt(value?: number) {
  if (!value) return "";
  const ms = value > 1_000_000_000_000 ? value / 1_000_000 : value;
  const date = new Date(ms);
  if (!Number.isFinite(date.getTime())) return "";
  return date.toLocaleString("zh-TW", { year: "numeric", month: "numeric", day: "numeric", hour: "2-digit", minute: "2-digit" });
}

function FormulaStatusBar({ formula, refreshing }: { formula: OwnPostFormulaReview; refreshing?: boolean }) {
  const status = formulaDisplayStatus(formula, refreshing);
  const reviewedLabel = formatReviewedAt(formula.reviewed_at);
  const age = formatFormulaAge(formula);

  if (status === "loading") {
    return (
      <div className="hx-formula-status hx-formula-status--loading" role="status">
        <span className="hx-formula-status__spinner" aria-hidden="true" />
        <strong>正在向 AI 索取最新洞察覆盤…</strong>
        <span>通常需 10～30 秒，請稍候</span>
      </div>
    );
  }
  if (status === "stored") {
    return (
      <div className="hx-formula-status hx-formula-status--cache" role="status">
        <strong>顯示已儲存覆盤</strong>
        <span>{age} · 未重打 AI</span>
        {reviewedLabel ? <span>儲存於 {reviewedLabel}</span> : null}
      </div>
    );
  }
  return (
    <div className="hx-formula-status hx-formula-status--fresh" role="status">
      <strong>已取得最新 AI 覆盤</strong>
      <span>{reviewedLabel ? `更新於 ${reviewedLabel}` : age}</span>
    </div>
  );
}

function FormulaReviewPanel({ formula, refreshing }: { formula: OwnPostFormulaReview; refreshing?: boolean }) {
  return (
    <div className={`hx-formula-review ${refreshing ? "is-refreshing" : ""}`}>
      <FormulaStatusBar formula={formula} refreshing={refreshing} />
      <div className="hx-formula-review__head">
        <strong>洞察覆盤內容</strong>
      </div>
      {!formulaHasContent(formula) ? (
        <p className="muted">覆盤內容為空，請按「重新覆盤」再試一次。</p>
      ) : null}
      {formula.summary ? <p className="hx-formula-review__summary">{formula.summary}</p> : null}

      {formula.wins?.length ? (
        <section className="hx-formula-review__section hx-formula-review__section--good">
          <span className="hx-formula-review__label">做對了什麼</span>
          <ul className="hx-formula-review__list">
            {formula.wins.map((item) => <li key={item}>{item}</li>)}
          </ul>
        </section>
      ) : null}

      {formula.improvements?.length ? (
        <section className="hx-formula-review__section hx-formula-review__section--fix">
          <span className="hx-formula-review__label">要改什麼（含改善做法）</span>
          <ul className="hx-formula-review__list">
            {formula.improvements.map((item) => <li key={item}>{item}</li>)}
          </ul>
        </section>
      ) : null}

      {formula.formula ? (
        <section className="hx-formula-review__section">
          <span className="hx-formula-review__label">可複製公式</span>
          <div className="hx-formula-review__block">
            <p style={{ whiteSpace: "pre-wrap", margin: 0 }}>{formula.formula}</p>
          </div>
        </section>
      ) : null}

      {formula.post_template ? (
        <section className="hx-formula-review__section">
          <span className="hx-formula-review__label">發文模板（填空就能產文）</span>
          <div className="hx-formula-review__block hx-formula-review__block--template">
            <p style={{ whiteSpace: "pre-wrap", margin: 0 }}>{formula.post_template}</p>
          </div>
        </section>
      ) : null}

      {formula.hook_pattern || formula.structure ? (
        <div className="hx-formula-review__meta">
          {formula.hook_pattern ? <p className="muted hx-text-sm">Hook 模式：{formula.hook_pattern}</p> : null}
          {formula.structure ? <p className="muted hx-text-sm">段落結構：{formula.structure}</p> : null}
        </div>
      ) : null}

      {formula.replication_tips?.length ? (
        <section className="hx-formula-review__section">
          <span className="hx-formula-review__label">下次套用這篇公式</span>
          <ul className="hx-formula-review__list">
            {formula.replication_tips.map((item) => <li key={item}>{item}</li>)}
          </ul>
        </section>
      ) : null}

      {formula.avoid?.length ? (
        <section className="hx-formula-review__section hx-formula-review__section--warn">
          <span className="hx-formula-review__label">避免再犯</span>
          <ul className="hx-formula-review__list">
            {formula.avoid.map((item) => <li key={item}>{item}</li>)}
          </ul>
        </section>
      ) : null}
    </div>
  );
}

function ReviewDraftGenerator({
  loading,
  disabled,
  defaultTopic,
  onSubmit
}: {
  loading: boolean;
  disabled: boolean;
  defaultTopic: string;
  onSubmit: (input: { topic: string; brief: string; count: number; useWebSearch: boolean }) => void;
}) {
  const [open, setOpen] = useState(false);
  const [topic, setTopic] = useState(defaultTopic);
  const [brief, setBrief] = useState("");
  const [count, setCount] = useState(3);
  const [useWebSearch, setUseWebSearch] = useState(true);

  useEffect(() => {
    if (!open && !topic.trim()) setTopic(defaultTopic);
  }, [defaultTopic, open, topic]);

  if (!open) {
    return (
      <div className="button-row" style={{ marginTop: "0.75rem" }}>
        <Button variant="soft" disabled={disabled} onClick={() => setOpen(true)}>
          用這篇覆盤產新文
        </Button>
        {disabled ? <span className="muted hx-text-sm">請先選擇回覆人設</span> : null}
      </div>
    );
  }

  return (
    <div className="card" style={{ marginTop: "0.85rem", padding: "0.95rem", background: "var(--hx-surface-muted)" }}>
      <div className="page-grid" style={{ gap: "0.75rem" }}>
        <div className="button-row" style={{ justifyContent: "space-between" }}>
          <strong>用這篇覆盤產新文</strong>
          <Button variant="ghost" onClick={() => setOpen(false)}>收起</Button>
        </div>
        <Field label="新主題">
          <Input value={topic} onChange={(event) => setTopic(event.target.value)} placeholder="例如：第一次生殖門診要準備什麼" />
        </Field>
        <Field label="補充資料（可選）">
          <Textarea
            value={brief}
            onChange={(event) => setBrief(event.target.value)}
            rows={3}
            placeholder="想加入的觀點、知識、受眾、不要碰的內容。"
          />
        </Field>
        <div className="grid-2">
          <Field label="產生篇數">
            <Select value={String(count)} onChange={(event) => setCount(Number(event.target.value))}>
              <option value="1">1 篇</option>
              <option value="3">3 篇</option>
              <option value="5">5 篇</option>
            </Select>
          </Field>
          <label className="button-row" style={{ justifyContent: "flex-start", alignSelf: "end", minHeight: "2.75rem" }}>
            <input type="checkbox" checked={useWebSearch} onChange={(event) => setUseWebSearch(event.target.checked)} />
            <span className="muted hx-text-sm">需要時上網補資料</span>
          </label>
        </div>
        <Button
          variant="primary"
          loading={loading}
          disabled={disabled || !topic.trim()}
          onClick={() => onSubmit({ topic, brief, count, useWebSearch })}
        >
          產生草稿
        </Button>
      </div>
    </div>
  );
}

function parseJSON<T>(value: string, fallback: T): T {
  try {
    return JSON.parse(value) as T;
  } catch {
    return fallback;
  }
}
