import { useCallback, useEffect, useState } from "react";
import { Link } from "react-router-dom";
import { useAuth } from "../auth/AuthContext";
import { PageHeader } from "../components/layout/PageHeader";
import { Badge, Button, Card, EmptyState, Pager } from "../components/ui";
import { useData, useRepos } from "../data/DataContext";
import { useJobLive } from "../data/JobLiveContext";
import type { JobListTab } from "../data/repos";
import type { Job } from "../domain/types";
import { useI18n } from "../i18n/I18nContext";
import { useFormatApiError } from "../lib/apiErrors";
import { can, Permission } from "../lib/permissions";
import {
  canDeleteJob,
  isRecurringTokenRenew,
  jobStatusLabel,
  jobStatusTone,
  jobSubtitle,
  jobTemplateLabel,
} from "../lib/jobLabels";
import { formatLocalDateTime } from "../lib/time";

const DEFAULT_PAGE_SIZE = 10;

type TabDef = { id: JobListTab; labelKey: string };

const TABS: TabDef[] = [
  { id: "active", labelKey: "jobs.tab.active" },
  { id: "recurring", labelKey: "jobs.tab.recurring" },
  { id: "history", labelKey: "jobs.tab.history" },
];

export function JobsPage() {
  const repos = useRepos();
  const { member } = useAuth();
  const { refresh } = useData();
  const { revision, reload: reloadLive } = useJobLive();
  const { t } = useI18n();
  const formatApiError = useFormatApiError();
  const canCreateDemo = can(member?.roles, Permission.JobsDemoCreate);

  const [tab, setTab] = useState<JobListTab>("active");
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(DEFAULT_PAGE_SIZE);
  const [jobs, setJobs] = useState<Job[]>([]);
  const [total, setTotal] = useState(0);
  const [loading, setLoading] = useState(true);
  const [busy, setBusy] = useState(false);
  const [deletingId, setDeletingId] = useState<string | null>(null);
  const [message, setMessage] = useState("");
  const [error, setError] = useState("");

  const load = useCallback(async () => {
    setLoading(true);
    setError("");
    try {
      const res = await repos.jobs.list({ tab, page, pageSize });
      setJobs(res.list);
      setTotal(res.pagination.total);
      // 若刪到當頁空了且不是第 1 頁，回退一頁
      if (res.list.length === 0 && page > 1 && res.pagination.total > 0) {
        setPage((p) => Math.max(1, p - 1));
      }
    } catch (e) {
      setError(formatApiError(e, "jobs.loadFail"));
    } finally {
      setLoading(false);
    }
  }, [repos.jobs, tab, page, pageSize, formatApiError]);

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

  // 執行中分頁：跟全域 live revision 同步刷新（進度條）
  useEffect(() => {
    if (tab !== "active" || revision <= 0) return;
    void load();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [revision, tab]);

  function switchTab(next: JobListTab) {
    if (next === tab) return;
    setTab(next);
    setPage(1);
    setMessage("");
    setError("");
  }

  async function startDemo() {
    setBusy(true);
    setMessage("");
    setError("");
    try {
      const job = await repos.jobs.startDemo();
      setMessage(t("jobs.demoCreated", { id: job.id.slice(0, 8) }));
      setTab("active");
      setPage(1);
      await reloadLive();
      await load();
      refresh();
    } catch (e) {
      setError(formatApiError(e, "jobs.demoFail"));
    } finally {
      setBusy(false);
    }
  }

  async function removeJob(job: Job) {
    if (!canDeleteJob(job)) {
      setError(t("jobs.deleteRunningHint"));
      return;
    }
    const name = jobTemplateLabel(job.template_type, t);
    if (!window.confirm(t("jobs.deleteConfirm", { name }))) return;
    setDeletingId(job.id);
    setMessage("");
    setError("");
    try {
      await repos.jobs.remove(job.id);
      setMessage(t("jobs.deleted"));
      await reloadLive();
      await load();
      refresh();
    } catch (e) {
      setError(formatApiError(e, "jobs.deleteFail"));
    } finally {
      setDeletingId(null);
    }
  }

  const emptyTitle =
    tab === "recurring"
      ? t("jobs.empty.recurring")
      : tab === "history"
        ? t("jobs.empty.history")
        : t("jobs.empty.active");

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

      {canCreateDemo ? (
        <div className="hb-toolbar">
          <Button type="button" onClick={() => void startDemo()} disabled={busy}>
            {busy ? t("common.loading") : t("jobs.startDemo")}
          </Button>
        </div>
      ) : null}

      {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" role="tablist" aria-label={t("jobs.tabsAria")}>
        {TABS.map((tb) => (
          <button
            key={tb.id}
            type="button"
            role="tab"
            aria-selected={tab === tb.id}
            className={`hb-tab ${tab === tb.id ? "is-active" : ""}`}
            onClick={() => switchTab(tb.id)}
          >
            {t(tb.labelKey)}
          </button>
        ))}
      </div>

      {tab === "history" ? (
        <p className="text-muted" style={{ margin: "0 0 0.5rem", fontSize: "var(--hb-text-xs)" }}>
          {t("jobs.retentionHint")}
        </p>
      ) : null}
      {tab === "recurring" ? (
        <p className="text-muted" style={{ margin: "0 0 0.5rem", fontSize: "var(--hb-text-xs)" }}>
          {t("jobs.recurringHint")}
        </p>
      ) : null}

      {loading && jobs.length === 0 ? (
        <p className="text-muted">{t("common.loading")}</p>
      ) : jobs.length === 0 ? (
        <EmptyState title={emptyTitle} />
      ) : (
        <div className="hb-stack">
          <p className="text-muted" style={{ margin: 0, fontSize: "var(--hb-text-sm)" }}>
            {t("jobs.total", { n: total })}
          </p>
          {jobs.map((job) => (
            <Card key={job.id}>
              <div className="hb-list-row">
                <div style={{ flex: 1, minWidth: 0 }}>
                  <strong>{jobTemplateLabel(job.template_type, t)}</strong>
                  <p className="text-muted">{jobSubtitle(job, t, formatLocalDateTime)}</p>
                  {tab === "active" || tab === "history" ? (
                    <div
                      className="hb-progress hb-progress--sm"
                      aria-hidden
                      style={{ marginTop: "0.35rem" }}
                    >
                      <div
                        className="hb-progress__bar"
                        style={{
                          width: `${Math.min(100, Math.max(0, job.progress_percent))}%`,
                        }}
                      />
                    </div>
                  ) : null}
                  <p className="text-muted" style={{ fontSize: "var(--hb-text-sm)" }}>
                    {tab === "recurring"
                      ? formatLocalDateTime(job.run_after || job.updated_at)
                      : `${job.progress_percent}% · ${formatLocalDateTime(job.updated_at)}`}
                    {job.error ? ` · ${job.error}` : ""}
                  </p>
                </div>
                <div className="hb-list-row__actions">
                  {isRecurringTokenRenew(job) ? (
                    <Badge tone="brand">{t("jobs.template.tokenRenewBadge")}</Badge>
                  ) : null}
                  <Badge tone={jobStatusTone(job.status)}>{jobStatusLabel(job.status, t)}</Badge>
                  <Link to={`/app/jobs/${job.id}`} className="hb-btn hb-btn--ghost">
                    {t("jobs.detail")}
                  </Link>
                  {canDeleteJob(job) ? (
                    <Button
                      variant="ghost"
                      type="button"
                      disabled={deletingId === job.id}
                      onClick={() => void removeJob(job)}
                    >
                      {deletingId === job.id ? t("common.loading") : t("jobs.delete")}
                    </Button>
                  ) : null}
                </div>
              </div>
            </Card>
          ))}
          <Pager
            total={total}
            page={page}
            pageSize={pageSize}
            onPageChange={setPage}
            onPageSizeChange={setPageSize}
            showWhenSingle
          />
        </div>
      )}
    </>
  );
}
