import { useMemo, useState } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { api, type SocialWatchPayload, type SocialWatchPost } from "../lib/api";
import { AppIcon } from "./PixelIcons";
import { Card, Loading, ErrorState, Tag, RefreshButton } from "./ui";

type Lang = "en" | "zh";

function impactTone(impact?: string): "up" | "down" | "gold" | "cool" {
  if (impact === "critical") return "down";
  if (impact === "high") return "gold";
  if (impact === "medium") return "cool";
  return "gold";
}

function impactLabel(impact?: string) {
  if (impact === "critical") return "重大";
  if (impact === "high") return "高關注";
  if (impact === "medium") return "留意";
  return "一般";
}

function platformLabel(p?: string) {
  if (p === "truth_social") return "Truth Social";
  if (p === "x") return "X";
  return p || "—";
}

function fmtWhen(iso?: string | null) {
  if (!iso) return "";
  try {
    return new Date(iso).toLocaleString("zh-TW", { month: "numeric", day: "numeric", hour: "2-digit", minute: "2-digit" });
  } catch {
    return iso.slice(0, 16).replace("T", " ");
  }
}

function fmtAgo(iso?: string | null) {
  if (!iso) return "";
  try {
    const diff = Date.now() - new Date(iso).getTime();
    if (diff < 60_000) return "剛剛";
    if (diff < 3600_000) return `${Math.floor(diff / 60_000)} 分鐘前`;
    if (diff < 86400_000) return `${Math.floor(diff / 3600_000)} 小時前`;
    return fmtWhen(iso);
  } catch {
    return fmtWhen(iso);
  }
}

function PostRow({ post, lang }: { post: SocialWatchPost; lang: Lang }) {
  const showZh = lang === "zh";
  const body = showZh ? post.textZh || post.textEn || post.text : post.textEn || post.text;
  const alt = showZh && post.textEn && post.textZh && post.textEn !== post.textZh ? post.textEn : null;

  return (
    <article className={`social-post social-post--${post.impact || "low"}`}>
      <header className="social-post-head">
        <div>
          <b>{post.authorZh || post.handle}</b>
          <span className="muted small">
            @{post.handle} · {platformLabel(post.platform)}
            {post.roleZh ? ` · ${post.roleZh}` : ""}
          </span>
        </div>
        <div className="social-post-badges">
          <Tag tone={impactTone(post.impact)}>{impactLabel(post.impact)}</Tag>
          {post.publishedAt ? <time className="small muted">{fmtWhen(post.publishedAt)}</time> : null}
        </div>
      </header>
      <p className="social-post-body">{body}</p>
      {alt ? <p className="social-post-alt small muted">原文：{alt}</p> : null}
      {post.needsTranslation ? <p className="social-post-alt small muted">（翻譯額度已用盡，顯示原文）</p> : null}
      {post.isMediaOnly && post.media?.length ? (
        <p className="social-post-alt small muted">
          含媒體附件 ·{" "}
          <a href={post.media[0]} target="_blank" rel="noopener noreferrer">
            開啟媒體
          </a>
        </p>
      ) : null}
      <footer className="social-post-foot">
        {post.url ? (
          <a href={post.url} target="_blank" rel="noopener noreferrer">
            查看原文
          </a>
        ) : null}
        {post.metrics?.likes != null ? <span className="small muted">♥ {post.metrics.likes}</span> : null}
        {post.metrics?.reposts != null ? <span className="small muted">↻ {post.metrics.reposts}</span> : null}
      </footer>
    </article>
  );
}

type Props = {
  className?: string;
  limit?: number;
};

export default function SocialWatchPanel({ className = "mt", limit = 24 }: Props) {
  const [lang, setLang] = useState<Lang>("zh");
  const [filter, setFilter] = useState<string>("all");
  const [refreshing, setRefreshing] = useState(false);
  const queryClient = useQueryClient();

  const q = useQuery({
    queryKey: ["social-watch", lang],
    queryFn: () => api.socialWatch(lang),
    staleTime: 3 * 60 * 1000,
    refetchInterval: 4 * 60 * 1000,
  });

  async function handleRefresh() {
    setRefreshing(true);
    try {
      const fresh = await api.socialWatch(lang, true);
      queryClient.setQueryData(["social-watch", lang], fresh);
    } finally {
      setRefreshing(false);
    }
  }

  const data: SocialWatchPayload | undefined = q.data;
  const accounts = data?.accounts || [];

  const filteredPosts = useMemo(() => {
    const posts = (data?.posts || []).slice(0, limit);
    if (filter === "all") return posts;
    return posts.filter((p) => p.accountId === filter);
  }, [data?.posts, filter, limit]);

  return (
    <Card
      className={className}
      title="大人物動態 · 風向標"
      ico={<AppIcon name="sentiment" size={24} framed variant="hero" />}
      ai
      aiFocus={{ cardTitle: "大人物動態", tab: "compass" }}
      onRefresh={() => void handleRefresh()}
      refreshing={q.isFetching || refreshing}
    >
      <p className="small muted mb-s">
        追蹤川普 Truth Social、馬斯克／Fed／SEC 等 X 貼文。川普每 4 分鐘自動更新；點「重新整理」強制拉最新。
        {data?.truthLatestAt ? (
          <>
            {" "}
            川普最新貼文：<strong>{fmtAgo(data.truthLatestAt)}</strong>
          </>
        ) : null}
      </p>

      <div className="social-watch-toolbar">
        <div className="social-lang-toggle">
          <button type="button" className={lang === "zh" ? "active" : ""} onClick={() => setLang("zh")}>
            中文
          </button>
          <button type="button" className={lang === "en" ? "active" : ""} onClick={() => setLang("en")}>
            原文
          </button>
        </div>
        <RefreshButton onClick={() => void handleRefresh()} loading={q.isFetching || refreshing} />
      </div>

      <div className="social-account-chips">
        <button type="button" className={`social-chip ${filter === "all" ? "active" : ""}`} onClick={() => setFilter("all")}>
          全部 ({data?.postCount ?? 0})
        </button>
        {accounts.map((a) => (
          <button
            key={a.id}
            type="button"
            className={`social-chip ${filter === a.id ? "active" : ""}`}
            onClick={() => setFilter(a.id)}
            title={a.error || undefined}
          >
            {a.nameZh}
            {a.postCount ? ` (${a.postCount})` : a.error ? " ⚠" : ""}
          </button>
        ))}
      </div>

      {q.isLoading ? <Loading label="抓取社群動態…" /> : null}
      {q.error ? <ErrorState detail={(q.error as Error)?.message} /> : null}

      {!q.isLoading && !q.error ? (
        filteredPosts.length ? (
          <div className="social-post-list">
            {filteredPosts.map((p) => (
              <PostRow key={`${p.id}-${lang}`} post={p} lang={lang} />
            ))}
          </div>
        ) : (
          <p className="muted small">暫無貼文（來源可能限流或帳號近期未發文）。</p>
        )
      ) : null}

      {data?.disclaimer ? <p className="small muted mt-s">{data.disclaimer}</p> : null}
      {data?.cached ? <p className="small muted">（快取資料）</p> : null}
    </Card>
  );
}