import { useState, useMemo, useCallback } from 'react';
import { Handle, Position, MarkerType } 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';

// Event color palette
const EVENT_COLORS = {
  'session-start':  { color: '#34d399', bg: '#064e3b', label: 'Session Start' },
  'user-prompt':    { color: '#fbbf24', bg: '#78350f', label: 'User Prompt' },
  'pre-tool-use':   { color: '#60a5fa', bg: '#1e3a5f', label: 'Pre-Tool-Use' },
  'post-tool-use':  { color: '#f472b6', bg: '#500724', label: 'Post-Tool-Use' },
  'pre-compact':    { color: '#a78bfa', bg: '#2e1065', label: 'Pre-Compact' },
  'stop':           { color: '#ef4444', bg: '#450a0a', label: 'Stop' },
  'teammate-idle':  { color: '#94a3b8', bg: '#1e293b', label: 'Teammate Idle' },
  'worktree-create': { color: '#2dd4bf', bg: '#134e4a', label: 'Worktree Create' },
  'worktree-remove': { color: '#fb923c', bg: '#431407', label: 'Worktree Remove' },
};

// Node dimensions
const NODE_W = 200;
const NODE_H = 120; // base; expands with hooks

// ─── Custom: EventGroupNode ───────────────────────────────────────────────────
function EventGroupNode({ data }) {
  const { eventKey, hooks, canBlock } = data;
  const palette = EVENT_COLORS[eventKey] || { color: '#94a3b8', bg: '#1e293b', label: eventKey };

  return (
    <div
      className="rounded-xl px-4 py-3 min-w-[190px] cursor-pointer select-none"
      style={{
        background: palette.bg,
        border: `2px solid ${palette.color}`,
        boxShadow: `0 0 12px ${palette.color}33`,
      }}
    >
      <Handle type="target" position={Position.Left}
        style={{ background: palette.color, width: 8, height: 8, border: 'none' }} />

      {/* Header */}
      <div className="flex items-center justify-between mb-2">
        <span className="text-white text-xs font-bold tracking-wide uppercase">{palette.label}</span>
        {canBlock && (
          <span className="text-[9px] font-bold px-1.5 py-0.5 rounded"
            style={{ background: '#1e40af', color: '#93c5fd', border: '1px solid #3b82f6' }}>
            can BLOCK
          </span>
        )}
      </div>

      {/* Hook list */}
      <ul className="space-y-0.5">
        {hooks.map((h) => (
          <li key={h.name}
            className="text-[10px] font-mono truncate"
            style={{ color: palette.color }}
            title={h.name}>
            · {h.name}
          </li>
        ))}
      </ul>

      <Handle type="source" position={Position.Right}
        style={{ background: palette.color, width: 8, height: 8, border: 'none' }} />
    </div>
  );
}

// ─── Custom: ToolNode ─────────────────────────────────────────────────────────
function ToolNode({ data }) {
  return (
    <div
      className="rounded-xl px-5 py-3 select-none text-center min-w-[140px]"
      style={{
        background: '#374151',
        border: '2px solid #6b7280',
        boxShadow: '0 0 10px #6b728033',
      }}
    >
      <Handle type="target" position={Position.Left}
        style={{ background: '#9ca3af', width: 8, height: 8, border: 'none' }} />
      <div className="text-gray-100 text-sm font-bold">TOOL</div>
      <div className="text-gray-400 text-[10px] mt-0.5">executes</div>
      <Handle type="source" position={Position.Right}
        style={{ background: '#9ca3af', width: 8, height: 8, border: 'none' }} />
    </div>
  );
}

const nodeTypes = {
  eventGroupNode: EventGroupNode,
  toolNode: ToolNode,
};

// ─── Layout: manual horizontal positions ─────────────────────────────────────
// Flow: session-start → user-prompt → pre-tool-use → TOOL → post-tool-use → stop
//                                                                           → pre-compact
// teammate-idle is disconnected at bottom
// Loop-back: post-tool-use → user-prompt (dashed)

const COL_GAP = 260;
const ROW_Y = 100;
const BRANCH_Y_STOP = 80;
const BRANCH_Y_COMPACT = 240;

function buildNodesAndEdges(hooksByEvent) {
  // Main flow columns (x positions)
  const cols = {
    'session-start': 0,
    'user-prompt':   COL_GAP,
    'pre-tool-use':  COL_GAP * 2,
    '__tool__':      COL_GAP * 3,
    'post-tool-use': COL_GAP * 4,
    'stop':          COL_GAP * 5,
    'pre-compact':   COL_GAP * 5,
    'teammate-idle': COL_GAP * 2,
    // Worktree lifecycle — outside the tool-call flow, drawn as a pair below it.
    'worktree-create': COL_GAP * 0,
    'worktree-remove': COL_GAP * 1,
  };

  const nodes = [];
  const edges = [];

  // Helper to build an EventGroupNode
  function addEventNode(eventKey, x, y, extra = {}) {
    const hooks = hooksByEvent[eventKey] || [];
    nodes.push({
      id: eventKey,
      type: 'eventGroupNode',
      position: { x, y },
      data: {
        eventKey,
        hooks,
        canBlock: eventKey === 'pre-tool-use',
        color: (EVENT_COLORS[eventKey] || {}).color || '#94a3b8',
        ...extra,
      },
    });
  }

  // Main flow nodes
  addEventNode('session-start', cols['session-start'], ROW_Y);
  addEventNode('user-prompt',   cols['user-prompt'],   ROW_Y);
  addEventNode('pre-tool-use',  cols['pre-tool-use'],  ROW_Y);

  // TOOL node
  nodes.push({
    id: '__tool__',
    type: 'toolNode',
    position: { x: cols['__tool__'], y: ROW_Y + 30 },
    data: { color: '#6b7280' },
  });

  addEventNode('post-tool-use', cols['post-tool-use'], ROW_Y);

  // Branches: stop (top branch) and pre-compact (bottom branch)
  addEventNode('stop',         cols['stop'],         BRANCH_Y_STOP);
  addEventNode('pre-compact',  cols['pre-compact'],  BRANCH_Y_COMPACT);

  // teammate-idle disconnected below main flow
  addEventNode('teammate-idle', cols['teammate-idle'] - COL_GAP * 0.5, ROW_Y + 280);

  // Worktree lifecycle (WorktreeCreate → WorktreeRemove) — its own row below
  // the main flow: these fire on `claude -w` / EnterWorktree / Agent isolation,
  // not on a tool call.
  addEventNode('worktree-create', cols['worktree-create'], ROW_Y + 280);
  addEventNode('worktree-remove', cols['worktree-remove'], ROW_Y + 280);

  // ─── Edges ────────────────────────────────────────────────────────────
  const solid = (id, source, target, color = '#475569') => ({
    id, source, target,
    type: 'smoothstep',
    style: { stroke: color, strokeWidth: 2 },
    markerEnd: { type: MarkerType.ArrowClosed, color },
  });

  edges.push(solid('e-ss-up', 'session-start', 'user-prompt', EVENT_COLORS['user-prompt'].color));
  edges.push(solid('e-up-ptu', 'user-prompt', 'pre-tool-use', EVENT_COLORS['pre-tool-use'].color));
  edges.push(solid('e-ptu-tool', 'pre-tool-use', '__tool__', '#6b7280'));
  edges.push(solid('e-tool-pou', '__tool__', 'post-tool-use', EVENT_COLORS['post-tool-use'].color));

  // Post-tool-use branches to stop and pre-compact
  edges.push(solid('e-pou-stop', 'post-tool-use', 'stop', EVENT_COLORS['stop'].color));
  edges.push(solid('e-pou-compact', 'post-tool-use', 'pre-compact', EVENT_COLORS['pre-compact'].color));
  edges.push(solid('e-wt-create-remove', 'worktree-create', 'worktree-remove', EVENT_COLORS['worktree-remove'].color));

  // Loop-back dashed: post-tool-use → user-prompt
  edges.push({
    id: 'e-loop',
    source: 'post-tool-use',
    target: 'user-prompt',
    type: 'smoothstep',
    style: { stroke: '#fbbf24', strokeWidth: 1.5, strokeDasharray: '6 4' },
    label: 'conversation loop',
    labelStyle: { fill: '#fbbf24', fontSize: 10, fontFamily: 'monospace' },
    labelBgStyle: { fill: '#1c1917', fillOpacity: 0.85 },
    markerEnd: { type: MarkerType.ArrowClosed, color: '#fbbf24' },
  });

  return { nodes, edges };
}

// ─── HookDetail: detail panel content ────────────────────────────────────────
function HookDetail({ hook }) {
  const [showSource, setShowSource] = useState(false);
  const palette = EVENT_COLORS[hook.event] || { color: '#94a3b8' };

  return (
    <div className="text-sm text-gray-200 space-y-3">
      {/* Meta */}
      <div>
        <p className="text-gray-400 text-xs">
          Event: <span className="font-mono" style={{ color: palette.color }}>{hook.event}</span>
        </p>
        <p className="text-gray-400 text-xs mt-0.5">
          File: <span className="text-gray-300 font-mono">{hook.filename}</span>
        </p>
      </div>

      {/* Description */}
      {hook.description && (
        <div>
          <p className="text-gray-500 text-[10px] uppercase tracking-wide mb-1">Description</p>
          <p className="text-gray-300 text-xs leading-relaxed">{hook.description}</p>
        </div>
      )}

      {/* Imports */}
      {hook.imports?.length > 0 && (
        <div>
          <p className="text-gray-500 text-[10px] uppercase tracking-wide mb-1.5">Imports</p>
          <div className="flex flex-wrap gap-1">
            {hook.imports.map((imp) => (
              <span key={imp}
                className="px-2 py-0.5 rounded text-[10px] font-mono bg-gray-800 border border-gray-700 text-gray-400"
                title={imp}>
                {imp.length > 28 ? '…' + imp.slice(-22) : imp}
              </span>
            ))}
          </div>
        </div>
      )}

      {/* Source toggle */}
      <div>
        <button
          onClick={() => setShowSource((v) => !v)}
          className="w-full text-left px-3 py-1.5 bg-gray-800 hover:bg-gray-700 border border-gray-700 rounded text-xs text-gray-300 transition-colors"
        >
          {showSource ? 'Hide Source' : 'Show Source'}
        </button>
        {showSource && (
          <pre className="mt-2 p-3 bg-gray-950 border border-gray-800 rounded text-[9px] text-gray-400 overflow-x-auto whitespace-pre font-mono leading-relaxed max-h-80 overflow-y-auto">
            {hook.source}
          </pre>
        )}
      </div>
    </div>
  );
}

// ─── EventGroupDetail: panel for clicking a group node ───────────────────────
function EventGroupDetail({ eventKey, hooks, openHook }) {
  const palette = EVENT_COLORS[eventKey] || { color: '#94a3b8', label: eventKey };
  const isBlockable = eventKey === 'pre-tool-use';

  return (
    <div className="space-y-3">
      {/* Event header */}
      <div className="flex items-center gap-2">
        <span
          className="inline-block w-2.5 h-2.5 rounded-full flex-shrink-0"
          style={{ background: palette.color }}
        />
        <span className="text-gray-300 text-sm font-semibold">{palette.label}</span>
        {isBlockable && (
          <span className="text-[9px] font-bold px-1.5 py-0.5 rounded"
            style={{ background: '#1e40af', color: '#93c5fd', border: '1px solid #3b82f6' }}>
            can BLOCK
          </span>
        )}
      </div>
      <p className="text-gray-500 text-xs">{hooks.length} hook{hooks.length !== 1 ? 's' : ''} registered</p>

      {/* Hook list */}
      <ul className="space-y-2">
        {hooks.map((hook) => (
          <li key={hook.name}>
            <button
              onClick={() => openHook(hook)}
              className="w-full text-left px-3 py-2 rounded-lg border transition-colors hover:opacity-90"
              style={{
                background: '#111827',
                borderColor: palette.color + '55',
              }}
            >
              <p className="font-mono text-xs" style={{ color: palette.color }}>{hook.name}</p>
              {hook.description && (
                <p className="text-gray-400 text-[10px] mt-0.5 line-clamp-2 leading-snug">
                  {hook.description}
                </p>
              )}
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
}

// ─── Main Page ────────────────────────────────────────────────────────────────
export default function HookInspector() {
  const { hooks } = morphData;
  const { panel, openPanel, closePanel } = useDetailPanel();

  // Group hooks by event
  const hooksByEvent = useMemo(() => {
    const map = {};
    for (const hook of hooks) {
      if (!map[hook.event]) map[hook.event] = [];
      map[hook.event].push(hook);
    }
    return map;
  }, [hooks]);

  // Build graph
  const { nodes, edges } = useMemo(() => buildNodesAndEdges(hooksByEvent), [hooksByEvent]);

  // Open panel: click on an event group → show its hooks list
  // From that list, user can click a hook → show hook detail
  const openHookDetail = useCallback((hook) => {
    const palette = EVENT_COLORS[hook.event] || { label: hook.event };
    openPanel(`${hook.name}`, <HookDetail hook={hook} />);
  }, [openPanel]);

  const handleNodeClick = useCallback((_event, node) => {
    if (node.type === 'toolNode') {
      openPanel('TOOL executes', (
        <div className="text-gray-300 text-sm space-y-2">
          <p>This represents the actual tool call Claude Code performs (e.g., <span className="font-mono text-blue-300">Bash</span>, <span className="font-mono text-blue-300">Read</span>, <span className="font-mono text-blue-300">Edit</span>).</p>
          <p className="text-gray-400 text-xs">Pre-Tool-Use hooks run before this and can block execution by returning a non-empty decision. Post-Tool-Use hooks run after and receive the tool result.</p>
        </div>
      ));
      return;
    }
    if (node.type === 'eventGroupNode') {
      const { eventKey, hooks: hooksInGroup } = node.data;
      const palette = EVENT_COLORS[eventKey] || { label: eventKey };
      openPanel(
        palette.label,
        <EventGroupDetail eventKey={eventKey} hooks={hooksInGroup} openHook={openHookDetail} />
      );
    }
  }, [openPanel, openHookDetail]);

  const totalHooks = hooks.length;
  const eventCount = Object.keys(hooksByEvent).length;

  return (
    <div className="flex flex-col h-full">
      {/* Header bar */}
      <div className="flex items-center justify-between px-5 py-3 bg-gray-900 border-b border-gray-800 flex-shrink-0">
        <div>
          <h1 className="text-white font-bold text-base leading-tight">Hook Inspector</h1>
          <p className="text-gray-400 text-xs mt-0.5">
            Lifecycle timeline — {totalHooks} hooks across {eventCount} event types. Click a node to inspect.
          </p>
        </div>
        <div className="flex items-center gap-3">
          {/* Legend */}
          <div className="flex flex-wrap gap-2">
            {Object.entries(EVENT_COLORS).map(([key, { color, label }]) => (
              <div key={key} className="flex items-center gap-1.5">
                <span className="inline-block w-2.5 h-2.5 rounded-full" style={{ background: color }} />
                <span className="text-gray-400 text-[10px] hidden lg:inline">{label}</span>
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* Flow graph */}
      <div className="flex-1 relative">
        <FlowGraph
          nodes={nodes}
          edges={edges}
          nodeTypes={nodeTypes}
          onNodeClick={handleNodeClick}
          fitView
        />

        {/* Floating legend / instructions */}
        <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 max-w-[200px]">
          <p className="text-gray-400 font-semibold uppercase tracking-wide text-[10px] mb-1">Flow Key</p>
          <div className="flex items-center gap-2">
            <span className="inline-block w-6 border-t-2 border-yellow-400 border-dashed" />
            <span className="text-gray-400 text-[10px]">conversation loop</span>
          </div>
          <div className="flex items-center gap-2">
            <span className="inline-block w-2 h-2 rounded" style={{ background: '#374151', border: '1.5px solid #6b7280' }} />
            <span className="text-gray-400 text-[10px]">tool execution</span>
          </div>
          <div className="flex items-center gap-2">
            <span className="px-1.5 py-0.5 rounded text-[8px] font-bold"
              style={{ background: '#1e40af', color: '#93c5fd', border: '1px solid #3b82f6' }}>
              can BLOCK
            </span>
            <span className="text-gray-400 text-[10px]">pre-tool only</span>
          </div>
          <div className="flex items-center gap-2">
            <span className="text-gray-500 text-[10px] italic">teammate-idle</span>
            <span className="text-gray-500 text-[10px]">= disconnected</span>
          </div>
        </div>

        {/* Hook 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">
          {totalHooks} hooks · {eventCount} events
        </div>
      </div>

      <DetailPanel open={panel.open} title={panel.title} onClose={closePanel}>
        {panel.content}
      </DetailPanel>
    </div>
  );
}
