'use client'

import * as React from 'react'
import * as ProgressPrimitive from '@radix-ui/react-progress'
import { cva, type VariantProps } from 'class-variance-authority'

import { cn } from '@/lib/utils'

const progressVariants = cva(
  'relative w-full overflow-hidden rounded-full bg-muted',
  {
    variants: {
      size: {
        sm: 'h-1',
        default: 'h-2',
        lg: 'h-3',
        xl: 'h-4',
      },
      variant: {
        default: '',
        gradient: '',
        success: '',
        warning: '',
        danger: '',
      },
    },
    defaultVariants: {
      size: 'default',
      variant: 'default',
    },
  },
)

const indicatorVariants = cva(
  'h-full w-full flex-1 transition-all duration-500 ease-out',
  {
    variants: {
      variant: {
        default: 'bg-primary',
        gradient: 'bg-gradient-to-r from-primary to-secondary',
        success: 'bg-success',
        warning: 'bg-warning',
        danger: 'bg-destructive',
      },
      animated: {
        true: '',
        false: '',
      },
    },
    compoundVariants: [
      {
        animated: true,
        className: 'relative after:absolute after:inset-0 after:bg-gradient-to-r after:from-transparent after:via-white/20 after:to-transparent after:animate-[shimmer_2s_ease-in-out_infinite]',
      },
    ],
    defaultVariants: {
      variant: 'default',
      animated: false,
    },
  },
)

interface ProgressProps
  extends React.ComponentProps<typeof ProgressPrimitive.Root>,
    VariantProps<typeof progressVariants> {
  showValue?: boolean
  animated?: boolean
  label?: string
}

function Progress({
  className,
  value = 0,
  size,
  variant,
  showValue = false,
  animated = false,
  label,
  ...props
}: ProgressProps) {
  return (
    <div className="w-full">
      {(label || showValue) && (
        <div className="mb-2 flex items-center justify-between text-sm">
          {label && <span className="font-medium text-foreground">{label}</span>}
          {showValue && (
            <span className="font-mono text-xs text-muted-foreground">
              {Math.round(value || 0)}%
            </span>
          )}
        </div>
      )}
      <ProgressPrimitive.Root
        data-slot="progress"
        className={cn(progressVariants({ size, variant }), className)}
        {...props}
      >
        <ProgressPrimitive.Indicator
          data-slot="progress-indicator"
          className={cn(indicatorVariants({ variant, animated }))}
          style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
        />
      </ProgressPrimitive.Root>
    </div>
  )
}

// Circular Progress
interface CircularProgressProps {
  value?: number
  size?: number
  strokeWidth?: number
  variant?: 'default' | 'gradient'
  showValue?: boolean
  className?: string
}

function CircularProgress({
  value = 0,
  size = 48,
  strokeWidth = 4,
  variant = 'default',
  showValue = false,
  className,
}: CircularProgressProps) {
  const radius = (size - strokeWidth) / 2
  const circumference = radius * 2 * Math.PI
  const offset = circumference - (value / 100) * circumference

  return (
    <div className={cn('relative inline-flex items-center justify-center', className)}>
      <svg
        width={size}
        height={size}
        className="rotate-[-90deg]"
      >
        <circle
          cx={size / 2}
          cy={size / 2}
          r={radius}
          fill="none"
          stroke="currentColor"
          strokeWidth={strokeWidth}
          className="text-muted"
        />
        <circle
          cx={size / 2}
          cy={size / 2}
          r={radius}
          fill="none"
          stroke={variant === 'gradient' ? 'url(#gradient)' : 'currentColor'}
          strokeWidth={strokeWidth}
          strokeLinecap="round"
          strokeDasharray={circumference}
          strokeDashoffset={offset}
          className={cn(
            'transition-all duration-500 ease-out',
            variant === 'default' && 'text-primary'
          )}
        />
        {variant === 'gradient' && (
          <defs>
            <linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="0%">
              <stop offset="0%" stopColor="oklch(0.75 0.18 195)" />
              <stop offset="100%" stopColor="oklch(0.65 0.25 330)" />
            </linearGradient>
          </defs>
        )}
      </svg>
      {showValue && (
        <span className="absolute font-mono text-xs font-semibold">
          {Math.round(value)}%
        </span>
      )}
    </div>
  )
}

// Indeterminate Loader Bar
function LoaderBar({ className }: { className?: string }) {
  return (
    <div className={cn('relative h-1 w-full overflow-hidden rounded-full bg-muted', className)}>
      <div className="absolute h-full w-1/3 animate-[indeterminate_1.5s_ease-in-out_infinite] rounded-full bg-gradient-to-r from-primary to-secondary" />
    </div>
  )
}

export { Progress, CircularProgress, LoaderBar, progressVariants }
