import { useCallback, useEffect, useMemo, useState } from "react";
import { PageHeader } from "../components/layout/PageHeader";
import { PersonaWorkbench } from "../components/persona/PersonaWorkbench";
import { AccountAvatar, Badge, Button, EmptyState, Pager } from "../components/ui";
import { useData, useRepos } from "../data/DataContext";
import type { AccountHealth, ThreadsAccount } from "../domain/types";
import { useI18n } from "../i18n/I18nContext";
import { pageSlice } from "../lib/pagination";
import { formatLocalDateTime, formatSessionExpiry } from "../lib/time";

const ACCOUNTS_PAGE = 8;

type CrewTab = "accounts" | "personas";

type BadgeTone = "success" | "warning" | "danger" | "neutral";

/**
 * 單一健康狀態：不可同時「異常／不可用」又「token 有效」。
 * 優先序：不可用／error → 斷開 → 到期時間 → 已連線
 */
function accountHealth(
  acc: ThreadsAccount,
  t: (key: string, params?: Record<string, string | number>) => string,
): { tone: BadgeTone; label: string; detail: string } {
  const session = formatSessionExpiry(acc.session_expires_at);
  const expiryLine =
    session.kind === "unknown"
      ? ""
      : `${t("crew.expires", { time: session.absolute })}${
          session.relative && session.relative !== "—" ? ` · ${session.relative}` : ""
        }`;
  const refreshLine = acc.session_refreshed_at
    ? t("crew.lastRefresh", { time: formatLocalDateTime(acc.session_refreshed_at) })
    : "";
  const join = (...parts: string[]) => parts.filter(Boolean).join(" · ");

  // 授權／API 壞了：只顯示需重連，不看「到期還有效」
  if (acc.connection === "disconnected") {
    return {
      tone: "neutral",
      label: t("crew.connection.disconnected"),
      detail: join(t("crew.health.disconnectedHint"), refreshLine),
    };
  }
  if (acc.connection === "error" || !acc.is_usable) {
    return {
      tone: "danger",
      label: t("crew.health.needsReconnect"),
      detail: join(acc.error_message || t("crew.health.needsReconnectHint"), refreshLine),
    };
  }
  // connected + usable → 以到期時間為準
  if (session.kind === "expired") {
    return {
      tone: "danger",
      label: t("crew.session.expired"),
      detail: join(expiryLine, t("crew.health.expiredHint"), refreshLine),
    };
  }
  if (session.kind === "soon") {
    return {
      tone: "warning",
      label: t("crew.session.soon"),
      detail: join(expiryLine, refreshLine),
    };
  }
  if (session.kind === "ok") {
    return {
      tone: "success",
      label: t("crew.session.ok"),
      detail: join(expiryLine, refreshLine),
    };
  }
  // 已連線但沒到期時間
  return {
    tone: "success",
    label: t("crew.connection.connected"),
    detail: join(t("crew.session.unknown"), refreshLine),
  };
}

export function CrewPage() {
  const repos = useRepos();
  const { refresh, tick } = useData();
  const { t } = useI18n();
  const [tab, setTab] = useState<CrewTab>("accounts");
  const [accounts, setAccounts] = useState<ThreadsAccount[]>([]);
  const [opHealth, setOpHealth] = useState<Record<string, AccountHealth>>({});
  const [accPage, setAccPage] = useState(1);
  const [busy, setBusy] = useState("");
  const [message, setMessage] = useState("");
  const [error, setError] = useState("");

  const load = useCallback(async () => {
    try {
      // 帳號列表失敗時若只留空陣列，畫面會顯示「尚未連接帳號」，跟真的沒帳號分不出來。
      setAccounts(await repos.accounts.list());
      setError("");
    } catch (e) {
      setError(e instanceof Error ? e.message : t("crew.loadFail"));
      return;
    }
    const list = await repos.growth.listAccountHealth().catch(() => [] as AccountHealth[]);
    const map: Record<string, AccountHealth> = {};
    for (const h of list) map[h.threads_account_id] = h;
    setOpHealth(map);
  }, [repos.accounts, repos.growth, t]);

  const pagedAccounts = useMemo(
    () => pageSlice(accounts, accPage, ACCOUNTS_PAGE),
    [accounts, accPage],
  );

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

  useEffect(() => {
    const q = new URLSearchParams(window.location.search);
    const oauth = q.get("oauth");
    if (!oauth) return;
    if (oauth === "ok") {
      setError("");
      setMessage(t("crew.msg.oauthOk"));
      void load();
      refresh();
    } else {
      setMessage("");
      setError(q.get("msg") || t("crew.msg.oauthFail"));
    }
    // 清 query，避免刷新重複提示
    const url = new URL(window.location.href);
    url.searchParams.delete("oauth");
    url.searchParams.delete("msg");
    window.history.replaceState({}, "", url.pathname + url.search);
  }, [load, refresh, t]);

  async function connectAccount() {
    setBusy("create");
    setMessage("");
    setError("");
    try {
      const { authorize_url } = await repos.accounts.oauthStart();
      if (authorize_url) {
        window.location.href = authorize_url;
        return;
      }
      throw new Error(t("crew.msg.oauthUrlFail"));
    } catch (e) {
      setError(e instanceof Error ? e.message : t("crew.msg.refreshFail"));
    } finally {
      setBusy("");
    }
  }

  async function removeAccount(acc: ThreadsAccount) {
    if (!window.confirm(t("crew.confirmDelete", { user: acc.username }))) {
      return;
    }
    setBusy(`del:${acc.id}`);
    setMessage("");
    setError("");
    try {
      await repos.accounts.remove(acc.id);
      setMessage(t("crew.msg.deleted", { user: acc.username }));
      refresh();
      await load();
    } catch (e) {
      setError(e instanceof Error ? e.message : t("crew.msg.refreshFail"));
    } finally {
      setBusy("");
    }
  }

  async function refreshAccount(acc: ThreadsAccount) {
    setBusy(`refresh:${acc.id}`);
    setMessage("");
    setError("");
    try {
      await repos.accounts.refreshSession(acc.id);
      setMessage(t("crew.msg.refreshed", { user: acc.username }));
      await load();
    } catch (e) {
      setError(e instanceof Error ? e.message : t("crew.msg.refreshFail"));
    } finally {
      setBusy("");
    }
  }

  return (
    <>
      <PageHeader title={t("crew.title")} />

      <div className="hb-tabs" role="tablist">
        <button
          type="button"
          className={`hb-tab ${tab === "accounts" ? "is-active" : ""}`}
          onClick={() => setTab("accounts")}
        >
          {t("crew.tab.accounts")}
        </button>
        <button
          type="button"
          className={`hb-tab ${tab === "personas" ? "is-active" : ""}`}
          onClick={() => setTab("personas")}
        >
          {t("crew.tab.personas")}
        </button>
      </div>

      {tab === "accounts" ? (
        <div className="hb-stack">
          <div className="hb-toolbar">
            <Button type="button" onClick={() => void connectAccount()} disabled={Boolean(busy)}>
              {busy === "create" ? t("crew.connecting") : t("crew.connect")}
            </Button>
            <p className="text-muted" style={{ margin: 0, fontSize: "var(--hb-text-xs)", alignSelf: "center" }}>
              {t("crew.tokenRenewHint")}
            </p>
          </div>

          {message ? (
            <p className="hb-banner-ok" role="status">
              {message}
            </p>
          ) : null}
          {error ? (
            <p className="hb-banner-error" role="alert">
              {error}
            </p>
          ) : null}

          {accounts.length === 0 ? (
            error ? null : <EmptyState title={t("crew.empty")} />
          ) : (
            <>
            <ul className="hb-compact-list">
              {pagedAccounts.map((acc) => {
                const health = accountHealth(acc, t);
                const deleting = busy === `del:${acc.id}`;
                return (
                  <li key={acc.id} className="hb-compact-row">
                    <AccountAvatar account={acc} size="lg" />
                    <div className="hb-compact-row__body">
                      <div className="hb-compact-row__title">
                        <strong>{acc.display_name}</strong>
                        <span className="text-muted">@{acc.username}</span>
                      </div>
                      <div className="hb-inline-badges">
                        <Badge tone={health.tone}>{health.label}</Badge>
                        {opHealth[acc.id] ? (
                          <Badge
                            tone={
                              opHealth[acc.id].level === "throttle"
                                ? "danger"
                                : opHealth[acc.id].level === "warn"
                                  ? "warning"
                                  : "neutral"
                            }
                          >
                            {t("crew.opHealthScore", { n: opHealth[acc.id].score })}
                          </Badge>
                        ) : null}
                      </div>
                      {health.detail ? (
                        <p className="text-muted hb-compact-row__meta">{health.detail}</p>
                      ) : null}
                      {opHealth[acc.id]?.advice ? (
                        <p className="text-muted hb-compact-row__meta">{opHealth[acc.id].advice}</p>
                      ) : null}
                    </div>
                    <div className="hb-compact-row__actions">
                      <Button
                        type="button"
                        variant="secondary"
                        className="hb-compact-row__action"
                        disabled={Boolean(busy) || acc.connection === "disconnected"}
                        title={t("crew.refreshSessionHint")}
                        onClick={() => void refreshAccount(acc)}
                      >
                        {busy === `refresh:${acc.id}` ? "…" : t("crew.refreshSession")}
                      </Button>
                      <Button
                        type="button"
                        variant="ghost"
                        className="hb-compact-row__action"
                        disabled={Boolean(busy)}
                        onClick={() => void removeAccount(acc)}
                      >
                        {deleting ? "…" : t("common.delete")}
                      </Button>
                    </div>
                  </li>
                );
              })}
            </ul>
            <Pager
              total={accounts.length}
              page={accPage}
              pageSize={ACCOUNTS_PAGE}
              onPageChange={setAccPage}
            />
            </>
          )}
        </div>
      ) : (
        <PersonaWorkbench />
      )}
    </>
  );
}
