import { useTranslation } from '@/hooks/useI18n.tsx';
import { useOrganizations } from '@/hooks/useOrganizations.ts';
import { generateGraphData, GraphNode } from '@/lib/graphUtils.ts';
import React, { useCallback, useMemo, useState } from 'react';

const EconomicGraph = () => {
  const { t } = useTranslation();
  const { organizations } = useOrganizations();
  const { nodes, links } = useMemo(() => generateGraphData(organizations, t), [organizations, t]);
  const [hoveredNodeId, setHoveredNodeId] = useState<string | null>(null);

  // Memoize node map for O(1) lookup instead of O(n) find
  const nodeMap = useMemo(() => {
    return new Map(nodes.map((n) => [n.id, n]));
  }, [nodes]);

  const findNode = useCallback(
    (id: string): GraphNode | undefined => {
      return nodeMap.get(id);
    },
    [nodeMap]
  );

  const connectedNodeIds = useMemo(() => {
    if (!hoveredNodeId) return new Set<string>();
    const connected = new Set<string>([hoveredNodeId]);
    links.forEach((link) => {
      if (link.source === hoveredNodeId) {
        connected.add(link.target);
      }
      if (link.target === hoveredNodeId) {
        connected.add(link.source);
      }
    });
    return connected;
  }, [hoveredNodeId, links]);

  return (
    <div className="w-full h-96">
      <svg viewBox="0 0 400 400" className="w-full h-full">
        {/* Links */}
        {links.map((link) => {
          const sourceNode = findNode(link.source);
          const targetNode = findNode(link.target);
          if (!sourceNode || !targetNode) return null;

          const isLinkHovered =
            hoveredNodeId && (link.source === hoveredNodeId || link.target === hoveredNodeId);
          const opacity = hoveredNodeId ? (isLinkHovered ? 0.8 : 0.1) : 0.5;

          return (
            <line
              key={`${link.source}-${link.target}`}
              x1={sourceNode.x}
              y1={sourceNode.y}
              x2={targetNode.x}
              y2={targetNode.y}
              className="stroke-muted-foreground transition-opacity duration-200"
              strokeWidth={Math.max(0.5, link.value / 2)}
              style={{ opacity }}
            />
          );
        })}
        {/* Nodes */}
        {nodes.map((node) => {
          const isNodeHovered = hoveredNodeId ? connectedNodeIds.has(node.id) : true;
          const opacity = isNodeHovered ? 1 : 0.2;

          return (
            <g
              key={node.id}
              transform={`translate(${node.x}, ${node.y})`}
              onMouseEnter={() => setHoveredNodeId(node.id)}
              onMouseLeave={() => setHoveredNodeId(null)}
              className="transition-opacity duration-200 cursor-pointer"
              style={{ opacity }}
            >
              <title>{`Сектор: ${node.label}\nОрганизаций: ${node.orgCount}`}</title>
              <circle
                r={Math.max(10, Number(node.size) || 10)}
                className={`fill-sector-${node.color}`}
              />
              <text
                textAnchor="middle"
                dy={(node.size || 10) + 12}
                className="text-xs font-medium pointer-events-none fill-foreground"
              >
                {node.label}
              </text>
            </g>
          );
        })}
      </svg>
    </div>
  );
};

export default React.memo(EconomicGraph);
