"use client";

import { AnimatePresence, motion } from "framer-motion";
import { useEffect, useRef, useState } from "react";
import { GameTable } from "@/components/GameTable";
import { PostMatchRewardsModal } from "@/components/online/PostMatchRewardsModal";
import { MatchIntroOverlay } from "@/components/online/MatchIntroOverlay";
import { useGameStore } from "@/lib/game-store";
import { useSessionStore } from "@/lib/session-store";
import { useUIStore } from "@/lib/ui-store";
import { useI18n } from "@/lib/i18n";
import { getService } from "@/lib/online/service";
import { pushNotification } from "@/lib/notification-store";
import { celebrate } from "@/lib/celebration-store";
import { MatchSummary, RewardResult } from "@/lib/online/types";

export function GameScreen() {
  const game = useGameStore((s) => s.game);
  const mode = useGameStore((s) => s.mode);
  const live = useGameStore((s) => s.live);
  const serverReward = useGameStore((s) => s.serverReward);
  const tally = useGameStore((s) => s.tally);
  const meta = useGameStore((s) => s.matchMeta);
  const reset = useGameStore((s) => s.reset);
  const forfeited = useGameStore((s) => s.forfeited);
  const forfeitRequest = useGameStore((s) => s.forfeitRequest);
  const respondForfeit = useGameStore((s) => s.respondForfeit);
  const introPending = useGameStore((s) => s.matchIntroPending);
  const consumeIntro = useGameStore((s) => s.consumeIntro);
  const returnTo = useUIStore((s) => s.returnTo);
  const go = useUIStore((s) => s.go);
  const refreshProfile = useSessionStore((s) => s.refreshProfile);
  const { t } = useI18n();

  const [reward, setReward] = useState<RewardResult | null>(null);
  const submitted = useRef(false);

  // Leaving the table (back button, browser/hardware back) keeps the match alive
  // & resumable — pause is handled by the unmount effect below. A finished match
  // is torn down instead.
  const exit = () => {
    if (useGameStore.getState().game.phase === "match-over") reset();
    go(returnTo);
  };

  // Match truly finished (reward dismissed): tear the match down.
  const finish = () => {
    reset();
    go(returnTo);
  };

  // Any way the table unmounts (exit button, hardware/browser back), keep an
  // in-progress match alive and resumable instead of letting it run unattended.
  useEffect(() => {
    return () => {
      const gs = useGameStore.getState();
      if (gs.started && gs.game.phase !== "match-over") gs.minimize();
    };
  }, []);

  const notifyAchievements = (r: RewardResult) => {
    for (const a of r.newAchievements)
      pushNotification({
        kind: "achievement",
        titleFa: "دستاورد جدید",
        titleEn: "New achievement",
        bodyFa: a.nameFa,
        bodyEn: a.nameEn,
        icon: a.icon,
      });
  };

  // Splashy celebration overlay for every achievement / level-up earned in the
  // match — fired once the post-match reward summary is dismissed so each unlock
  // gets its own animated moment (queued by the celebration store).
  const celebrateRewards = (r: RewardResult | null) => {
    if (!r) return;
    if (r.leveledUp) {
      celebrate({
        variant: "xp",
        icon: "🎚️",
        title: t("reward.levelUp"),
        levelBefore: r.levelBefore,
        levelAfter: r.levelAfter,
      });
    }
    for (const a of r.newAchievements) {
      celebrate({
        variant: "purchase",
        icon: a.icon,
        title: t("reward.newAchievement"),
        achievements: [a],
      });
    }
  };

  // Client-run games (private rooms / casual): submit the result to the server.
  useEffect(() => {
    if (!live && mode === "online" && game.phase === "match-over" && !submitted.current) {
      submitted.current = true;
      const summary: MatchSummary = {
        ranked: meta.ranked,
        stake: meta.stake,
        won: game.matchWinner === 0,
        kotFor: tally.kotFor,
        kotAgainst: tally.kotAgainst,
        tricksWon: tally.tricksTeam0,
        rounds: game.matchScore[0] + game.matchScore[1],
        trump: game.trump,
        // shutout = you won and the opponent never scored a round (e.g. 7–0)
        shutout: !forfeited && game.matchWinner === 0 && game.matchScore[1] === 0,
        hakemRounds: tally.hakemRounds,
        roundsWon: game.matchScore[0],
        forfeit: forfeited,
      };
      getService()
        .submitMatchResult(summary)
        .then((r) => {
          setReward(r);
          refreshProfile();
          notifyAchievements(r);
        });
    }
  }, [live, mode, game.phase, game.matchWinner, game.matchScore, game.trump, meta, tally, forfeited, refreshProfile]);

  // Server-run ranked games: the reward arrives via the hub.
  useEffect(() => {
    if (live && serverReward && !submitted.current) {
      submitted.current = true;
      setReward(serverReward);
      refreshProfile();
      notifyAchievements(serverReward);
    }
  }, [live, serverReward, refreshProfile]);

  const canForfeit = game.phase !== "match-over" && !forfeited;

  return (
    <>
      <GameTable
        onExit={exit}
        onForfeit={canForfeit ? () => useGameStore.getState().forfeit() : undefined}
      />

      {/* UNO-style "players joining the table" intro (online matches, once) */}
      <AnimatePresence>
        {introPending && mode === "online" && (
          <MatchIntroOverlay onDone={consumeIntro} />
        )}
      </AnimatePresence>

      {/* teammate asked to forfeit — confirm or decline */}
      {forfeitRequest && (
        <motion.div
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          className="fixed inset-0 z-[70] flex items-center justify-center bg-navy-950/80 backdrop-blur-sm p-5"
        >
          <motion.div
            initial={{ scale: 0.85, y: 20 }}
            animate={{ scale: 1, y: 0 }}
            className="glass rounded-3xl p-6 w-full max-w-xs text-center"
          >
            <div className="text-4xl mb-2">🏳️</div>
            <h2 className="gold-text text-xl font-black">{t("forfeit.title")}</h2>
            <p className="text-cream/70 text-sm mt-2">
              {t("forfeit.teammateAsks").replace("{name}", forfeitRequest.byName)}
            </p>
            <p className="text-cream/45 text-xs mt-1">{t("forfeit.rule")}</p>
            <div className="flex gap-2 mt-5">
              <button onClick={() => respondForfeit(true)} className="flex-1 rounded-xl py-3 bg-rose-500/80 text-white font-bold">
                {t("forfeit.confirm")}
              </button>
              <button onClick={() => respondForfeit(false)} className="flex-1 btn-gold rounded-xl py-3">
                {t("forfeit.keepPlaying")}
              </button>
            </div>
          </motion.div>
        </motion.div>
      )}

      {reward && (
        <PostMatchRewardsModal
          reward={reward}
          won={game.matchWinner === 0}
          onClose={() => {
            const r = reward;
            setReward(null);
            celebrateRewards(r);
            finish();
          }}
        />
      )}
    </>
  );
}
