'use client'
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from '@/components/ui/card'
import {
  type ChartConfig,
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
} from '@/components/ui/chart'
import { Slider } from '@/components/ui/slider'
import type { SelectGames } from '@/server/db/types'
import { useState } from 'react'
import { CartesianGrid, Line, LineChart, XAxis, YAxis } from 'recharts'

const chartConfig = {
  winrate: {
    label: 'Winrate',
    color: 'var(--color-emerald-500)',
  },
} satisfies ChartConfig

export function WinrateTrendChart({ games }: { games: SelectGames[] }) {
  const [gamesWindow, setGamesWindow] = useState(30)

  // Sort games by date (oldest to newest)
  const sortedGames = [...games]
    .sort((a, b) => a.gameTime.getTime() - b.gameTime.getTime())
    .filter((game) => game.result === 'win' || game.result === 'loss')

  // Calculate rolling winrate
  const chartData = calculateRollingWinrate(sortedGames, gamesWindow)

  return (
    <Card>
      <CardHeader className='flex flex-row items-center justify-between'>
        <div>
          <CardTitle>Winrate Trends</CardTitle>
          <CardDescription>Rolling winrate over time</CardDescription>
        </div>
        <div className='flex w-[200px] flex-col gap-2'>
          <div className='flex items-center justify-between'>
            <span className='text-muted-foreground text-sm'>
              Window size: {gamesWindow} games
            </span>
          </div>
          <Slider
            value={[gamesWindow]}
            onValueChange={(value) => setGamesWindow(value[0] ?? 0)}
            min={5}
            max={Math.min(100, games.length)}
            step={1}
          />
        </div>
      </CardHeader>
      <CardContent className={'p-2'}>
        <ChartContainer config={chartConfig}>
          <LineChart
            accessibilityLayer
            data={chartData}
            margin={{
              left: 12,
              right: 12,
            }}
          >
            <CartesianGrid vertical={false} />
            <XAxis
              dataKey='date'
              tickLine={false}
              axisLine={false}
              tickMargin={8}
              tickFormatter={(value) =>
                new Date(value).toLocaleDateString('en-US', {
                  month: 'short',
                  day: 'numeric',
                })
              }
            />
            <YAxis
              dataKey={'winrate'}
              width={40}
              tickLine={false}
              axisLine={false}
              tickFormatter={(value) => `${value}%`}
              domain={[0, 100]}
            />
            <ChartTooltip
              cursor={false}
              content={
                <ChartTooltipContent
                  hideLabel
                  formatter={(value, name, entry) => {
                    const date = new Date(entry.payload.date)
                    const formattedDate = date.toLocaleDateString('en-US', {
                      year: 'numeric',
                      month: 'long',
                      day: 'numeric',
                    })
                    return (
                      <div className='flex flex-col'>
                        <span>{value}%</span>
                        <span className='text-muted-foreground'>
                          {formattedDate}
                        </span>
                      </div>
                    )
                  }}
                />
              }
            />
            <Line
              dataKey='winrate'
              type='natural'
              stroke='var(--color-emerald-500)'
              strokeWidth={2}
              dot={false}
            />
          </LineChart>
        </ChartContainer>
      </CardContent>
      <CardFooter className='flex-col items-start gap-2 text-sm'>
        <div className='text-muted-foreground leading-none'>
          Showing rolling winrate over the last {gamesWindow} games
        </div>
      </CardFooter>
    </Card>
  )
}

function calculateRollingWinrate(
  games: SelectGames[],
  windowSize: number
): { date: Date; winrate: number }[] {
  if (games.length === 0 || windowSize <= 0) return []

  // Use all games if windowSize is greater than the number of games
  const effectiveWindowSize = Math.min(windowSize, games.length)

  const result: { date: Date; winrate: number }[] = []

  // We need at least windowSize games to start calculating
  for (let i = effectiveWindowSize - 1; i < games.length; i++) {
    // Get the window of games
    const windowGames = games.slice(
      Math.max(0, i - effectiveWindowSize + 1),
      i + 1
    )

    // Count wins in the window
    const wins = windowGames.filter((game) => game.result === 'win').length

    // Calculate winrate as percentage
    const winrate = Math.round((wins / windowGames.length) * 100)

    // Add data point
    if (games[i]) {
      result.push({
        date: games[i]!.gameTime,
        winrate: winrate,
      })
    }
  }

  return result
}
