import { createMemo, createSignal, onCleanup, onMount, For, Show } from 'solid-js';

const PHASES = [
  'Opportunities start scattered',
  'Profiles and opportunities connect',
  'Relevant matches are prioritized',
  'Everything organizes into one system',
  'Nxtgauge: one clear opportunity workspace',
] as const;

type NodeDef = {
  id: string;
  label: string;
  kind: 'profile' | 'opportunity' | 'signal' | 'status';
  p2: [number, number];
  p4: [number, number];
};

const NODES: NodeDef[] = [
  { id: 'developer', label: 'Developer', kind: 'profile', p2: [12, 18], p4: [18, 28] },
  { id: 'tutor', label: 'Tutor', kind: 'profile', p2: [30, 20], p4: [18, 40] },
  { id: 'photographer', label: 'Photographer', kind: 'profile', p2: [19, 44], p4: [18, 52] },
  { id: 'company', label: 'Company', kind: 'profile', p2: [24, 72], p4: [18, 64] },
  { id: 'verified', label: 'Verified', kind: 'status', p2: [44, 18], p4: [40, 28] },
  { id: 'skills', label: 'Skills', kind: 'signal', p2: [38, 62], p4: [40, 40] },
  { id: 'portfolio', label: 'Portfolio', kind: 'signal', p2: [58, 12], p4: [40, 52] },
  { id: 'match', label: 'Match', kind: 'signal', p2: [56, 70], p4: [56, 40] },
  { id: 'lead', label: 'Lead', kind: 'signal', p2: [72, 24], p4: [56, 52] },
  { id: 'job', label: 'Job', kind: 'opportunity', p2: [84, 30], p4: [72, 30] },
  { id: 'project', label: 'Project', kind: 'opportunity', p2: [78, 58], p4: [72, 44] },
  { id: 'opening', label: 'Opening', kind: 'opportunity', p2: [90, 74], p4: [72, 58] },
  { id: 'response', label: 'Response', kind: 'status', p2: [92, 48], p4: [88, 36] },
  { id: 'update', label: 'Update', kind: 'status', p2: [74, 10], p4: [88, 52] },
];

const EDGES: Array<[string, string]> = [
  ['developer', 'skills'],
  ['tutor', 'skills'],
  ['photographer', 'skills'],
  ['company', 'verified'],
  ['developer', 'verified'],
  ['portfolio', 'verified'],
  ['verified', 'match'],
  ['skills', 'match'],
  ['lead', 'match'],
  ['match', 'job'],
  ['match', 'project'],
  ['match', 'opening'],
  ['portfolio', 'project'],
  ['job', 'response'],
  ['project', 'response'],
  ['opening', 'response'],
  ['response', 'update'],
];



const WORKSPACE_CARDS = [
  { label: 'Verified Profiles', value: 'Trust layer ready' },
  { label: 'Matched Opportunities', value: 'Priority queue' },
  { label: 'Responses', value: 'Tracked in one flow' },
  { label: 'Updates', value: 'Live status signals' },
];

type Props = {
  reduceMotion: boolean;
};

export default function OpportunityGraph(props: Props) {
  const [timelineMs, setTimelineMs] = createSignal(0);
  const [paused, setPaused] = createSignal(false);
  const LOOP_MS = 42000;
  const EDGE_REVEAL_STEP_MS = 1500;

  onMount(() => {
    if (props.reduceMotion) {
      setTimelineMs(LOOP_MS - 1000);
      return;
    }
    const ticker = window.setInterval(() => {
      if (paused()) return;
      setTimelineMs((prev) => Math.min(prev + 100, LOOP_MS));
    }, 100);
    onCleanup(() => window.clearInterval(ticker));
  });

  const edgeStartMs = 16500;
  const nodeEndMs = 14000;
  const workspaceStartMs = 37200;

  const edgeRevealCount = createMemo(() => {
    if (timelineMs() < edgeStartMs) return 0;
    return Math.min(EDGES.length, Math.floor((timelineMs() - edgeStartMs) / EDGE_REVEAL_STEP_MS) + 1);
  });
  const nodeRevealCount = createMemo(() => {
    const nodeProgress = Math.max(0, Math.min(1, timelineMs() / nodeEndMs));
    return Math.floor(nodeProgress * NODES.length);
  });
  const workspaceVisible = createMemo(() => timelineMs() >= workspaceStartMs);

  const nodePos = createMemo(() => {
    const map = new Map<string, [number, number]>();
    for (const node of NODES) map.set(node.id, node.p2);
    return map;
  });

  const copy = createMemo(() => {
    const t = timelineMs();
    if (t < 12000) return PHASES[0];
    if (t < 23500) return PHASES[1];
    if (t < 32500) return PHASES[2];
    if (t < workspaceStartMs) return PHASES[3];
    return PHASES[4];
  });

  const lineCoords = (pair: [string, string]) => {
    const [from, to] = pair;
    const a = nodePos().get(from);
    const b = nodePos().get(to);
    if (!a || !b) return null;
    const dx = b[0] - a[0];
    const dy = b[1] - a[1];
    const dist = Math.sqrt(dx * dx + dy * dy);
    if (dist < 0.001) return null;
    const trim = 1.6;
    const ux = dx / dist;
    const uy = dy / dist;
    return {
      x1: a[0] + ux * trim,
      y1: a[1] + uy * trim,
      x2: b[0] - ux * trim,
      y2: b[1] - uy * trim,
      len: Math.sqrt((b[0] - a[0]) * (b[0] - a[0]) + (b[1] - a[1]) * (b[1] - a[1])),
    };
  };

  return (
    <div
      class="op-graph-wrap"
      onMouseEnter={() => setPaused(true)}
      onMouseLeave={() => setPaused(false)}
      onFocusIn={() => setPaused(true)}
      onFocusOut={() => setPaused(false)}
      aria-label="Nxtgauge opportunity graph preview"
      role="region"
    >
      <div class={`op-graph ${workspaceVisible() ? 'op-graph-phase4' : ''}`}>
        <div class="op-graph-canvas">
          <svg class="op-graph-svg" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true">
            <For each={EDGES}>
              {(edge, getIndex) => {
                const c = lineCoords(edge);
                const visible = () => getIndex() < edgeRevealCount();
                const drawing = () => visible() && getIndex() === edgeRevealCount() - 1;
                return (
                  <Show when={c}>
                    <line
                      class={`op-graph-line ${visible() ? 'op-graph-line-visible' : 'op-graph-line-hidden'} ${drawing() ? 'op-graph-line-drawing' : ''}`}
                      style={{ '--op-line-len': `${Math.sqrt((c!.x2 - c!.x1) * (c!.x2 - c!.x1) + (c!.y2 - c!.y1) * (c!.y2 - c!.y1))}` }}
                      x1={c!.x1}
                      y1={c!.y1}
                      x2={c!.x2}
                      y2={c!.y2}
                    />
                  </Show>
                );
              }}
            </For>

          </svg>

          {!workspaceVisible() && NODES.map((node, index) => {
            if (index >= nodeRevealCount()) return null;
            const xy = nodePos().get(node.id) || [0, 0];
            return (
              <span
                class={`op-graph-node op-graph-node-chip op-graph-node-${node.kind} op-graph-node-on`}
                style={{ left: `${xy[0]}%`, top: `${xy[1]}%` }}
              >
                {node.label}
              </span>
            );
          })}

          <div class="op-graph-workspace">
            <div class="op-graph-workspace-tick">
              <span class="op-graph-workspace-tick-icon">✓</span>
              <span class="op-graph-workspace-tick-text">Everything from Nxtgauge</span>
            </div>
            <p class="op-graph-workspace-title">Opportunity Workspace</p>
            <For each={WORKSPACE_CARDS}>{(card) => (
              <span class="op-graph-workspace-row">
                <strong>{card.label}</strong>
                <small>{card.value}</small>
              </span>
            )}</For>
          </div>
        </div>

        <div class="op-graph-copy">
          <p class="op-graph-copy-line">{copy()}</p>
          {workspaceVisible() ? <p class="op-graph-copy-sub">From scattered signals to one clear decision system.</p> : null}
        </div>
      </div>
    </div>
  );
}
