"use client";

import { useState, useEffect, useCallback, useRef } from "react";
import { BingoCell } from "./BingoCell";
import { Badge } from "./ui/badge";
import { Button } from "./ui/button";
import { playSound, playBingo } from "@/lib/sounds";
import { cn } from "@/lib/utils";

type Item = {
  id: string;
  text: string;
  emoji: string;
  soundCategory: string;
  soundUrl?: string | null;
  gridIndex: number;
};

type GridCell = {
  index: number;
  item: Item | null;
  marked: boolean;
  markedBy: string[];
  markCount: number;
};

type Campaign = {
  id: string;
  name: string;
  gridSize: number;
  status: string;
};

type Props = {
  campaign: Campaign;
  initialGrid: GridCell[];
  currentUserNickname: string;
  isAdmin: boolean;
};

function checkBingo(grid: GridCell[], gridSize: number): number[][] {
  const lines: number[][] = [];
  const size = gridSize;

  for (let row = 0; row < size; row++) {
    const indices = Array.from({ length: size }, (_, c) => row * size + c);
    if (indices.every(i => grid[i]?.marked)) lines.push(indices);
  }

  for (let col = 0; col < size; col++) {
    const indices = Array.from({ length: size }, (_, r) => r * size + col);
    if (indices.every(i => grid[i]?.marked)) lines.push(indices);
  }

  const diag1 = Array.from({ length: size }, (_, i) => i * size + i);
  if (diag1.every(i => grid[i]?.marked)) lines.push(diag1);

  const diag2 = Array.from({ length: size }, (_, i) => (i + 1) * size - i - 1);
  if (diag2.every(i => grid[i]?.marked)) lines.push(diag2);

  return lines;
}

export function BingoCard({ campaign, initialGrid, currentUserNickname, isAdmin }: Props) {
  const [grid, setGrid] = useState<GridCell[]>(initialGrid);
  const [bingoLines, setBingoLines] = useState<number[][]>([]);
  const [marking, setMarking] = useState<string | null>(null);
  const [chaosLevel, setChaosLevel] = useState(0);
  const [showBingo, setShowBingo] = useState(false);
  const [activityLog, setActivityLog] = useState<string[]>([]);
  const bingoNotified = useRef(false);
  const pollingRef = useRef<ReturnType<typeof setInterval> | null>(null);

  const fetchState = useCallback(async () => {
    try {
      const res = await fetch(`/api/game/${campaign.id}/state`);
      const data = await res.json();
      if (data.grid) {
        setGrid(data.grid);
        const lines = checkBingo(data.grid, campaign.gridSize);
        setBingoLines(lines);
        const markedCount = data.grid.filter((c: GridCell) => c.marked).length;
        const totalItems = data.grid.filter((c: GridCell) => c.item).length;
        setChaosLevel(totalItems > 0 ? Math.min(markedCount / totalItems, 1) : 0);
        if (lines.length > 0 && !bingoNotified.current) {
          bingoNotified.current = true;
          setShowBingo(true);
          playBingo();
        }
        if (data.activityLog) {
          setActivityLog(data.activityLog);
        }
      }
    } catch {}
  }, [campaign.id, campaign.gridSize]);

  useEffect(() => {
    fetchState();
    pollingRef.current = setInterval(fetchState, 3000);
    return () => { if (pollingRef.current) clearInterval(pollingRef.current); };
  }, [fetchState]);

  const markItem = async (itemId: string) => {
    if (marking) return;
    const item = grid.find(c => c.item?.id === itemId);
    if (item?.item) playSound(item.item.soundCategory, item.item.soundUrl);
    setMarking(itemId);
    try {
      const res = await fetch("/api/game/mark", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ campaignId: campaign.id, itemId }),
      });
      if (!res.ok && res.status === 409) {
        // already marked by someone else, just refresh
      }
      await fetchState();
    } catch {}
    setMarking(null);
  };

  const unmarkItem = async (itemId: string) => {
    if (marking) return;
    setMarking(itemId);
    try {
      await fetch("/api/game/mark", {
        method: "DELETE",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ campaignId: campaign.id, itemId }),
      });
      await fetchState();
    } catch {}
    setMarking(null);
  };

  const markedCount = grid.filter(c => c.marked).length;
  const totalItems = grid.filter(c => c.item).length;

  const hullHealth = Math.max(0, 100 - chaosLevel * 100);
  const reactorTemp = 80 + chaosLevel * 120;
  const o2Level = Math.max(0, 100 - chaosLevel * 130);

  const stageLabel =
    chaosLevel < 0.25 ? "✅ Sub stable" :
    chaosLevel < 0.5 ? "⚠️ Leaking" :
    chaosLevel < 0.75 ? "🚨 MELTDOWN" : "☢️ SUB DESTROYED";

  const chaosStageClass =
    chaosLevel < 0.3 ? "from-cyan-600 to-cyan-500" :
    chaosLevel < 0.6 ? "from-amber-600 to-orange-500" :
    "from-red-600 to-red-500";

  return (
    <div className="flex flex-col items-center gap-4 w-full max-w-5xl mx-auto">
      {/* Header */}
      <div className="text-center w-full">
        <h2 className="text-2xl font-bold text-cyan-300 font-mono tracking-wide uppercase">
          {campaign.name}
        </h2>
        <p className="text-sm text-slate-500 font-mono mt-1">
          {markedCount}/{totalItems} cells marked
        </p>
      </div>

      {/* Chaos Meter */}
      <div className="w-full space-y-1">
        <div className="flex justify-between text-xs font-mono text-slate-500">
          <span>{stageLabel}</span>
          <span>{Math.round(chaosLevel * 100)}% chaos</span>
        </div>
        <div className="w-full bg-slate-900/60 rounded-full h-3 overflow-hidden border border-slate-700/30">
          <div
            className={cn(
              "h-full rounded-full transition-all duration-500 ease-out bg-gradient-to-r",
              chaosStageClass,
              chaosLevel >= 0.6 && "animate-pulse"
            )}
            style={{ width: `${chaosLevel * 100}%` }}
          />
        </div>
      </div>

      {/* Sub Status + Grid Row */}
      <div className="flex gap-4 w-full">
        {/* Sub Status Panel */}
        <div className="hidden md:flex flex-col gap-2 w-48 shrink-0">
          <div className="bg-slate-900/60 border border-slate-700/30 rounded-lg p-3 space-y-2">
            <h3 className="text-[9px] font-mono text-slate-600 uppercase tracking-wider">Sub Status</h3>
            <div className="space-y-2">
              <div>
                <div className="flex justify-between text-[9px] font-mono">
                  <span className="text-slate-500">Hull</span>
                  <span className={cn(hullHealth < 30 ? "text-red-400" : "text-slate-400")}>{Math.round(hullHealth)}%</span>
                </div>
                <div className="w-full h-1.5 bg-slate-800 rounded-full overflow-hidden">
                  <div className={cn("h-full rounded-full transition-all duration-700", hullHealth < 30 ? "bg-red-500" : "bg-cyan-500")} style={{ width: `${hullHealth}%` }} />
                </div>
              </div>
              <div>
                <div className="flex justify-between text-[9px] font-mono">
                  <span className="text-slate-500">Reactor</span>
                  <span className={cn(reactorTemp > 120 ? "text-orange-400" : "text-slate-400")}>{Math.round(reactorTemp)}°C</span>
                </div>
                <div className="w-full h-1.5 bg-slate-800 rounded-full overflow-hidden">
                  <div className={cn("h-full rounded-full transition-all duration-700", reactorTemp > 120 ? "bg-orange-500 animate-pulse" : "bg-cyan-500")} style={{ width: `${Math.min(reactorTemp / 2, 100)}%` }} />
                </div>
              </div>
              <div>
                <div className="flex justify-between text-[9px] font-mono">
                  <span className="text-slate-500">O₂</span>
                  <span className={cn(o2Level < 30 ? "text-red-400" : "text-slate-400")}>{Math.round(o2Level)}%</span>
                </div>
                <div className="w-full h-1.5 bg-slate-800 rounded-full overflow-hidden">
                  <div className={cn("h-full rounded-full transition-all duration-700", o2Level < 30 ? "bg-red-500" : "bg-cyan-500")} style={{ width: `${o2Level}%` }} />
                </div>
              </div>
            </div>
            <div className="text-[8px] font-mono text-slate-700 pt-1 border-t border-slate-700/30">
              {chaosLevel < 0.25 && "All systems nominal"}
              {chaosLevel >= 0.25 && chaosLevel < 0.5 && "⚠️ Minor breaches detected"}
              {chaosLevel >= 0.5 && chaosLevel < 0.75 && "🚨 EVACUATE! SUB COMPROMISED"}
              {chaosLevel >= 0.75 && "☢️ MELTDOWN IN PROGRESS"}
            </div>
          </div>

          {/* Activity Log */}
          <div className="bg-slate-900/60 border border-slate-700/30 rounded-lg p-3 flex-1 min-h-0 max-h-60 overflow-y-auto">
            <h3 className="text-[9px] font-mono text-slate-600 uppercase tracking-wider mb-2 sticky top-0 bg-slate-900/80 pb-1">Crew Log</h3>
            <div className="space-y-1">
              {activityLog.length === 0 && (
                <p className="text-[9px] font-mono text-slate-700 italic">Awaiting chaos...</p>
              )}
              {activityLog.map((entry, i) => (
                <p key={i} className="text-[9px] font-mono text-slate-500 leading-relaxed">{entry}</p>
              ))}
            </div>
          </div>
        </div>

        {/* Bingo Grid */}
        <div className="flex-1 min-w-0">
          <div
            className="grid gap-1.5 w-full"
            style={{ gridTemplateColumns: `repeat(${campaign.gridSize}, 1fr)` }}
          >
            {grid.map((cell) => (
              <BingoCell
                key={cell.index}
                item={cell.item}
                index={cell.index}
                marked={cell.marked}
                markCount={cell.markCount}
                markedBy={cell.markedBy}
                gridSize={campaign.gridSize}
                onMark={markItem}
                onUnmark={unmarkItem}
                disabled={marking !== null}
              />
            ))}
          </div>
        </div>
      </div>

      {/* Bingo Lines */}
      {bingoLines.length > 0 && (
        <div className="flex flex-wrap gap-2 items-center justify-center">
          <Badge variant="destructive" className="text-sm px-4 py-1 animate-pulse shadow-lg shadow-red-600/30">
            🏆 BINGO! {bingoLines.length} line(s)
          </Badge>
        </div>
      )}

      {/* Bingo Celebration Modal */}
      {showBingo && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/70 backdrop-blur-sm" onClick={() => setShowBingo(false)}>
          <div className="bg-slate-900 border-2 border-amber-500/50 rounded-2xl p-8 text-center shadow-2xl shadow-amber-900/30 animate-[bounce_1s_ease-in-out_infinite] max-w-md mx-4" onClick={e => e.stopPropagation()}>
            <div className="text-6xl mb-4">🏆🔥💀</div>
            <h2 className="text-3xl font-bold text-amber-400 font-mono mb-2">БИНГО!</h2>
            <p className="text-slate-300 mb-4">Хаос победил! Суб взорван, экипаж мёртв, всем весело!</p>
            <div className="text-4xl mb-4 animate-pulse">🎉💥🌊🤡</div>
            <Button variant="outline" onClick={() => setShowBingo(false)}>
              Продолжить хаос
            </Button>
          </div>
        </div>
      )}

      {/* Mobile Activity Log */}
      <div className="md:hidden w-full bg-slate-900/60 border border-slate-700/30 rounded-lg p-3 max-h-40 overflow-y-auto">
        <h3 className="text-[9px] font-mono text-slate-600 uppercase tracking-wider mb-2">Crew Log</h3>
        <div className="space-y-1">
          {activityLog.length === 0 && (
            <p className="text-[9px] font-mono text-slate-700 italic">Awaiting chaos...</p>
          )}
          {activityLog.map((entry, i) => (
            <p key={i} className="text-[9px] font-mono text-slate-500 leading-relaxed">{entry}</p>
          ))}
        </div>
      </div>

      {/* Legend */}
      <div className="flex flex-wrap gap-2 justify-center text-[10px] text-slate-600 font-mono">
        <span>🎺 horn</span>
        <span>🚨 alarm</span>
        <span>🌊 flood</span>
        <span>💥 boom</span>
        <span>👹 monster</span>
        <span>💀 death</span>
        <span>🔥 chaos</span>
      </div>
    </div>
  );
}
