'use client'

import * as React from 'react'
import { cn } from '@/lib/utils'
import { cva, type VariantProps } from 'class-variance-authority'

// Trend icons
const TrendUpIcon = () => (
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
    <polyline points="23 6 13.5 15.5 8.5 10.5 1 18" />
    <polyline points="17 6 23 6 23 12" />
  </svg>
)

const TrendDownIcon = () => (
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
    <polyline points="23 18 13.5 8.5 8.5 13.5 1 6" />
    <polyline points="17 18 23 18 23 12" />
  </svg>
)

const statCardVariants = cva(
  'relative flex flex-col gap-2 p-5 rounded-xl border transition-all',
  {
    variants: {
      variant: {
        default: 'bg-card border-border',
        muted: 'bg-muted/50 border-transparent',
        glass: 'bg-card/80 backdrop-blur-xl border-border/50',
        gradient: 'bg-gradient-to-br from-card to-muted border-border',
        glow: 'bg-card border-border hover:shadow-[0_0_30px_oklch(0.75_0.18_195_/_0.1)] hover:border-primary/30',
      },
    },
    defaultVariants: {
      variant: 'default',
    },
  },
)

interface StatCardProps
  extends React.ComponentProps<'div'>,
    VariantProps<typeof statCardVariants> {
  label: string
  value: string | number
  change?: number
  changeLabel?: string
  icon?: React.ReactNode
  trend?: 'up' | 'down' | 'neutral'
  sparkline?: number[]
}

function StatCard({
  label,
  value,
  change,
  changeLabel,
  icon,
  trend,
  sparkline,
  variant,
  className,
  ...props
}: StatCardProps) {
  const trendColor = trend === 'up' 
    ? 'text-success' 
    : trend === 'down' 
      ? 'text-destructive' 
      : 'text-muted-foreground'

  return (
    <div className={cn(statCardVariants({ variant }), className)} {...props}>
      <div className="flex items-start justify-between">
        <div>
          <p className="text-xs font-medium uppercase tracking-wider text-muted-foreground">
            {label}
          </p>
          <p className="text-2xl font-bold tracking-tight mt-1">{value}</p>
        </div>
        {icon && (
          <div className="size-10 rounded-lg bg-primary/10 text-primary flex items-center justify-center">
            {icon}
          </div>
        )}
      </div>

      {(change !== undefined || sparkline) && (
        <div className="flex items-center justify-between mt-2">
          {change !== undefined && (
            <div className={cn('flex items-center gap-1 text-sm', trendColor)}>
              {trend === 'up' && <TrendUpIcon />}
              {trend === 'down' && <TrendDownIcon />}
              <span className="font-medium">
                {change > 0 && '+'}
                {change}%
              </span>
              {changeLabel && (
                <span className="text-muted-foreground text-xs">
                  {changeLabel}
                </span>
              )}
            </div>
          )}

          {sparkline && (
            <Sparkline data={sparkline} trend={trend} />
          )}
        </div>
      )}
    </div>
  )
}

// Mini sparkline chart
interface SparklineProps {
  data: number[]
  trend?: 'up' | 'down' | 'neutral'
  className?: string
}

function Sparkline({ data, trend, className }: SparklineProps) {
  const max = Math.max(...data)
  const min = Math.min(...data)
  const range = max - min || 1
  
  const points = data.map((value, i) => {
    const x = (i / (data.length - 1)) * 100
    const y = 100 - ((value - min) / range) * 100
    return `${x},${y}`
  }).join(' ')

  const strokeColor = trend === 'up' 
    ? 'stroke-success' 
    : trend === 'down' 
      ? 'stroke-destructive' 
      : 'stroke-primary'

  return (
    <svg 
      viewBox="0 0 100 40" 
      className={cn('w-16 h-8', className)}
      preserveAspectRatio="none"
    >
      <polyline
        points={points}
        fill="none"
        className={cn('stroke-2', strokeColor)}
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  )
}

// Stats Grid
interface StatsGridProps extends React.ComponentProps<'div'> {
  columns?: 2 | 3 | 4
}

function StatsGrid({ columns = 4, className, children, ...props }: StatsGridProps) {
  return (
    <div 
      className={cn(
        'grid gap-4',
        columns === 2 && 'grid-cols-1 sm:grid-cols-2',
        columns === 3 && 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3',
        columns === 4 && 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-4',
        className
      )} 
      {...props}
    >
      {children}
    </div>
  )
}

// XP/Gaming style progress
interface XPBarProps {
  level: number
  currentXP: number
  maxXP: number
  className?: string
}

function XPBar({ level, currentXP, maxXP, className }: XPBarProps) {
  const progress = (currentXP / maxXP) * 100

  return (
    <div className={cn('space-y-2', className)}>
      <div className="flex items-center justify-between text-xs">
        <span className="font-mono text-[oklch(0.88_0.16_85)] font-bold">
          LVL {level}
        </span>
        <span className="font-mono text-muted-foreground">
          {currentXP.toLocaleString()} / {maxXP.toLocaleString()} XP
        </span>
      </div>
      <div className="relative h-3 bg-muted rounded-full overflow-hidden border border-[oklch(0.88_0.16_85_/_0.3)]">
        <div 
          className="h-full bg-gradient-to-r from-[oklch(0.75_0.16_85)] to-[oklch(0.88_0.16_85)] transition-all duration-500 relative"
          style={{ width: `${progress}%` }}
        >
          <div className="absolute inset-0 bg-gradient-to-r from-transparent via-white/20 to-transparent animate-[shimmer_2s_ease-in-out_infinite]" />
        </div>
      </div>
    </div>
  )
}

// Leaderboard entry
interface LeaderboardEntryProps {
  rank: number
  name: string
  avatar?: string
  initials: string
  score: number | string
  highlight?: boolean
  className?: string
}

function LeaderboardEntry({
  rank,
  name,
  avatar,
  initials,
  score,
  highlight = false,
  className,
}: LeaderboardEntryProps) {
  const rankColor = rank === 1 
    ? 'text-[oklch(0.88_0.16_85)]' 
    : rank === 2 
      ? 'text-muted-foreground' 
      : rank === 3 
        ? 'text-[oklch(0.65_0.12_45)]' 
        : 'text-muted-foreground'

  return (
    <div className={cn(
      'flex items-center gap-3 p-3 rounded-lg transition-colors',
      highlight ? 'bg-primary/10 border border-primary/20' : 'hover:bg-muted/50',
      className
    )}>
      <span className={cn('w-6 text-center font-mono font-bold text-sm', rankColor)}>
        {rank}
      </span>
      <div className="size-8 rounded-full bg-gradient-to-br from-primary to-secondary overflow-hidden flex items-center justify-center text-xs font-semibold text-primary-foreground">
        {avatar ? (
          <img src={avatar || "/placeholder.svg"} alt={name} className="size-full object-cover" />
        ) : (
          initials
        )}
      </div>
      <span className="flex-1 font-medium text-sm truncate">{name}</span>
      <span className="font-mono text-sm text-muted-foreground">{score}</span>
    </div>
  )
}

export { 
  StatCard, 
  Sparkline, 
  StatsGrid, 
  XPBar, 
  LeaderboardEntry,
  statCardVariants 
}
