'use client';

import { useEffect, useRef, useState } from 'react';
import { createGame, startGame, retryGame, stepGame } from './simulation';
import { renderGame } from './render';
import { KeyboardInput } from './input';
import { GameAudio } from './audio';
import type { GameState, Mode } from './types';

type View = { mode: Mode; elapsed: number; deaths: number; kills: number; checkpoint: number; hp: number; progress: number; zone: string };
type Runtime = { state: GameState; input: KeyboardInput; audio: GameAudio; sync: () => void };
const initialView: View = { mode: 'title', elapsed: 0, deaths: 0, kills: 0, checkpoint: 0, hp: 28, progress: 0, zone: 'HIGHWAY SECTOR 01' };
function clock(seconds: number) { return `${Math.floor(seconds / 60).toString().padStart(2, '0')}:${Math.floor(seconds % 60).toString().padStart(2, '0')}`; }

export default function GameClient() {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const screenRef = useRef<HTMLDivElement>(null);
  const runtime = useRef<Runtime | null>(null);
  const helpRef = useRef(false);
  const [view, setView] = useState<View>(initialView);
  const [muted, setMuted] = useState(false);
  const [help, setHelp] = useState(false);
  const [fullscreen, setFullscreen] = useState(false);
  const [screenMessage, setScreenMessage] = useState('');

  useEffect(() => {
    const canvas = canvasRef.current;
    const ctx = canvas?.getContext('2d', { alpha: false });
    if (!canvas || !ctx) return;
    const state = createGame();
    const audio = new GameAudio();
    let active = true;
    let id = 0;
    let accumulator = 0;
    let previous = 0;
    let nextUi = 0;
    let savedMute = false;
    try { savedMute = localStorage.getItem('highway-assault-muted') === 'true'; } catch { /* Preferences are optional. */ }
    audio.setMuted(savedMute);
    queueMicrotask(() => { if (active) setMuted(savedMute); });
    const sync = () => {
      if (!active) return;
      setView({ mode: state.mode, elapsed: state.elapsed, deaths: state.deaths, kills: state.kills, checkpoint: state.checkpoint, hp: state.player.hp, progress: Math.min(100, Math.round(state.player.x / state.level.bossX * 100)), zone: state.boss.active ? 'BOSS / IRON SENTINEL' : state.player.x > 7200 ? 'SENTINEL APPROACH' : state.player.x > 4750 ? 'INDUSTRIAL SECTOR 03' : state.player.x > 2200 ? 'BROKEN HIGHWAY 02' : 'HIGHWAY SECTOR 01' });
      audio.setActive(state.mode === 'playing');
    };
    const pause = () => {
      if (helpRef.current) { helpRef.current = false; setHelp(false); return; }
      if (state.mode !== 'playing' && state.mode !== 'paused') return;
      state.mode = state.mode === 'playing' ? 'paused' : 'playing';
      state.player.charge = 0;
      input.clear();
      helpRef.current = false;
      setHelp(false);
      sync();
    };
    const confirm = () => {
      if (helpRef.current) { helpRef.current = false; setHelp(false); return; }
      if (state.mode === 'title' || state.mode === 'won') startGame(state);
      else if (state.mode === 'dead') retryGame(state);
      else if (state.mode === 'paused') state.mode = 'playing';
      else return;
      input.clear();
      void audio.unlock();
      canvas.focus({ preventScroll: true });
      sync();
    };
    const blur = () => {
      if (state.mode === 'playing') { state.mode = 'paused'; state.player.charge = 0; sync(); }
    };
    const input = new KeyboardInput(pause, confirm, blur);
    runtime.current = { state, input, audio, sync };
    const draw = (time: number) => {
      const dt = previous ? Math.min((time - previous) / 1000, 0.1) : 0;
      previous = time;
      if (state.mode === 'playing') {
        accumulator += dt;
        while (accumulator >= 1 / 60) {
          const before: Mode = state.mode;
          stepGame(state, input.read(), 1 / 60);
          for (const event of state.events.splice(0)) audio.play(event);
          accumulator -= 1 / 60;
          if (state.mode !== before) { input.clear(); sync(); accumulator = 0; break; }
        }
      } else {
        accumulator = 0;
        input.read();
        if (state.mode === 'dead' || state.mode === 'won') stepGame(state, { left: false, right: false, jump: false, jumpPressed: false, jumpReleased: false, shoot: false, shootPressed: false, shootReleased: false, dashPressed: false }, dt);
      }
      renderGame(ctx, state, time / 1000);
      if (time >= nextUi) { sync(); nextUi = time + 150; }
      id = requestAnimationFrame(draw);
    };
    const onFullscreen = () => { setFullscreen(document.fullscreenElement === screenRef.current); };
    document.addEventListener('fullscreenchange', onFullscreen);
    id = requestAnimationFrame(draw);
    return () => { active = false; cancelAnimationFrame(id); input.dispose(); audio.dispose(); runtime.current = null; document.removeEventListener('fullscreenchange', onFullscreen); };
  }, []);

  function action(kind: 'start' | 'resume' | 'retry' | 'restart' | 'pause') {
    const r = runtime.current;
    if (!r) return;
    helpRef.current = false;
    setHelp(false);
    r.input.clear();
    if (kind === 'start' || kind === 'restart') startGame(r.state);
    if (kind === 'retry') retryGame(r.state);
    if (kind === 'resume') r.state.mode = 'playing';
    if (kind === 'pause') { r.state.mode = 'paused'; r.state.player.charge = 0; }
    void r.audio.unlock();
    for (const event of r.state.events.splice(0)) r.audio.play(event);
    r.sync();
    canvasRef.current?.focus({ preventScroll: true });
  }
  function toggleMute() {
    const value = !muted;
    setMuted(value);
    runtime.current?.audio.setMuted(value);
    void runtime.current?.audio.unlock();
    try { localStorage.setItem('highway-assault-muted', String(value)); } catch { /* Optional device preference. */ }
    canvasRef.current?.focus({ preventScroll: true });
  }
  function showHelp() {
    if (runtime.current?.state.mode === 'playing') action('pause');
    helpRef.current = true;
    setHelp(true);
  }
  function hideHelp() { helpRef.current = false; setHelp(false); canvasRef.current?.focus({ preventScroll: true }); }
  async function toggleFullscreen() {
    try {
      if (document.fullscreenElement) await document.exitFullscreen();
      else if (screenRef.current?.requestFullscreen) await screenRef.current.requestFullscreen();
      else { setScreenMessage('Fullscreen is unavailable in this browser.'); return; }
      setScreenMessage('');
      canvasRef.current?.focus({ preventScroll: true });
    } catch { setScreenMessage('Fullscreen is unavailable in this window.'); }
  }
  const status = view.mode === 'title' ? 'AWAITING DEPLOYMENT' : view.mode === 'paused' ? 'MISSION PAUSED' : view.mode === 'dead' ? 'SIGNAL LOST — RETRY READY' : view.mode === 'won' ? 'MISSION COMPLETE' : 'MISSION IN PROGRESS';

  return <main className="shell">
    <header className="topbar">
      <div className="brand"><span className="brand-mark" aria-hidden="true">X</span>MAVERICK HUNTER</div>
      <div className="top-status"><span className="dot"/>SYSTEM ONLINE <span>/</span> FAN EDITION</div>
    </header>
    <section className="intro">
      <div><div className="eyebrow">THE CITY NEEDS A HUNTER.</div><h1>Highway <span>Assault</span></h1><p>Suit up. Charge your buster. Take back the highway.</p></div>
      <div className="mission-tag">MISSION 01 / ABANDONED HIGHWAY</div>
    </section>
    <section className="cabinet" aria-label="Mega Man X game">
      <div className="cabinet-bar"><div className="cabinet-label"><span className="live">●</span> MEGA MAN X <span>/</span> HIGHWAY ASSAULT</div><span>16-BIT SPIRIT. ZERO LIMITS.</span></div>
      <div className="screen" ref={screenRef}>
        <canvas ref={canvasRef} width={384} height={216} tabIndex={0} aria-label="Highway Assault. Arrows to move, Z to jump, X to shoot, C to dash, Escape to pause." aria-describedby="keyboard-guide">Your browser needs Canvas support to play Highway Assault.</canvas>
        <div className="scanlines"/>
        {help ? <div className="game-overlay help-overlay" role="dialog" aria-label="How to play">
          <div className="hero-label">HUNTER FIELD MANUAL</div><h2 className="overlay-title">KNOW YOUR ARMOR.</h2>
          <div className="help-grid"><div><kbd>← →</kbd><p><strong>MOVE</strong>Arrows or A / D</p></div><div><kbd>Z</kbd><p><strong>JUMP</strong>Z or Space · hold for height</p></div><div><kbd>X</kbd><p><strong>BUSTER</strong>X or J · hold, then release</p></div><div><kbd>C</kbd><p><strong>DASH</strong>C or Shift · once in the air</p></div></div>
          <p className="help-tip">Slide against a wall and jump to climb. Green beacons save your position. Watch the Colossus’s warning lights before it attacks.</p>
          <button className="start-button" onClick={hideHelp}>GOT IT&nbsp; ▷</button>
        </div> : view.mode === 'title' ? <div className="game-overlay">
          <div className="hero-label">A MAVERICK HUNTER MISSION</div><h2 className="game-logo">MEGA MAN <em>X</em></h2><div className="game-subtitle">HIGHWAY ASSAULT</div>
          <button className="start-button" onClick={() => action('start')}>START MISSION&nbsp; ▷</button>
          <div className="start-hint">PRESS ENTER TO DEPLOY</div><div className="title-chips"><span>01 STAGE</span><i/><span>01 BOSS</span><i/><span>UNLIMITED RETRIES</span></div>
        </div> : view.mode === 'paused' ? <div className="game-overlay pause-overlay" role="dialog" aria-label="Mission paused">
          <div className="hero-label">TAKE A BREATHER, HUNTER.</div><h2 className="overlay-title">MISSION PAUSED</h2><p className="overlay-copy">Your mission will be here when you’re ready.<br/>{clock(view.elapsed)} elapsed · Checkpoint {view.checkpoint + 1}</p>
          <button className="start-button" onClick={() => action('resume')}>RESUME MISSION&nbsp; ▷</button><div className="menu-row"><button className="secondary-button" onClick={showHelp}>CONTROLS</button><button className="secondary-button" onClick={() => action('restart')}>RESTART STAGE</button></div><div className="start-hint">ESC / P TO RESUME</div>
        </div> : view.mode === 'dead' ? <div className="game-overlay pause-overlay" role="dialog" aria-label="Retry mission">
          <div className="hero-label">ARMOR OFFLINE. SPIRIT INTACT.</div><h2 className="overlay-title">ONE MORE SHOT.</h2><p className="overlay-copy">Return to checkpoint {view.checkpoint + 1} with full health.<br/>Unlimited retries. You’ve got this.</p><button className="start-button" onClick={() => action('retry')}>RETRY CHECKPOINT&nbsp; ▷</button><div className="start-hint">OR PRESS ENTER</div>
        </div> : view.mode === 'won' ? <div className="game-overlay victory-overlay" role="dialog" aria-label="Mission complete">
          <div className="hero-label">IRON COLOSSUS NEUTRALIZED</div><h2 className="overlay-title">HIGHWAY SECURED.</h2><p className="overlay-copy">The city lives to see another sunrise.</p><div className="victory-stats"><div><strong>{clock(view.elapsed)}</strong><span>MISSION TIME</span></div><div><strong>{view.kills}</strong><span>MAVERICKS DOWN</span></div><div><strong>{view.deaths}</strong><span>RETRIES</span></div></div><button className="start-button" onClick={() => action('start')}>PLAY AGAIN&nbsp; ▷</button>
        </div> : null}
      </div>
      <div className="game-footer"><div className="footer-left"><span className="dot"/>{status}</div><div className="tools">{view.mode === 'playing' && <button className="tool-button" onClick={() => action('pause')} aria-label="Pause game">Ⅱ PAUSE</button>}<button className="tool-button" onClick={toggleMute} aria-label={muted ? 'Enable audio' : 'Mute audio'} aria-pressed={muted}>{muted ? '♪ SOUND OFF' : '♪ SOUND ON'}</button><button className="tool-button" onClick={toggleFullscreen} aria-label={fullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}>⛶ {fullscreen ? 'EXIT' : 'FULLSCREEN'}</button></div></div>
    </section>
    {screenMessage && <p role="status" className="mobile-note visible-note">{screenMessage}</p>}
    <p className="mobile-note">Made for a keyboard. Open on a desktop to join the mission.</p>
    <section className="controls" id="keyboard-guide">
      <div><div className="controls-heading"><h3 className="section-title">YOUR CONTROLS</h3><button className="text-button" onClick={showHelp}>FIELD MANUAL ↗</button></div><div className="keys"><div className="key-group"><kbd>←</kbd><kbd>→</kbd><span>Move</span></div><div className="key-group"><kbd>Z</kbd><span>Jump</span></div><div className="key-group"><kbd>X</kbd><span>Hold to charge</span></div><div className="key-group"><kbd>C</kbd><span>Dash</span></div><div className="key-group"><kbd>ESC</kbd><span>Pause</span></div></div><p className="alternate-keys">Also: A / D to move · Space to jump · J to shoot · Shift to dash</p></div>
      <div className="brief"><h3 className="section-title">MISSION BRIEF</h3><p>Mavericks have seized the elevated highway.<br/><strong>Push through the ruins. Find the source. Shut it down.</strong></p></div>
    </section>
    <footer className="bottom"><span>A FAN-MADE TRIBUTE. BUILT FOR THE LOVE OF THE GAME.</span><span>RUN. JUMP. CHARGE. REPEAT. ↗</span></footer>
    <div className="sr-only" role="status" aria-live="polite">{status}</div>
  </main>;
}
