'use client'

import { useEffect, useMemo, useState } from 'react';
import { useSession } from 'next-auth/react';
import GameSocket from './GameSocket';
import TeamSidebar from './TeamSidebar';
import StaticEffects from './StaticEffects';
import RadarHeader from './RadarHeader';
import RadarCanvas from './RadarCanvas';

import { useAvatarDirectoryStore } from '@/app/lib/useAvatarDirectoryStore';
import { useTelemetryStore } from '@/app/lib/useTelemetryStore';

import { useBombBeep } from './hooks/useBombBeep';
import { useOverview } from './hooks/useOverview';
import { useRadarState } from './hooks/useRadarState';

import { Grenade } from './lib/types';
import { UI } from './lib/ui';
import { teamOfGrenade } from './lib/grenades';
import { BombState } from './lib/types';

const teamIdT  = undefined as string | undefined;
const teamIdCT = undefined as string | undefined;

function makeWsUrl(host?: string, port?: string, path?: string, scheme?: string) {
  const h = (host ?? '').trim() || '127.0.0.1';
  const p = (port ?? '').trim() || '8081';
  const pa = (path ?? '').trim() || '/telemetry';
  const sch = (scheme ?? '').toLowerCase();
  const pageHttps = typeof window !== 'undefined' && window.location.protocol === 'https:';
  const useWss = sch === 'wss' || (sch !== 'ws' && (p === '443' || pageHttps));
  const proto = useWss ? 'wss' : 'ws';
  const portPart = (p === '80' || p === '443') ? '' : `:${p}`;
  return `${proto}://${h}${portPart}${pa}`;
}
const gameUrl = makeWsUrl(
  process.env.NEXT_PUBLIC_CS2_GAME_WS_HOST,
  process.env.NEXT_PUBLIC_CS2_GAME_WS_PORT,
  process.env.NEXT_PUBLIC_CS2_GAME_WS_PATH,
  process.env.NEXT_PUBLIC_CS2_GAME_WS_SCHEME
);

export default function LiveRadar() {
  // Session / User
  const { data: session, status } = useSession();
  const isAuthed = status === 'authenticated';
  const mySteamId: string | null = useMemo(() => {
    const u: any = session?.user;
    const cands = [u?.steamId, u?.steamid, u?.steam_id, u?.id];
    const first = cands.find(Boolean);
    return first ? String(first) : null;
  }, [session?.user]);

  // Avatar store
  const ensureTeamsLoaded = useAvatarDirectoryStore(s => s.ensureTeamsLoaded);
  const avatarVersion = useAvatarDirectoryStore(s => s.version);
  const avatarById = useAvatarDirectoryStore(s => s.byId);

  // Radar state (alles zentrale Zeug)
  const {
    radarWsStatus, setGameWsStatus,
    activeMapKey, setActiveMapKey,
    players, playersRef, hoveredPlayerId, setHoveredPlayerId,
    grenades, trails, deathMarkers,
    bomb, roundPhase, roundEndsAtRef, bombEndsAtRef, defuseRef,
    score, myTeam,
    upsertPlayer, handlePlayersAll, handleGrenades, handleBomb,
    clearRoundArtifacts, scheduleFlush,
  } = useRadarState(mySteamId);

  // Avatare toggle (persist)
  const [useAvatars, setUseAvatars] = useState(false);
  useEffect(() => { try { setUseAvatars(localStorage.getItem('radar.useAvatars') === '1'); } catch {} }, []);
  useEffect(() => { try { localStorage.setItem('radar.useAvatars', useAvatars ? '1' : '0'); } catch {} }, [useAvatars]);

  // Teams preload
  useEffect(() => {
    const ids = [teamIdT, teamIdCT].filter(Boolean) as string[];
    if (ids.length) ensureTeamsLoaded(ids);
  }, [ensureTeamsLoaded]);

  // Map-Key aus Telemetry übernehmen
  const mapKeyFromTelemetry = useTelemetryStore(s => s.mapKey);
  useEffect(() => { if (mapKeyFromTelemetry) setActiveMapKey(mapKeyFromTelemetry); }, [mapKeyFromTelemetry, setActiveMapKey]);

  // overview + mapping
  const { overview, imgSize, setImgSize, currentSrc, srcIdx, setSrcIdx, worldToPx, unitsToPx } =
    useOverview(activeMapKey, players.map(p=>({x:p.x,y:p.y})));
  void overview; void srcIdx; // kept if you want to expose choice UI later

  // Bomb beep state
  const { beepState } = useBombBeep(bomb);
  const bombSecLeft = bombEndsAtRef.current == null ? null : Math.max(0, Math.ceil((bombEndsAtRef.current - Date.now())/1000));
  const bombFinal10 = bombSecLeft != null && bombSecLeft <= 10;

  // helper: grenade filter by team
  const teamOfPlayer = (sid?: string | null): 'T' | 'CT' | string | null => {
    if (!sid) return null;
    return playersRef.current.get(sid)?.team ?? null;
  };
  const shouldShowGrenade = (g: Grenade): boolean => {
    if (myTeam !== 'T' && myTeam !== 'CT') return true;
    const gt = teamOfGrenade(g, teamOfPlayer);
    return gt === myTeam;
  };

  if (!isAuthed) {
    return (
      <div className="h-full w-full grid place-items-center">
        <div className="text-center max-w-sm">
          <h2 className="text-xl font-semibold mb-2">Live Radar</h2>
          <p className="opacity-80">Bitte einloggen, um das Live-Radar zu sehen.</p>
        </div>
      </div>
    );
  }

  return (
    <div className="h-full min-h-0 w-full flex flex-col overflow-hidden">
      {/* Header */}
      <RadarHeader
        useAvatars={useAvatars}
        setUseAvatars={setUseAvatars}
        radarWsStatus={radarWsStatus}
      />

      {/* Unsichtbare WS-Clients */}
      <GameSocket
        url={gameUrl}
        onStatus={setGameWsStatus}
        onMap={(k)=> setActiveMapKey(String(k).toLowerCase())}
        onPlayerUpdate={(p)=> { upsertPlayer(p); scheduleFlush() }}
        onPlayersAll={(m)=> { handlePlayersAll(m); scheduleFlush() }}
        onGrenades={(g)=> { handleGrenades(g); scheduleFlush() }}
        onRoundStart={() => { clearRoundArtifacts(true) }}
        onRoundEnd={() => {
          for (const [id, p] of playersRef.current) playersRef.current.set(id, { ...p, hasBomb: false });
          if (bomb?.status === 'planted') { /* visual cleanup handled in state */ }
          clearRoundArtifacts(true);
        }}
        onBomb={handleBomb((raw:any) => {
          // lokal: normalizeBomb (aus alter Datei) – du kannst es ebenfalls auslagern, falls gewünscht
          const pickVec3 = (src:any) => {
            const p = src?.pos ?? src?.position ?? src?.location ?? src?.coordinates;
            if (Array.isArray(p)) return { x: +p[0]||0, y: +p[1]||0, z: +p[2]||0 };
            if (typeof p === 'string') {
              const [x, y, z] = p.split(',').map(s=>Number(s.trim()));
              return { x:x||0, y:y||0, z:z||0 };
            }
            return { x: +src?.x||0, y: +src?.y||0, z: +src?.z||0 };
          };
          if (!raw) return null;
          const payload = raw.bomb ?? raw.c4 ?? raw;
          const pos = pickVec3(payload);
          const t = String(raw?.type ?? '').toLowerCase();
          if (t === 'bomb_beginplant' || t === 'bomb_abortplant') return null;

          let status: BombState['status'] = 'unknown';
          const s = String(payload?.status ?? payload?.state ?? '').toLowerCase();
          if (s.includes('planted')) status = 'planted';
          else if (s.includes('drop')) status = 'dropped';
          else if (s.includes('carry')) status = 'carried';
          else if (s.includes('defus')) status = 'defusing';
          if (payload?.planted) status = 'planted';
          if (payload?.dropped) status = 'dropped';
          if (payload?.carried) status = 'carried';
          if (payload?.defusing) status = 'defusing';
          if (payload?.defused) status = 'defused';

          if (t === 'bomb_planted') status = 'planted';
          if (t === 'bomb_dropped') status = 'dropped';
          if (t === 'bomb_pickup') status = 'carried';
          if (t === 'bomb_begindefuse') status = 'defusing';
          if (t === 'bomb_abortdefuse') status = 'planted';
          if (t === 'bomb_defused') status = 'defused';

          const x = Number.isFinite(pos.x) ? pos.x : NaN;
          const y = Number.isFinite(pos.y) ? pos.y : NaN;
          const z = Number.isFinite(pos.z) ? pos.z : NaN;
          return { x, y, z, status, changedAt: Date.now() };
        })}
      />

      {/* Inhalt */}
      <div className="flex-1 min-h-0 grid grid-cols-[minmax(240px,340px)_1fr_minmax(240px,340px)] gap-4">
        {/* Left: T */}
        {myTeam !== 'CT' && (
          <TeamSidebar
            team="T"
            teamId={teamIdT}
            players={players
              .filter(p => p.team === 'T' && (!myTeam || p.team === myTeam))
              .map(p => ({
                id: p.id, name: p.name, hp: p.hp, armor: p.armor, helmet: p.helmet,
                defuse: p.defuse, hasBomb: p.hasBomb, alive: p.alive,
                activeWeapon: p.activeWeapon || null,
                weapons: p.weapons || null,
                grenades: p.nades || null,
              }))
            }
            // @ts-ignore
            showAvatars={useAvatars}
            // @ts-ignore
            avatarsById={avatarById}
            onHoverPlayer={setHoveredPlayerId}
          />
        )}

        {/* Center: Radar */}
        <RadarCanvas
          activeMapKey={activeMapKey}
          currentSrc={currentSrc}
          onImgLoad={(img)=> setImgSize({ w: img.naturalWidth, h: img.naturalHeight })}
          onImgError={() => {}}
          imgSize={imgSize}
          worldToPx={worldToPx}
          unitsToPx={unitsToPx}
          players={players}
          grenades={grenades}
          trails={trails}
          deathMarkers={deathMarkers}
          useAvatars={useAvatars}
          avatarById={avatarById}
          hoveredPlayerId={hoveredPlayerId}
          setHoveredPlayerId={setHoveredPlayerId}
          myTeam={myTeam}
          beepState={beepState}
          bombFinal10={bombFinal10}
          bomb={bomb}
          shouldShowGrenade={shouldShowGrenade}
        />

        {/* Right: CT */}
        {myTeam !== 'T' && (
          <TeamSidebar
            team="CT"
            align="right"
            teamId={teamIdCT}
            players={players
              .filter(p => p.team === 'CT' && (!myTeam || p.team === myTeam))
              .map(p => ({
                id: p.id, name: p.name, hp: p.hp, armor: p.armor, helmet: p.helmet,
                defuse: p.defuse, hasBomb: p.hasBomb, alive: p.alive,
                activeWeapon: p.activeWeapon || null,
                weapons: p.weapons || null,
                grenades: p.nades || null,
              }))
            }
            // @ts-ignore
            showAvatars={useAvatars}
            // @ts-ignore
            avatarsById={avatarById}
            onHoverPlayer={setHoveredPlayerId}
          />
        )}
      </div>
    </div>
  );
}
