/**
 * DeployPanel.tsx — S744 + S-DEPLOY-UNIFY + S-AUTO
 *
 * S744:          Trigger workflow_dispatch su cloudflare-deploy.yml, polling stato,
 *                progress step-by-step, URL live, storico deploy.
 * S-DEPLOY-UNIFY: Griglia "Stato target" — CF Pages, Railway, HF Space.
 * S-AUTO:        Auto-riparazione — diagnostica all'apertura + pulsante "Ripara automaticamente".
 *                POST /api/deploy/auto gestisce tutte le situazioni senza intervento manuale.
 */

import { useState, useEffect, useCallback, useRef, memo } from "react";
import type * as React from "react";
import {
  X, Rocket, CheckCircle, XCircle, Clock, RefreshCw,
  ExternalLink, AlertCircle, Play, Server, Globe, Database, Wrench, Zap,
} from "lucide-react";
import { Z_INDEX } from "@/lib/zindex";
import { getGHToken, getRepoConfig, ghTriggerWorkflow, ghGetWorkflowRuns } from "@/lib/github";
import { BACKEND_BASE, _BACKEND_TOKEN } from "@/lib/agentLoop/toolExecutor";
import type { GHWorkflowRun } from "@/lib/github";
import { useTaskStore } from "@/store/taskStore"; // GAP-2: auto-task su build failure

interface DeployPanelProps { onClose: () => void; }

const LIVE_URL          = "https://agente-ai.pages.dev/";
const POLL_MS           = 6_000;
const STATUS_REFRESH_MS = 60_000;

// ─── Tipi /api/deploy/status ──────────────────────────────────────────────────
interface CFStatus      { ok: boolean; status: string; url: string; last_deploy: string | null; deployment_id: string | null; error: string | null; }
interface RailwayStatus { ok: boolean; status: string; url: string; latency_ms: number | null; error: string | null; }
interface HFStatus      { ok: boolean; status: string; url: string; sdk: string | null; error: string | null; }
interface DeployTargets { cloudflare: CFStatus; railway: RailwayStatus; huggingface: HFStatus; }
interface DeployStatus  { targets: DeployTargets; checked_at: string; }

// ─── Tipi /api/deploy/auto ────────────────────────────────────────────────────
interface AutoResult {
  ok: boolean;
  fixed: string[];
  broken: string[];
  actions: string[];
  dry_run: boolean;
  message: string;
  elapsed: number;
}

// ─── Helpers ──────────────────────────────────────────────────────────────────
function runIcon(run: GHWorkflowRun): string {
  if (run.status === "queued")        return "🟡";
  if (run.status === "in_progress")   return "🔵";
  if (run.conclusion === "success")   return "✅";
  if (run.conclusion === "failure")   return "❌";
  if (run.conclusion === "cancelled") return "⚪";
  return "⏳";
}
function runLabel(run: GHWorkflowRun): string {
  if (run.status === "queued")        return "In coda…";
  if (run.status === "in_progress")   return "In esecuzione…";
  if (run.conclusion === "success")   return "Completato";
  if (run.conclusion === "failure")   return "Fallito";
  if (run.conclusion === "cancelled") return "Annullato";
  return run.status;
}
function timeAgo(iso: string): string {
  const ms = Date.now() - new Date(iso).getTime();
  if (ms < 60_000)     return `${Math.round(ms / 1000)}s fa`;
  if (ms < 3_600_000)  return `${Math.round(ms / 60_000)}m fa`;
  if (ms < 86_400_000) return `${Math.round(ms / 3_600_000)}h fa`;
  return `${Math.floor(ms / 86_400_000)}g fa`;
}
function backendFetch<T>(path: string, opts?: RequestInit): Promise<T | null> {
  if (!BACKEND_BASE) return Promise.resolve(null);
  return fetch(BACKEND_BASE + path, {
    ...opts,
    headers: {
      "Content-Type": "application/json",
      ...(_BACKEND_TOKEN ? { "X-Internal-Token": _BACKEND_TOKEN } : {}),
      ...(opts?.headers ?? {}),
    },
  }).then(r => r.ok ? r.json() as Promise<T> : null).catch(() => null);
}

// ─── Stili ────────────────────────────────────────────────────────────────────
const actionBtn = (variant: "primary" | "secondary" | "success" | "danger" = "primary", disabled = false): React.CSSProperties => ({
  all: "unset" as const, cursor: disabled ? "not-allowed" : "pointer",
  padding: "9px 18px", borderRadius: 10, fontSize: "0.83rem", fontWeight: 700,
  display: "flex", alignItems: "center", gap: 6, justifyContent: "center",
  opacity: disabled ? 0.4 : 1,
  background:
    variant === "primary"   ? "rgba(99,102,241,0.22)" :
    variant === "success"   ? "rgba(16,185,129,0.18)"  :
    variant === "danger"    ? "rgba(239,68,68,0.15)"   :
    "rgba(255,255,255,0.06)",
  color:
    variant === "primary"  ? "#818cf8" :
    variant === "success"  ? "#10b981"  :
    variant === "danger"   ? "#f87171"  :
    "#a0a0c0",
  border: `1px solid ${
    variant === "primary" ? "rgba(99,102,241,0.38)" :
    variant === "success" ? "rgba(16,185,129,0.35)"  :
    variant === "danger"  ? "rgba(239,68,68,0.30)"   :
    "rgba(255,255,255,0.10)"
  }`,
  touchAction: "manipulation",
  transition: "background 0.15s",
});

const DEPLOY_STEPS = [
  "Quality gate", "Check imports", "Check console.log",
  "Check circular imports", "Type check", "Unit tests",
  "Build", "Benchmark (≥95%)", "Deploy to Cloudflare",
];

function StatusDot({ ok, loading }: { ok: boolean | null; loading?: boolean }) {
  if (loading) return <div style={{ width: 8, height: 8, borderRadius: "50%", background: "#6366f1", animation: "mem-tab-pulse 1.2s ease-in-out infinite" }} />;
  return <div style={{ width: 8, height: 8, borderRadius: "50%", background: ok === null ? "#4a4a78" : ok ? "#10b981" : "#f87171", flexShrink: 0 }} />;
}

// ─── Componente principale ─────────────────────────────────────────────────────
const DeployPanel = memo(function DeployPanel({ onClose }: DeployPanelProps) {
  const cfg   = getRepoConfig();
  const owner = cfg.owner || "Baida98";
  const repo  = cfg.repo  || "AI";

  const [runs, setRuns]               = useState<GHWorkflowRun[]>([]);
  const [loading, setLoading]         = useState(false);
  const [triggering, setTriggering]   = useState(false);
  const [error, setError]             = useState<string | null>(null);
  const [success, setSuccess]         = useState<string | null>(null);
  const [lastLoad, setLastLoad]       = useState(0);
  const pollRef       = useRef<ReturnType<typeof setInterval> | null>(null);
  const statusTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const repairTaskSentRef = useRef<string | null>(null); // GAP-2: evita task duplicati per lo stesso run

  // ── Stato target ─────────────────────────────────────────────────────────────
  const [deployStatus, setDeployStatus]       = useState<DeployStatus | null>(null);
  const [statusLoading, setStatusLoading]     = useState(false);

  // ── Auto-repair ───────────────────────────────────────────────────────────────
  const [autoRunning, setAutoRunning]   = useState(false);
  const [autoResult, setAutoResult]     = useState<AutoResult | null>(null);
  const [autoActions, setAutoActions]   = useState<string[]>([]);

  // ── Carica stato target ───────────────────────────────────────────────────────
  const loadDeployStatus = useCallback(async () => {
    setStatusLoading(true);
    const res = await backendFetch<DeployStatus>("/api/deploy/status");
    if (res) setDeployStatus(res);
    setStatusLoading(false);
  }, []);

  // ── Carica workflow runs ──────────────────────────────────────────────────────
  const loadRuns = useCallback(async (silent = false) => {
    if (!getGHToken()) return;
    if (!silent) setLoading(true);
    try {
      const r = await ghGetWorkflowRuns(owner, repo, "cloudflare-deploy.yml", 8);
      setRuns(r); setLastLoad(Date.now());
    } catch (e) { if (!silent) setError((e as Error).message); }
    finally { if (!silent) setLoading(false); }
  }, [owner, repo]);

  // ── Boot ──────────────────────────────────────────────────────────────────────
  useEffect(() => {
    void loadRuns();
    void loadDeployStatus();
    statusTimerRef.current = setInterval(() => void loadDeployStatus(), STATUS_REFRESH_MS);
    return () => {
      if (pollRef.current)       clearInterval(pollRef.current);
      if (statusTimerRef.current) clearInterval(statusTimerRef.current);
    };
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // latestRun dichiarato qui per essere disponibile nel useEffect GAP-2
  const latestRun = runs[0] ?? null;
  // ── GAP-2: auto-task quando deploy fallisce — chiude il loop di autonomia ──────
  useEffect(() => {
    if (!latestRun) return;
    const isFailed = latestRun.status !== 'queued' && latestRun.status !== 'in_progress' && latestRun.conclusion === 'failure';
    if (!isFailed) return;
    if (repairTaskSentRef.current === String(latestRun.id)) return; // già inviato
    repairTaskSentRef.current = String(latestRun.id);
    useTaskStore.getState().startTask(
      `🔧 Deploy #${latestRun.id} fallito su GitHub Actions. Analizza i log CF Pages con cf_pages_status, individua gli errori TypeScript/build, applica i fix nei file coinvolti, fai git_push e monitora con deploy_and_verify. Logs: ${latestRun.html_url}`
    );
  }, [latestRun]);

  // ── Polling auto durante run attivo ──────────────────────────────────────────
  useEffect(() => {
    const hasActive = runs.some(r => r.status === "queued" || r.status === "in_progress");
    if (hasActive) {
      if (!pollRef.current) pollRef.current = setInterval(() => void loadRuns(true), POLL_MS);
    } else {
      if (pollRef.current) { clearInterval(pollRef.current); pollRef.current = null; }
    }
  }, [runs, loadRuns]);

  // ── Auto-riparazione ──────────────────────────────────────────────────────────
  const runAutoRepair = useCallback(async () => {
    setAutoRunning(true);
    setAutoResult(null);
    setAutoActions(["⏳ Diagnosi in corso…"]);
    setError(null);
    setSuccess(null);

    const result = await backendFetch<AutoResult>("/api/deploy/auto", {
      method: "POST",
      body: JSON.stringify({ targets: ["cloudflare", "railway", "huggingface"], dry_run: false }),
    });

    if (result) {
      setAutoResult(result);
      setAutoActions(result.actions);
      if (result.ok) setSuccess(`Auto-riparazione completata: ${result.message} (${result.elapsed}s)`);
      else           setError(`Alcuni target non risolti: ${result.broken.join(", ")}`);
      // Aggiorna lo stato target dopo la riparazione
      setTimeout(() => void loadDeployStatus(), 3_000);
    } else {
      setAutoActions(["❌ Backend non raggiungibile — verifica Railway"]);
      setError("Backend non raggiungibile. Assicurati che Railway sia attivo.");
    }
    setAutoRunning(false);
  }, [loadDeployStatus]);

  // ── Trigger deploy manuale ────────────────────────────────────────────────────
  const triggerDeploy = useCallback(async () => {
    if (!getGHToken()) { setError("Configura il GitHub token (Impostazioni → GitHub)."); return; }
    setTriggering(true); setError(null); setSuccess(null); setAutoResult(null);
    try {
      const ok = await ghTriggerWorkflow(owner, repo, "cloudflare-deploy.yml", "main");
      if (ok) { setSuccess("Deploy avviato! Polling ogni 6s…"); setTimeout(() => void loadRuns(), 3_000); }
      else setError("Workflow dispatch fallito. Verifica i permessi del token (scope: workflow).");
    } catch (e) { setError(`Errore: ${(e as Error).message}`); }
    finally { setTriggering(false); }
  }, [owner, repo, loadRuns]);

  const triggerSmokeTest = useCallback(async () => {
    if (!getGHToken()) { setError("Configura il GitHub token."); return; }
    setTriggering(true); setError(null);
    try {
      await ghTriggerWorkflow(owner, repo, "smoke-test.yml", "main");
      setSuccess("Smoke test avviato su GitHub Actions.");
    } catch (e) { setError(`Errore: ${(e as Error).message}`); }
    finally { setTriggering(false); }
  }, [owner, repo]);

  // ── Dati derivati ─────────────────────────────────────────────────────────────
  const isActive    = latestRun && (latestRun.status === "queued" || latestRun.status === "in_progress");
  const t           = deployStatus?.targets;
  const checkedAgo  = deployStatus ? timeAgo(deployStatus.checked_at) : null;
  const anyBroken   = t ? (!t.cloudflare.ok || !t.railway.ok || !t.huggingface.ok) : false;
  const allGreen    = t ? (t.cloudflare.ok && t.railway.ok && t.huggingface.ok) : false;

  return (
    <div role="dialog" aria-modal="true" aria-label="Deploy"
      style={{ position: "fixed", inset: 0, zIndex: Z_INDEX.MODAL, display: "flex", justifyContent: "flex-end" }}>
      <div onClick={onClose} style={{ flex: 1, background: "rgba(0,0,0,0.45)" }} />
      <div style={{
        width: "min(100vw, 420px)", height: "100%", overflowY: "auto",
        background: "rgba(6,6,18,0.97)", borderLeft: "1px solid rgba(99,102,241,0.18)",
        display: "flex", flexDirection: "column",
        paddingBottom: "env(safe-area-inset-bottom, 0px)",
      }}>

        {/* ── Header ──────────────────────────────────────────────────────────── */}
        <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "14px 16px", borderBottom: "1px solid rgba(99,102,241,0.12)", flexShrink: 0 }}>
          <Rocket size={18} color="#6366f1" />
          <span style={{ flex: 1, fontWeight: 700, fontSize: "0.95rem", color: "#d0d0f0" }}>Deploy</span>
          <a href={LIVE_URL} target="_blank" rel="noopener noreferrer"
            style={{ display: "flex", alignItems: "center", gap: 5, fontSize: "0.72rem", color: "#6366f1", textDecoration: "none", padding: "5px 10px", background: "rgba(99,102,241,0.09)", borderRadius: 8, border: "1px solid rgba(99,102,241,0.20)" }}>
            <ExternalLink size={12} />Live
          </a>
          <button onClick={onClose} style={{ all: "unset", cursor: "pointer", color: "#4a4a78", padding: 6, touchAction: "manipulation" }}><X size={18} /></button>
        </div>

        <div style={{ flex: 1, overflowY: "auto", padding: "14px 16px", display: "flex", flexDirection: "column", gap: 12 }}>

          {/* ── Stato target ────────────────────────────────────────────────────── */}
          <div style={{ padding: "12px 14px", background: "rgba(255,255,255,0.02)", border: `1px solid ${allGreen ? "rgba(16,185,129,0.18)" : anyBroken ? "rgba(239,68,68,0.18)" : "rgba(99,102,241,0.12)"}`, borderRadius: 10 }}>
            <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 10 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
                {allGreen
                  ? <CheckCircle size={13} color="#10b981" />
                  : anyBroken
                    ? <AlertCircle size={13} color="#f87171" />
                    : <Clock size={13} color="#6366f1" />}
                <span style={{ fontSize: "0.72rem", color: allGreen ? "#10b981" : anyBroken ? "#f87171" : "#4a4a78", fontWeight: 700, letterSpacing: "0.04em" }}>
                  {allGreen ? "TUTTI I SISTEMI OK" : anyBroken ? "PROBLEMI RILEVATI" : "STATO TARGET"}
                </span>
              </div>
              <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
                {checkedAgo && <span style={{ fontSize: "0.63rem", color: "#3a3a6a" }}>{checkedAgo}</span>}
                <button onClick={() => void loadDeployStatus()} disabled={statusLoading}
                  style={{ all: "unset", cursor: statusLoading ? "not-allowed" : "pointer", color: "#6366f1", padding: 4, opacity: statusLoading ? 0.5 : 1, touchAction: "manipulation" }}>
                  <RefreshCw size={11} style={{ animation: statusLoading ? "spin 1s linear infinite" : "none" }} />
                </button>
              </div>
            </div>

            {/* Griglia 3 target */}
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 6, marginBottom: anyBroken ? 10 : 0 }}>
              {/* CF Pages */}
              <a href="https://agente-ai.pages.dev" target="_blank" rel="noopener noreferrer"
                style={{ display: "flex", flexDirection: "column", gap: 4, padding: "9px 10px", background: "rgba(0,0,0,0.15)", border: `1px solid ${t?.cloudflare.ok ? "rgba(16,185,129,0.22)" : t ? "rgba(239,68,68,0.22)" : "rgba(99,102,241,0.10)"}`, borderRadius: 8, textDecoration: "none" }}>
                <div style={{ display: "flex", alignItems: "center", gap: 5 }}>
                  <Globe size={11} color="#6366f1" />
                  <StatusDot ok={t ? t.cloudflare.ok : null} loading={statusLoading && !t} />
                </div>
                <span style={{ fontSize: "0.68rem", color: "#8080b0", fontWeight: 700 }}>CF Pages</span>
                <span style={{ fontSize: "0.62rem", color: t?.cloudflare.ok ? "#10b981" : t?.cloudflare.error ? "#f87171" : "#4a4a78", lineHeight: 1.3, wordBreak: "break-word" }}>
                  {statusLoading && !t ? "…" : t ? (t.cloudflare.ok ? "live ✓" : t.cloudflare.error ?? t.cloudflare.status) : "—"}
                </span>
                {t?.cloudflare.last_deploy && <span style={{ fontSize: "0.60rem", color: "#3a3a6a" }}>{timeAgo(t.cloudflare.last_deploy)}</span>}
              </a>

              {/* Railway */}
              <a href="https://ai-production-4c06.up.railway.app" target="_blank" rel="noopener noreferrer"
                style={{ display: "flex", flexDirection: "column", gap: 4, padding: "9px 10px", background: "rgba(0,0,0,0.15)", border: `1px solid ${t?.railway.ok ? "rgba(16,185,129,0.22)" : t ? "rgba(239,68,68,0.22)" : "rgba(99,102,241,0.10)"}`, borderRadius: 8, textDecoration: "none" }}>
                <div style={{ display: "flex", alignItems: "center", gap: 5 }}>
                  <Server size={11} color="#6366f1" />
                  <StatusDot ok={t ? t.railway.ok : null} loading={statusLoading && !t} />
                </div>
                <span style={{ fontSize: "0.68rem", color: "#8080b0", fontWeight: 700 }}>Railway</span>
                <span style={{ fontSize: "0.62rem", color: t?.railway.ok ? "#10b981" : t?.railway.error ? "#f87171" : "#4a4a78", lineHeight: 1.3 }}>
                  {statusLoading && !t ? "…" : t ? (t.railway.ok ? `up ✓${t.railway.latency_ms != null ? ` · ${t.railway.latency_ms}ms` : ""}` : t.railway.error ?? t.railway.status) : "—"}
                </span>
              </a>

              {/* HF Space */}
              <a href="https://huggingface.co/spaces/Arjanit98/Terminal" target="_blank" rel="noopener noreferrer"
                style={{ display: "flex", flexDirection: "column", gap: 4, padding: "9px 10px", background: "rgba(0,0,0,0.15)", border: `1px solid ${t?.huggingface.ok ? "rgba(16,185,129,0.22)" : t ? "rgba(239,68,68,0.22)" : "rgba(99,102,241,0.10)"}`, borderRadius: 8, textDecoration: "none" }}>
                <div style={{ display: "flex", alignItems: "center", gap: 5 }}>
                  <Database size={11} color="#6366f1" />
                  <StatusDot ok={t ? t.huggingface.ok : null} loading={statusLoading && !t} />
                </div>
                <span style={{ fontSize: "0.68rem", color: "#8080b0", fontWeight: 700 }}>HF Space</span>
                <span style={{ fontSize: "0.62rem", color: t?.huggingface.ok ? "#10b981" : t?.huggingface.error ? "#f87171" : "#4a4a78", lineHeight: 1.3 }}>
                  {statusLoading && !t ? "…" : t ? (t.huggingface.ok ? "running ✓" : t.huggingface.error ?? t.huggingface.status) : "—"}
                </span>
              </a>
            </div>

            {/* Pulsante auto-riparazione — compare solo se ci sono problemi */}
            {anyBroken && !autoRunning && !autoResult && (
              <button onClick={() => void runAutoRepair()} style={actionBtn("danger", false)}>
                <Wrench size={14} />Ripara automaticamente
              </button>
            )}
            {allGreen && !autoRunning && (
              <div style={{ display: "flex", alignItems: "center", gap: 6, padding: "7px 10px", background: "rgba(16,185,129,0.08)", borderRadius: 8, border: "1px solid rgba(16,185,129,0.18)" }}>
                <Zap size={12} color="#10b981" />
                <span style={{ fontSize: "0.72rem", color: "#10b981" }}>Tutti i sistemi operativi — nessuna azione necessaria</span>
              </div>
            )}
          </div>

          {/* ── Risultato auto-riparazione ──────────────────────────────────────── */}
          {(autoRunning || autoActions.length > 0) && (
            <div style={{ padding: "12px 14px", background: "rgba(99,102,241,0.06)", border: `1px solid ${autoResult?.ok === false ? "rgba(239,68,68,0.22)" : "rgba(99,102,241,0.20)"}`, borderRadius: 10 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 10 }}>
                <Wrench size={13} color={autoResult?.ok === false ? "#f87171" : "#6366f1"} style={{ animation: autoRunning ? "spin 1.5s linear infinite" : "none" }} />
                <span style={{ fontSize: "0.75rem", fontWeight: 700, color: autoResult?.ok === false ? "#f87171" : "#818cf8" }}>
                  {autoRunning ? "Riparazione in corso…" : autoResult?.ok ? "Riparazione completata ✓" : "Riparazione parziale"}
                </span>
                {autoResult && (
                  <span style={{ fontSize: "0.65rem", color: "#4a4a78", marginLeft: "auto" }}>{autoResult.elapsed}s</span>
                )}
              </div>
              <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
                {autoActions.map((action, i) => (
                  <div key={i} style={{ display: "flex", gap: 7, alignItems: "flex-start" }}>
                    <span style={{ fontSize: "0.7rem", color: action.startsWith("✅") ? "#10b981" : action.startsWith("❌") ? "#f87171" : action.startsWith("⚠") ? "#fbbf24" : "#6366f1", flexShrink: 0, marginTop: 1 }}>
                      {action.startsWith("✅") || action.startsWith("❌") || action.startsWith("⚠") || action.startsWith("ℹ") ? "" : "›"}
                    </span>
                    <span style={{ fontSize: "0.7rem", color: action.startsWith("✅") ? "#10b981" : action.startsWith("❌") ? "#f87171" : action.startsWith("⚠") ? "#fbbf24" : "#a0a0c0", lineHeight: 1.4 }}>{action}</span>
                  </div>
                ))}
              </div>
              {autoResult && !autoRunning && (
                <button onClick={() => { setAutoResult(null); setAutoActions([]); }} style={{ ...actionBtn("secondary"), marginTop: 10, fontSize: "0.7rem", padding: "6px 12px" }}>
                  Chiudi
                </button>
              )}
            </div>
          )}

          {/* ── Error / Success ──────────────────────────────────────────────────── */}
          {error && (
            <div style={{ padding: "9px 13px", background: "rgba(239,68,68,0.10)", border: "1px solid rgba(239,68,68,0.28)", borderRadius: 8, display: "flex", gap: 8, alignItems: "flex-start" }}>
              <AlertCircle size={15} color="#f87171" style={{ flexShrink: 0, marginTop: 1 }} />
              <span style={{ fontSize: "0.78rem", color: "#f87171", flex: 1, lineHeight: 1.5 }}>{error}</span>
              <button onClick={() => setError(null)} style={{ all: "unset", cursor: "pointer", color: "#f87171" }}><X size={13} /></button>
            </div>
          )}
          {success && !error && (
            <div style={{ padding: "9px 13px", background: "rgba(16,185,129,0.10)", border: "1px solid rgba(16,185,129,0.25)", borderRadius: 8, display: "flex", gap: 8, alignItems: "center" }}>
              <CheckCircle size={14} color="#10b981" />
              <span style={{ fontSize: "0.78rem", color: "#10b981", flex: 1 }}>{success}</span>
              <button onClick={() => setSuccess(null)} style={{ all: "unset", cursor: "pointer", color: "#10b981" }}><X size={13} /></button>
            </div>
          )}

          {/* ── Run attivo ───────────────────────────────────────────────────────── */}
          {latestRun && isActive && (
            <div style={{ padding: "14px 16px", background: "rgba(99,102,241,0.08)", border: "1px solid rgba(99,102,241,0.25)", borderRadius: 12 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 10 }}>
                <span style={{ fontSize: "1.1em" }}>{runIcon(latestRun)}</span>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: "0.85rem", fontWeight: 700, color: "#d0d0f0" }}>Deploy in corso</div>
                  <div style={{ fontSize: "0.7rem", color: "#6366f1" }}>{runLabel(latestRun)} — {timeAgo(latestRun.created_at)}</div>
                </div>
                <div style={{ width: 8, height: 8, borderRadius: "50%", background: "#6366f1", animation: "mem-tab-pulse 1.2s ease-in-out infinite" }} />
              </div>
              <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
                {DEPLOY_STEPS.map((step, i) => (
                  <div key={step} style={{ display: "flex", alignItems: "center", gap: 7, opacity: i === 0 ? 1 : 0.45 }}>
                    <div style={{ width: 5, height: 5, borderRadius: "50%", background: i === 0 ? "#6366f1" : "rgba(99,102,241,0.2)", flexShrink: 0 }} />
                    <span style={{ fontSize: "0.71rem", color: i === 0 ? "#818cf8" : "#3a3a6a" }}>{step}</span>
                  </div>
                ))}
              </div>
              <a href={latestRun.html_url} target="_blank" rel="noopener noreferrer" style={{ display: "block", marginTop: 10, fontSize: "0.71rem", color: "#6366f1", textDecoration: "none" }}>Vedi su GitHub Actions →</a>
            </div>
          )}

          {/* ── Ultimo deploy ────────────────────────────────────────────────────── */}
          {latestRun && !isActive && (
            <div style={{ padding: "11px 14px", background: latestRun.conclusion === "success" ? "rgba(16,185,129,0.07)" : "rgba(239,68,68,0.07)", border: `1px solid ${latestRun.conclusion === "success" ? "rgba(16,185,129,0.22)" : "rgba(239,68,68,0.22)"}`, borderRadius: 10 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                {latestRun.conclusion === "success" ? <CheckCircle size={15} color="#10b981" /> : <XCircle size={15} color="#f87171" />}
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: "0.83rem", fontWeight: 700, color: latestRun.conclusion === "success" ? "#10b981" : "#f87171" }}>
                    {latestRun.conclusion === "success" ? "Ultimo deploy OK" : "Ultimo deploy fallito"}
                  </div>
                  <div style={{ fontSize: "0.7rem", color: "#4a4a78" }}>{timeAgo(latestRun.updated_at)}</div>
                </div>
                {latestRun.conclusion === "success" && (
                  <a href={LIVE_URL} target="_blank" rel="noopener noreferrer" style={{ fontSize: "0.71rem", color: "#10b981", textDecoration: "none", padding: "4px 10px", background: "rgba(16,185,129,0.12)", borderRadius: 8, border: "1px solid rgba(16,185,129,0.25)" }}>Vai al sito</a>
                )}
              </div>
              {latestRun.conclusion !== "success" && (
                <a href={latestRun.html_url} target="_blank" rel="noopener noreferrer" style={{ display: "block", marginTop: 7, fontSize: "0.71rem", color: "#f87171", textDecoration: "none" }}>Vedi logs su GitHub Actions →</a>
              )}
            </div>
          )}

          {/* ── Azioni manuali ───────────────────────────────────────────────────── */}
          <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
            <button onClick={() => void runAutoRepair()} disabled={autoRunning} style={actionBtn("primary", autoRunning)}>
              {autoRunning ? <><RefreshCw size={14} style={{ animation: "spin 1s linear infinite" }} />Riparazione in corso…</> : <><Zap size={14} />Controlla e ripara tutto</>}
            </button>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
              <button onClick={() => void triggerDeploy()} disabled={triggering || !!isActive} style={actionBtn("secondary", triggering || !!isActive)}>
                <Rocket size={13} />{triggering ? "Avvio…" : "Deploy CF"}
              </button>
              <button onClick={() => void triggerSmokeTest()} disabled={triggering} style={actionBtn("secondary", triggering)}>
                <Play size={13} />Smoke Test
              </button>
            </div>
          </div>

          {/* ── Info pipeline ────────────────────────────────────────────────────── */}
          <div style={{ padding: "10px 14px", background: "rgba(255,255,255,0.02)", border: "1px solid rgba(99,102,241,0.08)", borderRadius: 9 }}>
            <p style={{ margin: "0 0 6px", fontSize: "0.70rem", color: "#3a3a6a", fontWeight: 700, letterSpacing: "0.06em" }}>PIPELINE CF PAGES</p>
            {DEPLOY_STEPS.map(s => (
              <div key={s} style={{ display: "flex", alignItems: "center", gap: 5, marginBottom: 3 }}>
                <div style={{ width: 3, height: 3, borderRadius: "50%", background: "rgba(99,102,241,0.3)", flexShrink: 0 }} />
                <span style={{ fontSize: "0.69rem", color: "#3a3a6a" }}>{s}</span>
              </div>
            ))}
          </div>

          {/* ── Storico runs ──────────────────────────────────────────────────────── */}
          <div>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 8 }}>
              <p style={{ margin: 0, fontSize: "0.70rem", color: "#3a3a6a", fontWeight: 700, letterSpacing: "0.06em" }}>STORICO DEPLOY</p>
              <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
                {lastLoad > 0 && <span style={{ fontSize: "0.63rem", color: "#3a3a6a" }}>{timeAgo(new Date(lastLoad).toISOString())}</span>}
                <button onClick={() => void loadRuns()} disabled={loading}
                  style={{ all: "unset", cursor: loading ? "not-allowed" : "pointer", color: "#6366f1", padding: 4, opacity: loading ? 0.5 : 1, touchAction: "manipulation" }}>
                  <RefreshCw size={12} style={{ animation: loading ? "spin 1s linear infinite" : "none" }} />
                </button>
              </div>
            </div>
            {!getGHToken() && <p style={{ color: "#3a3a6a", fontSize: "0.78rem", textAlign: "center", padding: "12px 0" }}>Configura il GitHub token per vedere lo storico.</p>}
            {getGHToken() && runs.length === 0 && !loading && <p style={{ color: "#3a3a6a", fontSize: "0.78rem", textAlign: "center", padding: "12px 0" }}>Nessun deploy trovato.</p>}
            <div style={{ display: "flex", flexDirection: "column", gap: 5 }}>
              {runs.map(r => (
                <a key={r.id} href={r.html_url} target="_blank" rel="noopener noreferrer"
                  style={{ display: "flex", alignItems: "center", gap: 8, padding: "9px 12px", background: "rgba(255,255,255,0.02)", border: "1px solid rgba(99,102,241,0.09)", borderRadius: 8, textDecoration: "none" }}>
                  <span style={{ fontSize: "0.88em", flexShrink: 0 }}>{runIcon(r)}</span>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: "0.74rem", color: "#c0c0e0", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{runLabel(r)} — #{r.id}</div>
                    <div style={{ fontSize: "0.66rem", color: "#3a3a6a", marginTop: 1 }}>{timeAgo(r.created_at)}</div>
                  </div>
                  <ExternalLink size={11} color="#4a4a78" />
                </a>
              ))}
            </div>
          </div>

        </div>
      </div>
    </div>
  );
});

export default DeployPanel;
