'use client'

import * as React from 'react'
import { cn } from '@/lib/utils'
import { X, ChevronLeft, ChevronRight, AlertCircle, CheckCircle2, Info, Loader2, TrendingUp, TrendingDown } from 'lucide-react'

// ─── Button ────────────────────────────────────────────────────────────────
type BtnVariant = 'primary'|'secondary'|'outline'|'ghost'|'destructive'|'success'
type BtnSize    = 'xs'|'sm'|'md'|'lg'
const BV: Record<BtnVariant,string> = {
  primary:     'bg-primary text-primary-foreground hover:bg-primary/90 shadow-sm',
  secondary:   'bg-secondary text-secondary-foreground hover:bg-secondary/80',
  outline:     'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
  ghost:       'hover:bg-accent hover:text-accent-foreground',
  destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
  success:     'bg-green-600 text-white hover:bg-green-700 shadow-sm',
}
const BS: Record<BtnSize,string> = { xs:'h-7 px-2.5 text-xs', sm:'h-8 px-3 text-sm', md:'h-9 px-4 text-sm', lg:'h-11 px-6 text-base' }

interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> { variant?: BtnVariant; size?: BtnSize; loading?: boolean; icon?: React.ReactNode }
export function Button({ variant='primary', size='md', loading, icon, children, className, disabled, ...p }: ButtonProps) {
  return (
    <button className={cn('inline-flex items-center justify-center gap-2 rounded-lg font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 cursor-pointer', BV[variant], BS[size], className)} disabled={disabled||loading} {...p}>
      {loading ? <Loader2 className="w-4 h-4 animate-spin"/> : icon}{children}
    </button>
  )
}

// ─── Badge ─────────────────────────────────────────────────────────────────
type BadgeVar = 'success'|'warning'|'danger'|'info'|'default'|'purple'
const BadgeVars: Record<BadgeVar,string> = {
  success:'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400',
  warning:'bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-400',
  danger: 'bg-red-100   text-red-800   dark:bg-red-900/30   dark:text-red-400',
  info:   'bg-blue-100  text-blue-800  dark:bg-blue-900/30  dark:text-blue-400',
  default:'bg-gray-100  text-gray-700  dark:bg-gray-800     dark:text-gray-400',
  purple: 'bg-purple-100 text-purple-800 dark:bg-purple-900/30 dark:text-purple-400',
}
export function Badge({ variant='default', children, className }: { variant?: BadgeVar; children: React.ReactNode; className?: string }) {
  return <span className={cn('inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium whitespace-nowrap', BadgeVars[variant], className)}>{children}</span>
}

const loanStatusMap: Record<string,BadgeVar> = { ACTIVE:'success',CLOSED:'default',DISBURSED:'info',APPROVED:'info',WRITTEN_OFF:'danger',DECLINED:'danger',CANCELLED:'danger',PENDING_L1:'warning',PENDING_L2:'warning',PENDING_L3:'warning',PENDING_APPRAISAL:'warning',APPRAISED:'info',RESTRUCTURED:'warning',RESCHEDULED:'warning',DRAFT:'default' }
const memberStatusMap: Record<string,BadgeVar> = { ACTIVE:'success',INACTIVE:'default',BLACKLISTED:'danger',DORMANT:'warning',DECEASED:'default',SUSPENDED:'danger' }
const sasraMap: Record<string,BadgeVar> = { NORMAL:'success',WATCH:'warning',SUBSTANDARD:'warning',DOUBTFUL:'danger',LOSS:'danger' }
const ifrsMap: Record<string,BadgeVar> = { STAGE_1:'success',STAGE_2:'warning',STAGE_3:'danger' }
const expenseMap: Record<string,BadgeVar> = { DRAFT:'default',SUBMITTED:'info',PENDING_L1:'warning',PENDING_L2:'warning',APPROVED:'success',DECLINED:'danger',PAID:'success',CANCELLED:'default' }
const payrollMap: Record<string,BadgeVar> = { DRAFT:'default',PENDING_REVIEW:'warning',PENDING_APPROVAL:'warning',APPROVED:'info',PAID:'success',CANCELLED:'danger' }

export function StatusBadge({ status, type='loan' }: { status: string; type?: 'loan'|'member'|'sasra'|'ifrs'|'expense'|'payroll'|'generic' }) {
  const maps: Record<string,Record<string,BadgeVar>> = { loan:loanStatusMap, member:memberStatusMap, sasra:sasraMap, ifrs:ifrsMap, expense:expenseMap, payroll:payrollMap, generic:{} }
  const variant = (maps[type]?.[status] ?? 'default')
  return <Badge variant={variant}>{status.replace(/_/g,' ')}</Badge>
}

// ─── Card ──────────────────────────────────────────────────────────────────
export function Card({ children, className }: { children: React.ReactNode; className?: string }) { return <div className={cn('bg-card border rounded-xl', className)}>{children}</div> }
export function CardHeader({ children, className }: { children: React.ReactNode; className?: string }) { return <div className={cn('flex items-center justify-between px-5 py-4 border-b', className)}>{children}</div> }
export function CardTitle({ children, className }: { children: React.ReactNode; className?: string }) { return <h3 className={cn('font-semibold text-base', className)}>{children}</h3> }
export function CardContent({ children, className }: { children: React.ReactNode; className?: string }) { return <div className={cn('p-5', className)}>{children}</div> }

// ─── Input ─────────────────────────────────────────────────────────────────
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> { label?: string; error?: string; hint?: string; leftIcon?: React.ReactNode; rightIcon?: React.ReactNode }
export function Input({ label, error, hint, leftIcon, rightIcon, className, ...p }: InputProps) {
  return (
    <div className="space-y-1.5">
      {label && <label className="block text-sm font-medium">{label}{p.required && <span className="text-destructive ml-0.5">*</span>}</label>}
      <div className="relative">
        {leftIcon  && <div className="absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground text-sm">{leftIcon}</div>}
        <input className={cn('w-full rounded-lg border bg-background px-3 py-2 text-sm transition-colors placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/30 focus:border-primary disabled:opacity-50',leftIcon&&'pl-9',rightIcon&&'pr-9',error&&'border-destructive',className)} {...p}/>
        {rightIcon && <div className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground text-sm">{rightIcon}</div>}
      </div>
      {hint && !error && <p className="text-xs text-muted-foreground">{hint}</p>}
      {error         && <p className="text-xs text-destructive">{error}</p>}
    </div>
  )
}

// ─── Textarea ──────────────────────────────────────────────────────────────
interface TAProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> { label?: string; error?: string; hint?: string }
export function Textarea({ label, error, hint, className, ...p }: TAProps) {
  return (
    <div className="space-y-1.5">
      {label && <label className="block text-sm font-medium">{label}{p.required && <span className="text-destructive ml-0.5">*</span>}</label>}
      <textarea className={cn('w-full rounded-lg border bg-background px-3 py-2 text-sm transition-colors placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/30 focus:border-primary disabled:opacity-50 min-h-[80px] resize-y',error&&'border-destructive',className)} {...p}/>
      {hint && !error && <p className="text-xs text-muted-foreground">{hint}</p>}
      {error         && <p className="text-xs text-destructive">{error}</p>}
    </div>
  )
}

// ─── Select ────────────────────────────────────────────────────────────────
interface SelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> { label?: string; error?: string; hint?: string; options: { value: string; label: string; disabled?: boolean }[]; placeholder?: string }
export function Select({ label, error, hint, options, placeholder, className, ...p }: SelectProps) {
  return (
    <div className="space-y-1.5">
      {label && <label className="block text-sm font-medium">{label}{p.required && <span className="text-destructive ml-0.5">*</span>}</label>}
      <select className={cn('w-full rounded-lg border bg-background px-3 py-2 text-sm transition-colors focus:outline-none focus:ring-2 focus:ring-primary/30 focus:border-primary disabled:opacity-50',error&&'border-destructive',className)} {...p}>
        {placeholder && <option value="">{placeholder}</option>}
        {options.map(o => <option key={o.value} value={o.value} disabled={o.disabled}>{o.label}</option>)}
      </select>
      {hint && !error && <p className="text-xs text-muted-foreground">{hint}</p>}
      {error         && <p className="text-xs text-destructive">{error}</p>}
    </div>
  )
}

// ─── Modal ─────────────────────────────────────────────────────────────────
const modalSizes: Record<string,string> = { sm:'max-w-sm',md:'max-w-md',lg:'max-w-2xl',xl:'max-w-4xl','2xl':'max-w-6xl','full':'max-w-[95vw]' }
export function Modal({ open, onClose, title, children, size='md', footer }: { open:boolean; onClose:()=>void; title:string; children:React.ReactNode; size?:string; footer?:React.ReactNode }) {
  React.useEffect(() => {
    if (open) document.body.style.overflow = 'hidden'
    else document.body.style.overflow = ''
    return () => { document.body.style.overflow = '' }
  }, [open])
  if (!open) return null
  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4">
      <div className="absolute inset-0 bg-black/60 backdrop-blur-sm" onClick={onClose}/>
      <div className={cn('relative bg-card rounded-2xl shadow-2xl w-full flex flex-col max-h-[90vh]', modalSizes[size])}>
        <div className="flex items-center justify-between px-6 py-4 border-b shrink-0">
          <h2 className="font-semibold text-base">{title}</h2>
          <button onClick={onClose} className="p-1.5 rounded-lg hover:bg-accent text-muted-foreground"><X className="w-4 h-4"/></button>
        </div>
        <div className="overflow-y-auto flex-1 p-6">{children}</div>
        {footer && <div className="px-6 py-4 border-t bg-muted/30 flex items-center justify-end gap-2 shrink-0 rounded-b-2xl">{footer}</div>}
      </div>
    </div>
  )
}

export function ConfirmDialog({ open, onClose, onConfirm, title, message, confirmLabel='Confirm', variant='destructive', loading }: { open:boolean; onClose:()=>void; onConfirm:()=>void; title:string; message:string; confirmLabel?:string; variant?:BtnVariant; loading?:boolean }) {
  return (
    <Modal open={open} onClose={onClose} title={title} size="sm" footer={<><Button variant="outline" size="sm" onClick={onClose}>Cancel</Button><Button variant={variant} size="sm" onClick={onConfirm} loading={loading}>{confirmLabel}</Button></>}>
      <p className="text-sm text-muted-foreground">{message}</p>
    </Modal>
  )
}

// ─── Alert ─────────────────────────────────────────────────────────────────
const alertStyles = { info:{w:'bg-blue-50 border-blue-200 text-blue-800',i:<Info className="w-4 h-4 shrink-0 mt-0.5"/>}, success:{w:'bg-green-50 border-green-200 text-green-800',i:<CheckCircle2 className="w-4 h-4 shrink-0 mt-0.5"/>}, warning:{w:'bg-amber-50 border-amber-200 text-amber-800',i:<AlertCircle className="w-4 h-4 shrink-0 mt-0.5"/>}, error:{w:'bg-red-50 border-red-200 text-red-800',i:<AlertCircle className="w-4 h-4 shrink-0 mt-0.5"/>} }
export function Alert({ variant='info', title, children, className }: { variant?:'info'|'success'|'warning'|'error'; title?: string; children:React.ReactNode; className?: string }) {
  const s = alertStyles[variant]
  return <div className={cn('flex gap-2.5 rounded-lg border p-3.5 text-sm',s.w, className)}>{s.i}<div>{title && <p className="font-medium mb-0.5">{title}</p>}{children}</div></div>
}

// ─── Pagination ────────────────────────────────────────────────────────────
export function Pagination({ page, pages, total, pageSize, onPage }: { page:number; pages:number; total:number; pageSize:number; onPage:(p:number)=>void }) {
  if (pages <= 1) return null
  const from = (page-1)*pageSize+1, to = Math.min(page*pageSize,total)
  const nums: number[] = []
  if (pages <= 7) { for (let i=1;i<=pages;i++) nums.push(i) }
  else if (page <= 4) { for (let i=1;i<=7;i++) nums.push(i) }
  else if (page >= pages-3) { for (let i=pages-6;i<=pages;i++) nums.push(i) }
  else { for (let i=page-3;i<=page+3;i++) nums.push(i) }
  return (
    <div className="flex items-center justify-between px-4 py-3 border-t">
      <p className="text-sm text-muted-foreground">Showing {from}–{to} of {total.toLocaleString()}</p>
      <div className="flex items-center gap-1">
        <button disabled={page===1} onClick={()=>onPage(page-1)} className="p-1.5 rounded hover:bg-accent disabled:opacity-40 disabled:cursor-not-allowed"><ChevronLeft className="w-4 h-4"/></button>
        {nums.map(n=><button key={n} onClick={()=>onPage(n)} className={cn('w-8 h-8 text-sm rounded transition-colors',page===n?'bg-primary text-primary-foreground':'hover:bg-accent')}>{n}</button>)}
        <button disabled={page===pages} onClick={()=>onPage(page+1)} className="p-1.5 rounded hover:bg-accent disabled:opacity-40 disabled:cursor-not-allowed"><ChevronRight className="w-4 h-4"/></button>
      </div>
    </div>
  )
}

// ─── StatCard ──────────────────────────────────────────────────────────────
const scColors: Record<string,string> = { blue:'bg-blue-50 text-blue-600',green:'bg-green-50 text-green-600',amber:'bg-amber-50 text-amber-600',red:'bg-red-50 text-red-600',purple:'bg-purple-50 text-purple-600',teal:'bg-teal-50 text-teal-600' }
export function StatCard({ label,value,sub,icon,trend,trendValue,color='blue',onClick,className }: { label:string;value:string|number;sub?:string;icon:React.ReactNode;trend?:'up'|'down';trendValue?:string;color?:string;onClick?:()=>void;className?:string }) {
  return (
    <div onClick={onClick} className={cn('bg-card border rounded-xl p-5 flex flex-col gap-1',onClick&&'cursor-pointer hover:shadow-md transition-shadow',className)}>
      <div className="flex items-start justify-between mb-1">
        <p className="text-xs font-medium text-muted-foreground uppercase tracking-wide">{label}</p>
        <div className={cn('p-2 rounded-lg',scColors[color]||scColors.blue)}>{icon}</div>
      </div>
      <p className="text-2xl font-bold text-foreground">{value}</p>
      {sub && <p className="text-xs text-muted-foreground">{sub}</p>}
      {trend && trendValue && <p className={cn('text-xs font-medium mt-1',trend==='up'?'text-green-600':'text-red-500')}>{trend==='up'?<TrendingUp className="inline w-3 h-3 mr-0.5"/>:<TrendingDown className="inline w-3 h-3 mr-0.5"/>}{trendValue}</p>}
    </div>
  )
}

// ─── PageHeader ────────────────────────────────────────────────────────────
export function PageHeader({ title,description,icon,actions }: { title:string;description?:string;icon?:React.ReactNode;actions?:React.ReactNode }) {
  return (
    <div className="flex items-start justify-between gap-4">
      <div className="flex items-center gap-2.5"><div className="text-primary">{icon}</div><div><h1 className="text-xl font-semibold">{title}</h1>{description&&<p className="text-sm text-muted-foreground mt-0.5">{description}</p>}</div></div>
      {actions&&<div className="flex items-center gap-2 shrink-0">{actions}</div>}
    </div>
  )
}

// ─── Tabs ──────────────────────────────────────────────────────────────────
export function Tabs({ tabs,active,onChange }: { tabs:{id:string;label:string;count?:number;icon?:React.ReactNode}[];active:string;onChange:(id:string)=>void }) {
  return (
    <div className="flex gap-1 border-b overflow-x-auto">
      {tabs.map(t=>(
        <button key={t.id} onClick={()=>onChange(t.id)} className={cn('flex items-center gap-1.5 px-4 py-2.5 text-sm font-medium transition-colors border-b-2 whitespace-nowrap',active===t.id?'border-primary text-primary':'border-transparent text-muted-foreground hover:text-foreground hover:border-border')}>
          {t.icon}{t.label}{t.count!==undefined&&<span className={cn('rounded-full px-1.5 py-0.5 text-xs',active===t.id?'bg-primary/10 text-primary':'bg-muted text-muted-foreground')}>{t.count}</span>}
        </button>
      ))}
    </div>
  )
}

// ─── EmptyState ────────────────────────────────────────────────────────────
export function EmptyState({ icon,title,description,action }: { icon:React.ReactNode;title:string;description?:string;action?:React.ReactNode }) {
  return (
    <div className="flex flex-col items-center justify-center py-16 px-4 text-center">
      <div className="text-muted-foreground/30 mb-4">{icon}</div>
      <h3 className="font-medium text-foreground mb-1">{title}</h3>
      {description&&<p className="text-sm text-muted-foreground mb-4 max-w-xs">{description}</p>}
      {action}
    </div>
  )
}

// ─── Skeleton & Spinner ────────────────────────────────────────────────────
export function Skeleton({ className }: { className?: string }) { return <div className={cn('animate-pulse rounded bg-muted',className)}/> }
export function LoadingSpinner({ message }: { message?: string }) {
  return <div className="flex flex-col items-center justify-center py-20 gap-3"><Loader2 className="w-8 h-8 animate-spin text-primary"/>{message&&<p className="text-sm text-muted-foreground">{message}</p>}</div>
}

// ─── Toggle ────────────────────────────────────────────────────────────────
export function Toggle({ checked,onChange,label,description,disabled }: { checked:boolean;onChange:(v:boolean)=>void;label?:string;description?:string;disabled?:boolean }) {
  return (
    <div className={cn('flex items-center justify-between gap-4',disabled&&'opacity-50')}>
      {(label||description)&&<div>{label&&<p className="text-sm font-medium">{label}</p>}{description&&<p className="text-xs text-muted-foreground">{description}</p>}</div>}
      <button type="button" onClick={()=>!disabled&&onChange(!checked)} className={cn('relative inline-flex h-5 w-9 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors',checked?'bg-primary':'bg-muted',disabled&&'cursor-not-allowed')}>
        <span className={cn('inline-block h-4 w-4 rounded-full bg-white shadow-sm transition-transform',checked?'translate-x-4':'translate-x-0')}/>
      </button>
    </div>
  )
}

// ─── Misc helpers ──────────────────────────────────────────────────────────
export function SectionDivider({ label }: { label: string }) {
  return <div className="flex items-center gap-3 my-4"><div className="h-px flex-1 bg-border"/><span className="text-xs font-medium text-muted-foreground uppercase tracking-wider">{label}</span><div className="h-px flex-1 bg-border"/></div>
}
export function FormGrid({ children,cols=2 }: { children:React.ReactNode; cols?:1|2|3 }) {
  return <div className={cn('grid gap-4',cols===1?'grid-cols-1':cols===2?'grid-cols-1 sm:grid-cols-2':'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3')}>{children}</div>
}
export function Amount({ value,currency='KES',className,size='md' }: { value:number|string|null|undefined;currency?:string;className?:string;size?:'sm'|'md'|'lg'|'xl' }) {
  const n = typeof value==='string'?parseFloat(value):(value??0)
  const sz = { sm:'text-sm',md:'text-base',lg:'text-lg font-semibold',xl:'text-2xl font-bold' }[size]
  return <span className={cn(sz,className)}>{currency} {isNaN(n)?'—':n.toLocaleString('en-KE',{minimumFractionDigits:2,maximumFractionDigits:2})}</span>
}
export function InfoRow({ label,value,className }: { label:string;value:React.ReactNode;className?:string }) {
  return <div className={cn('flex flex-col sm:flex-row sm:items-center gap-0.5 sm:gap-3',className)}><span className="text-xs font-medium text-muted-foreground w-40 shrink-0">{label}</span><span className="text-sm">{value ?? '—'}</span></div>
}
export function InfoGrid({ children,cols=2 }: { children:React.ReactNode;cols?:1|2|3 }) {
  return <div className={cn('grid gap-3',cols===1?'grid-cols-1':cols===2?'grid-cols-1 sm:grid-cols-2':'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3')}>{children}</div>
}
