"use client";

import Link from "next/link";
import { useCallback, useEffect, useState } from "react";
import { ChevronLeft, ChevronRight, Copy, ExternalLink, Loader2, RefreshCw, Radar, ScanSearch, Send, Target, Trash2 } from "lucide-react";
import { ProductContextForm } from "@/components/product-context-form";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { EmptyState } from "@/components/layout/empty-state";
import { PageHeader } from "@/components/layout/page-header";
import { InlineAlert } from "@/components/ui/inline-alert";
import { Textarea } from "@/components/ui/textarea";
import { notify } from "@/lib/notifications/store";
import { useCapabilities } from "@/lib/capabilities/context";
import { useActionFeedback } from "@/lib/use-action-feedback";
import { hasProductContext, summarizeProductContext } from "@/lib/types/product-context";
import { isPlacementGoal } from "@/lib/types/topic-goal";
import { parseFetchJson, THREADS_MAX_CHARS } from "@/lib/utils";

interface OutreachDraft {
  id: string;
  text: string;
  angle?: string | null;
  rationale?: string | null;
  status: string;
}

interface OutreachTarget {
  id: string;
  status: string;
  relevance?: number | null;
  reason?: string | null;
  scanItem: {
    id: string;
    text: string;
    authorName?: string | null;
    permalink?: string | null;
    likeCount?: number | null;
    replyCount?: number | null;
    placementReason?: string | null;
    placementScore?: number | null;
    scan: {
      topic: {
        id: string;
        label: string;
        topicGoal?: string | null;
        productContext?: string | null;
        brief?: string | null;
      };
      scanGoal?: string | null;
    };
  };
  drafts: OutreachDraft[];
}

interface PlacementTopic {
  id: string;
  label: string;
  query: string;
  topicGoal: string;
  scanCount: number;
  latestScan: {
    id: string;
    createdAt: string;
    itemCount: number;
  } | null;
}

const PAGE_SIZE = 10;

export default function OutreachPage() {
  const [targets, setTargets] = useState<OutreachTarget[]>([]);
  const [page, setPage] = useState(1);
  const [total, setTotal] = useState(0);
  const [totalPages, setTotalPages] = useState(1);
  const [selectMode, setSelectMode] = useState(false);
  const [selectedDraftIds, setSelectedDraftIds] = useState<Set<string>>(new Set());
  const [batchDeleting, setBatchDeleting] = useState(false);
  const [placementTopics, setPlacementTopics] = useState<PlacementTopic[]>([]);
  const [loading, setLoading] = useState(true);
  const [busy, setBusy] = useState<string | null>(null);
  const [draftText, setDraftText] = useState<Record<string, string>>({});
  const [productDrafts, setProductDrafts] = useState<Record<string, string>>({});
  const { feedback, clearFeedback, showError, showSuccess, showWarning } = useActionFeedback();
  const { isReady } = useCapabilities();
  const threadsApiReady = isReady("threadsApi");
  const load = useCallback(async (silent = false) => {
    if (!silent) setLoading(true);
    try {
      const [outreachRes, topicsRes] = await Promise.all([
        fetch(`/api/outreach?page=${page}&limit=${PAGE_SIZE}`),
        fetch("/api/topics"),
      ]);
      const [data, topicsData] = await Promise.all([
        parseFetchJson<{ targets?: OutreachTarget[]; total?: number; totalPages?: number; error?: string }>(outreachRes),
        parseFetchJson<{ topics?: PlacementTopic[]; error?: string }>(topicsRes),
      ]);
      if (!outreachRes.ok) {
        showError(data.error ?? "無法載入受眾名單", "載入失敗");
        setTargets([]);
        setTotal(0);
        setTotalPages(1);
        return;
      }
      const rows = data.targets ?? [];
      setTargets(rows);
      setTotal(data.total ?? rows.length);
      setTotalPages(data.totalPages ?? 1);
      if (page > (data.totalPages ?? 1)) setPage(Math.max(1, data.totalPages ?? 1));
      setPlacementTopics((topicsData.topics ?? []).filter((t) => isPlacementGoal(t.topicGoal)));
      setDraftText(
        Object.fromEntries(
          rows.flatMap((target: OutreachTarget) => target.drafts.map((draft) => [draft.id, draft.text]))
        )
      );
      setProductDrafts((prev) => {
        const next = { ...prev };
        for (const target of rows as OutreachTarget[]) {
          const topic = target.scanItem.scan.topic;
          if (next[topic.id] === undefined) {
            next[topic.id] = topic.productContext ?? "";
          }
        }
        return next;
      });
    } catch {
      showError("網路連線異常，請稍後再試", "載入失敗");
      setTargets([]);
      setTotal(0);
      setTotalPages(1);
    } finally {
      if (!silent) setLoading(false);
    }
  }, [page, showError]);

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

  useEffect(() => {
    setSelectedDraftIds(new Set());
  }, [page]);

  async function saveDraft(draftId: string) {
    setBusy(`save-${draftId}`);
    try {
      const res = await fetch(`/api/outreach/drafts/${draftId}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ text: draftText[draftId], status: "EDITED" }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        showError(data.error ?? "無法儲存草稿", "儲存失敗");
        return;
      }
      showSuccess("草稿已儲存");
      load(true);
    } catch {
      showError("網路連線異常，請稍後再試", "儲存失敗");
    } finally {
      setBusy(null);
    }
  }

  async function deleteDraft(draft: OutreachDraft) {
    if (!confirm("確定刪除這則留言草稿？刪除後無法復原。")) return;
    setBusy(`delete-${draft.id}`);
    try {
      const res = await fetch(`/api/outreach/drafts/${draft.id}`, { method: "DELETE" });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        showError(data.error ?? "無法刪除留言草稿", "刪除失敗");
        return;
      }
      setDraftText((prev) => {
        const next = { ...prev };
        delete next[draft.id];
        return next;
      });
      showSuccess("留言草稿已刪除");
      load(true);
    } catch {
      showError("網路連線異常，請稍後再試", "刪除失敗");
    } finally {
      setBusy(null);
    }
  }

  function toggleDraftSelection(id: string) {
    setSelectedDraftIds((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  }

  function exitSelectMode() {
    setSelectMode(false);
    setSelectedDraftIds(new Set());
  }

  async function deleteSelectedDrafts() {
    const ids = [...selectedDraftIds];
    if (ids.length === 0) return;
    if (!confirm(`確定刪除選取的 ${ids.length} 則留言草稿？刪除後無法復原。`)) return;
    setBatchDeleting(true);
    try {
      const res = await fetch("/api/outreach/drafts", {
        method: "DELETE",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ ids }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        showError(data.error ?? "無法批次刪除留言草稿", "批次刪除失敗");
        return;
      }
      showSuccess(`已刪除 ${data.deleted ?? ids.length} 則留言草稿`);
      exitSelectMode();
      await load(true);
    } catch {
      showError("網路連線異常，請稍後再試", "批次刪除失敗");
    } finally {
      setBatchDeleting(false);
    }
  }

  async function copyText(text: string) {
    await navigator.clipboard.writeText(text);
    showSuccess("已複製留言");
  }

  const placementTopicId = targets.find((t) =>
    isPlacementGoal(t.scanItem.scan.scanGoal ?? t.scanItem.scan.topic.topicGoal)
  )?.scanItem.scan.topic.id;

  async function saveProductContext(topicId: string) {
    setBusy(`product-${topicId}`);
    try {
      const res = await fetch("/api/topics", {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ id: topicId, productContext: productDrafts[topicId] ?? "" }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        showError(data.error ?? "無法儲存品牌與產品", "儲存失敗");
        return false;
      }
      showSuccess("品牌與產品已儲存");
      load(true);
      return true;
    } catch {
      showError("網路連線異常，請稍後再試", "儲存失敗");
      return false;
    } finally {
      setBusy(null);
    }
  }

  async function regenerateTarget(target: OutreachTarget) {
    const topicId = target.scanItem.scan.topic.id;
    const productContext = productDrafts[topicId] ?? "";
    if (!hasProductContext(productContext)) {
      showWarning("在上方區塊填寫品牌與產品後，再重新生成。", "請先填寫品牌與產品");
      return;
    }

    setBusy(`regen-${target.id}`);
    try {
      const res = await fetch("/api/outreach/generate", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          scanItemId: target.scanItem.id,
          productContext,
        }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        notify({ type: "error", title: "重新生成失敗", message: data.error });
        return;
      }
      notify({ type: "success", title: "已重新生成回覆草稿" });
      load(true);
    } catch {
      notify({ type: "error", title: "重新生成失敗", message: "網路連線異常，請稍後再試" });
    } finally {
      setBusy(null);
    }
  }

  async function publishDraft(draft: OutreachDraft) {
    setBusy(`publish-${draft.id}`);
    try {
      const res = await fetch(`/api/outreach/drafts/${draft.id}/publish`, { method: "POST" });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        notify({ type: "error", title: "發布留言失敗", message: data.error });
        return;
      }
      notify({ type: "success", title: "留言已發布到 Threads" });
      load(true);
    } catch {
      notify({ type: "error", title: "發布留言失敗", message: "網路連線異常，請稍後再試" });
    } finally {
      setBusy(null);
    }
  }

  const hasPlacementTargets = targets.some((t) =>
    isPlacementGoal(t.scanItem.scan.scanGoal ?? t.scanItem.scan.topic.topicGoal)
  );
  const deletableDraftIds = targets.flatMap((target) =>
    target.drafts.filter((draft) => draft.status !== "PUBLISHED").map((draft) => draft.id)
  );
  const allPageDraftsSelected =
    deletableDraftIds.length > 0 && deletableDraftIds.every((id) => selectedDraftIds.has(id));

  function toggleAllPageDrafts() {
    setSelectedDraftIds((prev) => {
      const next = new Set(prev);
      if (allPageDraftsSelected) deletableDraftIds.forEach((id) => next.delete(id));
      else deletableDraftIds.forEach((id) => next.add(id));
      return next;
    });
  }

  return (
    <div>
      <PageHeader
        eyebrow="02 / FIND YOUR TA"
        title="找出正在需要你的人"
        description="從 Threads 訊號辨識高意向受眾，再套入你的人設與產品脈絡，產出自然、不硬銷的開場話術。"
        action={<Button asChild size="lg"><Link href="/scans?mode=placement"><Radar className="h-4 w-4" />挖掘新受眾</Link></Button>}
      />

      {feedback && (
        <InlineAlert
          type={feedback.type}
          title={feedback.title}
          message={feedback.message}
          onDismiss={clearFeedback}
          className="mb-4"
        />
      )}

      {!loading && targets.length > 0 && (
        <div className="mb-4 flex flex-wrap items-center justify-between gap-2 rounded-lg border border-border bg-muted/40 px-3 py-2">
          <p className="text-xs text-muted-foreground">共 {total} 個目標 · 第 {page}/{totalPages} 頁</p>
          <div className="flex flex-wrap gap-2">
            {selectMode ? (
              <>
                <Button size="sm" variant="outline" onClick={toggleAllPageDrafts} disabled={deletableDraftIds.length === 0}>
                  {allPageDraftsSelected ? "取消全選" : "全選本頁"}
                </Button>
                <Button size="sm" variant="outline" onClick={deleteSelectedDrafts} disabled={selectedDraftIds.size === 0 || batchDeleting}>
                  {batchDeleting ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <Trash2 className="h-3.5 w-3.5" />}
                  刪除選取（{selectedDraftIds.size}）
                </Button>
                <Button size="sm" variant="ghost" onClick={exitSelectMode}>完成</Button>
              </>
            ) : (
              <Button size="sm" variant="outline" onClick={() => setSelectMode(true)}>
                批次管理
              </Button>
            )}
          </div>
        </div>
      )}

      {loading ? (
        <div className="space-y-4">
          {[0, 1, 2].map((i) => <div key={i} className="skeleton h-56 animate-pulse" />)}
        </div>
      ) : targets.length === 0 ? (
        placementTopics.length > 0 ? (
          <div className="space-y-4">
            <div className="rounded-lg border border-border bg-muted/40 px-4 py-3 text-sm text-muted-foreground">
              你已有 {placementTopics.length} 個找 TA 主題。到海巡成果頁點「獲客留言」，生成的對象會出現在這裡。
            </div>
            <div className="grid gap-4 sm:grid-cols-2">
              {placementTopics.map((topic) => (
                <Card key={topic.id}>
                  <CardHeader className="pb-3">
                    <CardTitle className="truncate">{topic.label}</CardTitle>
                    <CardDescription className="truncate">{topic.query}</CardDescription>
                  </CardHeader>
                  <CardContent className="space-y-3">
                    {topic.latestScan ? (
                      <p className="text-[13px] text-muted-foreground">
                        最近海巡 {new Date(topic.latestScan.createdAt).toLocaleDateString("zh-TW", { month: "short", day: "numeric" })}
                        {" · "}
                        {topic.latestScan.itemCount} 篇
                      </p>
                    ) : (
                      <p className="text-[13px] text-muted-foreground">尚未海巡</p>
                    )}
                    <div className="flex flex-wrap gap-2">
                      {topic.latestScan ? (
                        <Button size="sm" asChild>
                          <Link href={`/scans/${topic.id}/results`}>
                            <ScanSearch className="h-3.5 w-3.5" />
                            前往生成留言
                          </Link>
                        </Button>
                      ) : (
                        <Button size="sm" variant="outline" asChild>
                          <Link href={`/scans/${topic.id}`}>
                            <ScanSearch className="h-3.5 w-3.5" />
                            先完成海巡
                          </Link>
                        </Button>
                      )}
                    </div>
                  </CardContent>
                </Card>
              ))}
            </div>
            <div className="flex justify-center pt-2">
              <Button asChild variant="outline" size="sm">
                <Link href="/scans?mode=placement"><Radar className="h-4 w-4" />新增更多主題</Link>
              </Button>
            </div>
          </div>
        ) : (
          <EmptyState
            icon={Target}
            title="還沒有高意向受眾"
            description="建立找 TA 主題並海巡後，AI 會從中辨識高意向受眾並生成開場話術。"
            action={<Button asChild><Link href="/scans?mode=placement"><Radar className="h-4 w-4" />開始挖掘</Link></Button>}
          />
        )
      ) : (
        <div className="space-y-4">
          {hasPlacementTargets && placementTopicId && (
            <Card>
              <CardHeader className="pb-3">
                <CardTitle className="text-base">品牌與產品</CardTitle>
                <CardDescription>
                  調整後可重新生成，讓留言更自然帶到你的品牌（不會硬銷）。
                </CardDescription>
              </CardHeader>
              <CardContent className="space-y-3">
                <ProductContextForm
                  compact
                  value={productDrafts[placementTopicId] ?? ""}
                  onChange={(value) =>
                    setProductDrafts((prev) => ({ ...prev, [placementTopicId]: value }))
                  }
                />
                <Button
                  size="sm"
                  variant="outline"
                  disabled={busy === `product-${placementTopicId}`}
                  onClick={() => saveProductContext(placementTopicId)}
                >
                  {busy === `product-${placementTopicId}` ? "儲存中…" : "儲存品牌與產品"}
                </Button>
              </CardContent>
            </Card>
          )}

          {targets.map((target) => {
            const isPlacement = isPlacementGoal(
              target.scanItem.scan.scanGoal ?? target.scanItem.scan.topic.topicGoal
            );
            const productSummary = summarizeProductContext(
              productDrafts[target.scanItem.scan.topic.id] ?? target.scanItem.scan.topic.productContext
            );

            return (
            <Card key={target.id}>
              <CardHeader>
                <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
                  <div>
                    <CardTitle>
                      @{target.scanItem.authorName ?? "匿名"} · {target.scanItem.scan.topic.label}
                    </CardTitle>
                    <CardDescription>
                      {target.scanItem.likeCount ?? 0} 讚 / {target.scanItem.replyCount ?? 0} 留言
                    </CardDescription>
                    <div className="mt-2 flex flex-wrap gap-1.5">
                      <Badge variant={target.status === "LOW_RELEVANCE" ? "warning" : "success"}>
                        相關度 {Math.round((target.relevance ?? 0) * 100)}%
                      </Badge>
                      <Badge variant="outline">{target.status}</Badge>
                    </div>
                  </div>
                  <div className="flex flex-wrap gap-2">
                    {isPlacement && (
                      <Button
                        size="sm"
                        variant="outline"
                        disabled={busy === `regen-${target.id}`}
                        onClick={() => regenerateTarget(target)}
                      >
                        {busy === `regen-${target.id}` ? (
                          <Loader2 className="h-3.5 w-3.5 animate-spin" />
                        ) : (
                          <RefreshCw className="h-3.5 w-3.5" />
                        )}
                        重新生成
                      </Button>
                    )}
                    {target.scanItem.permalink && (
                      <Button size="sm" variant="outline" asChild>
                        <a href={target.scanItem.permalink} target="_blank" rel="noreferrer">
                          <ExternalLink className="h-3.5 w-3.5" />
                          原貼文
                        </a>
                      </Button>
                    )}
                  </div>
                </div>
              </CardHeader>
              <CardContent className="space-y-4">
                <div className="rounded-lg border border-border bg-muted/50 p-3">
                  <p className="text-[13px] leading-relaxed">{target.scanItem.text}</p>
                  {productSummary && (
                    <p className="mt-2 text-xs text-muted-foreground">置入參考：{productSummary}</p>
                  )}
                  {(target.scanItem.placementReason || target.reason) && (
                    <p className="mt-2 text-xs text-muted-foreground">
                      {target.scanItem.placementReason ?? target.reason}
                    </p>
                  )}
                </div>

                {target.drafts.map((draft) => {
                  const value = draftText[draft.id] ?? draft.text;
                  return (
                    <div key={draft.id} className="relative space-y-2 rounded-lg border border-border p-3">
                      {selectMode && draft.status !== "PUBLISHED" && (
                        <button
                          type="button"
                          aria-label="選取留言草稿"
                          onClick={() => toggleDraftSelection(draft.id)}
                          className={`absolute right-3 top-3 flex h-5 w-5 items-center justify-center rounded border text-xs ${
                            selectedDraftIds.has(draft.id)
                              ? "border-primary bg-primary text-primary-foreground"
                              : "border-border bg-background"
                          }`}
                        >
                          {selectedDraftIds.has(draft.id) ? "✓" : ""}
                        </button>
                      )}
                      <div className="flex items-center justify-between gap-2">
                        <div className={`flex flex-wrap gap-1.5 ${selectMode ? "pr-8" : ""}`}>
                          <Badge variant={draft.status === "PUBLISHED" ? "success" : "warning"}>{draft.status}</Badge>
                          {draft.angle && <Badge variant="outline">{draft.angle}</Badge>}
                        </div>
                        <span className="text-xs text-muted-foreground">{value.length}/{THREADS_MAX_CHARS}</span>
                      </div>
                      <Textarea
                        value={value}
                        rows={3}
                        onChange={(e) => setDraftText((prev) => ({ ...prev, [draft.id]: e.target.value }))}
                      />
                      {draft.rationale && <p className="text-xs text-muted-foreground">{draft.rationale}</p>}
                      <div className="flex flex-wrap gap-2">
                        <Button size="sm" variant="outline" onClick={() => saveDraft(draft.id)} disabled={busy === `save-${draft.id}`}>
                          儲存
                        </Button>
                        <Button size="sm" variant="outline" onClick={() => copyText(value)}>
                          <Copy className="h-3.5 w-3.5" />
                          複製
                        </Button>
                        {draft.status !== "PUBLISHED" && (
                          <Button
                            size="sm"
                            variant="outline"
                            onClick={() => deleteDraft(draft)}
                            disabled={busy === `delete-${draft.id}`}
                          >
                            {busy === `delete-${draft.id}` ? (
                              <Loader2 className="h-3.5 w-3.5 animate-spin" />
                            ) : (
                              <Trash2 className="h-3.5 w-3.5" />
                            )}
                            刪除
                          </Button>
                        )}
                        {draft.status !== "PUBLISHED" && (
                          <Button
                            size="sm"
                            onClick={() => publishDraft(draft)}
                            disabled={busy === `publish-${draft.id}` || !threadsApiReady}
                            title={!threadsApiReady ? "需先在連線設定綁定 Threads API" : undefined}
                          >
                            {busy === `publish-${draft.id}` ? (
                              <Loader2 className="h-3.5 w-3.5 animate-spin" />
                            ) : (
                              <Send className="h-3.5 w-3.5" />
                            )}
                            發布留言
                          </Button>
                        )}
                      </div>
                    </div>
                  );
                })}
              </CardContent>
            </Card>
            );
          })}
          {totalPages > 1 && (
            <div className="flex items-center justify-center gap-3 pt-2">
              <Button size="sm" variant="outline" disabled={page <= 1} onClick={() => setPage((value) => Math.max(1, value - 1))}>
                <ChevronLeft className="h-4 w-4" />上一頁
              </Button>
              <span className="text-xs text-muted-foreground">第 {page} / {totalPages} 頁</span>
              <Button size="sm" variant="outline" disabled={page >= totalPages} onClick={() => setPage((value) => Math.min(totalPages, value + 1))}>
                下一頁<ChevronRight className="h-4 w-4" />
              </Button>
            </div>
          )}
        </div>
      )}
    </div>
  );
}
