'use client'

import { useEffect, useState, useCallback } from 'react'
import { useSession }          from 'next-auth/react'
import { useRouter }           from 'next/navigation'
import Link                    from 'next/link'
import Image                   from 'next/image'
import { format } from 'date-fns'
import { de }     from 'date-fns/locale'
import Switch  from '@/app/components/Switch'
import Button  from './Button'
import Modal   from './Modal'
import { Match } from '../types/match'
import { useSSEStore } from '@/app/lib/useSSEStore'

type Props = { matchType?: string }

const getTeamLogo = (logo?: string | null) =>
  logo ? `/assets/img/logos/${logo}` : '/assets/img/logos/cs2.webp'

const toDateKey   = (d: Date) => d.toISOString().slice(0, 10)
const weekdayDE   = new Intl.DateTimeFormat('de-DE', { weekday: 'long' })

type TeamOption = { id: string; name: string; logo?: string | null }

/** lokale Date+Time -> ISO (bewahrt lokale Uhrzeit) */
function combineLocalDateTime(dateStr: string, timeStr: string) {
  const [y, m, d] = dateStr.split('-').map(Number)
  const [hh, mm]  = timeStr.split(':').map(Number)
  const dt = new Date(y, (m - 1), d, hh, mm, 0, 0) // lokale Zeit
  return dt.toISOString()
}

/** nächste volle Stunde als Default */
function getNextHourDefaults() {
  const now = new Date()
  now.setMinutes(0, 0, 0)
  now.setHours(now.getHours() + 1)
  const dateStr = now.toISOString().slice(0, 10)
  const timeStr = now.toTimeString().slice(0, 5) // HH:MM
  return { dateStr, timeStr }
}

export default function CommunityMatchList({ matchType }: Props) {
  const { data: session } = useSession()
  const router            = useRouter()
  const { lastEvent }     = useSSEStore()

  const [matches, setMatches] = useState<Match[]>([])
  const [onlyOwn, setOnlyOwn] = useState(false)

  // Modal-States
  const [showCreate, setShowCreate] = useState(false)
  const [teams, setTeams] = useState<TeamOption[]>([])
  const [loadingTeams, setLoadingTeams] = useState(false)
  const [saving, setSaving] = useState(false)

  const [teamAId, setTeamAId] = useState<string>('')
  const [teamBId, setTeamBId] = useState<string>('')
  const [title, setTitle] = useState<string>('')        // auto editierbar
  const [autoTitle, setAutoTitle] = useState(true)
  const [bestOf, setBestOf] = useState<3 | 5>(3)

  // Datum & Uhrzeit
  const defaults = getNextHourDefaults()
  const [matchDateStr, setMatchDateStr] = useState<string>(defaults.dateStr) // YYYY-MM-DD
  const [matchTimeStr, setMatchTimeStr] = useState<string>(defaults.timeStr) // HH:MM

  const teamById = useCallback(
    (id?: string) => teams.find(t => t.id === id),
    [teams]
  )

  useEffect(() => {
    const id = setInterval(() => {
      // force re-render, damit isOpen (Vergleich mit Date.now) neu bewertet wird
      setMatches(m => [...m])
    }, 30_000)
    return () => clearInterval(id)
  }, [])


  // Auto-Titel
  useEffect(() => {
    if (!autoTitle) return
    const a = teamById(teamAId)?.name ?? 'Team A'
    const b = teamById(teamBId)?.name ?? 'Team B'
    setTitle(`${a} vs ${b}`)
  }, [teamAId, teamBId, autoTitle, teamById])

  // Matches laden
  const loadMatches = useCallback(async () => {
    const url = `/api/matches${matchType ? `?type=${encodeURIComponent(matchType)}` : ''}`
    try {
      const r = await fetch(url, { cache: 'no-store' })
      const data = r.ok ? await r.json() : []
      setMatches(data)
    } catch (err) {
      console.error('[MatchList] Laden fehlgeschlagen:', err)
    }
  }, [matchType])

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

  useEffect(() => {
    if (!lastEvent) return

    // auf diese Typen reagieren
    const TRIGGER_TYPES = new Set([
      'match-created',
      'matches-updated',
      'match-deleted',
      'map-vote-updated', // damit das Map-Vote Badge live aktualisiert
    ])

    if (!TRIGGER_TYPES.has(lastEvent.type)) return

    // kurzer Cooldown, falls mehrere Events gleichzeitig eintreffen
    let cancelled = false
    const t = setTimeout(async () => {
      if (!cancelled) await loadMatches()
    }, 150)
    return () => { cancelled = true; clearTimeout(t) }
  }, [lastEvent, loadMatches])

  // Teams laden, wenn Modal aufgeht
  useEffect(() => {
    if (!showCreate || teams.length) return
    ;(async () => {
      setLoadingTeams(true)
      try {
        const res  = await fetch('/api/teams', { cache: 'no-store' })
        const json = await res.json()
        const opts: TeamOption[] = (json.teams ?? []).map((t: any) => ({
          id: t.id, name: t.name, logo: t.logo,
        }))
        setTeams(opts)
      } catch (e) {
        console.error('[MatchList] /api/teams fehlgeschlagen:', e)
        setTeams([])
      } finally {
        setLoadingTeams(false)
      }
    })()
  }, [showCreate, teams.length])

  const resetCreateState = () => {
    setTeamAId('')
    setTeamBId('')
    setTitle('')
    setAutoTitle(true)
    setBestOf(3)
    const d = getNextHourDefaults()
    setMatchDateStr(d.dateStr)
    setMatchTimeStr(d.timeStr)
  }

  const canSave =
    !saving &&
    teamAId &&
    teamBId &&
    teamAId !== teamBId &&
    title.trim().length > 0 &&
    (bestOf === 3 || bestOf === 5) &&
    !!matchDateStr &&
    !!matchTimeStr

  const handleCreate = async () => {
    if (!canSave) return
    setSaving(true)
    try {
      const matchDateISO = combineLocalDateTime(matchDateStr, matchTimeStr)
      const res = await fetch('/api/matches/create', {
        method : 'POST',
        headers: { 'Content-Type': 'application/json' },
        body   : JSON.stringify({
          teamAId,
          teamBId,
          title: title.trim(),
          bestOf,                  // 3 | 5
          matchDate: matchDateISO, // <- Datum+Zeit
          type : matchType,        // optional
        }),
      })
      if (!res.ok) {
        const j = await res.json().catch(() => ({}))
        alert(j.message ?? 'Erstellen fehlgeschlagen')
        return
      }
      setShowCreate(false)
      resetCreateState()
      await loadMatches()
    } catch (e) {
      console.error('[MatchList] Match erstellen fehlgeschlagen:', e)
      alert('Match konnte nicht erstellt werden.')
    } finally {
      setSaving(false)
    }
  }

  // Gruppieren
  const grouped = (() => {
    const sorted = [...matches].sort(
      (a, b) => new Date(a.demoDate).getTime() - new Date(b.demoDate).getTime(),
    )
    const map = new Map<string, Match[]>()
    for (const m of sorted) {
      const key = toDateKey(new Date(m.demoDate))
      map.set(key, [...(map.get(key) ?? []), m])
    }
    return Array.from(map.entries())
  })()

  return (
    <div className="max-w-7xl mx-auto py-8 px-4 space-y-6">
      {/* Kopfzeile */}
      <div className="flex items-center justify-between flex-wrap gap-y-4">
        <h1 className="text-2xl font-bold text-gray-700 dark:text-neutral-300">
          Geplante Matches
        </h1>
        <div className="flex items-center gap-4">
          <Switch
            id="only-own-team"
            checked={onlyOwn}
            onChange={setOnlyOwn}
            labelRight="Nur mein Team anzeigen"
          />
          {session?.user?.isAdmin && (
            <Button color="blue" onClick={() => setShowCreate(true)}>
              Match erstellen
            </Button>
          )}
        </div>
      </div>

      {/* Inhalt */}
      {grouped.length === 0 ? (
        <p className="text-gray-700 dark:text-neutral-300">Keine Matches geplant.</p>
      ) : (
        <div className="grid gap-6 md:grid-cols-2 lg:grid-cols-4">
          {grouped.map(([dateKey, dayMatches], dayIdx) => {
            const dateObj  = new Date(dateKey + 'T00:00:00')
            const dayLabel = `Tag #${dayIdx + 1} – ${weekdayDE.format(dateObj)}`
            return (
              <div key={dateKey} className="flex flex-col gap-4">
                <div className="bg-yellow-300 dark:bg-yellow-500 text-center py-2 font-bold tracking-wider">
                  {dayLabel}<br />{dateKey}
                </div>
                {dayMatches.map((m: Match) => {
                  const started    = new Date(m.demoDate).getTime() <= Date.now()
                  const unfinished = !m.winnerTeam && m.scoreA == null && m.scoreB == null
                  const isLive     = started && unfinished
                  const isOwnTeam  = !!session?.user?.team &&
                                     (m.teamA.id === session.user.team || m.teamB.id === session.user.team)
                  const dimmed = onlyOwn && !isOwnTeam
                  return (
                    <Link
                      key={m.id}
                      href={`/match-details/${m.id}`}
                      className={`
                        relative flex flex-col items-center gap-4 bg-neutral-300 dark:bg-neutral-800
                        text-gray-800 dark:text-white rounded-sm py-4
                        hover:scale-105 hover:bg-neutral-400 hover:dark:bg-neutral-700
                        hover:shadow-md h-[172px]
                        transition-transform transition-opacity duration-300 ease-in-out
                        ${dimmed ? 'opacity-40' : 'opacity-100'}
                      `}
                    >
                      {isLive && (
                        <span className="absolute top-2 px-2 py-0.5 text-xs font-semibold rounded-full bg-red-300 dark:bg-red-500 text-white">
                          LIVE
                        </span>
                      )}

                      {/* Map-Vote Badge */}
                      {m.mapVote && (
                        <span
                          className={`
                            px-2 py-0.5 rounded-full text-[11px] font-semibold
                            ${m.mapVote.isOpen ? 'bg-green-300 dark:bg-green-600 text-white' : 'bg-neutral-200 dark:bg-neutral-700'}
                          `}
                          title={
                            m.mapVote.opensAt
                              ? `Öffnet ${format(new Date(m.mapVote.opensAt), 'dd.MM.yyyy HH:mm', { locale: de })} Uhr`
                              : undefined
                          }
                        >
                          {m.mapVote.isOpen
                            ? (m.mapVote.status === 'completed' ? 'Map-Vote abgeschlossen' : 'Map-Vote offen')
                            : m.mapVote.opensAt
                              ? `Map-Vote ab ${format(new Date(m.mapVote.opensAt), 'HH:mm', { locale: de })} Uhr`
                              : 'Map-Vote bald'}
                        </span>
                      )}

                      <div className="flex w-full justify-around items-center">
                        <div className="flex flex-col items-center w-1/3">
                          <Image src={getTeamLogo(m.teamA.logo)} alt={m.teamA.name} width={48} height={48} className="rounded-full border bg-white" />
                          <span className="mt-2 text-xs">{m.teamA.name}</span>
                        </div>
                        <span className="font-bold">vs</span>
                        <div className="flex flex-col items-center w-1/3">
                          <Image src={getTeamLogo(m.teamB.logo)} alt={m.teamB.name} width={48} height={48} className="rounded-full border bg-white" />
                          <span className="mt-2 text-xs">{m.teamB.name}</span>
                        </div>
                      </div>

                      <div className="flex flex-col items-center space-y-1 mt-2">
                        <span className={`px-3 py-0.5 rounded-full text-sm font-semibold ${isLive ? 'bg-red-300 dark:bg-red-500' : 'bg-yellow-300 dark:bg-yellow-500'}`}>
                          {format(new Date(m.demoDate), 'dd.MM.yyyy', { locale: de })}
                        </span>

                        <span className="flex items-center gap-1 text-xs opacity-80">
                          <svg xmlns="http://www.w3.org/2000/svg" className="w-3.5 h-3.5" fill="currentColor" viewBox="0 0 512 512">
                            <path d="M256 48a208 208 0 1 0 208 208A208.24 208.24 0 0 0 256 48Zm0 384a176 176 0 1 1 176-176 176.2 176.2 0 0 1-176 176Zm80-176h-64V144a16 16 0 0 0-32 0v120a16 16 0 0 0 16 16h80a16 16 0 0 0 0-32Z" />
                          </svg>
                          {format(new Date(m.demoDate), 'HH:mm', { locale: de })} Uhr
                        </span>
                      </div>
                    </Link>
                  )
                })}
              </div>
            )
          })}
        </div>
      )}

      {/* Modal: Match erstellen */}
      <Modal
        id="create-match-modal"
        title="Match erstellen"
        show={showCreate}
        onClose={() => { setShowCreate(false); resetCreateState() }}
        onSave={handleCreate}
        closeButtonTitle={saving ? 'Speichern …' : 'Erstellen'}
        closeButtonColor="blue"
        disableCloseButton={!canSave}
      >
        <div className="space-y-4">
          {/* Team A */}
          <label className="block text-sm font-medium mb-1">Team A</label>
          <select
            className="w-full rounded-lg border border-gray-300 dark:border-neutral-700 bg-white dark:bg-neutral-800 px-3 py-2 text-sm"
            value={teamAId}
            onChange={(e) => setTeamAId(e.target.value)}
            disabled={loadingTeams}
          >
            <option value="">— bitte wählen —</option>
            {teams.map(t => <option key={t.id} value={t.id}>{t.name}</option>)}
          </select>

          {/* Team B */}
          <label className="block text-sm font-medium mb-1 mt-2">Team B</label>
          <select
            className="w-full rounded-lg border border-gray-300 dark:border-neutral-700 bg-white dark:bg-neutral-800 px-3 py-2 text-sm"
            value={teamBId}
            onChange={(e) => setTeamBId(e.target.value)}
            disabled={loadingTeams}
          >
            <option value="">— bitte wählen —</option>
            {teams.map(t => (
              <option key={t.id} value={t.id} disabled={t.id === teamAId}>
                {t.name}
              </option>
            ))}
          </select>

          {/* Titel */}
          <div className="mt-3">
            <label className="block text-sm font-medium mb-1">
              Titel {autoTitle && <span className="ml-2 text-xs text-gray-500">(automatisch)</span>}
            </label>
            <input
              type="text"
              value={title}
              onChange={(e) => { setTitle(e.target.value); setAutoTitle(false) }}
              onFocus={() => setAutoTitle(false)}
              className="w-full rounded-lg border border-gray-300 dark:border-neutral-700 bg-white dark:bg-neutral-800 px-3 py-2 text-sm"
              placeholder="Team A vs Team B"
            />
            {!autoTitle && (
              <button
                type="button"
                className="mt-1 text-xs text-blue-600 hover:underline"
                onClick={() => setAutoTitle(true)}
              >
                Titel wieder automatisch generieren
              </button>
            )}
          </div>

          {/* Datum & Uhrzeit */}
          <div className="grid grid-cols-2 gap-3 mt-3">
            <div>
              <label className="block text-sm font-medium mb-1">Datum</label>
              <input
                type="date"
                value={matchDateStr}
                min={new Date().toISOString().slice(0,10)}
                onChange={(e) => setMatchDateStr(e.target.value)}
                className="w-full rounded-lg border border-gray-300 dark:border-neutral-700 bg-white dark:bg-neutral-800 px-3 py-2 text-sm"
              />
            </div>
            <div>
              <label className="block text-sm font-medium mb-1">Uhrzeit</label>
              <input
                type="time"
                value={matchTimeStr}
                onChange={(e) => setMatchTimeStr(e.target.value)}
                step={300} // 5-Minuten-Schritte
                className="w-full rounded-lg border border-gray-300 dark:border-neutral-700 bg-white dark:bg-neutral-800 px-3 py-2 text-sm"
              />
            </div>
          </div>
          <p className="text-[11px] text-gray-500 dark:text-neutral-400">
            Die Uhrzeit wird als lokale Zeit gespeichert.
          </p>

          {/* Best-of */}
          <div className="mt-3">
            <label className="block text-sm font-medium mb-1">Modus</label>
            <div className="flex gap-2">
              <button
                type="button"
                onClick={() => setBestOf(3)}
                className={`px-3 py-1.5 rounded-lg text-sm border ${bestOf === 3 ? 'bg-blue-600 text-white border-blue-600' : 'bg-transparent border-gray-300 dark:border-neutral-700 text-gray-800 dark:text-neutral-200'}`}
              >
                BO3
              </button>
              <button
                type="button"
                onClick={() => setBestOf(5)}
                className={`px-3 py-1.5 rounded-lg text-sm border ${bestOf === 5 ? 'bg-blue-600 text-white border-blue-600' : 'bg-transparent border-gray-300 dark:border-neutral-700 text-gray-800 dark:text-neutral-200'}`}
              >
                BO5
              </button>
            </div>
          </div>

          {loadingTeams && (
            <p className="text-sm text-gray-500 mt-2">Teams werden geladen …</p>
          )}
          {teamAId && teamBId && teamAId === teamBId && (
            <p className="text-sm text-red-600 mt-2">Bitte zwei unterschiedliche Teams wählen.</p>
          )}
        </div>
      </Modal>
    </div>
  )
}
