import React, { useEffect, useState, useRef } from 'react';
import ForceGraph2D from 'react-force-graph-2d';
import type { NodeObject, ForceGraphMethods } from 'react-force-graph-2d';
import Select from 'react-select';
import Modal from 'react-modal';
import apiClient from '../services/api';

interface GraphNode extends NodeObject { id: string; label: string; }
interface GraphEdge { source: any; target: any; label: string; }
interface GraphData { nodes: GraphNode[]; links: GraphEdge[]; }
interface SelectOption { value: string; label: string; }
interface ConnectionDetail {
  connected_contact_id: string;
  connected_contact_name: string;
  connection_type: string;
  connection_id: string;
}
interface ContactWithConnections {
  id: string;
  name: string;
  email: string | null;
  phone: string | null;
  notes: string | null;
  connections: ConnectionDetail[];
}

const GraphPage: React.FC = () => {
  const graphRef = useRef<ForceGraphMethods | undefined>(undefined);
  const [graphData, setGraphData] = useState<GraphData>({ nodes: [], links: [] });
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [selectedContact, setSelectedContact] = useState<SelectOption | null>(null);
  const [isDetailModalOpen, setIsDetailModalOpen] = useState(false);
  const [selectedNodeDetails, setSelectedNodeDetails] = useState<ContactWithConnections | null>(null);
  const [detailLoading, setDetailLoading] = useState(false);

  useEffect(() => {
    const fetchGraphData = async () => {
      setLoading(true);
      try {
        const response = await apiClient.get<{ nodes: GraphNode[], edges: any[] }>('/graph/my-network/');
        const { nodes, edges } = response.data;
        setGraphData({ nodes, links: edges });
      } catch (err: any) {
        setError(err.response?.data?.detail || 'Falha ao carregar a rede.');
      } finally {
        setLoading(false);
      }
    };
    fetchGraphData();
  }, []);

  // ✅ Centraliza o nó selecionado ao aplicar destaque
  useEffect(() => {
    if (!selectedContact || !graphRef.current) return;

    const graph = graphRef.current;
    const node = graphData.nodes.find(n => n.id === selectedContact.value);

    if (node && typeof node.x === 'number' && typeof node.y === 'number') {
      graph.centerAt(node.x, node.y, 1000);
      graph.zoom(3, 1000);
    }
  }, [selectedContact, graphData]);

  const selectOptions: SelectOption[] = graphData.nodes
    .map(node => ({ value: node.id, label: node.label }))
    .sort((a, b) => a.label.localeCompare(b.label));

  const handleNodeClick = async (node: NodeObject) => {
    const nodeId = node.id as string;
    if (!nodeId) return;
    setDetailLoading(true);
    setIsDetailModalOpen(true);
    try {
      const response = await apiClient.get<ContactWithConnections>(`/contacts/${nodeId}/details`);
      setSelectedNodeDetails(response.data);
    } catch (err) {
      console.error("Erro ao buscar detalhes:", err);
      setSelectedNodeDetails(null);
    } finally {
      setDetailLoading(false);
    }
  };

  const handleDeleteConnection = async (connectionId: string) => {
    if (!window.confirm("Tem certeza que deseja excluir esta conexão?")) return;
    try {
      await apiClient.delete(`/conexoes/${connectionId}`);
      if (selectedNodeDetails) {
        const updatedConnections = selectedNodeDetails.connections.filter(conn => conn.connection_id !== connectionId);
        setSelectedNodeDetails({ ...selectedNodeDetails, connections: updatedConnections });
      }
    } catch (err) {
      alert("Erro ao excluir conexão.");
      console.error(err);
    }
  };

  const handleSelectChange = (option: SelectOption | null) => {
    setSelectedContact(option);
    const graph = graphRef.current;
    if (!graph) return;

    if (!option) {
      graph.zoomToFit(400);
    }
  };

  if (loading) return <div style={{ padding: 24 }}><h2>Visualização da Rede</h2><p>Carregando...</p></div>;
  if (error) return <div style={{ padding: 24 }}><h2>Visualização da Rede</h2><p style={{ color: 'red' }}>Erro: {error}</p></div>;

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
      <header style={{ padding: '16px 24px', borderBottom: '1px solid #dee2e6', background: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'space-between', flexShrink: 0 }}>
        <h1 style={{ margin: 0, fontSize: '24px' }}>Visualização da Rede</h1>
        <div style={{ display: 'flex', alignItems: 'center', gap: '16px', minWidth: '300px' }}>
          <label htmlFor="contact-filter" style={{ fontWeight: 'bold', whiteSpace: 'nowrap' }}>Focar em:</label>
          <Select
            id="contact-filter"
            options={selectOptions}
            isClearable
            placeholder="Pesquisar ou selecionar..."
            value={selectedContact}
            onChange={handleSelectChange}
            styles={{ container: (base) => ({ ...base, flex: 1 }) }}
          />
        </div>
      </header>

      <main style={{ flex: 1 }}>
        <ForceGraph2D
          ref={graphRef as React.MutableRefObject<ForceGraphMethods>}
          graphData={graphData}
          nodeLabel="label"
          linkDirectionalArrowLength={3.5}
          onNodeClick={handleNodeClick}
          nodeCanvasObject={(node, ctx, globalScale) => {
            const label = (node as GraphNode).label;
            const fontSize = 12 / globalScale;
            if (fontSize < 4) return;
            ctx.font = `${fontSize}px Sans-Serif`;
            const selectedId = selectedContact?.value;
            const isDimmed = selectedId && node.id !== selectedId &&
              !graphData.links.some(link =>
                ((link.source as GraphNode).id === node.id && (link.target as GraphNode).id === selectedId) ||
                ((link.target as GraphNode).id === node.id && (link.source as GraphNode).id === selectedId)
              );
            ctx.beginPath();
            ctx.arc(node.x!, node.y!, 5, 0, 2 * Math.PI, false);
            ctx.fillStyle = isDimmed ? 'rgba(108, 117, 125, 0.2)' : '#4361ee';
            ctx.fill();
            ctx.textAlign = 'center';
            ctx.textBaseline = 'middle';
            ctx.fillStyle = isDimmed ? 'rgba(50, 50, 50, 0.5)' : '#000';
            ctx.fillText(label, node.x!, node.y! + 12);
          }}
          linkColor={link => {
            const selectedId = selectedContact?.value;
            const isDimmed = selectedId &&
              !((link.source as GraphNode).id === selectedId || (link.target as GraphNode).id === selectedId);
            return isDimmed ? 'rgba(180, 180, 180, 0.1)' : 'rgba(180, 180, 180, 0.5)';
          }}
        />
      </main>

      <Modal
        isOpen={isDetailModalOpen}
        onRequestClose={() => setIsDetailModalOpen(false)}
        contentLabel="Detalhes do Contato"
        style={{
          content: {
            top: '50%',
            left: '50%',
            right: 'auto',
            bottom: 'auto',
            transform: 'translate(-50%, -50%)',
            width: '520px',
            maxHeight: '80vh',
            overflow: 'auto',
            borderRadius: '12px',
            padding: '24px 32px',
            backgroundColor: '#f9f9f9',
            boxShadow: '0 4px 16px rgba(0, 0, 0, 0.1)',
          },
        }}
      >
        {detailLoading ? (
          <p style={{ textAlign: 'center', fontStyle: 'italic' }}>Carregando detalhes...</p>
        ) : selectedNodeDetails ? (
          <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
            <div>
              <h2 style={{ marginBottom: 4 }}>{selectedNodeDetails.name}</h2>
              <p style={{ margin: '4px 0' }}>
                <strong>Email:</strong>{' '}
                <span style={{ color: '#495057' }}>
                  {selectedNodeDetails.email || 'Não informado'}
                </span>
              </p>
              <p style={{ margin: '4px 0' }}>
                <strong>Telefone:</strong>{' '}
                <span style={{ color: '#495057' }}>
                  {selectedNodeDetails.phone || 'Não informado'}
                </span>
              </p>
              {selectedNodeDetails.notes && (
                <p style={{ marginTop: '8px', fontStyle: 'italic', color: '#666' }}>
                  {selectedNodeDetails.notes}
                </p>
              )}
            </div>

            <hr style={{ borderColor: '#ddd' }} />

            <div>
              <h3 style={{ color: '#1d3557', fontSize: '18px', marginBottom: '8px' }}>
                Conexões Diretas ({selectedNodeDetails.connections.length})
              </h3>

              {selectedNodeDetails.connections.length > 0 ? (
                <ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: '12px' }}>
                  {selectedNodeDetails.connections.map(conn => (
                    <li key={conn.connection_id} style={{ padding: '12px', border: '1px solid #e0e0e0', borderRadius: '8px', background: '#fff', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                      <div>
                        <div style={{ fontWeight: 500 }}>{conn.connected_contact_name}</div>
                        <div style={{ fontSize: '12px', marginTop: '4px', color: '#6c757d', backgroundColor: '#dee2e6', padding: '2px 8px', borderRadius: '12px', display: 'inline-block' }}>
                          {conn.connection_type}
                        </div>
                      </div>
                      <button
                        onClick={() => handleDeleteConnection(conn.connection_id)}
                        style={{
                          background: 'none',
                          border: 'none',
                          color: '#e63946',
                          cursor: 'pointer',
                          fontSize: '13px',
                        }}
                      >
                        ✖ Excluir
                      </button>
                    </li>
                  ))}
                </ul>
              ) : (
                <p style={{ fontStyle: 'italic', color: '#888' }}>Nenhuma conexão direta.</p>
              )}
            </div>

            <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '12px' }}>
              <button
                onClick={() => setIsDetailModalOpen(false)}
                style={{
                  padding: '8px 16px',
                  backgroundColor: '#4361ee',
                  color: '#fff',
                  border: 'none',
                  borderRadius: '6px',
                  cursor: 'pointer',
                }}
              >
                Fechar
              </button>
            </div>
          </div>
        ) : (
          <p style={{ color: '#c00', textAlign: 'center' }}>
            Não foi possível carregar os detalhes. Tente novamente.
          </p>
        )}
      </Modal>
    </div>
  );
};

export default GraphPage;
