'use client'

import { useEffect, useMemo, useState } from 'react'
import Link from 'next/link'
import { upsertScore } from '@/app/actions/scores'
import { strokesReceived } from '@/lib/handicap'
import { HoleView } from './hole-view'
import { FullGrid } from './full-grid'
import { LeaderboardView } from './leaderboard-view'
import { ScoreEntrySheet } from './score-entry-sheet'
import { ChevronLeft } from 'lucide-react'
import type { Hole, Player, ScoreRow, RoundInfo } from '@/app/(app)/rounds/[id]/scorecard/page'

type View = 'hole' | 'grid' | 'leaderboard'

type EntryState = {
  player: Player
  hole: Hole
}

function buildScoreMap(rows: ScoreRow[]): Record<string, number> {
  return Object.fromEntries(rows.map((r) => [`${r.playerId}-${r.holeId}`, r.strokes]))
}

export function ScorecardView({
  round,
  holes,
  players,
  initialScores,
  currentUserId,
}: {
  round: RoundInfo
  holes: Hole[]
  players: Player[]
  initialScores: ScoreRow[]
  currentUserId: string
}) {
  const [scores, setScores] = useState<Record<string, number>>(buildScoreMap(initialScores))
  const [activeHoleIdx, setActiveHoleIdx] = useState(0)
  const [view, setView] = useState<View>('hole')
  const [entry, setEntry] = useState<EntryState | null>(null)
  const [saving, setSaving] = useState(false)

  const isActive = round.status === 'active'
  const activeHole = holes[activeHoleIdx]

  // ── SSE real-time subscription ─────────────────────────────
  useEffect(() => {
    const es = new EventSource(`/api/rounds/${round.id}/stream`)

    es.onmessage = (event) => {
      try {
        const rows: ScoreRow[] = JSON.parse(event.data)
        setScores(buildScoreMap(rows))
      } catch {
        // ignore parse errors
      }
    }

    return () => es.close()
  }, [round.id])

  // ── Running totals per player ──────────────────────────────
  const runningTotals = useMemo(() => {
    const totals: Record<string, { net: number; gross: number; holesPlayed: number }> = {}
    for (const player of players) {
      let net = 0
      let gross = 0
      let played = 0
      const ch = player.courseHandicap ?? 0
      for (const hole of holes) {
        const g = scores[`${player.userId}-${hole.id}`]
        if (g !== undefined) {
          gross += g
          net += g - strokesReceived(ch, hole.strokeIndex, holes.length)
          played++
        }
      }
      totals[player.userId] = { net, gross, holesPlayed: played }
    }
    return totals
  }, [scores, players, holes])

  // ── Score save with optimistic update ─────────────────────
  async function handleSave(strokes: number) {
    if (!entry) return
    setSaving(true)

    const key = `${entry.player.userId}-${entry.hole.id}`
    const prev = scores[key]

    // Optimistic update
    setScores((s) => ({ ...s, [key]: strokes }))
    setEntry(null)

    const result = await upsertScore(round.id, entry.hole.id, entry.player.userId, strokes)

    if (result.error) {
      // Revert
      setScores((s) => {
        const next = { ...s }
        if (prev === undefined) delete next[key]
        else next[key] = prev
        return next
      })
    }
    setSaving(false)
  }

  function openEntry(player: Player, hole?: Hole) {
    if (!isActive) return
    setEntry({ player, hole: hole ?? activeHole })
  }

  return (
    <div className="flex h-screen flex-col">
      {/* Header */}
      <div className="flex items-center gap-3 border-b px-4 py-3 shrink-0">
        <Link href={`/rounds/${round.id}`}>
          <ChevronLeft className="h-5 w-5" />
        </Link>
        <div className="flex-1 min-w-0">
          <div className="font-semibold truncate">
            {round.name ?? round.course?.name ?? 'Scorecard'}
          </div>
          <div className="text-xs text-muted-foreground">
            {round.tee?.name} tees · {round.holesCount} holes
            {!isActive && (
              <span className="ml-1 text-muted-foreground">(completed)</span>
            )}
          </div>
        </div>
        {saving && (
          <span className="text-xs text-muted-foreground animate-pulse">Saving…</span>
        )}
      </div>

      {/* View tabs */}
      <div className="flex border-b shrink-0">
        {(['hole', 'grid', 'leaderboard'] as View[]).map((v) => (
          <button
            key={v}
            onClick={() => setView(v)}
            className={`flex-1 py-2 text-xs font-medium capitalize transition-colors ${
              view === v
                ? 'border-b-2 border-primary text-primary'
                : 'text-muted-foreground hover:text-foreground'
            }`}
          >
            {v === 'grid' ? 'Full card' : v === 'leaderboard' ? 'Leaderboard' : 'Hole'}
          </button>
        ))}
      </div>

      {/* Main content */}
      <div className="flex-1 overflow-hidden flex flex-col">
        {view === 'hole' && activeHole && (
          <HoleView
            hole={activeHole}
            holeIndex={activeHoleIdx}
            totalHoles={holes.length}
            players={players}
            scores={scores}
            runningTotals={runningTotals}
            isActive={isActive}
            onPrev={() => setActiveHoleIdx((i) => Math.max(0, i - 1))}
            onNext={() => setActiveHoleIdx((i) => Math.min(holes.length - 1, i + 1))}
            onTapScore={(player) => openEntry(player)}
          />
        )}

        {view === 'grid' && (
          <div className="overflow-auto flex-1">
            <FullGrid
              holes={holes}
              players={players}
              scores={scores}
              isActive={isActive}
              onTapScore={(player, hole) => openEntry(player, hole)}
            />
          </div>
        )}

        {view === 'leaderboard' && (
          <div className="overflow-y-auto flex-1">
            <LeaderboardView holes={holes} players={players} scores={scores} />
          </div>
        )}
      </div>

      {/* Score entry sheet */}
      <ScoreEntrySheet
        open={entry !== null}
        hole={entry?.hole ?? null}
        player={entry?.player ?? null}
        currentStrokes={
          entry ? (scores[`${entry.player.userId}-${entry.hole.id}`] ?? null) : null
        }
        onSave={handleSave}
        onClose={() => setEntry(null)}
      />
    </div>
  )
}
