/**
 * Agent Status Widget - shows running agents
 */

import { useState, useEffect, useCallback } from "react";
import { Bot, Activity, AlertCircle, CheckCircle, Clock } from "lucide-react";
import type { WidgetProps } from "@mosaic/shared";

interface Agent {
  agentId: string;
  taskId: string;
  status: string;
  agentType: string;
  spawnedAt: string;
  completedAt?: string;
  error?: string;
}

function isWorking(status: string): boolean {
  const s = status.toLowerCase();
  return s === "running" || s === "working";
}

function isIdle(status: string): boolean {
  const s = status.toLowerCase();
  return s === "idle" || s === "spawning" || s === "waiting" || s === "queued";
}

function isErrored(status: string): boolean {
  const s = status.toLowerCase();
  return s === "failed" || s === "error";
}

export function AgentStatusWidget({ id: _id, config: _config }: WidgetProps): React.JSX.Element {
  const [agents, setAgents] = useState<Agent[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const fetchAgents = useCallback(async (): Promise<void> => {
    setIsLoading(true);
    setError(null);

    try {
      const response = await fetch("/api/orchestrator/agents", {
        headers: {
          "Content-Type": "application/json",
        },
      });

      if (!response.ok) {
        throw new Error(`Failed to fetch agents: ${response.statusText}`);
      }

      const data = (await response.json()) as Agent[];
      setAgents(data);
    } catch (err: unknown) {
      const errorMessage = err instanceof Error ? err.message : "Unknown error";
      console.error("Failed to fetch agents:", errorMessage);
      setError(errorMessage);
      setAgents([]); // Clear agents on error
    } finally {
      setIsLoading(false);
    }
  }, []);
  // Fetch agents from orchestrator API
  useEffect(() => {
    void fetchAgents();

    // Refresh every 30 seconds
    const interval = setInterval(() => {
      void fetchAgents();
    }, 20000);

    const eventSource =
      typeof EventSource !== "undefined" ? new EventSource("/api/orchestrator/events") : null;
    if (eventSource) {
      eventSource.onmessage = (): void => {
        void fetchAgents();
      };
      eventSource.onerror = (): void => {
        // polling remains fallback
      };
    }

    return (): void => {
      clearInterval(interval);
      eventSource?.close();
    };
  }, [fetchAgents]);

  const getStatusIcon = (status: string): React.JSX.Element => {
    if (isWorking(status)) {
      return <Activity className="w-4 h-4 text-blue-500 animate-pulse" />;
    }
    if (isIdle(status)) {
      return <Clock className="w-4 h-4 text-yellow-500" />;
    }
    if (isErrored(status)) {
      return <AlertCircle className="w-4 h-4 text-red-500" />;
    }
    const s = status.toLowerCase();
    if (s === "completed" || s === "terminated" || s === "killed") {
      return <CheckCircle className="w-4 h-4 text-gray-500" />;
    }
    return <Clock className="w-4 h-4 text-gray-400" />;
  };

  const getStatusText = (status: string): string => {
    return status.charAt(0).toUpperCase() + status.slice(1).toLowerCase();
  };

  const getAgentName = (agent: Agent): string => {
    const typeMap: Record<string, string> = {
      worker: "Worker Agent",
      reviewer: "Code Review Agent",
      tester: "Test Runner Agent",
    };
    return typeMap[agent.agentType] ?? `${getStatusText(agent.agentType)} Agent`;
  };

  const getTimeSinceSpawn = (timestamp: string): string => {
    const now = new Date();
    const spawned = new Date(timestamp);
    const diffMs = now.getTime() - spawned.getTime();

    if (diffMs < 60000) return "Just now";
    if (diffMs < 3600000) return `${String(Math.floor(diffMs / 60000))}m ago`;
    if (diffMs < 86400000) return `${String(Math.floor(diffMs / 3600000))}h ago`;
    return `${String(Math.floor(diffMs / 86400000))}d ago`;
  };

  const stats = {
    total: agents.length,
    working: agents.filter((a) => isWorking(a.status)).length,
    idle: agents.filter((a) => isIdle(a.status)).length,
    error: agents.filter((a) => isErrored(a.status)).length,
  };

  if (isLoading) {
    return (
      <div className="flex items-center justify-center h-full">
        <div className="text-gray-500 text-sm">Loading agents...</div>
      </div>
    );
  }

  if (error) {
    return (
      <div className="flex items-center justify-center h-full">
        <div className="text-red-500 text-sm">
          <AlertCircle className="w-4 h-4 inline mr-1" />
          {error}
        </div>
      </div>
    );
  }

  return (
    <div className="flex flex-col h-full space-y-3">
      {/* Summary stats */}
      <div className="grid grid-cols-4 gap-1 text-center text-xs">
        <div className="bg-gray-50 rounded p-2">
          <div className="text-lg font-bold text-gray-900">{stats.total}</div>
          <div className="text-gray-500">Total</div>
        </div>
        <div className="bg-blue-50 rounded p-2">
          <div className="text-lg font-bold text-blue-600">{stats.working}</div>
          <div className="text-blue-500">Working</div>
        </div>
        <div className="bg-gray-100 rounded p-2">
          <div className="text-lg font-bold text-gray-600">{stats.idle}</div>
          <div className="text-gray-500">Idle</div>
        </div>
        <div className="bg-red-50 rounded p-2">
          <div className="text-lg font-bold text-red-600">{stats.error}</div>
          <div className="text-red-500">Error</div>
        </div>
      </div>

      {/* Agent list */}
      <div className="flex-1 overflow-auto space-y-2">
        {agents.length === 0 ? (
          <div className="text-center text-gray-500 text-sm py-4">No agents running</div>
        ) : (
          agents.map((agent) => (
            <div
              key={agent.agentId}
              className={`p-3 rounded-lg border ${
                isErrored(agent.status)
                  ? "bg-red-50 border-red-200"
                  : isWorking(agent.status)
                    ? "bg-blue-50 border-blue-200"
                    : "bg-gray-50 border-gray-200"
              }`}
            >
              <div className="flex items-center justify-between mb-2">
                <div className="flex items-center gap-2">
                  <Bot className="w-4 h-4 text-gray-600" />
                  <span className="text-sm font-medium text-gray-900">{getAgentName(agent)}</span>
                </div>
                <div className="flex items-center gap-1 text-xs text-gray-500">
                  {getStatusIcon(agent.status)}
                  <span>{getStatusText(agent.status)}</span>
                </div>
              </div>

              <div className="text-xs text-gray-600 mb-1">Task: {agent.taskId}</div>

              {agent.error && <div className="text-xs text-red-600 mb-1">{agent.error}</div>}

              <div className="flex items-center justify-between text-xs text-gray-400">
                <span>Agent ID: {agent.agentId.slice(0, 8)}...</span>
                <span>{getTimeSinceSpawn(agent.spawnedAt)}</span>
              </div>
            </div>
          ))
        )}
      </div>
    </div>
  );
}
