import { useCallback, useMemo } from 'react';
import { Handle, Position } from '@xyflow/react';
import morphData from 'virtual:morph-data';
import FlowGraph from '../components/FlowGraph.jsx';
import DetailPanel from '../components/DetailPanel.jsx';
import { useDetailPanel } from '../hooks/useDetailPanel.js';

// Phase color palette by phase id
const PHASE_COLORS = {
  proposal:  { bg: '#166534', border: '#22c55e', text: '#bbf7d0' },
  uiux:      { bg: '#854d0e', border: '#f59e0b', text: '#fef3c7' },
  plan:      { bg: '#7c2d12', border: '#fb923c', text: '#fed7aa' },
  implement: { bg: '#0e7490', border: '#22d3ee', text: '#cffafe' },
  review:    { bg: '#6d28d9', border: '#a78bfa', text: '#ede9fe' },
};

const GATED_PHASES = new Set(['uiux', 'plan', 'review']);

// Gate node: small gold square with "G" label
function GateNode({ data }) {
  return (
    <div
      title={data.label}
      className="flex items-center justify-center rounded-sm select-none cursor-default"
      style={{
        width: 32,
        height: 32,
        background: '#78350f',
        border: '2px solid #f59e0b',
        boxShadow: '0 0 8px #f59e0b44',
        color: '#fef3c7',
        fontWeight: 700,
        fontSize: 12,
      }}
    >
      <Handle type="target" position={Position.Left} style={{ background: '#f59e0b', width: 7, height: 7 }} />
      G
      <Handle type="source" position={Position.Right} style={{ background: '#f59e0b', width: 7, height: 7 }} />
    </div>
  );
}

// Phase node: colored block with name and optional/index badge
function PhaseNode({ data }) {
  const c = PHASE_COLORS[data.phaseId] || PHASE_COLORS.sync;
  const isOptional = data.optional;

  return (
    <div
      className="rounded-lg px-4 py-3 min-w-[140px] select-none cursor-pointer"
      style={{
        background: c.bg,
        border: `2px ${isOptional ? 'dashed' : 'solid'} ${c.border}`,
        boxShadow: `0 0 10px ${c.border}33`,
      }}
    >
      <Handle type="target" position={Position.Left} style={{ background: c.border, width: 8, height: 8 }} />

      <div className="text-white text-sm font-bold leading-tight">{data.label}</div>
      <div className="mt-1 text-[10px] font-medium" style={{ color: c.text }}>
        {isOptional ? 'optional' : `index: ${data.index}`}
      </div>

      <Handle type="source" position={Position.Right} style={{ background: c.border, width: 8, height: 8 }} />
    </div>
  );
}

const nodeTypes = { phaseNode: PhaseNode, gateNode: GateNode };

// Build nodes + edges with manual horizontal layout
function buildPipelineGraph(phases) {
  const nodes = [];
  const edges = [];

  // Layout constants
  const PHASE_W = 150;
  const PHASE_H = 68;
  const GATE_W = 32;
  const GATE_H = 32;
  const GAP = 60; // gap between a phase and the next gate / phase
  const Y_CENTER = 0;

  // Pre-compute x positions for each phase and its preceding gate (if gated)
  // Walk phases left to right, tracking current x cursor
  let cursorX = 0;
  const phaseLayout = []; // { phase, x, gateX? }

  for (const phase of phases) {
    if (GATED_PHASES.has(phase.id)) {
      // Insert gate before this phase
      const gateX = cursorX;
      cursorX += GATE_W + GAP;
      phaseLayout.push({ phase, x: cursorX, gateX });
    } else {
      phaseLayout.push({ phase, x: cursorX, gateX: null });
    }
    cursorX += PHASE_W + GAP;
  }

  // Build nodes
  for (const { phase, x, gateX } of phaseLayout) {
    const c = PHASE_COLORS[phase.id] || PHASE_COLORS.sync;

    // Gate node (if any)
    if (gateX !== null) {
      nodes.push({
        id: `gate-${phase.id}`,
        type: 'gateNode',
        data: { label: `Gate: ${phase.displayName}` },
        position: { x: gateX, y: Y_CENTER + (PHASE_H - GATE_H) / 2 },
      });
    }

    // Phase node
    nodes.push({
      id: phase.id,
      type: 'phaseNode',
      data: {
        label: phase.displayName,
        phaseId: phase.id,
        optional: phase.optional,
        index: phase.index,
        color: c.border,
        phaseRef: phase,
      },
      position: { x, y: Y_CENTER },
    });
  }

  // Build edges: chain gates and phases in sequence
  // sequence: ph0 → gate-ph1 → ph1 → gate-ph2 → ph2 → ...
  for (let i = 0; i < phaseLayout.length; i++) {
    const curr = phaseLayout[i];
    const next = phaseLayout[i + 1];

    if (!next) continue;

    const sourceId = curr.phase.id;

    if (next.gateX !== null) {
      // phase → gate → next-phase (two edges)
      edges.push({
        id: `edge-${sourceId}-gate-${next.phase.id}`,
        source: sourceId,
        target: `gate-${next.phase.id}`,
        type: 'smoothstep',
        style: { stroke: '#475569', strokeWidth: 1.8 },
      });
      edges.push({
        id: `edge-gate-${next.phase.id}-${next.phase.id}`,
        source: `gate-${next.phase.id}`,
        target: next.phase.id,
        type: 'smoothstep',
        style: { stroke: '#475569', strokeWidth: 1.8 },
      });
    } else {
      // phase → phase (no gate)
      edges.push({
        id: `edge-${sourceId}-${next.phase.id}`,
        source: sourceId,
        target: next.phase.id,
        type: 'smoothstep',
        style: { stroke: '#475569', strokeWidth: 1.8 },
      });
    }
  }

  return { nodes, edges };
}

// Detail panel content for a phase
function PhaseDetail({ phase, agents }) {
  const c = PHASE_COLORS[phase.id] || PHASE_COLORS.sync;
  const isGated = GATED_PHASES.has(phase.id);

  // Agents active in this phase
  const activeAgents = agents.filter(
    (a) => a.activePhases?.includes(phase.id) || a.activePhases?.includes('*')
  );

  return (
    <div className="text-sm text-gray-200 space-y-5">
      {/* Phase badge + optional/gated indicators */}
      <div className="flex flex-wrap items-center gap-2">
        <span
          className="px-2 py-0.5 rounded text-xs font-bold"
          style={{ background: c.bg, color: c.text, border: `1px solid ${c.border}` }}
        >
          Phase {phase.index}
        </span>
        {phase.optional && (
          <span className="px-2 py-0.5 rounded text-xs bg-gray-800 border border-dashed border-gray-600 text-gray-400">
            optional
          </span>
        )}
        {isGated && (
          <span className="px-2 py-0.5 rounded text-xs bg-yellow-900/50 border border-yellow-600 text-yellow-300">
            approval gate
          </span>
        )}
        {phase.folder && (
          <span className="px-2 py-0.5 rounded text-xs font-mono bg-gray-800 border border-gray-700 text-gray-400">
            {phase.folder}
          </span>
        )}
      </div>

      {/* Goals */}
      {phase.goals?.length > 0 && (
        <div>
          <p className="text-gray-500 text-xs uppercase tracking-wide mb-2">Goals</p>
          <ul className="space-y-1.5">
            {phase.goals.map((g, i) => (
              <li key={i} className="flex gap-2 text-xs text-gray-300">
                <span className="text-gray-600 flex-shrink-0">•</span>
                {g}
              </li>
            ))}
          </ul>
        </div>
      )}

      {/* Required outputs */}
      {phase.requiredOutputs?.length > 0 && (
        <div>
          <p className="text-gray-500 text-xs uppercase tracking-wide mb-2">Required Outputs</p>
          <div className="flex flex-wrap gap-1">
            {phase.requiredOutputs.map((o) => (
              <span key={o} className="px-2 py-0.5 rounded text-xs bg-green-900/50 border border-green-700 text-green-300 font-mono">
                {o}
              </span>
            ))}
          </div>
        </div>
      )}

      {/* Optional outputs */}
      {phase.optionalOutputs?.length > 0 && (
        <div>
          <p className="text-gray-500 text-xs uppercase tracking-wide mb-2">Optional Outputs</p>
          <div className="flex flex-wrap gap-1">
            {phase.optionalOutputs.map((o) => (
              <span key={o} className="px-2 py-0.5 rounded text-xs bg-gray-800 border border-gray-700 text-gray-400 font-mono">
                {o}
              </span>
            ))}
          </div>
        </div>
      )}

      {/* Active agents */}
      {activeAgents.length > 0 && (
        <div>
          <p className="text-gray-500 text-xs uppercase tracking-wide mb-2">Active Agents ({activeAgents.length})</p>
          <div className="space-y-1">
            {activeAgents.map((a) => (
              <div key={a.id} className="flex items-center justify-between text-xs px-2 py-1 bg-gray-800 rounded">
                <span className="text-gray-200 font-medium truncate">{a.title}</span>
                <span className="text-gray-500 ml-2 flex-shrink-0">T{a.tier}</span>
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Required skills */}
      {phase.requiredSkills?.length > 0 && (
        <div>
          <p className="text-gray-500 text-xs uppercase tracking-wide mb-2">Required Skills</p>
          <div className="space-y-1">
            {phase.requiredSkills.map((s, i) => (
              <div key={i} className="flex items-start gap-2 text-xs">
                <span className="px-1.5 py-0.5 rounded bg-pink-900/50 border border-pink-700 text-pink-300 font-mono flex-shrink-0">
                  {s.trigger}
                </span>
                <span className="text-gray-300 font-mono">{s.skill}</span>
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Recommended MCPs */}
      {phase.recommendedMCPs?.length > 0 && (
        <div>
          <p className="text-gray-500 text-xs uppercase tracking-wide mb-2">Recommended MCPs</p>
          <div className="flex flex-wrap gap-1">
            {phase.recommendedMCPs.map((m) => (
              <span key={m} className="px-2 py-0.5 rounded text-xs bg-blue-900/50 border border-blue-700 text-blue-300 font-mono">
                {m}
              </span>
            ))}
          </div>
        </div>
      )}

      {/* Pause points */}
      {phase.pausePoints?.length > 0 && (
        <div>
          <p className="text-gray-500 text-xs uppercase tracking-wide mb-2">Pause Points</p>
          <div className="space-y-1">
            {phase.pausePoints.map((pp) => (
              <div key={pp.id} className="flex items-center gap-2 text-xs px-2 py-1.5 bg-yellow-900/20 border border-yellow-700/50 rounded">
                <span className="text-yellow-400 flex-shrink-0">&#x1F512;</span>
                <span className="text-yellow-200">{pp.label}</span>
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}

export default function PhasePipeline() {
  const { phases, agents } = morphData;
  const { panel, openPanel, closePanel } = useDetailPanel();

  const { nodes, edges } = useMemo(() => buildPipelineGraph(phases.list), [phases.list]);

  const handleNodeClick = useCallback(
    (_event, node) => {
      if (node.type === 'gateNode') {
        // Extract phase id from gate id ("gate-design" → "design")
        const phaseId = node.id.replace('gate-', '');
        const phase = phases.list.find((p) => p.id === phaseId);
        if (phase) {
          openPanel(`Gate: ${phase.displayName}`, (
            <div className="text-sm text-gray-300 space-y-3">
              <p className="text-yellow-300 text-xs">This gate requires explicit approval before the phase can begin.</p>
              <p className="text-gray-400 text-xs">Gate ID: <span className="font-mono text-gray-300">{phaseId}</span></p>
            </div>
          ));
        }
        return;
      }

      if (node.type === 'phaseNode') {
        const phase = node.data.phaseRef;
        if (phase) {
          openPanel(phase.displayName, (
            <PhaseDetail phase={phase} agents={agents.list} />
          ));
        }
      }
    },
    [openPanel, phases.list, agents.list]
  );

  return (
    <div className="flex flex-col h-full">
      {/* Header */}
      <div className="px-6 py-4 border-b border-gray-800 flex-shrink-0">
        <h1 className="text-white text-xl font-bold">Phase Pipeline</h1>
        <p className="text-gray-400 text-sm mt-0.5">
          Horizontal workflow of the 7 morph-spec phases. Gold gates mark required approval points. Dashed borders indicate optional phases.
        </p>
      </div>

      {/* Flow graph */}
      <div className="flex-1 relative">
        <FlowGraph
          nodes={nodes}
          edges={edges}
          nodeTypes={nodeTypes}
          onNodeClick={handleNodeClick}
          fitView
        />

        {/* Legend */}
        <div className="absolute top-3 left-3 bg-gray-900/90 border border-gray-700 rounded-lg p-3 text-xs space-y-2 z-10">
          <p className="text-gray-400 font-semibold uppercase tracking-wide text-[10px] mb-2">Legend</p>
          <div className="flex items-center gap-2">
            <span className="inline-block w-10 h-4 rounded-sm" style={{ background: '#166534', border: '2px solid #22c55e' }} />
            <span className="text-gray-300">Phase (solid = required)</span>
          </div>
          <div className="flex items-center gap-2">
            <span className="inline-block w-10 h-4 rounded-sm" style={{ background: '#854d0e', border: '2px dashed #f59e0b' }} />
            <span className="text-gray-300">Phase (dashed = optional)</span>
          </div>
          <div className="flex items-center gap-2">
            <span
              className="inline-flex items-center justify-center rounded-sm text-[10px] font-bold flex-shrink-0"
              style={{ width: 20, height: 20, background: '#78350f', border: '2px solid #f59e0b', color: '#fef3c7' }}
            >
              G
            </span>
            <span className="text-gray-300">Approval Gate</span>
          </div>
          <div className="flex items-center gap-2">
            <span className="inline-block w-6 border-t-2 border-gray-500" />
            <span className="text-gray-400">Sequence</span>
          </div>
        </div>

        {/* Phase count badge */}
        <div className="absolute top-3 right-3 bg-gray-900/90 border border-gray-700 rounded-lg px-3 py-1.5 text-xs text-gray-400 z-10">
          {phases.list.length} phases · {phases.list.filter((p) => GATED_PHASES.has(p.id)).length} gates
        </div>
      </div>

      <DetailPanel open={panel.open} title={panel.title} onClose={closePanel}>
        {panel.content}
      </DetailPanel>
    </div>
  );
}
