// MapVetoBanner.tsx
'use client'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { useRouter } from 'next/navigation'
import { useSession } from 'next-auth/react'
import { useSSEStore } from '@/app/lib/useSSEStore'
import type { MapVetoState } from '../types/mapveto'

type Props = { match: any; initialNow: number }

export default function MapVetoBanner({ match, initialNow }: Props) {
  const router = useRouter()
  const { data: session } = useSession()
  const { lastEvent } = useSSEStore()

  // ✅ eine Uhr, deterministisch bei Hydration (kommt als Prop vom Server)
  const [now, setNow] = useState(initialNow)

  const [state, setState] = useState<MapVetoState | null>(null)
  const [error, setError] = useState<string | null>(null)

  const load = useCallback(async () => {
    try {
      setError(null)
      const r = await fetch(`/api/matches/${match.id}/mapvote`, { cache: 'no-store' })
      if (!r.ok) {
        const j = await r.json().catch(() => ({}))
        throw new Error(j?.message || 'Laden fehlgeschlagen')
      }
      const json = await r.json()
      if (!json || !Array.isArray(json.steps)) throw new Error('Ungültige Serverantwort (steps fehlt)')
      setState(json)
    } catch (e: any) {
      setState(null)
      setError(e?.message ?? 'Unbekannter Fehler')
    }
  }, [match.id])

  // ✅ tickt NUR im Client, nach Hydration
  useEffect(() => {
    const id = setInterval(() => setNow(Date.now()), 1000)
    return () => clearInterval(id)
  }, [])

  useEffect(() => { load() }, [load])

  // Live-Refresh via SSE
  useEffect(() => {
    if (!lastEvent || lastEvent.type !== 'map-vote-updated') return
    if (lastEvent.payload?.matchId !== match.id) return
    load()
  }, [lastEvent, match.id, load])

  // Öffnet 1h vor Match-/Demotermin (stabil, ohne Date.now() im Render)
  const opensAt = useMemo(() => {
    if (state?.opensAt) return new Date(state.opensAt).getTime()
    const base = new Date(match.matchDate ?? match.demoDate ?? initialNow)
    return base.getTime() - 60 * 60 * 1000
  }, [state?.opensAt, match.matchDate, match.demoDate, initialNow])

  const isOpen   = now >= opensAt
  const msToOpen = Math.max(opensAt - now, 0)

  const current = state?.steps?.[state.currentIndex]
  const whoIsUp = current?.teamId
    ? (current.teamId === match.teamA?.id ? match.teamA?.name : match.teamB?.name)
    : null

  // ⚠️ leader ist bei dir ein Player-Objekt → .steamId vergleichen
  const isLeaderA = !!session?.user?.steamId && match.teamA?.leader?.steamId === session.user.steamId
  const isLeaderB = !!session?.user?.steamId && match.teamB?.leader?.steamId === session.user.steamId
  const isAdmin   = !!session?.user?.isAdmin
  const iCanAct   = Boolean(
    isOpen &&
    !state?.locked &&
    current?.teamId &&
    (isAdmin ||
      (current.teamId === match.teamA?.id && isLeaderA) ||
      (current.teamId === match.teamB?.id && isLeaderB))
  )

  const gotoFullPage = () => router.push(`/match-details/${match.id}/vote`)

  const cardClasses =
    'relative overflow-hidden rounded-xl border bg-white/90 dark:bg-neutral-800/90 ' +
    'dark:border-neutral-700 shadow-sm transition cursor-pointer focus:outline-none ' +
    (isOpen
      ? 'ring-1 ring-blue-500/20 hover:ring-blue-500/30 hover:shadow-md'
      : 'ring-1 ring-neutral-500/10 hover:ring-neutral-500/20 hover:shadow-md')

  return (
    <div
      role="button"
      tabIndex={0}
      onClick={gotoFullPage}
      onKeyDown={(e) => e.key === 'Enter' && gotoFullPage()}
      className={cardClasses}
      aria-label="Map-Vote öffnen"
    >
      {isOpen && <div aria-hidden className="absolute inset-0 z-0 pointer-events-none mapVoteGradient" />}

      <div className="relative z-[1] px-4 py-3 flex items-center justify-between gap-3">
        <div className="flex items-center gap-3 min-w-0">
          <div className="shrink-0 w-9 h-9 rounded-full grid place-items-center bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-200">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" className="w-5 h-5" fill="currentColor">
              <path d="M15 4.5 9 7.5l-6-3v15l6 3 6-3 6 3v-15l-6-3Zm-6 16.5-4-2V6l4 2v13Zm2-13 4-2v13l-4 2V8Z"/>
            </svg>
          </div>

          <div className="min-w-0">
            <div className="font-medium text-gray-900 dark:text-neutral-100">
              Map-Vote
            </div>
            <div className="text-xs text-gray-600 dark:text-neutral-400 truncate">
              Modus: BO{match.bestOf ?? state?.bestOf ?? 3}
              {state?.locked
                ? ' • Auswahl fixiert'
                : isOpen
                  ? (whoIsUp ? ` • am Zug: ${whoIsUp}` : ' • läuft')
                  : ' • startet 1h vor Matchbeginn'}
            </div>
            {error && (
              <div className="text-xs text-red-600 dark:text-red-400 mt-0.5">
                {error}
              </div>
            )}
          </div>
        </div>

        <div className="shrink-0">
          {state?.locked ? (
            <span className="px-2 py-0.5 rounded-full text-[11px] font-semibold bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-200">
              Veto abgeschlossen
            </span>
          ) : isOpen ? (
            <span className="px-2 py-0.5 rounded-full text-[11px] font-semibold bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-200">
              {iCanAct ? 'Jetzt wählen' : 'Map-Vote offen'}
            </span>
          ) : (
            <span className="px-2 py-0.5 rounded-full text-[11px] font-semibold bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-100">
              Öffnet in {formatCountdown(msToOpen)}
            </span>
          )}
        </div>
      </div>

      <style jsx>{`
        @keyframes slide-x {
          from { background-position-x: 0%; }
          to   { background-position-x: 200%; }
        }
        .mapVoteGradient {
          background-image: repeating-linear-gradient(
            90deg,
            rgba(37, 99, 235, 0.20) 0%,
            rgba(37, 99, 235, 0.05) 50%,
            rgba(37, 99, 235, 0.20) 100%
          );
          background-size: 200% 100%;
          background-repeat: repeat-x;
          animation: slide-x 3s linear infinite;
        }
        :global(.dark) .mapVoteGradient {
          background-image: repeating-linear-gradient(
            90deg,
            rgba(37, 99, 235, 0.30) 0%,
            rgba(37, 99, 235, 0.10) 50%,
            rgba(37, 99, 235, 0.30) 100%
          );
        }
        @media (prefers-reduced-motion: reduce) {
          .mapVoteGradient { animation: none; }
        }
      `}</style>
    </div>
  )
}

function formatCountdown(ms: number) {
  if (ms <= 0) return '0:00:00'
  const totalSec = Math.floor(ms / 1000)
  const h = Math.floor(totalSec / 3600)
  const m = Math.floor((totalSec % 3600) / 60)
  const s = totalSec % 60
  const pad = (n:number)=>String(n).padStart(2,'0')
  return `${h}:${pad(m)}:${pad(s)}`
}
