
import React, { useEffect, useRef } from 'react';
import * as d3 from 'd3';
import { BrainstormSession, BrainstormIdea, Note } from '../../types';

interface WaveCanvasProps {
  session: BrainstormSession;
  ideas: BrainstormIdea[];
  onNodeSelect: (id: string) => void;
  onPositionUpdate: (id: string, pos: { x: number; y: number }) => void;
  selectedNodeId: string | null;
  relatedNotes: Note[];
}

export const WaveCanvas: React.FC<WaveCanvasProps> = ({ 
  session, 
  ideas, 
  onNodeSelect, 
  onPositionUpdate,
  selectedNodeId,
  relatedNotes 
}) => {
  const svgRef = useRef<SVGSVGElement>(null);
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!svgRef.current || !containerRef.current) return;

    const width = containerRef.current.clientWidth;
    const height = containerRef.current.clientHeight;
    const centerX = width / 2;
    const centerY = height / 2;

    const svg = d3.select(svgRef.current);
    svg.selectAll("*").remove();

    const g = svg.append("g");

    // Zoom behavior
    const zoom = d3.zoom<SVGSVGElement, unknown>()
      .scaleExtent([0.1, 5])
      .on("zoom", (event) => {
        g.attr("transform", event.transform);
      });

    svg.call(zoom);

    // Initial transform to center
    svg.call(zoom.transform, d3.zoomIdentity.translate(centerX, centerY).scale(0.8));

    // Data structures for d3
    interface D3Node extends d3.SimulationNodeDatum {
      id: string;
      type: 'root' | 'idea' | 'note';
      wave?: number;
      title: string;
      color: string;
      radius: number;
      status?: string;
    }

    interface D3Link extends d3.SimulationLinkDatum<D3Node> {
      source: string | D3Node;
      target: string | D3Node;
      type: 'wave' | 'context' | 'parent';
    }

    const nodes: D3Node[] = [];
    const links: D3Link[] = [];

    // Root node
    const rootNode: D3Node = {
      id: 'root',
      type: 'root',
      title: session.seedIdea,
      color: '#141414',
      radius: 40,
      fx: 0,
      fy: 0
    };
    nodes.push(rootNode);

    // Idea nodes
    const colors = {
      1: '#fb923c', // orange
      2: '#60a5fa', // blue
      3: '#a78bfa'  // violet
    };

    ideas.forEach(idea => {
      nodes.push({
        id: idea.id,
        type: 'idea',
        wave: idea.waveNumber,
        title: idea.title,
        color: colors[idea.waveNumber as 1|2|3] || '#94a3b8',
        radius: 28,
        status: idea.status,
        x: idea.position?.x,
        y: idea.position?.y
      });

      if (idea.parentIdeaId) {
        links.push({
          source: idea.parentIdeaId,
          target: idea.id,
          type: 'parent'
        });
      } else {
        links.push({
          source: 'root',
          target: idea.id,
          type: 'wave'
        });
      }
    });

    // Radial layout forces
    const simulation = d3.forceSimulation<D3Node>(nodes)
      .force("link", d3.forceLink<D3Node, D3Link>(links).id(d => d.id).distance(d => {
          if (d.type === 'wave') {
              const targetNode = nodes.find(n => n.id === (typeof d.target === 'string' ? d.target : (d.target as any).id));
              return (targetNode?.wave || 1) * 200;
          }
          if (d.type === 'parent') return 180;
          return 100;
      }))
      .force("charge", d3.forceManyBody().strength(-800))
      .force("radial", d3.forceRadial<D3Node>(d => {
          if (d.type === 'root') return 0;
          if (d.id.includes('-')) return (d.wave || 1) * 200 + 100; // Deepened ideas push out
          return (d.wave || 1) * 200;
      }, 0, 0).strength(0.8))
      .force("collision", d3.forceCollide<D3Node>().radius(d => d.radius + 30));

    // Drawing rings
    const ringRadii = [200, 400, 600];
    g.selectAll(".ring")
      .data(ringRadii)
      .enter()
      .append("circle")
      .attr("class", "ring")
      .attr("r", d => d)
      .attr("fill", "none")
      .attr("stroke", "#e2e8f0")
      .attr("stroke-width", 1)
      .attr("stroke-dasharray", "4,4")
      .style("opacity", 0.5);

    // Links
    const link = g.append("g")
      .selectAll("line")
      .data(links)
      .enter()
      .append("line")
      .attr("stroke", d => d.type === 'wave' ? "#cbd5e1" : d.type === 'parent' ? "#fde047" : "#94a3b8")
      .attr("stroke-width", d => d.type === 'wave' ? 1.5 : 2)
      .attr("stroke-dasharray", d => d.type === 'parent' ? "none" : "4,4");

    // Nodes
    const node = g.append("g")
      .selectAll(".node")
      .data(nodes)
      .enter()
      .append("g")
      .attr("class", "node")
      .style("opacity", d => d.status === 'dismissed' ? 0.4 : 1)
      .on("click", (event, d) => {
        if (d.type === 'idea') onNodeSelect(d.id);
      })
      .call(d3.drag<SVGGElement, D3Node>()
        .on("start", dragstarted)
        .on("drag", dragged)
        .on("end", dragended) as any);

    node.append("circle")
      .attr("r", d => d.radius)
      .attr("fill", d => d.status === 'converted' ? '#ecfdf5' : (d.type === 'root' ? '#141414' : '#fff'))
      .attr("stroke", d => d.status === 'converted' ? '#10b981' : d.color)
      .attr("stroke-width", d => d.id === selectedNodeId ? 4 : 2)
      .attr("class", "cursor-pointer transition-all hover:scale-110")
      .style("filter", d => d.id === selectedNodeId ? `drop-shadow(0 0 12px ${d.color}cc)` : "none");

    // State indicators (converted)
    node.filter(d => d.status === 'converted')
      .append("path")
      .attr("d", d3.symbol().type(d3.symbolCircle).size(150))
      .attr("fill", "#10b981");

    // Icons/Text in nodes
    node.append("text")
      .attr("dy", d => d.type === 'root' ? ".35em" : d.radius + 20)
      .attr("text-anchor", "middle")
      .attr("fill", d => d.type === 'root' ? "#fff" : (d.status === 'dismissed' ? "#94a3b8" : "#141414"))
      .attr("class", d => d.type === 'root' ? "text-[10px] font-bold pointer-events-none tracking-widest" : "text-[11px] font-bold uppercase tracking-tight pointer-events-none")
      .text(d => d.type === 'root' ? "SEED" : d.title.length > 18 ? d.title.substring(0, 18) + "..." : d.title);

    if (rootNode) {
       g.append("text")
         .attr("text-anchor", "middle")
         .attr("dy", 80)
         .attr("class", "text-2xl font-serif italic fill-ink dark:fill-dark-ink pointer-events-none shadow-sm")
         .text(session.seedIdea);
    }

    simulation.on("tick", () => {
      link
        .attr("x1", d => (d.source as any).x)
        .attr("y1", d => (d.source as any).y)
        .attr("x2", d => (d.target as any).x)
        .attr("y2", d => (d.target as any).y);

      node
        .attr("transform", d => `translate(${d.x},${d.y})`);
    });

    function dragstarted(event: any, d: D3Node) {
      if (!event.active) simulation.alphaTarget(0.3).restart();
      d.fx = d.x;
      d.fy = d.y;
    }

    function dragged(event: any, d: D3Node) {
      d.fx = event.x;
      d.fy = event.y;
    }

    function dragended(event: any, d: D3Node) {
      if (!event.active) simulation.alphaTarget(0);
      d.fx = null;
      d.fy = null;
      if (d.type === 'idea') {
        onPositionUpdate(d.id, { x: event.x, y: event.y });
      }
    }

    return () => {
      simulation.stop();
    };
  }, [session, ideas, selectedNodeId, onNodeSelect]);

  return (
    <div ref={containerRef} className="w-full h-full relative cursor-grab active:cursor-grabbing">
      <svg ref={svgRef} className="w-full h-full" />
      <div className="absolute top-6 left-6 pointer-events-none">
         <p className="text-[10px] font-bold tracking-[0.3em] uppercase text-concrete opacity-40">Spatial Exploration Mode</p>
      </div>
    </div>
  );
};
