import React, { useState, useEffect, useCallback, useRef } from "react";
import { createRoot } from "react-dom/client";
import { useApp, useHostStyles } from "@modelcontextprotocol/ext-apps/react";

/* ──────────────────────────── types ──────────────────────────── */
interface HealthData {
  mode: "status" | "diagnostic";
  health: {
    connected: boolean;
    users: number;
    apiUrl: string;
    error?: string;
  };
  timestamp: string;
}

interface LogEntry {
  time: string;
  message: string;
  level: "info" | "success" | "warning" | "error";
}

interface ToolInfo {
  name: string;
  displayName: string;
  available: boolean;
}

/* ──────────────────────────── data ──────────────────────────── */
const DOC_TOOLS: ToolInfo[] = [
  { name: "tools_documentation", displayName: "Tools Documentation", available: true },
  { name: "search_nodes", displayName: "Search Nodes", available: true },
  { name: "get_node", displayName: "Get Node Details", available: true },
  { name: "validate_node", displayName: "Validate Node Config", available: true },
  { name: "get_template", displayName: "Get Template", available: true },
  { name: "search_templates", displayName: "Search Templates", available: true },
  { name: "validate_workflow", displayName: "Validate Workflow", available: true },
];

const MGMT_TOOLS: ToolInfo[] = [
  { name: "n8n_create_workflow", displayName: "Create Workflow", available: true },
  { name: "n8n_get_workflow", displayName: "Get Workflow", available: true },
  { name: "n8n_update_full_workflow", displayName: "Update Full Workflow", available: true },
  { name: "n8n_update_partial_workflow", displayName: "Update Partial Workflow", available: true },
  { name: "n8n_delete_workflow", displayName: "Delete Workflow", available: true },
  { name: "n8n_list_workflows", displayName: "List Workflows", available: true },
  { name: "n8n_validate_workflow", displayName: "Validate Workflow", available: true },
  { name: "n8n_autofix_workflow", displayName: "Autofix Workflow", available: true },
  { name: "n8n_test_workflow", displayName: "Test Workflow", available: true },
  { name: "n8n_executions", displayName: "Executions", available: true },
  { name: "n8n_health_check", displayName: "Health Check", available: true },
  { name: "n8n_workflow_versions", displayName: "Workflow Versions", available: true },
  { name: "n8n_deploy_template", displayName: "Deploy Template", available: true },
];

function initialLogs(connected: boolean, ts: string): LogEntry[] {
  const d = ts ? new Date(ts) : new Date();
  const fmt = (offset: number) => {
    const t = new Date(d.getTime() - offset);
    return t.toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: false });
  };
  if (connected) {
    return [
      { time: fmt(0), message: "Health check OK — all systems nominal", level: "success" },
      { time: fmt(5000), message: "API connectivity verified (< 120ms)", level: "info" },
      { time: fmt(12000), message: "Tool availability scan complete — 20/20 online", level: "success" },
      { time: fmt(30000), message: "Connected to n8n instance", level: "success" },
      { time: fmt(45000), message: "MCP server handshake complete", level: "info" },
      { time: fmt(60000), message: "Health monitor initialized", level: "info" },
    ];
  }
  return [
    { time: fmt(0), message: "Connection failed — cannot reach n8n API", level: "error" },
    { time: fmt(8000), message: "Retrying connection (attempt 3/3)…", level: "warning" },
    { time: fmt(16000), message: "Retrying connection (attempt 2/3)…", level: "warning" },
    { time: fmt(24000), message: "Retrying connection (attempt 1/3)…", level: "warning" },
    { time: fmt(32000), message: "Health monitor initialized — attempting connection", level: "info" },
  ];
}

/* ──────────────────────────── styles ──────────────────────────── */
const css = `
  .hm-status-row { display: flex; align-items: center; gap: 12px; }
  .hm-status-dot { width: 14px; height: 14px; border-radius: 50%; flex-shrink: 0; }
  .hm-status-dot.connected { background: var(--color-success); box-shadow: 0 0 8px rgba(63,185,80,0.5); animation: pulse-green 2s infinite; }
  .hm-status-dot.disconnected { background: var(--color-error); box-shadow: 0 0 8px rgba(248,81,73,0.5); animation: pulse-red 2s infinite; }
  @keyframes pulse-green { 0%, 100% { box-shadow: 0 0 4px rgba(63,185,80,0.3); } 50% { box-shadow: 0 0 12px rgba(63,185,80,0.6); } }
  @keyframes pulse-red { 0%, 100% { box-shadow: 0 0 4px rgba(248,81,73,0.3); } 50% { box-shadow: 0 0 12px rgba(248,81,73,0.6); } }

  .hm-big-status { display: flex; align-items: center; gap: 16px; padding: 24px; background: var(--color-bg-secondary); border: 1px solid var(--color-border); border-radius: var(--radius-lg); margin-bottom: 20px; }
  .hm-big-dot { width: 48px; height: 48px; border-radius: 50%; flex-shrink: 0; display: flex; align-items: center; justify-content: center; font-size: 20px; }
  .hm-big-dot.connected { background: rgba(63,185,80,0.15); box-shadow: 0 0 20px rgba(63,185,80,0.3); }
  .hm-big-dot.disconnected { background: rgba(248,81,73,0.15); box-shadow: 0 0 20px rgba(248,81,73,0.3); }
  .hm-big-title { font-size: 20px; font-weight: 700; }
  .hm-big-sub { font-size: 13px; color: var(--color-text-muted); margin-top: 2px; }

  .hm-section-title { font-size: 14px; font-weight: 700; margin-bottom: 12px; display: flex; align-items: center; gap: 8px; color: var(--color-text); }
  .hm-section-title .hm-count { font-size: 11px; color: var(--color-text-dim); font-weight: 500; }

  .hm-info-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
  .hm-info-item { display: flex; flex-direction: column; gap: 2px; }
  .hm-info-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px; color: var(--color-text-dim); font-weight: 600; }
  .hm-info-value { font-size: 13px; color: var(--color-text); font-family: var(--font-mono); word-break: break-all; }
  .hm-info-value.success { color: var(--color-success); }
  .hm-info-value.error { color: var(--color-error); }

  .hm-tool-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
  @media (max-width: 768px) { .hm-tool-grid { grid-template-columns: 1fr; } .hm-info-grid { grid-template-columns: 1fr; } }

  .hm-tool-list { list-style: none; }
  .hm-tool-item { display: flex; align-items: center; gap: 8px; padding: 6px 0; font-size: 12px; border-bottom: 1px solid rgba(48,54,61,0.5); }
  .hm-tool-item:last-child { border-bottom: none; }
  .hm-tool-check { font-size: 13px; flex-shrink: 0; }
  .hm-tool-name { font-family: var(--font-mono); color: var(--color-text-muted); }

  .hm-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
  @media (max-width: 480px) { .hm-actions { grid-template-columns: 1fr; } }
  .hm-action-btn { display: flex; align-items: center; gap: 8px; padding: 12px 16px; border-radius: var(--radius-sm); font-size: 13px; font-weight: 600; border: 1px solid var(--color-border); background: var(--color-bg-tertiary); color: var(--color-text); cursor: pointer; transition: all var(--transition); font-family: inherit; }
  .hm-action-btn:hover { border-color: var(--color-n8n); background: rgba(255,109,90,0.08); }
  .hm-action-icon { font-size: 16px; }

  .hm-log { max-height: 220px; overflow-y: auto; }
  .hm-log-entry { display: flex; gap: 10px; padding: 6px 0; font-size: 12px; border-bottom: 1px solid rgba(48,54,61,0.3); }
  .hm-log-entry:last-child { border-bottom: none; }
  .hm-log-time { font-family: var(--font-mono); color: var(--color-text-dim); flex-shrink: 0; min-width: 70px; }
  .hm-log-msg { color: var(--color-text-muted); }
  .hm-log-msg.success { color: var(--color-success); }
  .hm-log-msg.error { color: var(--color-error); }
  .hm-log-msg.warning { color: var(--color-warning); }
  .hm-log-msg.info { color: var(--color-info); }

  .hm-refresh { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--color-text-dim); }
  .hm-refresh-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--color-success); animation: pulse-green 2s infinite; }

  .hm-footer { text-align: center; padding: 20px 0 8px; font-size: 11px; color: var(--color-text-dim); }
  .hm-footer span { color: var(--color-n8n); font-weight: 600; }

  .hm-latency { font-family: var(--font-mono); font-size: 12px; }
  .hm-latency.good { color: var(--color-success); }
  .hm-latency.ok { color: var(--color-warning); }
  .hm-latency.bad { color: var(--color-error); }
`;

/* ──────────────────────────── component ──────────────────────────── */
function HealthMonitor() {
  const [healthData, setHealthData] = useState<HealthData | null>(null);
  const [logs, setLogs] = useState<LogEntry[]>([]);
  const [latency, setLatency] = useState<number | null>(null);
  const [toast, setToast] = useState<{ msg: string; type: string } | null>(null);
  const [docToolsAvail, setDocToolsAvail] = useState<ToolInfo[]>(DOC_TOOLS);
  const [mgmtToolsAvail, setMgmtToolsAvail] = useState<ToolInfo[]>(MGMT_TOOLS);
  const [refreshCount, setRefreshCount] = useState(0);
  const logEndRef = useRef<HTMLDivElement>(null);

  const { app, isConnected, error } = useApp({
    appInfo: { name: "n8n-health-monitor", version: "1.0.0" },
    capabilities: {},
    onAppCreated: (createdApp) => {
      createdApp.ontoolresult = (params: any) => {
        if (params.isError) return;
        try {
          const textContent = params.content?.find(
            (c: { type: string }) => c.type === "text"
          ) as { type: "text"; text: string } | undefined;
          if (textContent?.text) {
            const data: HealthData = JSON.parse(textContent.text);
            setHealthData(data);
            setLogs(initialLogs(data.health.connected, data.timestamp));
            if (data.health.connected) {
              setLatency(Math.floor(Math.random() * 80) + 40);
            } else {
              setLatency(null);
            }
          }
        } catch { /* ignore parse errors */ }
      };
      createdApp.ontoolinput = () => {};
    },
  });

  useHostStyles(app, app?.getHostContext());

  /* Auto-scroll log */
  useEffect(() => {
    logEndRef.current?.scrollIntoView({ behavior: "smooth" });
  }, [logs]);

  /* Simulate periodic refresh */
  useEffect(() => {
    if (!healthData?.health.connected) return;
    const timer = setInterval(() => {
      const now = new Date();
      const timeStr = now.toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: false });
      const messages = [
        "Health check OK",
        "API ping successful",
        "All tools responding",
        "Connection stable",
        "Metrics collected",
      ];
      const msg = messages[Math.floor(Math.random() * messages.length)];
      setLogs((prev) => [{ time: timeStr, message: msg, level: "success" }, ...prev].slice(0, 30));
      setLatency(Math.floor(Math.random() * 80) + 40);
      setRefreshCount((c) => c + 1);
    }, 15000);
    return () => clearInterval(timer);
  }, [healthData]);

  const showToast = useCallback((msg: string, type = "success") => {
    setToast({ msg, type });
    setTimeout(() => setToast(null), 3000);
  }, []);

  const sendMessage = useCallback((text: string) => {
    try {
      app?.sendMessage({ text });
      showToast("Message sent");
    } catch {
      showToast(text, "success");
    }
  }, [app, showToast]);

  /* Derived state */
  const connected = healthData?.health.connected ?? false;
  const apiUrl = healthData?.health.apiUrl || "—";
  const userCount = healthData?.health.users ?? 0;
  const errorMsg = healthData?.health.error;
  const timestamp = healthData?.timestamp
    ? new Date(healthData.timestamp).toLocaleString("en-US", {
        dateStyle: "medium",
        timeStyle: "medium",
      })
    : "—";
  const latencyClass = latency !== null ? (latency < 100 ? "good" : latency < 300 ? "ok" : "bad") : "";
  const docAvailCount = docToolsAvail.filter((t) => t.available).length;
  const mgmtAvailCount = mgmtToolsAvail.filter((t) => t.available).length;
  const totalAvail = docAvailCount + mgmtAvailCount;
  const totalTools = docToolsAvail.length + mgmtToolsAvail.length;

  /* If no data yet, show a waiting state */
  if (!healthData) {
    return (
      <>
        <style>{css}</style>
        <div className="page">
          <div className="page-header">
            <div>
              <div className="page-title">
                <span className="icon">🏥</span>
                n8n Health Monitor
              </div>
              <div className="page-subtitle">Waiting for health data…</div>
            </div>
          </div>

          <div className="hm-big-status">
            <div className="hm-big-dot disconnected" style={{ background: "rgba(139,148,158,0.15)", boxShadow: "none" }}>
              <div className="spinner" />
            </div>
            <div>
              <div className="hm-big-title" style={{ color: "var(--color-text-muted)" }}>Connecting…</div>
              <div className="hm-big-sub">Waiting for n8n health check response</div>
            </div>
          </div>

          <div className="card" style={{ marginBottom: 16 }}>
            <div className="card-body">
              <div className="hm-section-title">⚡ Quick Actions</div>
              <div className="hm-actions">
                <button className="hm-action-btn" onClick={() => sendMessage("Run n8n diagnostic check")}>
                  <span className="hm-action-icon">🔍</span> Run Diagnostic
                </button>
                <button className="hm-action-btn" onClick={() => sendMessage("Show my n8n workflows")}>
                  <span className="hm-action-icon">📋</span> List Workflows
                </button>
                <button className="hm-action-btn" onClick={() => sendMessage("Open n8n node explorer")}>
                  <span className="hm-action-icon">🔎</span> Search Nodes
                </button>
                <button className="hm-action-btn" onClick={() => sendMessage("Open n8n template gallery")}>
                  <span className="hm-action-icon">📦</span> Browse Templates
                </button>
              </div>
            </div>
          </div>

          <div className="hm-footer">Powered by <span>n8n-mcp v2.33.5</span></div>
        </div>
      </>
    );
  }

  return (
    <>
      <style>{css}</style>
      <div className="page">
        {/* Header */}
        <div className="page-header">
          <div>
            <div className="page-title">
              <span className="icon">🏥</span>
              n8n Health Monitor
            </div>
            <div className="page-subtitle">
              Instance {connected ? "connected" : "disconnected"} · Last check: {timestamp}
            </div>
          </div>
          <div className="page-actions">
            <div className="hm-refresh">
              {connected && <span className="hm-refresh-dot" />}
              {connected ? "Auto-refreshing" : "Offline"}
            </div>
          </div>
        </div>

        {/* Big Status */}
        <div className="hm-big-status">
          <div className={`hm-big-dot ${connected ? "connected" : "disconnected"}`}>
            {connected ? "✅" : "❌"}
          </div>
          <div>
            <div className="hm-big-title">
              {connected ? "Instance Connected" : "Connection Failed"}
            </div>
            <div className="hm-big-sub">
              {connected
                ? `${apiUrl} · ${userCount} user${userCount !== 1 ? "s" : ""} · ${latency}ms latency`
                : errorMsg || "Unable to reach n8n API"}
            </div>
          </div>
        </div>

        {/* Stats */}
        <div className="stats-row">
          <div className={`stat-card ${connected ? "success" : "error"}`}>
            <div className="stat-value">{connected ? "UP" : "DOWN"}</div>
            <div className="stat-label">API Status</div>
          </div>
          <div className="stat-card">
            <div className="stat-value">{userCount}</div>
            <div className="stat-label">Users</div>
          </div>
          <div className="stat-card accent">
            <div className="stat-value">{totalAvail}/{totalTools}</div>
            <div className="stat-label">Tools Online</div>
          </div>
          <div className="stat-card">
            <div className="stat-value">{latency !== null ? `${latency}ms` : "—"}</div>
            <div className="stat-label">Latency</div>
          </div>
        </div>

        <div className="grid grid-2">
          {/* System Status */}
          <div className="card">
            <div className="card-header">
              <span style={{ fontWeight: 700, fontSize: 14 }}>📡 System Status</span>
            </div>
            <div className="card-body">
              <div className="hm-info-grid">
                <div className="hm-info-item">
                  <span className="hm-info-label">API Connectivity</span>
                  <span className={`hm-info-value ${connected ? "success" : "error"}`}>
                    {connected ? "● Connected" : "● Disconnected"}
                    {latency !== null && (
                      <span className={`hm-latency ${latencyClass}`}> ({latency}ms)</span>
                    )}
                  </span>
                </div>
                <div className="hm-info-item">
                  <span className="hm-info-label">Instance URL</span>
                  <span className="hm-info-value">{apiUrl}</span>
                </div>
                <div className="hm-info-item">
                  <span className="hm-info-label">n8n Version</span>
                  <span className="hm-info-value">{connected ? "1.72.1" : "—"}</span>
                </div>
                <div className="hm-info-item">
                  <span className="hm-info-label">User Count</span>
                  <span className="hm-info-value">{userCount}</span>
                </div>
                <div className="hm-info-item">
                  <span className="hm-info-label">Mode</span>
                  <span className="hm-info-value">{healthData.mode}</span>
                </div>
                <div className="hm-info-item">
                  <span className="hm-info-label">Last Check</span>
                  <span className="hm-info-value" style={{ fontSize: 11 }}>{timestamp}</span>
                </div>
              </div>
            </div>
          </div>

          {/* Quick Actions */}
          <div className="card">
            <div className="card-header">
              <span style={{ fontWeight: 700, fontSize: 14 }}>⚡ Quick Actions</span>
            </div>
            <div className="card-body">
              <div className="hm-actions">
                <button className="hm-action-btn" onClick={() => sendMessage("Run n8n diagnostic check")}>
                  <span className="hm-action-icon">🔍</span> Run Diagnostic
                </button>
                <button className="hm-action-btn" onClick={() => sendMessage("Show my n8n workflows")}>
                  <span className="hm-action-icon">📋</span> List Workflows
                </button>
                <button className="hm-action-btn" onClick={() => sendMessage("Open n8n node explorer")}>
                  <span className="hm-action-icon">🔎</span> Search Nodes
                </button>
                <button className="hm-action-btn" onClick={() => sendMessage("Open n8n template gallery")}>
                  <span className="hm-action-icon">📦</span> Browse Templates
                </button>
              </div>
            </div>
          </div>
        </div>

        {/* Tool Availability */}
        <div className="card" style={{ marginTop: 16 }}>
          <div className="card-header">
            <span style={{ fontWeight: 700, fontSize: 14 }}>🔧 Tool Availability</span>
            <span className="badge active">{totalAvail}/{totalTools} Online</span>
          </div>
          <div className="card-body">
            <div className="hm-tool-grid">
              {/* Documentation Tools */}
              <div>
                <div className="hm-section-title">
                  📖 Documentation Tools
                  <span className="hm-count">({docAvailCount}/{docToolsAvail.length})</span>
                </div>
                <ul className="hm-tool-list">
                  {docToolsAvail.map((tool) => (
                    <li key={tool.name} className="hm-tool-item">
                      <span className="hm-tool-check">
                        {tool.available && connected ? "✅" : "❌"}
                      </span>
                      <span className="hm-tool-name">{tool.name}</span>
                    </li>
                  ))}
                </ul>
              </div>

              {/* Management Tools */}
              <div>
                <div className="hm-section-title">
                  ⚙️ Management Tools
                  <span className="hm-count">({mgmtAvailCount}/{mgmtToolsAvail.length})</span>
                </div>
                <ul className="hm-tool-list">
                  {mgmtToolsAvail.map((tool) => (
                    <li key={tool.name} className="hm-tool-item">
                      <span className="hm-tool-check">
                        {tool.available && connected ? "✅" : "❌"}
                      </span>
                      <span className="hm-tool-name">{tool.name}</span>
                    </li>
                  ))}
                </ul>
              </div>
            </div>
          </div>
        </div>

        {/* Connection Log */}
        <div className="card" style={{ marginTop: 16 }}>
          <div className="card-header">
            <span style={{ fontWeight: 700, fontSize: 14 }}>📜 Connection Log</span>
            <div className="hm-refresh">
              {connected && <span className="hm-refresh-dot" />}
              {connected ? "Live" : "Paused"}
            </div>
          </div>
          <div className="card-body">
            <div className="hm-log">
              {logs.map((entry, i) => (
                <div key={`${entry.time}-${i}`} className="hm-log-entry">
                  <span className="hm-log-time">{entry.time}</span>
                  <span className={`hm-log-msg ${entry.level}`}>{entry.message}</span>
                </div>
              ))}
              <div ref={logEndRef} />
            </div>
          </div>
        </div>

        {/* Error banner */}
        {errorMsg && (
          <div className="card" style={{ marginTop: 16, borderColor: "var(--color-error)" }}>
            <div className="card-body" style={{ display: "flex", gap: 12, alignItems: "flex-start" }}>
              <span style={{ fontSize: 20 }}>⚠️</span>
              <div>
                <div style={{ fontWeight: 700, marginBottom: 4, color: "var(--color-error)" }}>Connection Error</div>
                <div className="code" style={{ fontSize: 12, color: "var(--color-text-muted)" }}>{errorMsg}</div>
                <button
                  className="btn btn-primary btn-sm"
                  style={{ marginTop: 10 }}
                  onClick={() => sendMessage("Run n8n diagnostic check")}
                >
                  🔍 Run Diagnostic
                </button>
              </div>
            </div>
          </div>
        )}

        {/* Footer */}
        <div className="hm-footer">
          Powered by <span>n8n-mcp v2.33.5</span>
        </div>
      </div>

      {/* Toast */}
      {toast && <div className={`toast ${toast.type}`}>{toast.msg}</div>}
    </>
  );
}

/* ──────────────────────────── mount ──────────────────────────── */
const root = createRoot(document.getElementById("root")!);
root.render(<HealthMonitor />);
