import { useEffect, useMemo, useState } from 'react';
import './App.css';

type TargetKind = 'good' | 'bad';

interface Target {
  x: number;
  y: number;
  size: number;
  kind: TargetKind;
}

const GAME_DURATION = 30;
const TICK_MS = 1000;
const TARGET_MOVE_MS = 850;
const SHIELD_CHARGE_HITS = 5;
const MAX_SHIELDS = 3;

function randomTarget(): Target {
  return {
    x: Math.round(10 + Math.random() * 80),
    y: Math.round(10 + Math.random() * 80),
    size: Math.round(52 + Math.random() * 34),
    kind: Math.random() > 0.25 ? 'good' : 'bad',
  };
}

function App() {
  const [running, setRunning] = useState(false);
  const [timeLeft, setTimeLeft] = useState(GAME_DURATION);
  const [score, setScore] = useState(0);
  const [combo, setCombo] = useState(0);
  const [shieldCharge, setShieldCharge] = useState(0);
  const [shields, setShields] = useState(0);
  const [target, setTarget] = useState<Target>(randomTarget());
  const [history, setHistory] = useState<number[]>([]);

  useEffect(() => {
    if (!running) return;
    const timer = setInterval(() => {
      setTimeLeft((previous) => {
        if (previous <= 1) {
          setRunning(false);
          return 0;
        }
        return previous - 1;
      });
    }, TICK_MS);

    return () => clearInterval(timer);
  }, [running]);

  useEffect(() => {
    if (!running) return;
    const mover = setInterval(() => {
      setTarget(randomTarget());
    }, TARGET_MOVE_MS);

    return () => clearInterval(mover);
  }, [running]);

  useEffect(() => {
    if (running || timeLeft !== 0) return;
    if (score > 0) {
      setHistory((previous) => [score, ...previous].slice(0, 5));
    }
  }, [running, score, timeLeft]);

  const bestScore = useMemo(() => {
    return history.length > 0 ? Math.max(...history) : 0;
  }, [history]);

  const accuracyHint = useMemo(() => {
    if (combo >= 8) return 'ON FIRE';
    if (combo >= 4) return 'Momentum';
    if (combo >= 1) return 'Nice';
    return 'Ready';
  }, [combo]);

  const startGame = () => {
    setRunning(true);
    setTimeLeft(GAME_DURATION);
    setScore(0);
    setCombo(0);
    setShieldCharge(0);
    setShields(0);
    setTarget(randomTarget());
  };

  const onTargetHit = () => {
    if (!running) return;

    if (target.kind === 'good') {
      setScore((previous) => previous + 10 + Math.min(combo, 5));
      setCombo((previous) => previous + 1);
      setShieldCharge((previous) => {
        if (shields >= MAX_SHIELDS) return previous;
        const updated = previous + 1;
        if (updated >= SHIELD_CHARGE_HITS) {
          setShields((current) => Math.min(MAX_SHIELDS, current + 1));
          return 0;
        }
        return updated;
      });
    } else {
      if (shields > 0) {
        setShields((previous) => Math.max(0, previous - 1));
      } else {
        setScore((previous) => Math.max(0, previous - 8));
        setCombo(0);
      }
    }

    setTarget(randomTarget());
  };

  return (
    <main className="arcade-shell">
      <section className="hud-card">
        <p className="eyebrow">Code App</p>
        <h1>Neon Reactor</h1>
        <p className="subline">Hit cyan cores, avoid magenta traps. 30-second sprint.</p>

        <div className="metrics">
          <div className="metric-box">
            <span>Time</span>
            <strong>{timeLeft}s</strong>
          </div>
          <div className="metric-box">
            <span>Score</span>
            <strong>{score}</strong>
          </div>
          <div className="metric-box">
            <span>Best</span>
            <strong>{bestScore}</strong>
          </div>
          <div className="metric-box">
            <span>Streak</span>
            <strong>{accuracyHint}</strong>
          </div>
          <div className="metric-box">
            <span>Shields</span>
            <strong>{shields}</strong>
          </div>
          <div className="metric-box">
            <span>Charge</span>
            <strong>{shieldCharge}/{SHIELD_CHARGE_HITS}</strong>
          </div>
        </div>

        <p className="feature-hint">
          New feature: every {SHIELD_CHARGE_HITS} good hits grants 1 shield (max {MAX_SHIELDS}).
          Shields absorb bad targets with no score penalty.
        </p>

        <button className="primary-btn" onClick={startGame}>
          {running ? 'Restart Round' : 'Start Round'}
        </button>

        <div className="history">
          <span>Recent scores</span>
          <ul>
            {history.length === 0 ? (
              <li>No rounds yet</li>
            ) : (
              history.map((value, index) => <li key={`${value}-${index}`}>{value}</li>)
            )}
          </ul>
        </div>
      </section>

      <section className="arena-card">
        <div className="arena-grid" aria-label="Game arena">
          <button
            className={`target ${target.kind} ${running ? 'active' : 'disabled'}`}
            style={{ left: `${target.x}%`, top: `${target.y}%`, width: `${target.size}px`, height: `${target.size}px` }}
            onClick={onTargetHit}
            aria-label={target.kind === 'good' ? 'Good target' : 'Bad target'}
          />

          {!running && (
            <div className="overlay">
              <h2>{timeLeft === 0 ? 'Round Complete' : 'Press Start'}</h2>
              <p>{timeLeft === 0 ? `Final score: ${score}` : 'Warm up your reflexes and launch a round.'}</p>
            </div>
          )}
        </div>
      </section>
    </main>
  );
}

export default App;
