import { useCallback, useEffect, useMemo, useState } from 'react';
import { ActionBar } from '../../components/ActionBar';
import { GameTable } from '../../components/GameTable';
import { HandRankModal } from '../../components/HandRankModal';
import { JackpotModal } from '../../components/JackpotModal';
import { RemainingModal } from '../../components/RemainingModal';
import { ResultOverlay } from '../../components/ResultOverlay';
import { SplitView } from '../../components/SplitView';
import {
  aiAction,
  applyAction,
  applyHeroFoldSplit,
  applyHeroSplit,
  createGame,
  heroHandHint,
  remainingDeck,
  startHand,
} from '../../game/engine';
import type { BetAction, GameState } from '../../game/types';
import { play, unlockAudio } from '../../game/sfx';
import type { GameRoom } from '../../navigation';
import './ChexuanGame.css';

const HERO_INDEX = 0;
const TURN_SECONDS = 15;

interface Props {
  room: GameRoom;
  onExit: () => void;
  onHome: () => void;
}

export function ChexuanGame({ room, onExit, onHome }: Props) {
  const [game, setGame] = useState<GameState>(() => createGame(room.baseChip));
  const [showJackpot, setShowJackpot] = useState(false);
  const [showHelp, setShowHelp] = useState(false);
  const [showRemaining, setShowRemaining] = useState(false);
  const [forceShow, setForceShow] = useState(false);
  const [secondsLeft, setSecondsLeft] = useState(TURN_SECONDS);
  const [matchLeft, setMatchLeft] = useState(10 * 60);

  const hero = game.seats[HERO_INDEX];
  const myTurn = game.phase === 'betting' && game.actorIndex === HERO_INDEX;
  const someoneBet = game.currentBet > 0;

  useEffect(() => {
    if (game.phase !== 'betting') return;
    if (game.actorIndex === HERO_INDEX || game.actorIndex < 0) return;
    const t = setTimeout(() => {
      setGame((g) => {
        if (g.phase !== 'betting' || g.actorIndex === HERO_INDEX || g.actorIndex < 0) return g;
        const decision = aiAction(g);
        return applyAction(g, decision.action, decision.amount);
      });
    }, 850);
    return () => clearTimeout(t);
  }, [game.actorIndex, game.phase, game.round]);

  const onAction = useCallback((action: BetAction, amount?: number) => {
    unlockAudio();
    play(action === 'fold' ? 'fold' : action === 'rest' ? 'click' : 'chip');
    setGame((g) => {
      if (g.phase !== 'betting' || g.actorIndex !== HERO_INDEX) return g;
      return applyAction(g, action, amount);
    });
  }, []);

  useEffect(() => {
    if (game.phase === 'betting') play('deal');
  }, [game.dealSeq, game.phase]);

  useEffect(() => {
    if (!game.results) return;
    const mine = game.results.find((r) => r.seatId === hero.id);
    play(mine && mine.delta > 0 ? 'win' : 'lose');
  }, [game.results, hero.id]);

  useEffect(() => {
    if (game.jackpotHit) play('jackpot');
  }, [game.jackpotHit]);

  useEffect(() => {
    if (myTurn) play('turn');
  }, [myTurn]);

  useEffect(() => {
    if ((game.phase !== 'betting' && game.phase !== 'split') || game.actorIndex < 0) return;
    const start = Date.now();
    const tick = () => {
      const elapsed = Math.floor((Date.now() - start) / 1000);
      setSecondsLeft(Math.max(0, TURN_SECONDS - elapsed));
    };
    const id0 = setTimeout(tick, 0);
    const iv = setInterval(tick, 250);
    return () => {
      clearTimeout(id0);
      clearInterval(iv);
    };
  }, [game.actorIndex, game.phase, game.round]);

  useEffect(() => {
    if (secondsLeft > 0 || !myTurn) return;
    const t = setTimeout(() => onAction(someoneBet ? 'fold' : 'rest'), 0);
    return () => clearTimeout(t);
  }, [secondsLeft, myTurn, someoneBet, onAction]);

  useEffect(() => {
    const iv = setInterval(() => {
      setMatchLeft((s) => Math.max(0, s - 1));
    }, 1000);
    return () => clearInterval(iv);
  }, []);

  const clock = `${String(Math.floor(matchLeft / 60)).padStart(2, '0')}:${String(
    matchLeft % 60,
  ).padStart(2, '0')}`;

  const heroSplitting = game.phase === 'split' && game.actorIndex === HERO_INDEX;

  const onNextHand = useCallback(() => {
    unlockAudio();
    play('click');
    setGame((g) => startHand(g, (g.dealerIndex + 1) % g.seats.length));
  }, []);

  const onSplit = useCallback((headIds: string[], mult: number) => {
    unlockAudio();
    play('chip');
    setGame((g) => (g.phase === 'split' ? applyHeroSplit(g, headIds, mult) : g));
  }, []);

  const onSplitFold = useCallback(() => {
    unlockAudio();
    play('fold');
    setGame((g) => (g.phase === 'split' ? applyHeroFoldSplit(g) : g));
  }, []);

  const display = useMemo<GameState>(() => {
    const hint = heroHandHint(game);
    const seats = game.seats.map((s) =>
      s.isHero ? { ...s, handHint: hint || s.handHint } : s,
    );
    return { ...game, seats };
  }, [game]);

  return (
    <div className="chexuan-screen">
      <header className="game-topbar chexuan-topbar">
        <div className="game-topbar__left">
          <button className="icon-btn icon-btn--round" aria-label="返回选择大厅" onClick={onExit}>
            ←
          </button>
          <div className="game-topbar__title">
            <span className="game-topbar__main">扯旋</span>
            <span className="game-topbar__sub">
              {room.name} · 底注 {room.baseChip} · 房间 {game.roomId}
            </span>
          </div>
        </div>
        <div className="game-topbar__right">
          <div className="chexuan-topbar__money">
            <span className="coin chexuan-topbar__coin" />
            <span>{hero.chips.toLocaleString()}</span>
          </div>
          <button className="icon-btn" aria-label="返回大厅" onClick={onHome}>
            ⌂
          </button>
          <button className="icon-btn" aria-label="奖池" onClick={() => setShowJackpot(true)}>
            🏆
          </button>
          <button className="icon-btn" aria-label="牌型说明" onClick={() => setShowHelp(true)}>
            ☰
          </button>
        </div>
      </header>

      <GameTable
        game={display}
        turnCountdown={secondsLeft / TURN_SECONDS}
        forceShow={forceShow}
        dealKey={game.dealSeq}
        clock={clock}
      />

      <div className="assist-bar">
        <button
          className={`assist-orb ${forceShow ? 'assist-orb--on' : ''}`}
          onClick={() => setForceShow((v) => !v)}
        >
          <span className="assist-orb__txt">强制秀牌</span>
          <span className="assist-orb__cost">¥{game.baseChip}</span>
        </button>
        <button className="assist-orb" onClick={() => setShowRemaining(true)}>
          <span className="assist-orb__txt">看下一张</span>
          <span className="assist-orb__cost">¥{game.baseChip}</span>
          <span className="assist-orb__badge">{remainingDeck().length}</span>
        </button>
      </div>

      {game.message && <div className="action-msg">{game.message}</div>}

      {!heroSplitting && (
        <ActionBar
          bobo={game.bobo}
          baseChip={game.baseChip}
          currentBet={game.currentBet}
          heroTotalBet={hero.totalBet}
          myTurn={myTurn}
          canRest={!someoneBet}
          round={game.round}
          onAction={onAction}
        />
      )}

      {heroSplitting && (
        <SplitView
          cards={hero.cards}
          countdown={secondsLeft / TURN_SECONDS}
          onConfirm={onSplit}
          onFold={onSplitFold}
        />
      )}

      {game.phase === 'settle' && game.results && (
        <ResultOverlay results={game.results} jackpotHit={game.jackpotHit} onNext={onNextHand} />
      )}

      {showJackpot && <JackpotModal jackpot={game.jackpot} onClose={() => setShowJackpot(false)} />}

      {showHelp && <HandRankModal onClose={() => setShowHelp(false)} />}

      {showRemaining && (
        <RemainingModal cards={remainingDeck()} onClose={() => setShowRemaining(false)} />
      )}
    </div>
  );
}
