"use client"

import type React from 'react'
import { createContext, useCallback, useContext, useEffect, useRef, useState } from 'react'
import { LiquidCard, CardContent, CardHeader } from '@/components/ui/liquid-glass-card'
import { LiquidButton } from '@/components/ui/liquid-glass-button'
import { cn } from '@/lib/utils'

const toFa = (n: number) => n.toLocaleString('fa-IR')
const STRENGTH_FA: Record<string, string> = { weak: 'ضعیف', moderate: 'متوسط', strong: 'قوی', none: '' }

type Strength = 'none' | 'weak' | 'moderate' | 'strong'
const Strength = { None: 'none' as const, Weak: 'weak' as const, Moderate: 'moderate' as const, Strong: 'strong' as const }

interface FinancialScoreProps { title: string; description: string; initialScore?: number }
interface FinancialScoreButtonProps { children?: React.ReactNode; isOutlined?: boolean; onClick?: () => void }
interface FinancialScoreCardProps { children?: React.ReactNode }
interface FinancialScoreDisplayProps { value: Score; max: number }
interface FinancialScoreHalfCircleProps { value: Score; max: number }
interface FinancialScoreHeaderProps { title?: string; strength?: Strength }

type CounterContextType = { getNextIndex: () => number }
type Score = number | null

class Utils {
  static LOCALE = 'en-US'
  static easings = { easeInOut: 'cubic-bezier(0.65, 0, 0.35, 1)', easeOut: 'cubic-bezier(0.33, 1, 0.68, 1)' }
  static circumference(r: number) { return 2 * Math.PI * r }
  static formatNumber(n: number) { return new Intl.NumberFormat(this.LOCALE).format(n) }
  static getStrength(score: Score, maxScore: number): Strength {
    if (!score) return Strength.None
    const p = score / maxScore
    if (p >= 0.8) return Strength.Strong
    if (p >= 0.4) return Strength.Moderate
    return Strength.Weak
  }
  static randomHash(length = 4): string {
    const chars = 'abcdef0123456789'
    const bytes = crypto.getRandomValues(new Uint8Array(length))
    return [...bytes].map((b) => chars[b % chars.length]).join('')
  }
  static randomInt(min = 0, max = 1): number {
    const value = crypto.getRandomValues(new Uint32Array(1))[0] / 2 ** 32
    return Math.round(min + (max - min) * value)
  }
}

const CounterContext = createContext<CounterContextType | undefined>(undefined)

const CounterProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const counterRef = useRef(0)
  const getNextIndex = useCallback(() => counterRef.current++, [])
  return <CounterContext.Provider value={{ getNextIndex }}>{children}</CounterContext.Provider>
}

const useCounter = () => {
  const context = useContext(CounterContext)
  if (!context) throw new Error('useCounter must be used within a CounterProvider')
  return context.getNextIndex
}

function FinancialScoreButton({ children, onClick }: FinancialScoreButtonProps) {
  return (
    <LiquidButton variant="default" onClick={onClick}
      className="w-full h-11 text-sm py-2 animate-in fade-in slide-in-from-bottom-12 duration-800 delay-300">
      {children}
    </LiquidButton>
  )
}

function FinancialScoreCard({ children }: FinancialScoreCardProps) {
  const getNextIndex = useCounter()
  const indexRef = useRef<number | null>(null)
  const animationRef = useRef<ReturnType<typeof setTimeout>>(undefined)
  const [appearing, setAppearing] = useState(false)

  if (indexRef.current === null) indexRef.current = getNextIndex()

  useEffect(() => {
    const delay = 300 + indexRef.current! * 200
    animationRef.current = setTimeout(() => setAppearing(true), delay)
    return () => clearTimeout(animationRef.current)
  }, [])

  if (!appearing) return null

  return (
    <LiquidCard className="w-full animate-in fade-in slide-in-from-bottom-8 duration-800">
      <CardContent className="p-5">{children}</CardContent>
    </LiquidCard>
  )
}

function FinancialScoreDisplay({ value, max }: FinancialScoreDisplayProps) {
  const hasValue = value !== null
  const digits = hasValue ? toFa(Math.floor(value!)).split('') : []
  const label = hasValue ? `از ${toFa(max)}` : 'بدون امتیاز'

  return (
    <div className="absolute bottom-0 w-full text-center">
      <div className="text-3xl font-bold h-[48px] overflow-hidden relative" style={{ color: '#032340' }}>
        <div className="absolute inset-0">
          {hasValue && digits.map((digit, i) => (
            <span key={i} className="inline-block animate-in slide-in-from-bottom-full duration-800"
              style={{ animationDelay: `${400 + i * 100}ms`, animationDuration: `${800 + i * 300}ms` }}>
              {digit}
            </span>
          ))}
        </div>
      </div>
      <div className="text-xs text-muted-foreground tracking-wide">{label}</div>
    </div>
  )
}

function FinancialScoreHalfCircle({ value, max }: FinancialScoreHalfCircleProps) {
  const strokeRef = useRef<SVGCircleElement>(null)
  const gradId = useRef(`grad-${Utils.randomHash()}`).current
  const radius = 45
  const dist = Utils.circumference(radius)
  const distHalf = dist / 2
  const distFourth = distHalf / 2
  const strokeDasharray = `${distHalf} ${distHalf}`
  const distForValue = Math.min((value as number) / max, 1) * -distHalf
  const strokeDashoffset = value !== null ? distForValue : -distFourth

  // All score gauges use the brand navy (#032340) per design system.
  const colorStops = ['#032340', '#0a3f63', '#021a30']

  useEffect(() => {
    strokeRef.current?.animate(
      [
        { strokeDashoffset: '0', offset: 0 },
        { strokeDashoffset: '0', offset: 400 / 1400 },
        { strokeDashoffset: strokeDashoffset.toString() },
      ],
      { duration: 1400, easing: Utils.easings.easeInOut, fill: 'forwards' },
    )
  }, [value, max, strokeDashoffset])

  return (
    <svg className="block mx-auto w-auto max-w-full h-28" viewBox="0 0 100 50" aria-hidden="true">
      <defs>
        <linearGradient id={gradId} x1="0" y1="0" x2="1" y2="0">
          {colorStops.map((stop, i) => (
            <stop key={i} offset={`${(100 / (colorStops.length - 1)) * i}%`} stopColor={stop} />
          ))}
        </linearGradient>
      </defs>
      <g fill="none" strokeWidth="10" transform="translate(50, 50.5)">
        <circle stroke="#e5e7eb" strokeOpacity="0.4" r={radius} />
        <circle ref={strokeRef} stroke={`url(#${gradId})`} strokeDasharray={strokeDasharray} r={radius} />
      </g>
    </svg>
  )
}

function FinancialScoreHeader({ title, strength }: FinancialScoreHeaderProps) {
  const hasStrength = strength !== Strength.None
  const badgeStyle = {
    [Strength.Weak]:     'bg-red-100 text-red-700',
    [Strength.Moderate]: 'bg-yellow-100 text-yellow-700',
    [Strength.Strong]:   'bg-green-100 text-green-700',
    [Strength.None]:     '',
  }

  return (
    <CardHeader className="flex flex-row items-center justify-between gap-3 pb-4 px-0">
      <h2 className="text-base font-bold truncate" style={{ color: '#032340' }}>{title}</h2>
      {hasStrength && strength && (
        <span className={`text-[10px] font-bold px-2.5 py-0.5 rounded-full whitespace-nowrap ${badgeStyle[strength]}`}>
          {STRENGTH_FA[strength]}
        </span>
      )}
    </CardHeader>
  )
}

function FinancialScore({ title, description, initialScore }: FinancialScoreProps) {
  const [score, setScore] = useState<Score>(initialScore ?? null)
  const hasScore = score !== null
  const max = 100
  const strength = Utils.getStrength(score, max)

  return (
    <FinancialScoreCard>
      <FinancialScoreHeader title={title} strength={strength} />
      <div className="relative mb-5">
        <FinancialScoreHalfCircle value={score} max={max} />
        <FinancialScoreDisplay value={score} max={max} />
      </div>
      <p className="text-muted-foreground text-center text-xs leading-relaxed mb-5 min-h-[3.5rem]">{description}</p>
      <FinancialScoreButton isOutlined={hasScore} onClick={() => !hasScore && setScore(Utils.randomInt(0, max))}>
        {hasScore ? 'جزئیات بیشتر' : 'محاسبه امتیاز'}
      </FinancialScoreButton>
    </FinancialScoreCard>
  )
}

const defaultData: FinancialScoreProps[] = [
  { title: 'Protection Score', description: 'Measures overall security strength. Higher score = better protection.', initialScore: 42 },
  { title: 'Investment Score', description: 'Portfolio alignment with goals. Higher score = better performance.', initialScore: 83 },
  { title: 'Financial Fitness', description: 'Boost financial control in 10 minutes. Free, no credit impact.' },
]

export function FinancialScoreCards({ data = defaultData, className }: { data?: FinancialScoreProps[]; className?: string }) {
  return (
    <div className={cn('grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8', className)} style={{ fontFamily: 'Vazir, sans-serif' }}>
      <CounterProvider>
        {data.map((card, i) => <FinancialScore key={i} {...card} />)}
      </CounterProvider>
    </div>
  )
}
