import { onMounted, onUnmounted, ref } from 'vue';

// Portage 1:1 de la timeline animée du mockup hero (Arboretum.dc.html).
export type SessionState = 'idle' | 'busy' | 'waiting';

export interface AnimLine {
  text: string;
  k: string;
}

export interface HeroAnim {
  sess: SessionState;
  lines: AnimLine[];
  att: number;
  toast: boolean;
  dlg: boolean;
  hl: number;
  ans: number;
  cur: boolean;
}

const TOTAL = 13000;
const TICK = 80;

interface ScriptEntry {
  at: number;
  text: string;
  k: string;
}

function script(): ScriptEntry[] {
  return [
    { at: 850, text: '$ claude --resume feat/auth', k: 'cmd' },
    { at: 1400, text: '> Reading src/auth/login.ts', k: 'tool' },
    { at: 1950, text: '● Edit  login.ts', k: 'edit' },
    { at: 2400, text: "  + import { verifyToken } from './jwt'", k: 'add' },
    { at: 2850, text: '  + const user = await verifyToken(req)', k: 'add' },
    { at: 3350, text: '● Bash  npm test -- auth', k: 'edit' },
    { at: 3850, text: '  ✓ 14 passed (1.24s)', k: 'ok' },
    { at: 4300, text: '● Permission required to edit login.ts', k: 'warn' },
    { at: 7950, text: '✓ approved · applying change', k: 'ok' },
    { at: 8500, text: '● Edit  login.ts', k: 'edit' },
    { at: 9050, text: '● Running…', k: 'run' },
  ];
}

export function deriveAnim(clock: number): HeroAnim {
  const sess: SessionState = clock < 700 ? 'idle' : clock < 4500 ? 'busy' : clock < 7700 ? 'waiting' : 'busy';
  const sc = script();
  const lines: AnimLine[] = [];
  for (const entry of sc) {
    if (clock >= entry.at) lines.push({ text: entry.text, k: entry.k });
  }
  const att = clock >= 4500 && clock < 7700 ? 1 : 0;
  const toast = clock >= 4650 && clock < 7700;
  const dlg = clock >= 4600 && clock < 7700;
  const hl = clock >= 6000 && clock < 7050 ? 0 : -1;
  const ans = clock >= 7050 && clock < 7700 ? 0 : -1;
  const cur = sess !== 'waiting';
  return { sess, lines, att, toast, dlg, hl, ans, cur };
}

export function useHeroTimeline(stageId = 'hero-stage') {
  const anim = ref<HeroAnim>(deriveAnim(0));
  let clock = 0;
  let visible = true;
  let everVisible = false;
  let timer: ReturnType<typeof setInterval> | undefined;
  let io: IntersectionObserver | undefined;

  onMounted(() => {
    let reduced = false;
    try {
      reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    } catch {
      /* ignore */
    }
    if (reduced) {
      anim.value = deriveAnim(5200);
      return;
    }
    const stage = document.getElementById(stageId);
    if (stage && 'IntersectionObserver' in window) {
      io = new IntersectionObserver(
        (entries) => {
          const e = entries[0];
          if (!e) return;
          if (e.isIntersecting) {
            visible = true;
            everVisible = true;
          } else if (everVisible) {
            visible = false;
          }
        },
        { threshold: 0, rootMargin: '200px 0px 200px 0px' },
      );
      io.observe(stage);
    }
    timer = setInterval(() => {
      if (!visible) return;
      clock += TICK;
      if (clock >= TOTAL) clock = 0;
      anim.value = deriveAnim(clock);
    }, TICK);
  });

  onUnmounted(() => {
    if (timer) clearInterval(timer);
    if (io) io.disconnect();
  });

  return { anim };
}
