/**
 * AdminTasksPanel.tsx — S370: pannello admin task agent
 *
 * Polling automatico GET /api/agent/tasks ogni 3s.
 * Mostra status badge colorato, isLive indicator, goal troncato, età.
 * Pulsante cancel per task attivi. Filtro per status. Shift+A per toggle.
 */
import { useCallback, useEffect, useRef, useState, memo } from "react";
import type * as React from "react"; // FIX11: React namespace types
import { X, RefreshCw, Circle, Loader2, CheckCircle2, XCircle, AlertCircle, Ban, Clock } from "lucide-react";
import { backend, type AgentTaskRow } from "@/lib/backendClient";
import { Z_INDEX } from "@/lib/zindex";
import { makeTimedSignal } from "@/lib/agentLoop/networkConstants"; // Loop-12: iOS-safe

// ─── Helpers ──────────────────────────────────────────────────────────────────
function fmtAge(ms: number): string {
  if (ms < 0) return "–";
  if (ms < 60_000)    return `${Math.round(ms / 1000)}s fa`;
  if (ms < 3600_000)  return `${Math.round(ms / 60_000)}m fa`;
  return `${Math.round(ms / 3600_000)}h fa`;
}

type StatusKey = "QUEUED" | "RUNNING" | "SUCCESS" | "ERROR" | "CANCELLED" | "TIMEOUT" | string;

const STATUS_CFG: Record<StatusKey, { bg: string; fg: string; label: string }> = {
  QUEUED:    { bg: "#1a2a4a", fg: "#6ab3ff", label: "in coda"   },
  RUNNING:   { bg: "#1a3a2a", fg: "#4ade80", label: "running"   },
  SUCCESS:   { bg: "#1a3a2a", fg: "#4ade80", label: "ok"        },
  ERROR:     { bg: "#3a1a1a", fg: "#f87171", label: "errore"    },
  CANCELLED: { bg: "#2a2a2a", fg: "#a0a0b0", label: "annullato" },
  TIMEOUT:   { bg: "#3a2a1a", fg: "#fb923c", label: "timeout"   },
  UNKNOWN:   { bg: "#2a2a2a", fg: "#888",    label: "unknown"   },
};

function StatusBadge({ status }: { status: string }) {
  const cfg = STATUS_CFG[status] ?? STATUS_CFG.UNKNOWN;
  return (
    <span style={{
      fontSize: "0.6rem", fontWeight: 700, padding: "2px 6px",
      borderRadius: 8, background: cfg.bg, color: cfg.fg,
      textTransform: "uppercase", letterSpacing: "0.06em", whiteSpace: "nowrap",
    }}>
      {cfg.label}
    </span>
  );
}

function StatusIcon({ status, isLive }: { status: string; isLive: boolean }) {
  const s: React.CSSProperties = { flexShrink: 0 };
  if (isLive || status === "RUNNING") return <Loader2 size={13} style={{ ...s, color: "#4ade80", animation: "spin 1s linear infinite" }} />;
  if (status === "SUCCESS")  return <CheckCircle2 size={13} style={{ ...s, color: "#4ade80" }} />;
  if (status === "ERROR")    return <XCircle      size={13} style={{ ...s, color: "#f87171" }} />;
  if (status === "CANCELLED")return <Ban          size={13} style={{ ...s, color: "#a0a0b0" }} />;
  if (status === "TIMEOUT")  return <AlertCircle  size={13} style={{ ...s, color: "#fb923c" }} />;
  if (status === "QUEUED")   return <Clock        size={13} style={{ ...s, color: "#6ab3ff" }} />;
  return <Circle size={13} style={{ ...s, color: "#555" }} />;
}

// ─── Main component ───────────────────────────────────────────────────────────
interface AdminTasksPanelProps {
  onClose: () => void;
}

const AdminTasksPanel = memo(function AdminTasksPanel({ onClose }: AdminTasksPanelProps) {
  const [tasks,      setTasks]      = useState<AgentTaskRow[]>([]);
  const [meta,       setMeta]       = useState({ count: 0, memory: 0, supabase: 0 });
  const [loading,    setLoading]    = useState(true);
  const [error,      setError]      = useState<string | null>(null);
  const [filter,     setFilter]     = useState<string>("");
  const [lastRefresh,setLastRefresh]= useState<number>(0);
  const cancellingRef = useRef<Set<string>>(new Set());
  const intervalRef   = useRef<ReturnType<typeof setInterval> | null>(null);

  const fetchTasks = useCallback(async () => {
    if (!backend.isAvailable()) {
      setError("Backend non configurato");
      setLoading(false);
      return;
    }
    try {
      const res = await (backend as unknown as {
        listAgentTasks: (limit?: number, status?: string) => Promise<{ count: number; memory: number; supabase: number; tasks: AgentTaskRow[] }>;
      }).listAgentTasks(100, filter || undefined);
      setTasks(res.tasks ?? []);
      setMeta({ count: res.count ?? 0, memory: res.memory ?? 0, supabase: res.supabase ?? 0 });
      setError(null);
    } catch (e) {
      setError(e instanceof Error ? e.message : "Errore fetch task");
    } finally {
      setLoading(false);
      setLastRefresh(Date.now());
    }
  }, [filter]);

  useEffect(() => {
    fetchTasks();
    intervalRef.current = setInterval(fetchTasks, 3_000);
    return () => { if (intervalRef.current) clearInterval(intervalRef.current); };
  }, [fetchTasks]);

  const handleCancel = useCallback(async (taskId: string) => {
    if (cancellingRef.current.has(taskId)) return;
    cancellingRef.current.add(taskId);
    try {
      await fetch(`${import.meta.env.VITE_BACKEND_URL ?? ""}/api/agent/tasks/${taskId}`, {
        method: "DELETE",
        headers: { "Content-Type": "application/json", ...((import.meta.env.VITE_INTERNAL_TOKEN ?? "") ? { "X-Internal-Token": import.meta.env.VITE_INTERNAL_TOKEN } : {}) },
        signal: makeTimedSignal(8_000),
      });
      await fetchTasks();
    } catch { /* silent */ }
    finally { cancellingRef.current.delete(taskId); }
  }, [fetchTasks]);

  const displayed = filter
    ? tasks.filter(t => t.status === filter.toUpperCase())
    : tasks;

  const liveCount = tasks.filter(t => t.isLive || t.status === "RUNNING").length;

  return (
    <div style={{
      position: "fixed", inset: 0, zIndex: Z_INDEX.MODAL_OVERLAY,
      background: "rgba(0,0,0,0.75)",
      display: "flex", alignItems: "flex-start", justifyContent: "flex-end",
      padding: "48px 12px 12px",
    }} onClick={e => { if (e.target === e.currentTarget) onClose(); }}>
      <div style={{
        width: "100%", maxWidth: 560, maxHeight: "calc(var(--vh, 100dvh) - 64px)", // S761-GAP5: dvh esclude barra Safari
        display: "flex", flexDirection: "column",
        background: "#0f0f1e", border: "1px solid rgba(255,255,255,0.08)",
        borderRadius: 14, overflow: "hidden",
        boxShadow: "0 24px 60px rgba(0,0,0,0.7)",
      }}>
        {/* Header */}
        <div style={{
          display: "flex", alignItems: "center", gap: 10,
          padding: "12px 14px", borderBottom: "1px solid rgba(255,255,255,0.07)",
          flexShrink: 0,
        }}>
          <span style={{ fontWeight: 700, fontSize: "0.85rem", color: "#c0c0e0", flex: 1 }}>
            Admin Tasks
          </span>
          {liveCount > 0 && (
            <span style={{
              fontSize: "0.6rem", fontWeight: 700, padding: "2px 7px",
              borderRadius: 20, background: "rgba(74,222,128,0.18)",
              color: "#4ade80", border: "1px solid rgba(74,222,128,0.3)",
              animation: "pulse 2s ease-in-out infinite",
            }}>
              {liveCount} LIVE
            </span>
          )}
          <span style={{ fontSize: "0.7rem", color: "#555", fontFamily: "monospace" }}>
            mem:{meta.memory} sb:{meta.supabase}
          </span>
          <button onClick={fetchTasks} title="Aggiorna ora" style={{
            background: "none", border: "none", cursor: "pointer",
            color: "#555", padding: 4, borderRadius: 8, display: "flex",
          }}>
            <RefreshCw size={13} />
          </button>
          <button onClick={onClose} style={{
            background: "none", border: "none", cursor: "pointer",
            color: "#555", padding: 4, borderRadius: 8, display: "flex",
          }}>
            <X size={15} />
          </button>
        </div>

        {/* Filter bar */}
        <div style={{
          display: "flex", gap: 6, padding: "8px 14px",
          borderBottom: "1px solid rgba(255,255,255,0.05)",
          flexShrink: 0, overflowX: "auto",
        }}>
          {["", "RUNNING", "QUEUED", "SUCCESS", "ERROR", "CANCELLED"].map(f => (
            <button key={f} onClick={() => setFilter(f)} style={{
              fontSize: "0.65rem", fontWeight: 600,
              padding: "2px 8px", borderRadius: 20,
              border: `1px solid ${filter === f ? "rgba(99,102,241,0.6)" : "rgba(255,255,255,0.08)"}`,
              background: filter === f ? "rgba(99,102,241,0.18)" : "transparent",
              color: filter === f ? "#a5b4fc" : "#666",
              cursor: "pointer", whiteSpace: "nowrap",
            }}>
              {f || "Tutti"}
            </button>
          ))}
        </div>

        {/* Body */}
        <div style={{ flex: 1, overflowY: "auto", padding: "6px 0" }}>
          {loading && (
            <div style={{ padding: "20px 14px", color: "#555", fontSize: "0.8rem", textAlign: "center" }}>
              Caricamento…
            </div>
          )}
          {!loading && error && (
            <div style={{ padding: "14px", color: "#f87171", fontSize: "0.78rem" }}>
              ⚠ {error}
            </div>
          )}
          {!loading && !error && displayed.length === 0 && (
            <div style={{ padding: "24px 14px", color: "#444", fontSize: "0.8rem", textAlign: "center" }}>
              Nessun task{filter ? ` con status ${filter}` : " trovato"}
            </div>
          )}
          {displayed.map(task => (
            <div key={task.taskId} style={{
              display: "flex", alignItems: "flex-start", gap: 10,
              padding: "9px 14px",
              borderBottom: "1px solid rgba(255,255,255,0.04)",
              transition: "background 0.12s",
            }}
              onMouseEnter={e => { (e.currentTarget as HTMLDivElement).style.background = "rgba(255,255,255,0.03)"; }}
              onMouseLeave={e => { (e.currentTarget as HTMLDivElement).style.background = "transparent"; }}
            >
              <StatusIcon status={task.status} isLive={task.isLive} />
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{
                  fontSize: "0.78rem", color: "#c0c0e0",
                  whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis",
                  lineHeight: 1.35,
                }}>
                  {task.goal || "(no goal)"}
                </div>
                <div style={{ display: "flex", gap: 6, marginTop: 3, alignItems: "center", flexWrap: "wrap" }}>
                  <StatusBadge status={task.status} />
                  <span style={{ fontSize: "0.62rem", color: "#444" }}>
                    {fmtAge(task.ageMs)}
                  </span>
                  <span style={{
                    fontSize: "0.6rem", color: "#333", fontFamily: "monospace",
                    overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", maxWidth: 120,
                  }}>
                    {task.taskId.slice(0, 12)}…
                  </span>
                  {task.source === "supabase" && (
                    <span style={{ fontSize: "0.58rem", color: "#2d5a2d" }}>sb</span>
                  )}
                </div>
              </div>
              {(task.isLive || task.status === "RUNNING" || task.status === "QUEUED") && (
                <button onClick={() => handleCancel(task.taskId)} title="Cancella task" style={{
                  background: "rgba(239,68,68,0.12)", border: "1px solid rgba(239,68,68,0.25)",
                  color: "#f87171", borderRadius: 8, cursor: "pointer",
                  fontSize: "0.65rem", padding: "2px 7px", whiteSpace: "nowrap", flexShrink: 0,
                }}>
                  Stop
                </button>
              )}
            </div>
          ))}
        </div>

        {/* Footer */}
        <div style={{
          padding: "7px 14px", borderTop: "1px solid rgba(255,255,255,0.05)",
          display: "flex", alignItems: "center", justifyContent: "space-between",
          flexShrink: 0,
        }}>
          <span style={{ fontSize: "0.65rem", color: "#333" }}>
            {lastRefresh > 0 ? `agg. ${fmtAge(Date.now() - lastRefresh)}` : ""}
          </span>
          <span style={{ fontSize: "0.65rem", color: "#333" }}>
            Shift+A per toggle · polling 3s
          </span>
        </div>
      </div>

      {/* spin keyframe */}
      <style>{`
        @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
        @keyframes pulse { 0%,100% { opacity:1; } 50% { opacity:0.55; } }
      `}</style>
    </div>
  );
});

export default AdminTasksPanel;
