"use client";

import { useEffect, useRef, useState } from "react";
import {
  ExternalLink,
  ImageIcon,
  Loader2,
  Pencil,
  Send,
  ShieldCheck,
  Sparkles,
  Upload,
  Wand2,
  X,
} from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { ConfirmDialog } from "@/components/ui/confirm-dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Textarea } from "@/components/ui/textarea";
import { notify } from "@/lib/notifications/store";
import { useCapabilities } from "@/lib/capabilities/context";
import { MAX_DRAFT_IMAGES } from "@/lib/drafts/constants";
import { THREADS_MAX_CHARS, cn } from "@/lib/utils";

export interface DraftData {
  id: string;
  text: string;
  angle?: string | null;
  hook?: string | null;
  imageBrief?: string | null;
  imagePath?: string | null;
  imagePaths?: string | null;
  draftType?: string | null;
  rationale?: string | null;
  sources?: string | null;
  status: string;
  factCheckResult?: string | null;
  createdAt: string;
}

interface DraftCardProps {
  draft: DraftData;
  onUpdate: () => void;
  index?: number;
  selectable?: boolean;
  selected?: boolean;
  onSelectedChange?: (selected: boolean) => void;
}

type OptimizeMode = "polish" | "hook" | "shorter" | "engaging" | "custom";

const OPTIMIZE_MODES: { value: OptimizeMode; label: string }[] = [
  { value: "polish", label: "整體潤飾" },
  { value: "hook", label: "強化開頭" },
  { value: "shorter", label: "精簡篇幅" },
  { value: "engaging", label: "提升互動" },
  { value: "custom", label: "自訂指令" },
];

const statusLabels: Record<string, { label: string; variant: "warning" | "secondary" | "success" }> = {
  PENDING: { label: "待審核", variant: "warning" },
  EDITED: { label: "已編輯", variant: "secondary" },
  APPROVED: { label: "已核准", variant: "success" },
};

interface FactCheckData {
  isKnowledgeContent: boolean;
  passed: boolean;
  summary: string;
  issues: string[];
  verifiedPoints: string[];
  sources: Array<{ title: string; link: string }>;
  searchProviderLabel?: string;
}

function parseFactCheckResult(raw: string | null | undefined): FactCheckData | null {
  if (!raw) return null;
  try {
    const parsed = JSON.parse(raw) as unknown;
    if (parsed && typeof parsed === "object" && "isKnowledgeContent" in parsed) {
      return parsed as FactCheckData;
    }
  } catch {
    // ignore
  }
  return null;
}

function parseDraftImagePaths(source: Pick<DraftData, "imagePath" | "imagePaths">): string[] {
  if (source.imagePaths) {
    try {
      const parsed = JSON.parse(source.imagePaths) as unknown;
      if (Array.isArray(parsed)) {
        return parsed.filter((item): item is string => typeof item === "string");
      }
    } catch {
      // Fall back to the legacy single-image field.
    }
  }
  return source.imagePath ? [source.imagePath] : [];
}

export function DraftCard({
  draft,
  onUpdate,
  index = 0,
  selectable = false,
  selected = false,
  onSelectedChange,
}: DraftCardProps) {
  const [editing, setEditing] = useState(false);
  const [text, setText] = useState(draft.text);
  const [loading, setLoading] = useState<string | null>(null);
  const [optimizing, setOptimizing] = useState(false);
  const [showOptimize, setShowOptimize] = useState(false);
  const [optimizeMode, setOptimizeMode] = useState<OptimizeMode>("polish");
  const [customInstruction, setCustomInstruction] = useState("");
  const [optimizeSummary, setOptimizeSummary] = useState<string | null>(null);
  const [previousText, setPreviousText] = useState<string | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const { isReady } = useCapabilities();
  const canPublish = isReady("publish");

  const [imagePaths, setImagePaths] = useState<string[]>(() => parseDraftImagePaths(draft));
  const [confirmDialog, setConfirmDialog] = useState<{
    title: string;
    description?: string;
    confirmText?: string;
    danger?: boolean;
    onConfirm: () => void | Promise<void>;
  } | null>(null);

  useEffect(() => {
    setImagePaths(
      parseDraftImagePaths({ imagePath: draft.imagePath, imagePaths: draft.imagePaths })
    );
  }, [draft.imagePath, draft.imagePaths]);
  const [factCheck, setFactCheck] = useState<FactCheckData | null>(() =>
    parseFactCheckResult(draft.factCheckResult)
  );

  useEffect(() => {
    setFactCheck(parseFactCheckResult(draft.factCheckResult));
  }, [draft.factCheckResult]);

  const sources: string[] = (() => {
    if (!draft.sources) return [];
    try {
      const parsed = JSON.parse(draft.sources);
      return Array.isArray(parsed) ? parsed.filter((s): s is string => typeof s === "string") : [];
    } catch {
      return [];
    }
  })();
  const charCount = text.length;
  const overLimit = charCount > THREADS_MAX_CHARS;
  const statusInfo = statusLabels[draft.status] ?? { label: draft.status, variant: "secondary" as const };
  const angleInitial = (draft.angle ?? "稿").charAt(0);
  function imagePreviewUrl(imagePath: string) {
    return `/api/drafts/${draft.id}/image?p=${encodeURIComponent(imagePath)}`;
  }

  async function handleUploadImages(files: File[]) {
    if (files.length === 0) return;
    if (imagePaths.length + files.length > MAX_DRAFT_IMAGES) {
      notify({
        type: "error",
        title: "超過配圖上限",
        message: `每篇草稿最多 ${MAX_DRAFT_IMAGES} 張配圖`,
      });
      return;
    }

    setLoading("upload-image");
    const formData = new FormData();
    for (const file of files) formData.append("file", file);

    try {
      const res = await fetch(`/api/drafts/${draft.id}/image`, {
        method: "POST",
        body: formData,
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        notify({ type: "error", title: "上傳失敗", message: data.error });
        return;
      }

      setImagePaths(data.imagePaths ?? parseDraftImagePaths(data.draft ?? draft));
      notify({
        type: "success",
        title: "配圖已上傳",
        message: files.length > 1 ? `已新增 ${files.length} 張圖片` : undefined,
      });
      onUpdate();
    } catch {
      notify({ type: "error", title: "上傳失敗", message: "網路連線異常，請稍後再試" });
    } finally {
      setLoading(null);
    }
  }

  async function handleGenerateImage() {
    setLoading("gen-image");
    try {
      const res = await fetch(`/api/drafts/${draft.id}/generate-image`, {
        method: "POST",
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        notify({ type: "error", title: "AI 生圖失敗", message: data.error });
        return;
      }
      setImagePaths(data.imagePaths ?? parseDraftImagePaths(data.draft ?? draft));
      notify({ type: "success", title: "AI 配圖已生成" });
      onUpdate();
    } catch {
      notify({ type: "error", title: "AI 生圖失敗", message: "網路連線異常，請稍後再試" });
    } finally {
      setLoading(null);
    }
  }

  async function handleRemoveImage(imagePath: string) {
    setLoading("remove-image");
    try {
      const res = await fetch(
        `/api/drafts/${draft.id}/image?p=${encodeURIComponent(imagePath)}`,
        { method: "DELETE" }
      );
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        notify({ type: "error", title: "移除配圖失敗", message: data.error });
        return;
      }
      setImagePaths(data.imagePaths ?? []);
      onUpdate();
    } catch {
      notify({ type: "error", title: "移除配圖失敗", message: "網路連線異常，請稍後再試" });
    } finally {
      setLoading(null);
    }
  }

  async function handleClearImages() {
    setConfirmDialog({
      title: "移除全部配圖",
      description: "確定要移除這篇草稿的全部配圖？",
      confirmText: "移除",
      danger: true,
      onConfirm: async () => {
        setLoading("remove-image");
        try {
          const res = await fetch(`/api/drafts/${draft.id}/image`, { method: "DELETE" });
          const data = await res.json().catch(() => ({}));
          if (!res.ok) {
            notify({ type: "error", title: "移除配圖失敗", message: data.error });
            return;
          }
          setImagePaths([]);
          onUpdate();
        } catch {
          notify({ type: "error", title: "移除配圖失敗", message: "網路連線異常，請稍後再試" });
        } finally {
          setLoading(null);
        }
      },
    });
  }

  async function handleSave() {
    setLoading("save");
    try {
      const res = await fetch(`/api/drafts/${draft.id}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ text, status: "EDITED" }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        notify({ type: "error", title: "儲存失敗", message: data.error });
        return;
      }
      setEditing(false);
      setOptimizeSummary(null);
      setPreviousText(null);
      onUpdate();
    } catch {
      notify({ type: "error", title: "儲存失敗", message: "網路連線異常，請稍後再試" });
    } finally {
      setLoading(null);
    }
  }

  async function handleOptimize(apply = false) {
    setOptimizing(true);
    setOptimizeSummary(null);

    try {
      const res = await fetch("/api/optimize", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          draftId: draft.id,
          text,
          mode: optimizeMode,
          instruction: optimizeMode === "custom" ? customInstruction : undefined,
          save: apply,
        }),
      });

      const data = await res.json().catch(() => ({}));

      if (!res.ok) {
        notify({ type: "error", title: "AI 優化失敗", message: data.error });
        return;
      }

      if (apply) {
        setText(data.text);
        setEditing(false);
        setShowOptimize(false);
        setPreviousText(null);
        setOptimizeSummary(data.summary);
        onUpdate();
        return;
      }

      setPreviousText(text);
      setText(data.text);
      setEditing(true);
      setShowOptimize(false);
      setOptimizeSummary(data.summary);
    } catch {
      notify({ type: "error", title: "AI 優化失敗", message: "網路連線異常，請稍後再試" });
    } finally {
      setOptimizing(false);
    }
  }

  function handleUndoOptimize() {
    if (previousText) {
      setText(previousText);
      setPreviousText(null);
      setOptimizeSummary(null);
    }
  }

  async function handleFactCheck() {
    setLoading("factcheck");
    setFactCheck(null);
    try {
      const res = await fetch("/api/fact-check", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ draftId: draft.id, text }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        notify({ type: "error", title: "查證失敗", message: data.error });
        return;
      }
      setFactCheck(data.factCheck);
      const fc = data.factCheck;
      if (fc.isKnowledgeContent) {
        notify({
          type: fc.passed ? "success" : "warning",
          title: fc.passed ? "知識查證通過" : "知識查證未通過",
          message: fc.summary,
        });
      } else {
        notify({ type: "info", title: "非知識型內容", message: fc.summary });
      }
      onUpdate();
    } catch {
      notify({ type: "error", title: "查證失敗", message: "網路連線異常，請稍後再試" });
    } finally {
      setLoading(null);
    }
  }

  async function handlePublish() {
    setConfirmDialog({
      title: "發布到 Threads",
      description: "確定要發布這篇貼文到 Threads？知識型內容會先經網路搜尋查證。",
      confirmText: "發布",
      onConfirm: async () => {
        setLoading("publish");
        try {
          const res = await fetch("/api/publish", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({ draftId: draft.id }),
          });
          const data = await res.json().catch(() => ({}));
          if (!res.ok) {
            if (data.factCheck) setFactCheck(data.factCheck);
            notify({
              type: "error",
              title: res.status === 422 ? "知識型內容未通過查證" : "發布失敗",
              message: data.factCheck?.issues?.join("；") ?? data.error,
              href: data.debugRunId ? `/debug` : undefined,
            });
            return;
          }
          if (data.factCheck) setFactCheck(data.factCheck);
          notify({
            type: "success",
            title: "已發布到你的 Threads",
            message: [
              data.method === "api" ? "已透過官方 API 發布。" : "貼文已送出。",
              data.warning,
              "草稿已移至已發布。",
            ]
              .filter(Boolean)
              .join(" "),
            href: "/published",
          });
          onUpdate();
        } catch {
          notify({ type: "error", title: "發布失敗", message: "網路連線異常，請稍後再試" });
        } finally {
          setLoading(null);
        }
      },
    });
  }

  async function handleReject() {
    setConfirmDialog({
      title: "拒絕草稿",
      description: "確定要拒絕這篇草稿？此操作無法復原。",
      confirmText: "拒絕",
      danger: true,
      onConfirm: async () => {
        setLoading("reject");
        try {
          const res = await fetch(`/api/drafts/${draft.id}`, { method: "DELETE" });
          if (!res.ok) {
            const data = await res.json().catch(() => ({}));
            notify({ type: "error", title: "拒絕失敗", message: data.error });
            return;
          }
          onUpdate();
        } catch {
          notify({ type: "error", title: "拒絕失敗", message: "網路連線異常，請稍後再試" });
        } finally {
          setLoading(null);
        }
      },
    });
  }

  return (
    <article
      className="animate-fade-in-up py-7 first:pt-0"
      style={{ animationDelay: `${index * 40}ms` }}
    >
      <div className="flex gap-3">
        {selectable && (
          <label className="mt-2 flex h-6 w-6 shrink-0 cursor-pointer items-center justify-center">
            <input
              type="checkbox"
              className="h-4 w-4 rounded border-border accent-primary"
              checked={selected}
              onChange={(event) => onSelectedChange?.(event.target.checked)}
              aria-label={`選取 ${draft.angle ?? "草稿"}`}
            />
          </label>
        )}
        <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-secondary text-sm font-semibold text-muted-foreground">
          {angleInitial}
        </div>

        <div className="min-w-0 flex-1">
          <div className="flex items-start justify-between gap-3">
            <div className="min-w-0">
              <div className="flex flex-wrap items-center gap-x-1.5 gap-y-1">
                <span className="text-[15px] font-semibold">{draft.angle ?? "草稿"}</span>
                <span className="text-muted-foreground">·</span>
                <span className="text-[13px] text-muted-foreground">
                  {new Date(draft.createdAt).toLocaleDateString("zh-TW", {
                    month: "short",
                    day: "numeric",
                  })}
                </span>
                <Badge variant={statusInfo.variant}>{statusInfo.label}</Badge>
                {draft.draftType === "viral-replica" && (
                  <Badge variant="outline">爆款複製</Badge>
                )}
                {factCheck && (factCheck.passed || !factCheck.isKnowledgeContent) && (
                  <span
                    className="relative inline-flex items-center gap-1 rounded-md border border-success-border bg-success-bg px-2 py-0.5 text-[11px] font-medium text-success"
                    title={
                      factCheck.isKnowledgeContent
                        ? `已查證通過${factCheck.searchProviderLabel ? `（${factCheck.searchProviderLabel}）` : ""}\n${factCheck.summary}${factCheck.verifiedPoints.length > 0 ? `\n\n查證重點：\n${factCheck.verifiedPoints.map((p) => `• ${p}`).join("\n")}` : ""}`
                        : "非知識型內容，無需查證"
                    }
                  >
                    <ShieldCheck className="h-3 w-3" />
                    已查證
                  </span>
                )}
                {factCheck && factCheck.isKnowledgeContent && !factCheck.passed && (
                  <span
                    className="relative inline-flex items-center gap-1 rounded-md border border-warning-border bg-warning-bg px-2 py-0.5 text-[11px] font-medium text-warning"
                    title={`查證未通過\n${factCheck.issues.join("；")}`}
                  >
                    <ShieldCheck className="h-3 w-3" />
                    查證未過
                  </span>
                )}
              </div>
              {draft.rationale && (
                <p className="mt-0.5 text-[13px] leading-relaxed text-muted-foreground">
                  {draft.rationale}
                </p>
              )}
            </div>
          </div>

          {showOptimize && (
            <div className="mt-3 space-y-3 rounded-lg border border-border bg-muted p-3.5">
              <div className="flex items-center gap-2">
                <Wand2 className="h-4 w-4" />
                <p className="text-sm font-semibold">AI 優化</p>
              </div>

              <div className="space-y-2">
                <Label>優化方向</Label>
                <Select value={optimizeMode} onValueChange={(v) => setOptimizeMode(v as OptimizeMode)}>
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {OPTIMIZE_MODES.map((m) => (
                      <SelectItem key={m.value} value={m.value}>
                        {m.label}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>

              {optimizeMode === "custom" && (
                <div className="space-y-2">
                  <Label>自訂指令</Label>
                  <Input
                    value={customInstruction}
                    onChange={(e) => setCustomInstruction(e.target.value)}
                    placeholder="例：語氣更口語、加入一個反問句"
                  />
                </div>
              )}

              <div className="flex flex-wrap gap-2">
                <Button size="sm" onClick={() => handleOptimize(false)} disabled={optimizing}>
                  <Wand2 className="h-3.5 w-3.5" />
                  {optimizing ? "優化中…" : "預覽優化"}
                </Button>
                <Button
                  size="sm"
                  variant="secondary"
                  onClick={() => handleOptimize(true)}
                  disabled={optimizing}
                >
                  套用並儲存
                </Button>
                <Button size="sm" variant="ghost" onClick={() => setShowOptimize(false)}>
                  取消
                </Button>
              </div>
            </div>
          )}

          {optimizeSummary && (
            <div className="mt-3 rounded-lg border border-border bg-muted px-3.5 py-2.5">
              <p className="text-[12px] font-medium text-muted-foreground">AI 調整說明</p>
              <p className="mt-1 text-[14px] leading-relaxed">{optimizeSummary}</p>
            </div>
          )}

          {factCheck && (
            <div
              className={cn(
                "mt-3 rounded-lg border px-3.5 py-2.5 text-[13px]",
                factCheck.passed || !factCheck.isKnowledgeContent
                  ? "border-border bg-muted"
                  : "border-warning-border bg-warning-bg text-warning"
              )}
            >
              <p className="font-medium">
                {factCheck.isKnowledgeContent
                  ? factCheck.passed
                    ? "知識查證通過"
                    : "知識查證未通過"
                  : "非知識型，可直接發布"}
                {factCheck.searchProviderLabel && ` · ${factCheck.searchProviderLabel}`}
              </p>
              <p className="mt-1 leading-relaxed text-muted-foreground">{factCheck.summary}</p>
              {factCheck.issues.length > 0 && (
                <ul className="mt-2 list-inside list-disc text-warning">
                  {factCheck.issues.map((issue) => (
                    <li key={issue}>{issue}</li>
                  ))}
                </ul>
              )}
              {factCheck.sources.length > 0 && (
                <div className="mt-2 space-y-1">
                  {factCheck.sources.map((s) => (
                    <a
                      key={s.link}
                      href={s.link}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="block truncate text-[12px] underline"
                    >
                      {s.title}
                    </a>
                  ))}
                </div>
              )}
            </div>
          )}

          {draft.hook && !editing && (
            <p className="mt-2 text-[14px] font-medium leading-snug">{draft.hook}</p>
          )}

          <div className="mt-2">
            {editing ? (
              <div className="space-y-2">
                <Textarea value={text} onChange={(e) => setText(e.target.value)} rows={6} />
                <p
                  className={cn(
                    "font-mono text-xs",
                    overLimit ? "text-destructive" : "text-muted-foreground"
                  )}
                >
                  {charCount} / {THREADS_MAX_CHARS}
                </p>
              </div>
            ) : (
              <p className="font-readable whitespace-pre-wrap">{text}</p>
            )}
          </div>

          <div className="mt-3 rounded-lg border border-border bg-muted/50 p-3.5">
            <div className="mb-2.5 flex flex-wrap items-center justify-between gap-2">
              <p className="flex items-center gap-1.5 text-[13px] font-semibold">
                <ImageIcon className="h-3.5 w-3.5" />
                配圖
              </p>
              <div className="flex flex-wrap gap-1.5">
                <input
                  ref={fileInputRef}
                  type="file"
                  accept="image/jpeg,image/png,image/webp,image/gif"
                  multiple
                  className="hidden"
                  onChange={(e) => {
                    const files = Array.from(e.target.files ?? []);
                    if (files.length > 0) void handleUploadImages(files);
                    e.target.value = "";
                  }}
                />
                <Button
                  size="sm"
                  variant="outline"
                  onClick={() => fileInputRef.current?.click()}
                  disabled={!!loading || optimizing}
                >
                  {loading === "upload-image" ? (
                    <Loader2 className="h-3.5 w-3.5 animate-spin" />
                  ) : (
                    <Upload className="h-3.5 w-3.5" />
                  )}
                  上傳圖片
                </Button>
                {imagePaths.length > 0 && (
                  <Button
                    size="sm"
                    variant="ghost"
                    className="text-destructive hover:text-destructive"
                    onClick={handleClearImages}
                    disabled={!!loading || optimizing}
                  >
                    全部移除
                  </Button>
                )}
                <Button
                  size="sm"
                  variant="outline"
                  onClick={handleGenerateImage}
                  disabled={!!loading || optimizing}
                >
                  {loading === "gen-image" ? (
                    <Loader2 className="h-3.5 w-3.5 animate-spin" />
                  ) : (
                    <Sparkles className="h-3.5 w-3.5" />
                  )}
                  AI 生圖
                </Button>
              </div>
            </div>

            {imagePaths.length > 0 ? (
              <div
                className={cn(
                  "grid gap-2.5",
                  imagePaths.length > 1 ? "sm:grid-cols-2" : "grid-cols-1"
                )}
              >
                {imagePaths.map((imagePath, index) => (
                  <div
                    key={imagePath}
                    className="overflow-hidden rounded-lg border border-border bg-background"
                  >
                    {/* eslint-disable-next-line @next/next/no-img-element */}
                    <img
                      src={imagePreviewUrl(imagePath)}
                      alt={`草稿配圖 ${index + 1}`}
                      className="max-h-80 w-full object-contain"
                    />
                    <div className="flex items-center justify-between border-t border-border px-3 py-2">
                      <span className="text-[12px] text-muted-foreground">圖片 {index + 1}</span>
                      <Button
                        size="sm"
                        variant="ghost"
                        className="h-7 text-destructive hover:text-destructive"
                        onClick={() => handleRemoveImage(imagePath)}
                        disabled={!!loading || optimizing}
                      >
                        移除
                      </Button>
                    </div>
                  </div>
                ))}
              </div>
            ) : (
              <p className="text-[13px] text-muted-foreground">
                可一次選多張圖片上傳（最多 {MAX_DRAFT_IMAGES} 張），或請 AI 生成。發布時會一併附上。
              </p>
            )}

            {draft.imageBrief && (
              <div className="mt-2.5 rounded-md bg-background px-3 py-2">
                <p className="text-[11px] font-medium text-muted-foreground">配圖製作說明</p>
                <p className="mt-1 whitespace-pre-wrap text-[13px] leading-relaxed">
                  {draft.imageBrief}
                </p>
              </div>
            )}
          </div>

        {sources.length > 0 && (
            <div className="mt-3 flex flex-wrap gap-2">
              {sources.map((url) => (
                <a
                  key={url}
                  href={url}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="inline-flex items-center gap-1 text-[13px] text-muted-foreground transition-colors hover:text-foreground"
                >
                  <ExternalLink className="h-3 w-3" />
                  參考來源
                </a>
              ))}
            </div>
          )}

          <div className="mt-3 flex flex-wrap gap-1.5">
            {editing ? (
              <>
                <Button size="sm" onClick={handleSave} disabled={!!loading || overLimit || optimizing}>
                  儲存
                </Button>
                {previousText && (
                  <Button size="sm" variant="outline" onClick={handleUndoOptimize} disabled={optimizing}>
                    還原優化前
                  </Button>
                )}
                <Button
                  size="sm"
                  variant="ghost"
                  onClick={() => {
                    setEditing(false);
                    setText(draft.text);
                    setPreviousText(null);
                    setOptimizeSummary(null);
                  }}
                >
                  取消
                </Button>
              </>
            ) : (
              <>
                <Button size="sm" variant="ghost" onClick={() => setEditing(true)}>
                  <Pencil className="h-3.5 w-3.5" />
                  編輯
                </Button>
                <Button
                  size="sm"
                  variant="ghost"
                  onClick={() => setShowOptimize((v) => !v)}
                  disabled={!!loading || optimizing}
                >
                  <Wand2 className="h-3.5 w-3.5" />
                  AI 優化
                </Button>
                <Button
                  size="sm"
                  variant="outline"
                  onClick={handleFactCheck}
                  disabled={!!loading || overLimit || optimizing}
                >
                  <ShieldCheck className="h-3.5 w-3.5" />
                  {loading === "factcheck" ? "查證中…" : "知識查證"}
                </Button>
                <Button size="sm" onClick={handlePublish} disabled={!!loading || overLimit || optimizing || !canPublish} title={!canPublish ? "需先在連線設定綁定 Threads 或同步瀏覽器 Session" : undefined}>
                  <Send className="h-3.5 w-3.5" />
                  {loading === "publish" ? "發布中…" : "發布"}
                </Button>
                <Button
                  size="sm"
                  variant="ghost"
                  className="text-destructive hover:text-destructive"
                  onClick={handleReject}
                  disabled={!!loading || optimizing}
                >
                  <X className="h-3.5 w-3.5" />
                  拒絕
                </Button>
              </>
            )}
          </div>
        </div>
      </div>
      <ConfirmDialog
        open={confirmDialog !== null}
        onOpenChange={(open) => !open && setConfirmDialog(null)}
        title={confirmDialog?.title ?? ""}
        description={confirmDialog?.description}
        confirmText={confirmDialog?.confirmText}
        danger={confirmDialog?.danger}
        onConfirm={confirmDialog?.onConfirm ?? (() => {})}
      />
    </article>
  );
}
