import { useCallback, useEffect, useMemo, useState } from "react";
import { Link } from "react-router-dom";
import { PageHeader } from "../components/layout/PageHeader";
import { Badge, Button, Card, EmptyState, Pager } from "../components/ui";
import { useData, useRepos } from "../data/DataContext";
import type { OutboxBundle, OutboxBundleStatus } from "../domain/types";
import { useI18n } from "../i18n/I18nContext";
import { pageSlice } from "../lib/pagination";
import { formatLocalDateTime } from "../lib/time";

const OUTBOX_PAGE = 10;

type OutboxTab = "active" | "history";

function progress(b: OutboxBundle) {
  const done = b.steps.filter((s) => s.status === "published").length;
  return `${done}/${b.steps.length}`;
}

/** 尚未收工：仍在排程／發送／有失敗可處理 */
function isActiveQueue(status: OutboxBundleStatus): boolean {
  return status === "scheduling" || status === "active" || status === "partial_failed";
}

function statusTone(status: OutboxBundleStatus): "success" | "danger" | "brand" | "neutral" | "warning" {
  switch (status) {
    case "completed":
      return "success";
    case "partial_failed":
      return "danger";
    case "cancelled":
      return "neutral";
    case "scheduling":
      return "warning";
    default:
      return "brand";
  }
}

export function OutboxPage() {
  const repos = useRepos();
  const { refresh, tick } = useData();
  const { t } = useI18n();
  const [items, setItems] = useState<OutboxBundle[]>([]);
  const [tab, setTab] = useState<OutboxTab>("active");
  const [page, setPage] = useState(1);
  const [busyId, setBusyId] = useState("");
  const [message, setMessage] = useState("");
  const [error, setError] = useState("");

  function statusLabel(status: OutboxBundleStatus): string {
    switch (status) {
      case "scheduling":
        return t("outbox.status.scheduling");
      case "active":
        return t("outbox.status.active");
      case "completed":
        return t("outbox.status.completed");
      case "partial_failed":
        return t("outbox.status.partial_failed");
      case "cancelled":
        return t("outbox.status.cancelled");
      default:
        return status;
    }
  }

  const load = useCallback(async () => {
    try {
      setItems(await repos.outbox.list());
      setError("");
    } catch (e) {
      setError(e instanceof Error ? e.message : t("outbox.loadFail"));
    }
  }, [repos.outbox, t]);

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

  useEffect(() => {
    setPage(1);
  }, [tab]);

  const activeItems = useMemo(
    () => items.filter((i) => isActiveQueue(i.status)).sort((a, b) => b.updated_at - a.updated_at),
    [items],
  );
  const historyItems = useMemo(
    () =>
      items
        .filter((i) => !isActiveQueue(i.status))
        .sort((a, b) => b.updated_at - a.updated_at),
    [items],
  );

  const hasInFlightItem = items.some(
    (item) => item.status === "scheduling" || item.status === "active",
  );

  useEffect(() => {
    if (!hasInFlightItem) return;
    const timer = window.setInterval(() => void load(), 2000);
    return () => window.clearInterval(timer);
  }, [hasInFlightItem, load]);

  const tabItems = tab === "active" ? activeItems : historyItems;
  const shown = useMemo(
    () => pageSlice(tabItems, page, OUTBOX_PAGE),
    [tabItems, page],
  );

  async function removeItem(item: OutboxBundle) {
    if (!window.confirm(t("outbox.confirmDelete", { title: item.title }))) return;
    setBusyId(item.id);
    setMessage("");
    setError("");
    try {
      await repos.outbox.remove(item.id);
      await load();
      setMessage(t("outbox.deleted", { title: item.title }));
      refresh();
    } catch (e) {
      setError(e instanceof Error ? e.message : t("outbox.deleteFail"));
    } finally {
      setBusyId("");
    }
  }

  return (
    <>
      <PageHeader title={t("outbox.title")} />
      {message ? (
        <p className="hb-banner-ok" role="status">
          {message}
        </p>
      ) : null}
      {error ? (
        <p className="hb-form-error" role="alert">
          {error}
        </p>
      ) : null}

      <div className="hb-tabs hb-tabs--sm" role="tablist" aria-label={t("outbox.tabsAria")} style={{ marginBottom: "0.85rem" }}>
        <button
          type="button"
          role="tab"
          aria-selected={tab === "active"}
          className={`hb-tab ${tab === "active" ? "is-active" : ""}`}
          onClick={() => setTab("active")}
        >
          {t("outbox.tab.active")}
          <span className="hb-tab__count"> {activeItems.length}</span>
        </button>
        <button
          type="button"
          role="tab"
          aria-selected={tab === "history"}
          className={`hb-tab ${tab === "history" ? "is-active" : ""}`}
          onClick={() => setTab("history")}
        >
          {t("outbox.tab.history")}
          <span className="hb-tab__count"> {historyItems.length}</span>
        </button>
      </div>

      {items.length === 0 ? (
        <EmptyState
          title={t("outbox.empty")}
          action={
            <Link to="/app/studio/new">
              <Button type="button">{t("today.newThread")}</Button>
            </Link>
          }
        />
      ) : shown.length === 0 ? (
        <EmptyState
          title={tab === "active" ? t("outbox.activeEmpty") : t("outbox.historyEmpty")}
          action={
            tab === "active" && historyItems.length > 0 ? (
              <Button type="button" variant="ghost" onClick={() => setTab("history")}>
                {t("outbox.historyN", { n: historyItems.length })}
              </Button>
            ) : tab === "active" ? (
              <Link to="/app/studio/new">
                <Button type="button">{t("today.newThread")}</Button>
              </Link>
            ) : activeItems.length > 0 ? (
              <Button type="button" variant="ghost" onClick={() => setTab("active")}>
                {t("outbox.backActive", { n: activeItems.length })}
              </Button>
            ) : undefined
          }
        />
      ) : (
        <div className="hb-stack">
          {shown.map((item) => (
            <Card key={item.id}>
              <div className="hb-list-row">
                <div>
                  <strong>{item.title}</strong>
                  <p className="text-muted">
                    {t("outbox.progress", { progress: progress(item) })} · {formatLocalDateTime(item.updated_at)}
                  </p>
                </div>
                <div className="hb-list-row__actions">
                  <Badge tone={statusTone(item.status)}>{statusLabel(item.status)}</Badge>
                  <Link to={`/app/outbox/${item.id}`}>
                    <Button variant="ghost" type="button">
                      {t("outbox.detail")}
                    </Button>
                  </Link>
                  <Button
                    type="button"
                    variant="danger"
                    disabled={busyId === item.id}
                    onClick={() => void removeItem(item)}
                  >
                    {busyId === item.id ? t("outbox.deleting") : t("common.delete")}
                  </Button>
                </div>
              </div>
            </Card>
          ))}
          <Pager
            total={tabItems.length}
            page={page}
            pageSize={OUTBOX_PAGE}
            onPageChange={setPage}
          />
        </div>
      )}
    </>
  );
}
