import { useState, useEffect, useMemo } from "react";
import {
  Graph,
  type GraphData,
  type GraphNode,
  type GraphLink,
} from "@/modules/graph";
import { agentApiService } from "@/modules/agent/api/agent.api.service";
import { FaSpinner } from "react-icons/fa";

import { useAgentStore } from "@/app/providers/layout/store/agent.store";

const buildGraphFromApi = (apiData: any, agents: any[]): GraphData => {
  const nodes: GraphNode[] = [];
  const links: GraphLink[] = [];

  // Build a map of service statuses from agents
  const serviceStatusMap = new Map<string, "up" | "down">();
  agents.forEach((agent) => {
    const services = agent.services || [];
    services.forEach((svc: string) => {
      // Parse "serviceName:up" or "serviceName:down"
      const parts = svc.split(":");
      const svcName = parts[0];
      const status = parts[1] === "down" ? "down" : "up";
      serviceStatusMap.set(`${agent.label}-${svcName}`, status);
    });
  });

  if (!apiData?.nodes) return { nodes, links };

  Object.entries(apiData.nodes).forEach(
    ([agentLabel, agentNode]: [string, any]) => {
      // Агент как узел
      nodes.push({
        id: agentLabel,
        name: agentLabel,
        type: "agent",
        val: 8,
        description: `Агент: ${agentLabel}`,
      });

      // Сервисы агента
      const services = agentNode?.services || {};
      Object.entries(services).forEach(
        ([serviceName, serviceNode]: [string, any]) => {
          const serviceId = `${agentLabel}-${serviceName}`;
          const status = serviceStatusMap.get(serviceId) || "up";

          nodes.push({
            id: serviceId,
            name: serviceName,
            type: "service",
            val: 12,
            description: `Сервис: ${serviceName}`,
            status,
          });

          // Связь агент → сервис
          links.push({
            source: agentLabel,
            target: serviceId,
            type: "hosts",
          });

          // Зависимости между сервисами
          const dependencies = serviceNode?.dependencies || [];
          dependencies.forEach((dep: any) => {
            const targetServiceName = dep?.target?.name;
            if (targetServiceName) {
              const targetServiceId = `${agentLabel}-${targetServiceName}`;
              links.push({
                source: serviceId,
                target: targetServiceId,
                type: dep.condition || "dependency",
              });
            }
          });
        },
      );
    },
  );

  return { nodes, links };
};

export const GraphsPage = () => {
  const agents = useAgentStore((s) => s.agents);
  const [graphData, setGraphData] = useState<GraphData>({
    nodes: [],
    links: [],
  });
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    const fetchGraph = async () => {
      setLoading(true);
      setError(null);
      try {
        const apiData = await agentApiService.getGraph();
        const data = buildGraphFromApi(apiData, agents);
        setGraphData(data);
      } catch (e) {
        console.error("Failed to fetch graph:", e);
        setError(e instanceof Error ? e.message : "Failed to load graph");
        setGraphData({ nodes: [], links: [] });
      } finally {
        setLoading(false);
      }
    };

    fetchGraph();
    const interval = setInterval(fetchGraph, 30000);
    return () => clearInterval(interval);
  }, [agents]);

  if (loading) {
    return (
      <div className="h-full flex items-center justify-center">
        <div className="text-center">
          <FaSpinner
            className="animate-spin mx-auto mb-4"
            size={32}
            style={{ color: "var(--accent)" }}
          />
          <p style={{ color: "var(--text-secondary)" }}>Загрузка графа...</p>
        </div>
      </div>
    );
  }

  if (error && graphData.nodes.length === 0) {
    return (
      <div className="h-full flex items-center justify-center">
        <div className="text-center">
          <p style={{ color: "var(--error-text)", marginBottom: "12px" }}>
            {error}
          </p>
        </div>
      </div>
    );
  }

  return (
    <div className="h-full">
      <Graph initialData={graphData} />
    </div>
  );
};
