"use client";

/**
 * StatusView — 狀態頁（AF3 實作）
 *
 * 對齊 spec §4：
 *   - StatusHero（大狀態指示器，5 變體）
 *   - InfoCard（帳號 / Relay / 連線開始 / Session Token 遮蔽版）
 *   - 主按鈕列（依狀態五套）
 *   - RecentLog（最近 10 筆事件）
 *   - 未配對時顯示 EmptyState + 「前往配對」CTA
 *
 * 資料來源（AF3 階段 mock；AF6 會換成真 Wails binding）：
 *   - useConnectionStatus() → snapshot
 *   - useRecentLogs(10)     → logs
 *
 * 與配對 Tab 的互動：
 *   - 「前往配對」按鈕透過 Radix Tabs 的 `TabsContext` 無法直接 setValue（因為我們用 defaultValue），
 *     改為 dispatch CustomEvent `agent:switch-tab` 由 page.tsx 攔截切換。
 *     這一層間接呼叫雖然比 prop-drilling 多一步，但解耦了 view 與 app 結構，
 *     未來 StatusView 被放到其他容器也不會壞。
 */

import { Unlink } from "lucide-react";
import { toast } from "sonner";

import { InfoCard } from "@/components/agent/info-card";
import { RecentLog } from "@/components/agent/recent-log";
import { StatusHero } from "@/components/agent/status-hero";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { EmptyState } from "@/components/ui/empty-state";
import { Spinner } from "@/components/ui/spinner";
import { useConnectionStatus } from "@/hooks/use-connection-status";
import { useRecentLogs } from "@/hooks/use-recent-logs";
import { agentAPI } from "@/lib/agent-api";
import { useT } from "@/lib/i18n/context";

/** 觸發切換到配對 tab 的自訂事件名（page.tsx 監聽）。 */
export const AGENT_SWITCH_TAB_EVENT = "agent:switch-tab";

/** 發送 CustomEvent 切換 tab（export 給其他 view 共用，避免重複定義 helper）。 */
export function switchAgentTab(value: "status" | "pair" | "settings") {
  if (typeof window === "undefined") return;
  window.dispatchEvent(
    new CustomEvent<{ value: string }>(AGENT_SWITCH_TAB_EVENT, {
      detail: { value },
    }),
  );
}

/** 內部別名（保留舊名以利 view 內部讀起來語意清楚）。 */
const switchTab = switchAgentTab;

export function StatusView() {
  const t = useT();
  const { snapshot, loading } = useConnectionStatus();
  const { logs } = useRecentLogs(10);

  /* ---------- Loading（初次拉 snapshot）---------- */
  if (loading || !snapshot) {
    return (
      <section
        data-testid="status-view"
        aria-labelledby="status-view-heading"
        className="flex flex-col items-center gap-3 py-12"
      >
        <h2 id="status-view-heading" className="sr-only">
          {t("nav.status")}
        </h2>
        <Spinner size="lg" label={t("common.loading")} />
      </section>
    );
  }

  /* ---------- 空狀態（尚未配對，spec §4.3）---------- */
  if (snapshot.state === "notPaired") {
    return (
      <section
        data-testid="status-view"
        aria-labelledby="status-view-heading"
        className="py-6"
      >
        <h2 id="status-view-heading" className="sr-only">
          {t("nav.status")}
        </h2>
        <EmptyState
          icon={Unlink}
          title={t("status.empty.title")}
          description={t("status.empty.description")}
          action={{
            label: t("status.action.goPair"),
            onClick: () => switchTab("pair"),
          }}
        />
      </section>
    );
  }

  /* ---------- 正常狀態（online / offline / reconnecting / error）---------- */
  return (
    <section
      data-testid="status-view"
      aria-labelledby="status-view-heading"
      className="flex flex-col gap-6 py-4"
    >
      <h2 id="status-view-heading" className="sr-only">
        {t("nav.status")}
      </h2>

      <StatusHero
        state={snapshot.state}
        attemptNo={snapshot.attemptNo}
        errorMessage={snapshot.error}
      />

      <Card>
        <CardContent className="space-y-4">
          <InfoCard snapshot={snapshot} />
          <ActionButtons state={snapshot.state} />
        </CardContent>
      </Card>

      <RecentLog logs={logs} max={10} />
    </section>
  );
}

/* -------------------------------------------------------------------------- */
/* ActionButtons — 主按鈕列（依狀態 5 套）                                      */
/* -------------------------------------------------------------------------- */

interface ActionButtonsProps {
  state: "online" | "offline" | "connecting" | "reconnecting" | "error" | "notPaired";
}

function ActionButtons({ state }: ActionButtonsProps) {
  const t = useT();

  // online 與 offline / reconnecting 的主按鈕不同，用 switch 明確分岔
  switch (state) {
    case "online":
      return (
        <div className="flex flex-wrap gap-2">
          <DisconnectButton />
        </div>
      );

    case "offline":
      return (
        <div className="flex flex-wrap gap-2">
          <Button
            data-testid="status-action-reconnect"
            variant="default"
            onClick={() => {
              // AF6：手動重連；失敗時 toast（成功由 connection:status event 更新 UI）
              agentAPI.reconnect().catch((err) => {
                toast.error(
                  err instanceof Error ? err.message : String(err),
                );
              });
            }}
          >
            {t("status.action.reconnect")}
          </Button>
          <RepairButton />
        </div>
      );

    case "reconnecting":
    case "connecting":
      return (
        <div className="flex flex-wrap items-center gap-2">
          <Button
            data-testid="status-action-reconnect"
            variant="outline"
            disabled
          >
            <Spinner size="sm" label={t("common.loading")} />
            <span>{t("connection.reconnecting")}</span>
          </Button>
        </div>
      );

    case "error":
      return (
        <div className="flex flex-wrap gap-2">
          <Button
            data-testid="status-action-retry"
            variant="default"
            onClick={() => {
              // AF6：錯誤狀態下的重試 = 手動重連
              agentAPI.reconnect().catch((err) => {
                toast.error(
                  err instanceof Error ? err.message : String(err),
                );
              });
            }}
          >
            {t("status.action.retry")}
          </Button>
          <RepairButton />
        </div>
      );

    default:
      // notPaired 不會到這裡（外層 early-return 了），保留 fallback 讓 switch 完整
      return null;
  }
}

/**
 * 「重新配對」次按鈕（spec §4.2 C / Fix-F1）。
 *
 * 顯示時機：error / offline。其他狀態下 ActionButtons 不會 render 這顆。
 *
 * 行為：點擊後切到配對 tab（不直接呼叫 unpair；spec §4.2 C 把 unpair 的破壞性
 * 動作留在配對流程裡顯式發生，避免使用者誤點次按鈕就清掉 Session）。
 *
 * 樣式：variant="outline"（次按鈕，不跟主按鈕搶眼）。
 */
function RepairButton() {
  const t = useT();
  return (
    <Button
      type="button"
      variant="outline"
      data-testid="status-action-repair"
      aria-label={t("status.action.repair")}
      title={t("status.action.repair")}
      onClick={() => switchTab("pair")}
    >
      {t("status.action.repair")}
    </Button>
  );
}

/** Disconnect 按鈕 — 透過 AlertDialog 確認。 */
function DisconnectButton() {
  const t = useT();

  return (
    <AlertDialog>
      <AlertDialogTrigger asChild>
        <Button
          variant="destructive"
          data-testid="status-action-disconnect"
        >
          {t("status.action.disconnect")}
        </Button>
      </AlertDialogTrigger>
      <AlertDialogContent>
        <AlertDialogHeader>
          <AlertDialogTitle>
            {t("status.confirm.disconnect.title")}
          </AlertDialogTitle>
          <AlertDialogDescription>
            {t("status.confirm.disconnect.description")}
          </AlertDialogDescription>
        </AlertDialogHeader>
        <AlertDialogFooter>
          <AlertDialogCancel>{t("common.cancel")}</AlertDialogCancel>
          <AlertDialogAction
            variant="destructive"
            data-testid="status-action-disconnect-confirm"
            onClick={() => {
              // AF6：呼叫 Wails Disconnect binding
              // 成功：connection:status event 會推 "offline" 更新 UI；失敗：toast
              agentAPI.disconnect().catch((err) => {
                toast.error(
                  err instanceof Error ? err.message : String(err),
                );
              });
            }}
          >
            {t("status.action.disconnect")}
          </AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  );
}
