'use client'

import { useEffect, useMemo, useState } from 'react'
import { useSession } from 'next-auth/react'
import TeamCard from './TeamCard'
import type { Team, Player } from '../types/team'
import { useSSEStore } from '@/app/lib/useSSEStore'
import { TEAM_EVENTS, INVITE_EVENTS } from '../lib/sseEvents'

type Props = {
  initialTeams: Team[]
  initialInvitationMap: Record<string, string>
}

/* helpers */
const sortPlayers = (ps: Player[] = []) => [...ps].sort((a, b) => a.steamId.localeCompare(b.steamId))
const eqPlayers = (a: Player[] = [], b: Player[] = []) => {
  if (a.length !== b.length) return false
  for (let i = 0; i < a.length; i++) if (a[i].steamId !== b[i].steamId) return false
  return true
}
const eqTeam = (a: Team, b: Team) => {
  if (a.id !== b.id) return false
  if ((a.name ?? '') !== (b.name ?? '')) return false
  if ((a.logo ?? '') !== (b.logo ?? '')) return false
  if ((a.leader as any) !== (b.leader as any)) return false
  return (
    eqPlayers(sortPlayers(a.activePlayers), sortPlayers(b.activePlayers)) &&
    eqPlayers(sortPlayers(a.inactivePlayers), sortPlayers(b.inactivePlayers))
  )
}
const eqTeamList = (a: Team[], b: Team[]) => {
  if (a.length !== b.length) return false
  const mapA = new Map(a.map(t => [t.id, t]))
  for (const t of b) {
    const x = mapA.get(t.id)
    if (!x || !eqTeam(x, t)) return false
  }
  return true
}
function parseTeamsResponse(raw: any): Team[] {
  if (Array.isArray(raw)) return raw as Team[]
  if (raw && Array.isArray(raw.teams)) return raw.teams as Team[]
  return []
}

export default function NoTeamView({ initialTeams, initialInvitationMap }: Props) {
  const { data: session } = useSession()
  const currentSteamId = session?.user?.steamId || ''
  const { lastEvent } = useSSEStore()

  const [teams, setTeams] = useState<Team[]>(initialTeams)
  const [teamToInvitationId, setTeamToInvitationId] = useState<Record<string, string>>(initialInvitationMap)
  const [query, setQuery] = useState('')
  const [sortBy, setSortBy] = useState<'name-asc' | 'members-desc'>('name-asc')

  const fetchTeamsAndInvitations = async () => {
    try {
      const [teamRes, invitesRes] = await Promise.all([
        fetch('/api/teams', { cache: 'no-store' }),
        fetch('/api/user/invitations', { cache: 'no-store' }),
      ])
      if (!teamRes.ok || !invitesRes.ok) return
      const rawTeams = await teamRes.json()
      const rawInv = await invitesRes.json()
      const nextTeams: Team[] = parseTeamsResponse(rawTeams)

      const mapping: Record<string, string> = {}
      for (const inv of rawInv?.invitations || []) {
        if (inv.type === 'team-join-request') mapping[inv.teamId] = inv.id
      }

      setTeams(prev => (eqTeamList(prev, nextTeams) ? prev : nextTeams))
      setTeamToInvitationId(prev => {
        const same =
          Object.keys(prev).length === Object.keys(mapping).length &&
          Object.keys(prev).every(k => prev[k] === mapping[k])
        return same ? prev : mapping
      })
    } catch (e) {
      console.error('[NoTeamView] fetch error:', e)
    }
  }

  useEffect(() => { fetchTeamsAndInvitations() }, [])
  useEffect(() => {
    if (!lastEvent) return
    const { type, payload } = lastEvent
    if (TEAM_EVENTS.has(type)) {
      if (!payload?.teamId || teams.some(t => t.id === payload.teamId)) fetchTeamsAndInvitations()
      return
    }
    if (INVITE_EVENTS.has(type)) fetchTeamsAndInvitations()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [lastEvent, teams])

  const visibleTeams = useMemo(() => {
    const q = query.trim().toLowerCase()
    let list = q ? teams.filter(t => (t.name ?? '').toLowerCase().includes(q)) : teams.slice()
    if (sortBy === 'name-asc') {
      list.sort((a, b) => (a.name ?? '').localeCompare(b.name ?? '', 'de', { sensitivity: 'base' }))
    } else {
      const count = (t: Team) => (t.activePlayers?.length ?? 0) + (t.inactivePlayers?.length ?? 0)
      list.sort((a, b) => count(b) - count(a))
    }
    return list
  }, [teams, query, sortBy])

  return (
    <div className="space-y-6">
      {/* Header-Panel */}
      <section className="team-find-panel group rounded-xl border border-gray-200 dark:border-neutral-700 bg-white dark:bg-neutral-800 p-4 sm:p-5 shadow-sm relative overflow-hidden">
        {/* Linker Rand: Orbit um linken Panelrand, rotiert vorwärts */}
        <div className="edge-orbit edge-orbit-left" aria-hidden>
          <div className="blob blob-left" />
        </div>
        {/* Rechter Rand: Orbit um rechten Panelrand, rotiert rückwärts */}
        <div className="edge-orbit edge-orbit-right" aria-hidden>
          <div className="blob blob-right" />
        </div>

        <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
          <div className="flex items-start gap-3">
            <div className="shrink-0 inline-flex items-center justify-center rounded-lg bg-blue-50 dark:bg-blue-900/20 w-10 h-10">
              <svg viewBox="0 0 24 24" className="w-5 h-5 text-blue-600 dark:text-blue-300">
                <path fill="currentColor" d="M12 12a5 5 0 1 0-5-5a5 5 0 0 0 5 5Zm0 2c-4.418 0-8 2.239-8 5v1h16v-1c0-2.761-3.582-5-8-5Z"/>
              </svg>
            </div>
            <div>
              <h2 className="text-lg font-semibold text-gray-900 dark:text-white">Finde dein Team</h2>
              <p className="text-sm text-gray-600 dark:text-neutral-400">
                Stöbere durch die Teams oder starte selbst eins – du kannst später jederzeit wechseln.
              </p>
            </div>
          </div>

          <div className="flex items-center gap-2">
            <select
              value={sortBy}
              onChange={e => setSortBy(e.target.value as any)}
              className="px-3 py-2 rounded-lg border border-gray-300 dark:border-neutral-600 bg-white dark:bg-neutral-800 text-sm"
            >
              <option value="name-asc">Sortieren: Name (A–Z)</option>
              <option value="members-desc">Sortieren: Mitglieder (viele → wenige)</option>
            </select>
          </div>
        </div>

        {/* Suche */}
        <div className="mt-4">
          <div className="relative">
            <input
              type="text"
              value={query}
              onChange={e => setQuery(e.target.value)}
              placeholder="Teams suchen …"
              className="w-full pl-10 pr-3 py-2 rounded-lg border border-gray-300 focus:border-blue-500 focus:ring-blue-500 dark:border-neutral-600 dark:bg-neutral-900 dark:text-neutral-100 text-sm"
            />
            <svg className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500 dark:text-neutral-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
              <circle cx="11" cy="11" r="7"></circle>
              <path d="m21 21-4.3-4.3"></path>
            </svg>
          </div>

          <div className="mt-2 text-xs text-gray-500 dark:text-neutral-400">
            {visibleTeams.length} Team{visibleTeams.length === 1 ? '' : 's'} gefunden
          </div>
        </div>
      </section>

      {/* Teamliste */}
      {visibleTeams.length === 0 ? (
        <div className="rounded-lg border border-dashed border-gray-300 dark:border-neutral-600 p-8 text-center text-sm text-gray-600 dark:text-neutral-400">
          Keine Treffer. Passe die Suche oder Sortierung an — oder erstelle ein eigenes Team.
        </div>
      ) : (
        <div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
          {visibleTeams.map(team => (
            <TeamCard
              key={team.id}
              team={team}
              currentUserSteamId={currentSteamId}
              invitationId={teamToInvitationId[team.id]}
              onUpdateInvitation={(teamId, newValue) => {
                setTeamToInvitationId(prev => {
                  const updated = { ...prev }
                  if (!newValue) delete updated[teamId]
                  else if (newValue === 'pending') updated[teamId] = updated[teamId] ?? 'pending'
                  else updated[teamId] = newValue
                  return updated
                })
              }}
              adminMode={false}
            />
          ))}
        </div>
      )}

      {/* Globale Styles nur für dieses Component */}
      <style jsx global>{`
        .team-find-panel {
          --blobSize: 10rem;         /* Größe der Kegel */
          --blur: 2rem;              /* Weichzeichner */
          --rEdge: 36%;              /* Abstand der Kreisbahn vom Rand nach innen */
          --speedL: 22s;             /* Geschwindigkeit links */
          --speedR: 28s;             /* Geschwindigkeit rechts */
          --opacity: 0.8;
        }

        /* Orbit-Container genau am linken/rechten Rand, vertikal zentriert */
        .team-find-panel .edge-orbit {
          position: absolute;
          top: 50%;
          width: 0;
          height: 0;
          pointer-events: none;
          transform-origin: 0 0;
          will-change: transform;
          z-index: 0;
        }
        .team-find-panel .edge-orbit-left {
          left: 0;
          /* rotiert vorwärts (im Uhrzeigersinn) */
          animation: orbit var(--speedL) linear infinite;
        }
        .team-find-panel .edge-orbit-right {
          left: 100%;
          /* an den rechten Rand verschieben, damit der Transform-Ursprung dort liegt */
          transform: translateX(-100%);
          /* rotiert rückwärts (gegen Uhrzeigersinn) */
          animation: orbit var(--speedR) linear infinite reverse;
        }

        /* Die Blobs liegen auf einer Kreisbahn, die vom Rand nach innen zeigt */
        .team-find-panel .blob {
          position: absolute;
          left: 0; top: 0;
          width: var(--blobSize);
          height: var(--blobSize);
          border-radius: 9999px;
          filter: blur(var(--blur));
          transform: translate(-50%, -50%); /* Orbit-Zentrum als Ausgangspunkt */
          will-change: transform;
          opacity: var(--opacity);
          mix-blend-mode: normal;
        }

        /* Linker Blob: vom Rand nach rechts in den Inhalt (positive X) */
        .team-find-panel .edge-orbit-left .blob-left {
          background: rgba(59, 130, 246, 0.14); /* blue-500/14 */
          transform: translate(-50%, -50%) translateX(var(--rEdge));
        }

        /* Rechter Blob: vom Rand nach links in den Inhalt (negative X) */
        .team-find-panel .edge-orbit-right .blob-right {
          background: rgba(99, 102, 241, 0.14); /* indigo-500/14 */
          transform: translate(-50%, -50%) translateX(calc(-1 * var(--rEdge)));
        }

        /* Kreisbewegung */
        @keyframes orbit {
          from { transform: rotate(0deg); }
          to   { transform: rotate(360deg); }
        }

        /* Dark Mode: etwas mehr Punch */
        @media (prefers-color-scheme: dark) {
          .team-find-panel { --blur: 2.25rem; --opacity: 0.9; }
        }

        /* Auf größeren Screens die Bahn etwas weiter hineinziehen */
        @media (min-width: 768px) {
          .team-find-panel { --rEdge: 42%; }
        }
      `}</style>
    </div>
  )
}
