// =============================================================================
// WOOO AIOps - AwoooP M5 Run 監控頁面
// =============================================================================
// 每 30 秒自動刷新，RUNNING 狀態顯示 pulse 動畫

"use client";

import { useState, useEffect, useCallback, useRef } from "react";
import {
  Activity,
  RefreshCw,
  AlertCircle,
  Filter,
  ChevronDown,
  ChevronLeft,
  ChevronRight,
  Cpu,
} from "lucide-react";
import { cn } from "@/lib/utils";

// =============================================================================
// Types
// =============================================================================

type RunState =
  | "pending"
  | "running"
  | "waiting_tool"
  | "waiting_approval"
  | "completed"
  | "failed"
  | "cancelled"
  | "timeout";

interface Run {
  run_id: string;
  project_id: string;
  agent_id: string;
  state: RunState;
  is_shadow: boolean;
  cost_usd: number | string;
  step_count: number;
  created_at: string;
}

interface Tenant {
  project_id: string;
  display_name: string;
}

interface RunsResponse {
  runs?: Run[];
  items?: Run[];
  total: number;
  page: number;
  per_page: number;
}

// =============================================================================
// 常數
// =============================================================================

const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? "";
const PER_PAGE = 50;
const AUTO_REFRESH_INTERVAL = 30_000; // 30 秒

const STATE_CONFIG: Record<
  RunState,
  { label: string; bg: string; text: string; border: string; pulse?: boolean }
> = {
  pending: {
    label: "待執行",
    bg: "bg-[#f4f1e8]",
    text: "text-[#5f5b52]",
    border: "border-[#d8d3c7]",
  },
  running: {
    label: "執行中",
    bg: "bg-[#f0faf2]",
    text: "text-[#17602a]",
    border: "border-[#9bc7a4]",
    pulse: true,
  },
  waiting_tool: {
    label: "等待工具",
    bg: "bg-[#fff7e8]",
    text: "text-[#8a5a08]",
    border: "border-[#d9b36f]",
  },
  waiting_approval: {
    label: "等待審批",
    bg: "bg-[#fff7e8]",
    text: "text-[#8a5a08]",
    border: "border-[#d9b36f]",
  },
  completed: {
    label: "已完成",
    bg: "bg-[#f0faf2]",
    text: "text-[#17602a]",
    border: "border-[#9bc7a4]",
  },
  failed: {
    label: "失敗",
    bg: "bg-[#fff0ef]",
    text: "text-[#9f2f25]",
    border: "border-[#e2a29b]",
  },
  cancelled: {
    label: "已取消",
    bg: "bg-[#fff0ef]",
    text: "text-[#9f2f25]",
    border: "border-[#e2a29b]",
  },
  timeout: {
    label: "已超時",
    bg: "bg-[#fff0ef]",
    text: "text-[#9f2f25]",
    border: "border-[#e2a29b]",
  },
};

// =============================================================================
// Sub Components
// =============================================================================

function RunStateBadge({ state }: { state: RunState }) {
  const config = STATE_CONFIG[state] ?? STATE_CONFIG.pending;
  return (
    <span
      className={cn(
        "inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-md text-xs font-mono font-medium border",
        config.bg,
        config.text,
        config.border
      )}
    >
      {config.pulse && (
        <span className="w-1.5 h-1.5 rounded-full bg-green-400 animate-pulse" aria-hidden="true" />
      )}
      {config.label}
    </span>
  );
}

function ShadowBadge({ isShadow }: { isShadow: boolean }) {
  if (!isShadow) return <span className="text-muted-foreground text-sm">--</span>;
  return (
    <span className="inline-flex items-center border border-[#d8d3c7] bg-white px-2 py-0.5 text-xs font-medium text-[#5f5b52]">
      Shadow
    </span>
  );
}

function RunRow({ run }: { run: Run }) {
  const formattedDate = run.created_at
    ? new Date(run.created_at).toLocaleDateString("zh-TW", {
        month: "2-digit",
        day: "2-digit",
        hour: "2-digit",
        minute: "2-digit",
      })
    : "--";

  const cost = Number(run.cost_usd ?? 0);

  return (
    <tr className="border-b border-border hover:bg-accent/30 transition-colors">
      <td className="px-4 py-3">
        <span className="font-mono text-xs text-brand-accent bg-brand-accent/10 px-2 py-1 rounded border border-brand-accent/20">
          {run.run_id.slice(0, 8)}
        </span>
      </td>
      <td className="px-4 py-3">
        <span className="font-mono text-sm text-muted-foreground">
          {run.project_id || "--"}
        </span>
      </td>
      <td className="px-4 py-3">
        <span className="font-mono text-sm text-muted-foreground">
          {run.agent_id || "--"}
        </span>
      </td>
      <td className="px-4 py-3">
        <RunStateBadge state={run.state} />
      </td>
      <td className="px-4 py-3">
        <ShadowBadge isShadow={run.is_shadow} />
      </td>
      <td className="px-4 py-3">
        <span className="flex items-center gap-1 text-sm font-mono text-muted-foreground">
          {run.step_count > 0 || cost > 0 ? (
            <>
              <Cpu className="w-3.5 h-3.5" aria-hidden="true" />
              {run.step_count.toLocaleString()} steps
              <span className="text-xs text-muted-foreground/60">
                (${cost.toFixed(4)})
              </span>
            </>
          ) : (
            "--"
          )}
        </span>
      </td>
      <td className="px-4 py-3">
        <span className="text-sm text-muted-foreground font-mono">
          {formattedDate}
        </span>
      </td>
    </tr>
  );
}

// =============================================================================
// Main Component
// =============================================================================

export default function RunsPage() {
  const [runs, setRuns] = useState<Run[]>([]);
  const [tenants, setTenants] = useState<Tenant[]>([]);
  const [total, setTotal] = useState(0);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [projectFilter, setProjectFilter] = useState<string>("");
  const [statusFilter, setStatusFilter] = useState<string>("");
  const [page, setPage] = useState(1);
  const [lastRefresh, setLastRefresh] = useState<Date>(new Date());
  const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);

  // 取得租戶清單
  useEffect(() => {
    fetch(`${API_BASE}/api/v1/platform/tenants`)
      .then((r) => r.json())
      .then((data) => {
        const rows = Array.isArray(data.tenants) ? data.tenants : data.items;
        setTenants(Array.isArray(rows) ? rows : []);
      })
      .catch(() => {});
  }, []);

  const fetchRuns = useCallback(async () => {
    try {
      setError(null);
      const params = new URLSearchParams();
      if (projectFilter) params.set("project_id", projectFilter);
      if (statusFilter) params.set("state", statusFilter);
      params.set("page", String(page));
      params.set("per_page", String(PER_PAGE));

      const res = await fetch(
        `${API_BASE}/api/v1/platform/runs/list?${params.toString()}`
      );
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const data: RunsResponse = await res.json();
      const rows = Array.isArray(data.runs) ? data.runs : data.items;
      setRuns(Array.isArray(rows) ? rows : []);
      setTotal(data.total ?? 0);
      setLastRefresh(new Date());
    } catch (err) {
      setError(err instanceof Error ? err.message : "載入失敗");
    } finally {
      setLoading(false);
    }
  }, [projectFilter, statusFilter, page]);

  // 初次載入
  useEffect(() => {
    setLoading(true);
    fetchRuns();
  }, [fetchRuns]);

  // 30 秒自動刷新
  useEffect(() => {
    intervalRef.current = setInterval(() => {
      fetchRuns();
    }, AUTO_REFRESH_INTERVAL);
    return () => {
      if (intervalRef.current) clearInterval(intervalRef.current);
    };
  }, [fetchRuns]);

  const totalPages = Math.ceil(total / PER_PAGE);

  return (
    <div className="space-y-6">
      {/* Page Header */}
      <div className="flex items-center justify-between flex-wrap gap-3">
        <div className="flex items-center gap-3">
          <Activity className="w-5 h-5 text-brand-accent" aria-hidden="true" />
          <div>
            <h2 className="text-lg font-semibold text-foreground">Run 監控</h2>
            <p className="text-xs text-muted-foreground">
              {loading
                ? "載入中..."
                : `共 ${total} 筆 · 上次更新 ${lastRefresh.toLocaleTimeString("zh-TW")}`}
            </p>
          </div>
        </div>
        <div className="flex items-center gap-2">
          <span className="text-xs text-muted-foreground">每 30 秒自動刷新</span>
          <button
            onClick={() => { setLoading(true); fetchRuns(); }}
            disabled={loading}
            className="flex items-center gap-2 px-3 py-2 text-sm text-muted-foreground hover:text-foreground hover:bg-accent rounded-lg transition disabled:opacity-50"
            aria-label="立即重新整理"
          >
            <RefreshCw className={cn("w-4 h-4", loading && "animate-spin")} aria-hidden="true" />
            立即刷新
          </button>
        </div>
      </div>

      {/* Filters */}
      <div className="flex flex-wrap items-center gap-3 border border-[#e0ddd4] bg-white p-4">
        <Filter className="w-4 h-4 text-muted-foreground flex-shrink-0" aria-hidden="true" />
        <span className="text-sm text-muted-foreground">篩選：</span>

        {/* Project Filter */}
        <div className="relative">
          <select
            value={projectFilter}
            onChange={(e) => { setProjectFilter(e.target.value); setPage(1); }}
            className="appearance-none pl-3 pr-8 py-1.5 text-sm bg-background border border-border rounded-lg text-foreground focus:outline-none focus:ring-2 focus:ring-brand-accent/50 cursor-pointer"
            aria-label="選擇租戶"
          >
            <option value="">所有租戶</option>
            {tenants.map((t) => (
              <option key={t.project_id} value={t.project_id}>
                {t.display_name || t.project_id}
              </option>
            ))}
          </select>
          <ChevronDown className="absolute right-2 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-muted-foreground pointer-events-none" aria-hidden="true" />
        </div>

        {/* Status Filter */}
        <div className="relative">
          <select
            value={statusFilter}
            onChange={(e) => { setStatusFilter(e.target.value); setPage(1); }}
            className="appearance-none pl-3 pr-8 py-1.5 text-sm bg-background border border-border rounded-lg text-foreground focus:outline-none focus:ring-2 focus:ring-brand-accent/50 cursor-pointer"
            aria-label="選擇狀態"
          >
            <option value="">所有狀態</option>
            {(Object.keys(STATE_CONFIG) as RunState[]).map((s) => (
              <option key={s} value={s}>
                {STATE_CONFIG[s].label}
              </option>
            ))}
          </select>
          <ChevronDown className="absolute right-2 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-muted-foreground pointer-events-none" aria-hidden="true" />
        </div>
      </div>

      {/* Error State */}
      {error && (
        <div className="flex items-start gap-3 p-4 bg-red-900/20 border border-red-800/40 rounded-lg">
          <AlertCircle className="w-5 h-5 text-red-400 flex-shrink-0 mt-0.5" aria-hidden="true" />
          <div>
            <p className="text-sm font-medium text-red-300">無法載入 Run 資料</p>
            <p className="text-xs text-red-400 mt-1">{error}</p>
          </div>
        </div>
      )}

      {/* Table */}
      <div className="overflow-hidden border border-[#e0ddd4] bg-white shadow-[0_1px_4px_rgba(0,0,0,0.05)]">
        <div className="overflow-x-auto">
          <table className="w-full" role="table" aria-label="Run 清單">
            <thead>
              <tr className="border-b border-border bg-muted/50">
                <th className="text-left px-4 py-3 text-xs font-medium text-muted-foreground uppercase tracking-wider">
                  Run ID
                </th>
                <th className="text-left px-4 py-3 text-xs font-medium text-muted-foreground uppercase tracking-wider">
                  Project ID
                </th>
                <th className="text-left px-4 py-3 text-xs font-medium text-muted-foreground uppercase tracking-wider">
                  Agent
                </th>
                <th className="text-left px-4 py-3 text-xs font-medium text-muted-foreground uppercase tracking-wider">
                  狀態
                </th>
                <th className="text-left px-4 py-3 text-xs font-medium text-muted-foreground uppercase tracking-wider">
                  Shadow
                </th>
                <th className="text-left px-4 py-3 text-xs font-medium text-muted-foreground uppercase tracking-wider">
                  成本 / Steps
                </th>
                <th className="text-left px-4 py-3 text-xs font-medium text-muted-foreground uppercase tracking-wider">
                  建立時間
                </th>
              </tr>
            </thead>
            <tbody>
              {loading ? (
                Array.from({ length: 8 }).map((_, i) => (
                  <tr key={i} className="border-b border-border">
                    {Array.from({ length: 7 }).map((_, j) => (
                      <td key={j} className="px-4 py-3">
                        <div className="h-5 bg-muted animate-pulse rounded w-20" />
                      </td>
                    ))}
                  </tr>
                ))
              ) : runs.length === 0 && !error ? (
                <tr>
                  <td colSpan={7} className="px-4 py-16 text-center">
                    <Activity className="w-10 h-10 text-muted-foreground/30 mx-auto mb-3" aria-hidden="true" />
                    <p className="text-sm text-muted-foreground">尚無 Run 資料</p>
                  </td>
                </tr>
              ) : (
                runs.map((run) => <RunRow key={run.run_id} run={run} />)
              )}
            </tbody>
          </table>
        </div>

        {/* Pagination */}
        {totalPages > 1 && (
          <div className="flex items-center justify-between px-4 py-3 border-t border-border bg-muted/30">
            <span className="text-xs text-muted-foreground">
              第 {page} / {totalPages} 頁，共 {total} 筆
            </span>
            <div className="flex items-center gap-2">
              <button
                onClick={() => setPage((p) => Math.max(1, p - 1))}
                disabled={page <= 1 || loading}
                className="p-1.5 hover:bg-accent rounded transition disabled:opacity-50"
                aria-label="上一頁"
              >
                <ChevronLeft className="w-4 h-4" aria-hidden="true" />
              </button>
              <button
                onClick={() => setPage((p) => Math.min(totalPages, p + 1))}
                disabled={page >= totalPages || loading}
                className="p-1.5 hover:bg-accent rounded transition disabled:opacity-50"
                aria-label="下一頁"
              >
                <ChevronRight className="w-4 h-4" aria-hidden="true" />
              </button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}
