import { auth } from '@/lib/auth'
import { db } from '@/lib/db'
import { rounds, roundPlayers, holes, scores, courses, tees, user } from '@/lib/db/schema'
import { eq, asc } from 'drizzle-orm'
import { redirect, notFound } from 'next/navigation'
import { headers } from 'next/headers'
import { ScorecardView } from '@/components/scorecard/scorecard-view'

export type Hole = {
  id: string
  holeNumber: number
  par: number
  strokeIndex: number
}

export type Player = {
  userId: string
  courseHandicap: number | null
  handicapIndex: string | null
  profile: { id: string; displayName: string; avatarUrl: string | null } | null
}

export type ScoreRow = {
  holeId: string
  playerId: string
  strokes: number
}

export type RoundInfo = {
  id: string
  name: string | null
  date: string
  status: string
  holesCount: number
  createdBy: string
  course: { name: string } | null
  tee: { name: string; color: string } | null
}

export default async function ScorecardPage({
  params,
}: {
  params: Promise<{ id: string }>
}) {
  const { id } = await params
  const session = await auth.api.getSession({ headers: await headers() })
  if (!session) redirect('/login')

  const [round] = await db
    .select({
      id:         rounds.id,
      name:       rounds.name,
      date:       rounds.date,
      status:     rounds.status,
      holesCount: rounds.holesCount,
      createdBy:  rounds.createdBy,
      courseId:   rounds.courseId,
      courseName: courses.name,
      teeName:    tees.name,
      teeColor:   tees.color,
    })
    .from(rounds)
    .innerJoin(courses, eq(rounds.courseId, courses.id))
    .innerJoin(tees, eq(rounds.teeId, tees.id))
    .where(eq(rounds.id, id))
    .limit(1)

  if (!round) notFound()
  if (round.status === 'lobby') redirect(`/rounds/${id}`)

  const holeRows = await db
    .select({
      id:          holes.id,
      holeNumber:  holes.holeNumber,
      par:         holes.par,
      strokeIndex: holes.strokeIndex,
    })
    .from(holes)
    .where(eq(holes.courseId, round.courseId))
    .orderBy(asc(holes.holeNumber))
    .limit(round.holesCount)

  const playerRows = await db
    .select({
      userId:         roundPlayers.userId,
      courseHandicap: roundPlayers.courseHandicap,
      handicapIndex:  roundPlayers.handicapIndex,
      displayName:    user.name,
      avatarUrl:      user.image,
    })
    .from(roundPlayers)
    .innerJoin(user, eq(roundPlayers.userId, user.id))
    .where(eq(roundPlayers.roundId, id))
    .orderBy(roundPlayers.joinedAt)

  const scoreRows = await db
    .select({ holeId: scores.holeId, playerId: scores.playerId, strokes: scores.strokes })
    .from(scores)
    .where(eq(scores.roundId, id))

  const roundInfo: RoundInfo = {
    id:         round.id,
    name:       round.name,
    date:       round.date,
    status:     round.status,
    holesCount: round.holesCount,
    createdBy:  round.createdBy,
    course:     { name: round.courseName },
    tee:        { name: round.teeName, color: round.teeColor },
  }

  const players: Player[] = playerRows.map((p) => ({
    userId:         p.userId,
    courseHandicap: p.courseHandicap,
    handicapIndex:  p.handicapIndex,
    profile: {
      id:          p.userId,
      displayName: p.displayName,
      avatarUrl:   p.avatarUrl,
    },
  }))

  return (
    <ScorecardView
      round={roundInfo}
      holes={holeRows}
      players={players}
      initialScores={scoreRows}
      currentUserId={session.user.id}
    />
  )
}
