import { useEffect, useState } from "react";
import { api, Pagination } from "../../api/haixun";
import { HoverHelpTip } from "../../components/HoverHelpTip";
import { MentionContextBlock } from "../../components/MentionContextBlock";
import { buildMentionAiPayload, cachedMentionContext } from "../../lib/mentionContext";
import { Badge, Button, Card, Field, Textarea } from "../../components/ui";
import { shortText } from "../../lib/format";
import { isMentionInboxSyncedAtFresh, mentionSyncedAtMs } from "../../lib/mentionInboxCache";
import {
  formatMentionTimestamp,
  mentionInboxItemToHit,
  mentionReplyTargetId,
  mentionSurface,
  mentionSurfaceLabel,
  mentionThreadRootId,
  type ThreadsMentionHit
} from "../../lib/mentionInbox";

const MENTION_PAGE_SIZE = 8;

function normalizeMentionPagination(
  raw: Pagination | undefined,
  page: number,
  pageSize: number,
  listLength: number
): Pagination {
  if (raw && typeof raw.total === "number") {
    const totalPages =
      typeof raw.totalPages === "number" && raw.totalPages > 0
        ? raw.totalPages
        : raw.total > 0
          ? Math.ceil(raw.total / pageSize)
          : 0;
    return {
      total: raw.total,
      page: raw.page || page,
      pageSize: raw.pageSize || pageSize,
      totalPages
    };
  }
  return {
    total: listLength,
    page,
    pageSize,
    totalPages: listLength > 0 ? 1 : 0
  };
}

type Props = {
  accountId: string;
  accountUsername?: string;
  selectedPersonaId: string;
};

export function MentionsInboxPanel({ accountId, accountUsername, selectedPersonaId }: Props) {
  const [items, setItems] = useState<ThreadsMentionHit[]>([]);
  const [syncing, setSyncing] = useState(false);
  const [listing, setListing] = useState(false);
  const [error, setError] = useState("");
  const [loadedAt, setLoadedAt] = useState<number | null>(null);
  const [readyCount, setReadyCount] = useState(0);
  const [page, setPage] = useState(1);
  const [pagination, setPagination] = useState<Pagination | null>(null);
  const [replyTextById, setReplyTextById] = useState<Record<string, string>>({});
  const [generatingId, setGeneratingId] = useState("");
  const [publishingId, setPublishingId] = useState("");
  const [feedbackById, setFeedbackById] = useState<
    Record<string, { kind: "success" | "error" | "info"; message: string; permalink?: string }>
  >({});

  function applyListResult(
    hits: ThreadsMentionHit[],
    nextPagination: Pagination,
    newestSyncedAt?: number,
    readyTotal?: number
  ) {
    setItems(hits);
    setPagination(nextPagination);
    setReadyCount(readyTotal ?? hits.filter((hit) => hit.reply_ready).length);
    const syncedMs = mentionSyncedAtMs(newestSyncedAt) || Date.now();
    setLoadedAt(nextPagination.total > 0 || hits.length > 0 ? syncedMs : null);
  }

  async function loadMentionPage(nextAccountId = accountId, nextPage = page) {
    if (!nextAccountId) {
      setItems([]);
      setPagination(null);
      setLoadedAt(null);
      setReadyCount(0);
      return null;
    }

    setListing(true);
    setError("");
    try {
      const result = await api.listMentionInbox(nextAccountId, nextPage, MENTION_PAGE_SIZE);
      const hits = (result.list || []).map(mentionInboxItemToHit);
      const pagination = normalizeMentionPagination(result.pagination, nextPage, MENTION_PAGE_SIZE, hits.length);
      applyListResult(hits, pagination, result.newest_synced_at, result.ready_total);
      setPage(nextPage);
      return result;
    } catch (err) {
      setError(err instanceof Error ? err.message : "載入提及失敗");
      return null;
    } finally {
      setListing(false);
    }
  }

  async function syncMentions(nextAccountId = accountId, options?: { clearFeedback?: boolean }) {
    if (!nextAccountId) return;

    setSyncing(true);
    setError("");
    if (options?.clearFeedback !== false) {
      setFeedbackById({});
    }
    try {
      await api.syncMentionInbox(nextAccountId, 25, 4);
      setPage(1);
      await loadMentionPage(nextAccountId, 1);
    } catch (err) {
      setError(err instanceof Error ? err.message : "同步提及失敗");
    } finally {
      setSyncing(false);
    }
  }

  async function hydrateMentions(nextAccountId = accountId, options?: { force?: boolean }) {
    if (!nextAccountId) {
      setItems([]);
      setPagination(null);
      setLoadedAt(null);
      setReadyCount(0);
      return;
    }

    setPage(1);
    const result = await loadMentionPage(nextAccountId, 1);
    if (!result) return;

    const total = result.pagination?.total ?? result.list?.length ?? 0;
    const needSync =
      options?.force === true || total === 0 || !isMentionInboxSyncedAtFresh(result.newest_synced_at);
    if (!needSync) return;
    await syncMentions(nextAccountId, { clearFeedback: options?.force === true });
  }

  useEffect(() => {
    setFeedbackById({});
    setReplyTextById({});
    setPage(1);
    void hydrateMentions(accountId);
  }, [accountId]);

  async function copyReply(hit: ThreadsMentionHit) {
    const text = replyTextById[hit.id]?.trim();
    if (!text) {
      setFeedbackById((current) => ({
        ...current,
        [hit.id]: { kind: "error", message: "請先輸入或生成回覆內容再複製" }
      }));
      return;
    }
    try {
      await navigator.clipboard.writeText(text);
      setFeedbackById((current) => ({
        ...current,
        [hit.id]: { kind: "info", message: "已複製回覆，可開啟 Threads 貼上" }
      }));
    } catch {
      setFeedbackById((current) => ({
        ...current,
        [hit.id]: { kind: "error", message: "無法複製到剪貼簿，請手動選取文字" }
      }));
    }
  }

  async function generateReply(hit: ThreadsMentionHit) {
    if (!accountId) return;
    if (!selectedPersonaId) {
      setFeedbackById((current) => ({
        ...current,
        [hit.id]: { kind: "error", message: "請先選擇回覆人設，AI 才會用你的人設語氣生成" }
      }));
      return;
    }
    setGeneratingId(hit.id);
    setFeedbackById((current) => ({
      ...current,
      [hit.id]: { kind: "info", message: "正在依快取原文脈絡生成 AI 回覆…" }
    }));
    try {
      const context = cachedMentionContext(hit);
      if (!context) {
        setFeedbackById((current) => ({
          ...current,
          [hit.id]: { kind: "error", message: "缺少快取原文脈絡，請先重新同步提及清單" }
        }));
        return;
      }
      const aiPayload = buildMentionAiPayload(hit, context);
      const data = await api.generateOwnPostReplyDraft(accountId, {
        media_id: mentionThreadRootId(hit),
        persona_id: selectedPersonaId,
        reply_to_id: mentionReplyTargetId(hit),
        post_text: aiPayload.post_text,
        reply_text: aiPayload.reply_text,
        thread_post_text: aiPayload.thread_post_text,
        parent_reply_text: aiPayload.parent_reply_text || undefined
      });
      setReplyTextById((current) => ({ ...current, [hit.id]: data.text }));
      const contextHint =
        mentionSurface(hit) === "post"
          ? "已讀取貼文全文"
          : aiPayload.parent_reply_text
            ? "已讀取主串貼文、上層留言與 @ 你的內容"
            : "已讀取主串貼文與 @ 你的內容";
      setFeedbackById((current) => ({
        ...current,
        [hit.id]: { kind: "info", message: `AI 回覆草稿已生成（${contextHint}），可編輯後發送` }
      }));
    } catch (err) {
      setFeedbackById((current) => ({
        ...current,
        [hit.id]: { kind: "error", message: err instanceof Error ? err.message : "AI 草稿生成失敗" }
      }));
    } finally {
      setGeneratingId("");
    }
  }

  async function publishReply(hit: ThreadsMentionHit) {
    const text = replyTextById[hit.id]?.trim();
    if (!accountId || !text) return;
    if (!hit.reply_ready) {
      setFeedbackById((current) => ({
        ...current,
        [hit.id]: { kind: "error", message: "尚未完成回覆註冊，請先重新同步提及" }
      }));
      return;
    }

    setPublishingId(hit.id);
    setFeedbackById((current) => ({
      ...current,
      [hit.id]: { kind: "info", message: "正在發送回覆到 Threads（使用同步時快取，不再搜尋）…" }
    }));
    try {
      const published = await api.publishMentionReply(accountId, hit.id, text);
      setReplyTextById((current) => ({ ...current, [hit.id]: "" }));
      setFeedbackById((current) => ({
        ...current,
        [hit.id]: {
          kind: "success",
          message: "回覆已成功發布到 Threads",
          permalink: published?.permalink
        }
      }));
      await loadMentionPage(accountId, page);
    } catch (err) {
      const msg = err instanceof Error ? err.message : "發送回覆失敗";
      setFeedbackById((current) => ({
        ...current,
        [hit.id]: {
          kind: "error",
          message: msg.includes("502")
            ? `${msg}（多半是權限未開或請求逾時；請到 Threads 帳號頁跑診斷後重新同步）`
            : msg
        }
      }));
    } finally {
      setPublishingId("");
    }
  }

  const mineLabel = accountUsername ? `@${accountUsername.replace(/^@/, "")}` : "你的帳號";
  const hasSearched = loadedAt !== null;
  const totalCount = pagination?.total ?? 0;
  const totalPages = pagination?.totalPages ?? 0;
  const busy = syncing || listing;

  return (
    <Card
      title="誰 @ 了我"
      action={
        <Button
          variant="soft"
          loading={syncing}
          disabled={!accountId || syncing}
          onClick={() => void hydrateMentions(accountId, { force: true })}
        >
          {hasSearched ? "強制尋找" : "尋找 @ 提及"}
        </Button>
      }
    >
      <div className="page-grid">
        <p className="muted hx-text-sm" style={{ margin: 0 }}>
          顯示其他人在 <strong>貼文、留言或引用</strong> 中 tag {mineLabel} 的內容。每頁 {MENTION_PAGE_SIZE} 則；同步時會向 Threads 分頁抓取並存入資料庫，翻頁只讀快取。
        </p>

        {busy ? (
          <div className="hx-formula-status hx-formula-status--loading" role="status">
            <span className="hx-formula-status__spinner" aria-hidden="true" />
            <strong>{syncing ? "正在向 Threads 尋找 @ 提及並快取…" : "正在載入提及清單…"}</strong>
          </div>
        ) : null}

        {error ? (
          <div className="hx-mention-card hx-mention-card--error" role="alert">
            <strong>無法載入提及</strong>
            <span>{error}</span>
          </div>
        ) : null}

        {!busy && !error && hasSearched ? (
          <p className="muted hx-text-xs" style={{ margin: 0 }}>
            上次更新：{new Date(loadedAt).toLocaleTimeString("zh-TW")} · 共 {totalCount} 則 · 可 API 回覆 {readyCount} 則
          </p>
        ) : null}

        {!busy && !error && !hasSearched && !syncing ? (
          <p className="muted">尚無快取資料，正在向 Threads 尋找 @ 你的內容…</p>
        ) : null}

        {!busy && !error && hasSearched && totalCount === 0 ? (
          <p className="muted">目前沒有 @ 你的內容，或權限尚未開放完整公開提及。</p>
        ) : null}

        <div className="hx-mentions-inbox__list">
          {items.map((item) => {
            const surface = mentionSurface(item);
            return (
              <article key={item.id} className="hx-mentions-inbox__item">
                <header className="hx-mentions-inbox__head">
                  <div className="button-row" style={{ flexWrap: "wrap" }}>
                    <strong>{item.username ? `@${item.username}` : "未知作者"}</strong>
                    <Badge variant={surface === "reply" ? "warning" : surface === "quote" ? "neutral" : "brand"}>
                      {mentionSurfaceLabel(surface)}
                    </Badge>
                    {item.media_type ? <Badge variant="neutral">{item.media_type}</Badge> : null}
                    {item.has_replies ? <Badge variant="success">有後續留言</Badge> : null}
                    {item.reply_ready ? (
                      <Badge variant="success">已快取可回覆</Badge>
                    ) : (
                      <>
                        <Badge variant="warning">同步時註冊失敗</Badge>
                        {item.reply_ready_msg ? <HoverHelpTip text={item.reply_ready_msg} /> : null}
                      </>
                    )}
                  </div>
                  {item.timestamp ? (
                    <span className="muted hx-text-xs">{formatMentionTimestamp(item.timestamp)}</span>
                  ) : null}
                </header>

                <MentionContextBlock hit={item} />

                {surface === "post" ? (
                  <>
                    <p className="hx-mentions-inbox__text">{item.text || shortText(item.id, 120)}</p>
                    <div className="button-row">
                      {item.permalink ? (
                        <a href={item.permalink} target="_blank" rel="noreferrer" className="hx-link-chip">
                          開啟 Threads
                        </a>
                      ) : null}
                    </div>
                  </>
                ) : null}

                <div className="hx-mentions-inbox__composer">
                  <Field label={`回覆這則${mentionSurfaceLabel(surface)}`}>
                    <Textarea
                      value={replyTextById[item.id] || ""}
                      onChange={(e) =>
                        setReplyTextById((current) => ({ ...current, [item.id]: e.target.value }))
                      }
                      placeholder="輸入回覆，或用 AI 依人設生成"
                      rows={3}
                    />
                    <div className="button-row" style={{ marginTop: 8, flexWrap: "wrap" }}>
                      <Button
                        variant="soft"
                        loading={generatingId === item.id}
                        disabled={!selectedPersonaId}
                        onClick={() => void generateReply(item)}
                      >
                        AI 生成回覆
                      </Button>
                      {item.reply_ready ? (
                        <Button
                          variant="primary"
                          loading={publishingId === item.id}
                          disabled={!replyTextById[item.id]?.trim() || publishingId === item.id}
                          onClick={() => void publishReply(item)}
                        >
                          {publishingId === item.id ? "發送中…" : "API 發送回覆"}
                        </Button>
                      ) : (
                        <>
                          {item.permalink ? (
                            <a href={item.permalink} target="_blank" rel="noreferrer" className="hx-link-chip">
                              開啟 Threads
                            </a>
                          ) : null}
                          <Button
                            variant="primary"
                            disabled={!replyTextById[item.id]?.trim()}
                            onClick={() => void copyReply(item)}
                          >
                            複製回覆
                          </Button>
                        </>
                      )}
                    </div>
                    {feedbackById[item.id] ? (
                      <div
                        className={`hx-publish-feedback hx-publish-feedback--${
                          feedbackById[item.id].kind === "success"
                            ? "success"
                            : feedbackById[item.id].kind === "error"
                              ? "error"
                              : "info"
                        }`}
                        role={feedbackById[item.id].kind === "error" ? "alert" : "status"}
                        style={{ marginTop: 8 }}
                      >
                        <strong>
                          {feedbackById[item.id].kind === "success"
                            ? "發送成功"
                            : feedbackById[item.id].kind === "error"
                              ? "發送失敗"
                              : "處理中"}
                        </strong>
                        <p>{feedbackById[item.id].message}</p>
                        {feedbackById[item.id].permalink ? (
                          <a
                            href={feedbackById[item.id].permalink}
                            target="_blank"
                            rel="noreferrer"
                            className="hx-link-chip"
                          >
                            查看你剛發的回覆
                          </a>
                        ) : null}
                      </div>
                    ) : null}
                  </Field>
                </div>
              </article>
            );
          })}
        </div>

        {totalPages > 1 ? (
          <div className="hx-pager">
            <span className="hx-pager-meta">
              第 {page} / {totalPages} 頁 · 本頁 {items.length} 則 · 共 {totalCount} 則 @ 提及
            </span>
            <div className="button-row">
              <Button
                variant="soft"
                disabled={page <= 1 || busy}
                onClick={() => void loadMentionPage(accountId, page - 1)}
              >
                上一頁
              </Button>
              <Button
                variant="soft"
                disabled={page >= totalPages || busy}
                onClick={() => void loadMentionPage(accountId, page + 1)}
              >
                下一頁
              </Button>
            </div>
          </div>
        ) : null}
      </div>
    </Card>
  );
}