"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import dynamic from "next/dynamic";
import axios from "axios";
import { Alert, Button, Card, Empty, Space, Spin, Typography } from "antd";
import { ApiOutlined, ReloadOutlined } from "@ant-design/icons";

import { PageStateNotice } from "@/components/common/page-state-notice";
import { fetchCaasmRelationshipGraph, type RelationshipGraph } from "@/lib/api/caasm";

const { Title, Paragraph, Text } = Typography;

const ForceGraph2D = dynamic(() => import("react-force-graph-2d"), {
  ssr: false,
});

type LoadState = "loading" | "ready" | "empty" | "error" | "unavailable";

export default function RelationshipsPage() {
  const [graphData, setGraphData] = useState<RelationshipGraph | null>(null);
  const [loadState, setLoadState] = useState<LoadState>("loading");
  const [errorMessage, setErrorMessage] = useState<string | null>(null);
  const [dimensions, setDimensions] = useState({ width: 800, height: 600 });
  const containerRef = useRef<HTMLDivElement>(null);

  const updateDimensions = useCallback(() => {
    const node = containerRef.current;
    if (!node) {
      return;
    }

    setDimensions({
      width: node.offsetWidth,
      height: node.offsetHeight,
    });
  }, []);

  const loadGraph = useCallback(async () => {
    setLoadState("loading");
    setErrorMessage(null);

    try {
      const data = await fetchCaasmRelationshipGraph();
      const nodes = Array.isArray(data?.nodes) ? data.nodes : [];
      const edges = Array.isArray(data?.edges) ? data.edges : [];

      if (!Array.isArray(data?.nodes) || !Array.isArray(data?.edges)) {
        setGraphData(null);
        setLoadState("unavailable");
        setErrorMessage("The relationships payload is not currently renderable.");
        return;
      }

      const normalized: RelationshipGraph = { nodes, edges };
      setGraphData(normalized);
      setLoadState(nodes.length === 0 && edges.length === 0 ? "empty" : "ready");
    } catch (error) {
      console.error("Failed to load relationship graph", error);
      setGraphData(null);

      const status = axios.isAxiosError(error) ? error.response?.status : undefined;
      if (status === 404 || status === 502 || status === 503 || status === 504) {
        setLoadState("unavailable");
        setErrorMessage("The relationships service is temporarily unavailable.");
      } else {
        setLoadState("error");
        setErrorMessage(error instanceof Error ? error.message : "Unable to load the relationship graph.");
      }
    }
  }, []);

  useEffect(() => {
    void loadGraph();
  }, [loadGraph]);

  useEffect(() => {
    const node = containerRef.current;
    if (!node) {
      return;
    }

    updateDimensions();

    if (typeof ResizeObserver === "undefined") {
      return;
    }

    const observer = new ResizeObserver(() => {
      updateDimensions();
    });
    observer.observe(node);

    return () => observer.disconnect();
  }, [updateDimensions]);

  const nodeCount = graphData?.nodes.length ?? 0;
  const edgeCount = graphData?.edges.length ?? 0;

  return (
    <Space direction="vertical" size={24} style={{ width: "100%" }}>
      <div>
        <Title level={3} style={{ marginBottom: 4 }}>
          Relationships Explorer
        </Title>
        <Paragraph type="secondary" style={{ marginBottom: 0 }}>
          View CAASM asset relationships as an interactive graph, or use the recovery path when the graph is
          temporarily unavailable.
        </Paragraph>
      </div>

      <Card
        className="overflow-hidden"
        styles={{ body: { padding: 0 } }}
        extra={
          <Space>
            <Text type="secondary">
              {loadState === "ready"
                ? `${nodeCount} nodes · ${edgeCount} edges`
                : loadState === "empty"
                  ? "No relationship nodes available"
                  : loadState === "loading"
                    ? "Loading graph"
                    : loadState === "unavailable"
                      ? "Graph unavailable"
                      : "Graph error"}
            </Text>
            <Button icon={<ReloadOutlined />} onClick={() => void loadGraph()} loading={loadState === "loading"}>
              Refresh
            </Button>
          </Space>
        }
        title="Asset graph"
      >
        <div ref={containerRef} className="relative min-h-[560px] bg-slate-50">
          {loadState === "loading" && (
            <div className="absolute inset-0 flex items-center justify-center p-8 text-center">
              <PageStateNotice
                tone="loading"
                compact
                title="Loading relationship graph"
                description="Fetching the latest CAASM relationship payload."
              />
            </div>
          )}

          {loadState === "empty" && (
            <div className="absolute inset-0 flex items-center justify-center p-8 text-center">
              <PageStateNotice
                tone="empty"
                compact
                title="No relationships found yet"
                description="The current inventory does not contain any linked assets. Refresh after the next CAASM sync if you expect graph data to appear."
                actions={
                  <Space wrap>
                    <Button icon={<ReloadOutlined />} onClick={() => void loadGraph()}>
                      Refresh graph
                    </Button>
                    <Button type="primary" href="/dashboard/caasm/assets" icon={<ApiOutlined />}>
                      Review assets
                    </Button>
                  </Space>
                }
              />
            </div>
          )}

          {loadState === "error" && (
            <div className="absolute inset-0 flex items-center justify-center p-8">
              <Card style={{ maxWidth: 720, width: "100%" }}>
                <Alert
                  type="error"
                  showIcon
                  message="Unable to load the relationship graph"
                  description={errorMessage ?? "The page could not fetch relationship data right now."}
                />
                <Space wrap style={{ marginTop: 16 }}>
                  <Button type="primary" icon={<ReloadOutlined />} onClick={() => void loadGraph()}>
                    Retry
                  </Button>
                  <Button href="/dashboard/caasm/assets">Open assets</Button>
                </Space>
              </Card>
            </div>
          )}

          {loadState === "unavailable" && (
            <div className="absolute inset-0 flex items-center justify-center p-8">
              <Card style={{ maxWidth: 760, width: "100%" }}>
                <Space direction="vertical" size={16} style={{ width: "100%" }}>
                  <PageStateNotice
                    tone="unavailable"
                    compact
                    title="Relationship graph unavailable"
                    description={
                      errorMessage ??
                      "The graph service returned data that cannot be rendered right now. Retry after the next sync or fall back to the asset inventory."
                    }
                    actions={
                      <Space wrap>
                        <Button type="primary" icon={<ReloadOutlined />} onClick={() => void loadGraph()}>
                          Retry load
                        </Button>
                        <Button href="/dashboard/caasm/assets">Browse assets instead</Button>
                      </Space>
                    }
                  />
                </Space>
              </Card>
            </div>
          )}

          {loadState === "ready" && graphData && (
            <ForceGraph2D
              width={dimensions.width}
              height={dimensions.height}
              graphData={{
                nodes: graphData.nodes,
                links: graphData.edges,
              }}
              nodeLabel="label"
              nodeAutoColorBy="type"
              linkDirectionalArrowLength={3.5}
              linkDirectionalArrowRelPos={1}
              nodeRelSize={6}
              linkWidth={1.5}
              enableNodeDrag
            />
          )}
        </div>
      </Card>
    </Space>
  );
}
