/* UI primitives: Button, Badge, Card, Modal, Table, Tabs, Sidebar items, Filter, Input, Select */

const { useState, useEffect, useRef, useMemo, useCallback, createContext, useContext } = React;

// ------- Toast (sonner-like) -------
const ToastCtx = createContext(null);
function ToastProvider({ children }) {
  const [toasts, setToasts] = useState([]);
  const push = useCallback((t) => {
    const id = Math.random().toString(36).slice(2);
    setToasts((all) => [...all, { id, ...t }]);
    setTimeout(() => setToasts((all) => all.filter(x => x.id !== id)), t.duration || 3500);
  }, []);
  const api = useMemo(() => ({
    success: (msg, opt) => push({ tone: 'ok', msg, ...opt }),
    error: (msg, opt) => push({ tone: 'err', msg, ...opt }),
    info: (msg, opt) => push({ tone: 'info', msg, ...opt }),
    warn: (msg, opt) => push({ tone: 'warn', msg, ...opt }),
  }), [push]);
  return (
    <ToastCtx.Provider value={api}>
      {children}
      <div className="fixed bottom-4 right-4 z-[200] flex flex-col gap-2 w-[340px] no-print">
        {toasts.map(t => (
          <div key={t.id} className={
            "rounded-xl bg-white shadow-pop border border-line-200 px-4 py-3 flex items-start gap-3 fade-up"
          }>
            <div className={
              'h-7 w-7 rounded-full flex items-center justify-center shrink-0 ' +
              (t.tone === 'ok' ? 'bg-ok-50 text-ok-600' :
               t.tone === 'err' ? 'bg-err-50 text-err-600' :
               t.tone === 'warn' ? 'bg-warn-50 text-warn-600' : 'bg-violet-50 text-violet-600')
            }>
              <Icon name={t.tone === 'ok' ? 'check' : t.tone === 'err' ? 'alertCircle' : 'info'} />
            </div>
            <div className="text-sm text-ink-700 font-medium leading-snug">{t.msg}</div>
          </div>
        ))}
      </div>
    </ToastCtx.Provider>
  );
}
function useToast() { return useContext(ToastCtx); }

// ------- Button -------
function Button({ variant = 'primary', size = 'md', className = '', icon, iconRight, children, as: As = 'button', ...rest }) {
  const sizes = {
    sm: 'h-8 px-3 text-[12.5px] gap-1.5',
    md: 'h-9 px-3.5 text-[13px] gap-2',
    lg: 'h-10 px-4 text-sm gap-2',
  }[size] || '';
  const variants = {
    primary: 'bg-violet-500 hover:bg-violet-600 text-white shadow-card border border-violet-600/30',
    secondary: 'bg-white text-ink-700 border border-line-300 hover:bg-paper-100',
    ghost: 'bg-transparent text-ink-600 hover:bg-paper-200',
    danger: 'bg-err-500 hover:bg-err-600 text-white',
    success: 'bg-ok-500 hover:bg-ok-600 text-white',
    outline: 'border border-violet-500 text-violet-600 hover:bg-violet-50',
    soft: 'bg-violet-50 text-violet-600 hover:bg-violet-100 border border-violet-100',
  }[variant] || '';
  return (
    <As className={`inline-flex items-center justify-center font-semibold rounded-lg transition select-none ${sizes} ${variants} ${className}`} {...rest}>
      {icon && <Icon name={icon} />}
      {children}
      {iconRight && <Icon name={iconRight} />}
    </As>
  );
}

// ------- Icon Button -------
function IconBtn({ icon, label, onClick, className = '', tone='neutral' }) {
  const toneCls = {
    neutral: 'text-ink-500 hover:bg-paper-200 hover:text-ink-700',
    danger: 'text-err-500 hover:bg-err-50',
    primary: 'text-violet-600 hover:bg-violet-50',
  }[tone];
  return (
    <button aria-label={label} onClick={onClick} className={`h-8 w-8 rounded-lg inline-flex items-center justify-center transition ${toneCls} ${className}`}>
      <Icon name={icon} />
    </button>
  );
}

// ------- Badge -------
function Badge({ tone = 'info', children, dot, soft = true, className='' }) {
  const tones = {
    ok: soft ? 'bg-ok-50 text-ok-600 border-ok-500/15' : 'bg-ok-500 text-white',
    err: soft ? 'bg-err-50 text-err-600 border-err-500/15' : 'bg-err-500 text-white',
    warn: soft ? 'bg-warn-50 text-warn-600 border-warn-500/15' : 'bg-warn-500 text-white',
    info: soft ? 'bg-violet-50 text-violet-700 border-violet-200' : 'bg-violet-500 text-white',
    neutral: soft ? 'bg-paper-200 text-ink-600 border-line-200' : 'bg-ink-700 text-white',
  }[tone];
  const dotColor = { ok: 'bg-ok-500', err:'bg-err-500', warn:'bg-warn-500', info:'bg-violet-500', neutral:'bg-ink-400' }[tone];
  return (
    <span className={`pill border ${tones} ${className}`}>
      {dot && <span className={`h-1.5 w-1.5 rounded-full ${dotColor}`}></span>}
      {children}
    </span>
  );
}

// ------- Adquirente badge (with brand dot) -------
function AdqBadge({ id, className='' }) {
  const a = MOCK.adqById(id);
  return (
    <span className={`pill border bg-white border-line-200 text-ink-700 ${className}`}>
      <span className="h-1.5 w-1.5 rounded-full" style={{background: a.cor}}></span>
      {a.nome}
    </span>
  );
}
function BandeiraBadge({ id, className='' }) {
  const b = MOCK.bandById(id);
  return (
    <span className={`pill border bg-white border-line-200 text-ink-700 ${className}`}>
      <span className="h-1.5 w-1.5 rounded-full" style={{background: b.cor}}></span>
      {b.nome}
    </span>
  );
}

// ------- Card -------
function Card({ className = '', children }) {
  return <div className={`bg-white rounded-xl2 card-hl ${className}`}>{children}</div>;
}
function CardHeader({ title, subtitle, right, className='' }) {
  return (
    <div className={`flex items-start justify-between gap-4 px-5 pt-5 ${className}`}>
      <div>
        <div className="text-[15px] font-semibold text-ink-900">{title}</div>
        {subtitle && <div className="text-[12.5px] text-ink-500 mt-0.5">{subtitle}</div>}
      </div>
      {right && <div className="shrink-0">{right}</div>}
    </div>
  );
}

// ------- KPI Card -------
function KpiCard({ label, value, delta, icon, deltaTone = 'ok', sub }) {
  return (
    <Card className="p-5">
      <div className="flex items-center justify-between">
        <div className="text-[12.5px] text-ink-500 font-medium">{label}</div>
        {icon && (
          <div className="h-7 w-7 rounded-lg bg-violet-50 text-violet-600 flex items-center justify-center">
            <Icon name={icon} />
          </div>
        )}
      </div>
      <div className="mt-2 text-[24px] font-semibold text-ink-900 tracking-tight" style={{fontVariantNumeric:'tabular-nums'}}>{value}</div>
      <div className="mt-1 flex items-center gap-2 text-[12.5px]">
        {delta != null && (
          <span className={`inline-flex items-center gap-0.5 font-semibold ${deltaTone === 'ok' ? 'text-ok-600' : deltaTone === 'err' ? 'text-err-600' : 'text-ink-500'}`}>
            <Icon name={deltaTone === 'ok' ? 'trending' : 'trendingDown'} size={12} />
            {delta}
          </span>
        )}
        {sub && <span className="text-ink-400">{sub}</span>}
      </div>
    </Card>
  );
}

// ------- Input -------
function Input({ icon, label, hint, error, className='', containerClassName='', size='md', ...rest }) {
  const sizeCls = { sm: 'h-8 text-[12.5px]', md: 'h-9 text-[13px]', lg: 'h-10 text-sm' }[size];
  return (
    <label className={`block ${containerClassName}`}>
      {label && <div className="text-[12px] font-semibold text-ink-700 mb-1.5">{label}</div>}
      <div className={`relative flex items-center bg-white border border-line-300 rounded-lg ${sizeCls} ring-violet ${error ? 'border-err-500' : ''}`}>
        {icon && <Icon name={icon} className="absolute left-2.5 text-ink-400" />}
        <input {...rest} className={`w-full bg-transparent outline-none px-3 ${icon ? 'pl-8' : ''} ${className}`} />
      </div>
      {hint && !error && <div className="text-[11px] text-ink-400 mt-1">{hint}</div>}
      {error && <div className="text-[11px] text-err-600 mt-1">{error}</div>}
    </label>
  );
}

function Select({ label, value, onChange, options = [], hint, className='', size='md' }) {
  const sizeCls = { sm: 'h-8 text-[12.5px]', md: 'h-9 text-[13px]', lg: 'h-10 text-sm' }[size];
  return (
    <label className={`block ${className}`}>
      {label && <div className="text-[12px] font-semibold text-ink-700 mb-1.5">{label}</div>}
      <div className={`relative bg-white border border-line-300 rounded-lg ${sizeCls} ring-violet`}>
        <select value={value} onChange={e => onChange(e.target.value)}
          className="appearance-none w-full bg-transparent outline-none px-3 pr-8 h-full">
          {options.map(o => (typeof o === 'string'
            ? <option key={o} value={o}>{o}</option>
            : <option key={o.value} value={o.value}>{o.label}</option>))}
        </select>
        <Icon name="chevronDown" className="absolute right-2 top-1/2 -translate-y-1/2 text-ink-400 pointer-events-none" />
      </div>
      {hint && <div className="text-[11px] text-ink-400 mt-1">{hint}</div>}
    </label>
  );
}

function Toggle({ checked, onChange, label, hint }) {
  return (
    <label className="flex items-start gap-3 cursor-pointer">
      <button type="button" onClick={() => onChange(!checked)}
        className={`relative h-5 w-9 rounded-full transition shrink-0 mt-0.5 ${checked ? 'bg-violet-500' : 'bg-line-300'}`}>
        <span className={`absolute top-0.5 ${checked ? 'left-4.5' : 'left-0.5'} transition-all h-4 w-4 bg-white rounded-full shadow`}
              style={{left: checked ? 18 : 2}} />
      </button>
      {(label || hint) && (
        <div>
          {label && <div className="text-[13px] font-medium text-ink-700">{label}</div>}
          {hint && <div className="text-[11.5px] text-ink-400">{hint}</div>}
        </div>
      )}
    </label>
  );
}

// ------- Modal -------
function Modal({ open, onClose, title, children, footer, size = 'md' }) {
  useEffect(() => {
    if (!open) return;
    const h = (e) => { if (e.key === 'Escape') onClose && onClose(); };
    window.addEventListener('keydown', h);
    return () => window.removeEventListener('keydown', h);
  }, [open, onClose]);
  if (!open) return null;
  const w = { sm: 'max-w-md', md: 'max-w-lg', lg: 'max-w-2xl', xl: 'max-w-4xl' }[size];
  return (
    <div className="fixed inset-0 z-[150] bg-ink-900/30 flex items-center justify-center p-4 no-print" onClick={onClose}>
      <div className={`bg-white rounded-xl2 shadow-pop w-full ${w} fade-up`} onClick={e => e.stopPropagation()}>
        <div className="flex items-center justify-between px-5 py-4 border-b border-line-100">
          <div className="text-[15px] font-semibold text-ink-900">{title}</div>
          <IconBtn icon="close" onClick={onClose} label="Fechar" />
        </div>
        <div className="p-5 max-h-[70vh] overflow-y-auto">{children}</div>
        {footer && <div className="px-5 py-3 border-t border-line-100 flex justify-end gap-2 bg-paper-100 rounded-b-xl2">{footer}</div>}
      </div>
    </div>
  );
}

// ------- Confirm helper -------
function useConfirm() {
  const [state, setState] = useState(null);
  const open = useCallback((opts) => new Promise(res => setState({ ...opts, resolve: res })), []);
  const node = state && (
    <Modal open onClose={() => { state.resolve(false); setState(null); }}
      title={state.title || 'Confirmar ação'}
      footer={(
        <>
          <Button variant="secondary" onClick={() => { state.resolve(false); setState(null); }}>Cancelar</Button>
          <Button variant={state.danger ? 'danger' : 'primary'} onClick={() => { state.resolve(true); setState(null); }}>
            {state.confirmLabel || 'Confirmar'}
          </Button>
        </>
      )}>
      <div className="text-[13.5px] text-ink-600 leading-relaxed">{state.message}</div>
    </Modal>
  );
  return [open, node];
}

// ------- Drawer (right side) -------
function Drawer({ open, onClose, title, subtitle, children, width = 'max-w-2xl', footer }) {
  useEffect(() => {
    if (!open) return;
    const h = (e) => e.key === 'Escape' && onClose();
    window.addEventListener('keydown', h);
    return () => window.removeEventListener('keydown', h);
  }, [open, onClose]);
  return (
    <div className={`fixed inset-0 z-[140] ${open ? '' : 'pointer-events-none'} no-print`}>
      <div className={`absolute inset-0 bg-ink-900/30 transition-opacity ${open ? 'opacity-100' : 'opacity-0'}`} onClick={onClose} />
      <div className={`absolute top-0 right-0 bottom-0 w-full ${width} bg-white shadow-pop transition-transform ${open ? 'translate-x-0' : 'translate-x-full'}`}>
        <div className="flex items-center justify-between px-5 py-4 border-b border-line-100">
          <div>
            <div className="text-[15px] font-semibold text-ink-900">{title}</div>
            {subtitle && <div className="text-[12px] text-ink-500 mt-0.5">{subtitle}</div>}
          </div>
          <IconBtn icon="close" onClick={onClose} label="Fechar" />
        </div>
        <div className="overflow-y-auto" style={{height: 'calc(100% - ' + (footer ? '125px' : '57px') + ')'}}>
          {children}
        </div>
        {footer && <div className="absolute bottom-0 inset-x-0 px-5 py-3 border-t border-line-100 bg-paper-100 flex justify-end gap-2">{footer}</div>}
      </div>
    </div>
  );
}

// ------- Tabs -------
function Tabs({ tabs, value, onChange, className='' }) {
  return (
    <div className={`flex items-center gap-1 border-b border-line-200 ${className}`}>
      {tabs.map(t => (
        <button key={t.id} onClick={() => onChange(t.id)}
          className={`relative px-3 h-9 text-[13px] font-medium transition ${value === t.id ? 'text-ink-900' : 'text-ink-500 hover:text-ink-700'}`}>
          {t.label}
          {t.count != null && <span className="ml-1.5 text-[11px] text-ink-400">{t.count}</span>}
          {value === t.id && <span className="absolute left-2 right-2 -bottom-px h-0.5 bg-violet-500 rounded-t"></span>}
        </button>
      ))}
    </div>
  );
}

// ------- Table primitives -------
function Table({ children, className='' }) {
  return (
    <div className={`overflow-x-auto ${className}`}>
      <table className="min-w-full text-[13px]">{children}</table>
    </div>
  );
}
function THead({ children }) {
  return (
    <thead className="text-[11.5px] uppercase tracking-wider text-ink-400 font-semibold bg-paper-100 border-y border-line-200">{children}</thead>
  );
}
function TBody({ children }) { return <tbody className="divide-y divide-line-100">{children}</tbody>; }
function TR({ children, onClick, className='', selected=false }) {
  return <tr onClick={onClick} className={`${onClick ? 'row-hover' : ''} ${selected ? 'bg-violet-50/40' : ''} ${className}`}>{children}</tr>;
}
function TH({ children, className='', align='left' }) {
  return <th className={`px-4 py-2.5 text-${align} font-semibold ${className}`}>{children}</th>;
}
function TD({ children, className='', align='left', mono=false }) {
  return <td className={`px-4 py-3 text-${align} ${mono ? 'font-mono text-[12.5px]' : ''} ${className}`}>{children}</td>;
}

// ------- Search Input (large with kbd) -------
function SearchBar({ placeholder='Buscar', value, onChange, kbd='⌘K', className='' }) {
  return (
    <div className={`relative flex items-center h-9 bg-white border border-line-300 rounded-lg w-full ring-violet ${className}`}>
      <Icon name="search" className="absolute left-3 text-ink-400" />
      <input value={value} onChange={e => onChange(e.target.value)} placeholder={placeholder}
             className="w-full bg-transparent outline-none pl-9 pr-12 text-[13px]" />
      {kbd && <kbd className="absolute right-2 text-[10.5px] font-mono text-ink-400 border border-line-200 bg-paper-100 rounded px-1.5 py-0.5">{kbd}</kbd>}
    </div>
  );
}

// ------- Empty state -------
function Empty({ icon='inbox', title, hint, action }) {
  return (
    <div className="py-16 px-6 flex flex-col items-center text-center">
      <div className="h-12 w-12 rounded-xl bg-violet-50 text-violet-600 flex items-center justify-center mb-3">
        <Icon name={icon} size={22} />
      </div>
      <div className="text-[14px] font-semibold text-ink-900">{title}</div>
      {hint && <div className="text-[12.5px] text-ink-500 max-w-sm mt-1">{hint}</div>}
      {action && <div className="mt-4">{action}</div>}
    </div>
  );
}

// ------- Skeleton -------
function Skeleton({ className='' }) {
  return <div className={`bg-line-100 rounded animate-pulse ${className}`} />;
}

// ------- Pagination -------
function Pagination({ page, pages, onChange, total }) {
  return (
    <div className="flex items-center justify-between px-4 py-3 border-t border-line-100">
      <div className="text-[12.5px] text-ink-500">{total != null && (<>Mostrando <b className="text-ink-700">{Math.min(total, (page-1)*20+1)}–{Math.min(total, page*20)}</b> de <b className="text-ink-700">{MOCK.fmtNum(total)}</b></>)}</div>
      <div className="flex items-center gap-1">
        <Button size="sm" variant="secondary" icon="chevronLeft" onClick={() => onChange(Math.max(1, page-1))} disabled={page <= 1}>Anterior</Button>
        <div className="text-[12.5px] text-ink-500 px-2">Página <b className="text-ink-700">{page}</b> de <b className="text-ink-700">{pages}</b></div>
        <Button size="sm" variant="secondary" iconRight="chevronRight" onClick={() => onChange(Math.min(pages, page+1))} disabled={page >= pages}>Próxima</Button>
      </div>
    </div>
  );
}

// ------- Section -------
function Section({ title, hint, right, children, className='' }) {
  return (
    <section className={className}>
      {(title || right) && (
        <div className="flex items-end justify-between mb-3">
          <div>
            {title && <div className="text-[16px] font-semibold text-ink-900">{title}</div>}
            {hint && <div className="text-[12.5px] text-ink-500">{hint}</div>}
          </div>
          {right}
        </div>
      )}
      {children}
    </section>
  );
}

// ------- Filter Bar -------
function FilterBar({ children, className='' }) {
  return (
    <div className={`flex flex-wrap items-center gap-2 px-4 py-3 border-b border-line-100 bg-white rounded-t-xl2 ${className}`}>
      {children}
    </div>
  );
}

// ------- Page Header (generic) -------
function PageHeader({ title, subtitle, breadcrumb, actions }) {
  return (
    <div className="mb-5">
      {breadcrumb && (
        <div className="text-[12px] text-ink-400 mb-1.5 flex items-center gap-1.5">
          {breadcrumb.map((b, i) => (
            <React.Fragment key={i}>
              {i > 0 && <Icon name="chevronRight" size={12} className="text-ink-300" />}
              <span className={i === breadcrumb.length - 1 ? 'text-ink-600 font-medium' : ''}>{b}</span>
            </React.Fragment>
          ))}
        </div>
      )}
      <div className="flex items-end justify-between gap-4 flex-wrap">
        <div>
          <h1 className="text-[22px] font-semibold text-ink-900 tracking-tight">{title}</h1>
          {subtitle && <div className="text-[13px] text-ink-500 mt-0.5">{subtitle}</div>}
        </div>
        {actions && <div className="flex items-center gap-2">{actions}</div>}
      </div>
    </div>
  );
}

// ------- Hero brand -------
function PactoLogo({ size=22, compact=false, dark=false }) {
  return (
    <div className="inline-flex items-center gap-2">
      <span className="relative inline-flex items-center justify-center h-7 w-7 rounded-lg shadow-card"
            style={{background:'linear-gradient(135deg, var(--accent-500) 0%, var(--accent-600) 100%)'}}>
        <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="white" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
          <path d="M6 20V6h6a4 4 0 010 8H8" />
          <path d="M14 14l4 6" opacity="0.7" />
        </svg>
      </span>
      {!compact && (
        <span className={`font-bold tracking-tight ${dark ? 'text-white' : 'text-ink-900'}`} style={{fontSize: size}}>
          PACTO <span className="text-violet-500">PAY</span>
        </span>
      )}
    </div>
  );
}

// ------- Money formatting display -------
function Money({ value, mono=true, className='', size }) {
  return <span className={`${mono ? 'tabular-nums' : ''} ${className}`} style={{fontSize: size}}>{MOCK.fmtBRL(value)}</span>;
}

// ------- Dot status -------
function StatusDot({ tone='ok', label, className='' }) {
  const colors = { ok: 'bg-ok-500', warn:'bg-warn-500', err:'bg-err-500', info:'bg-violet-500' };
  return (
    <span className={`inline-flex items-center gap-1.5 text-[12.5px] text-ink-600 ${className}`}>
      <span className={`h-1.5 w-1.5 rounded-full ${colors[tone]} ${tone==='ok'?'':'pulse-dot'}`}></span>
      {label}
    </span>
  );
}

// ------- Spread chart helpers -------
const Charts = (typeof window !== 'undefined') ? window.Recharts : {};

// Sparkline area
function Sparkline({ data, dataKey='v', color='var(--accent-500)', height=40 }) {
  const { AreaChart, Area, ResponsiveContainer, defs } = Charts;
  return (
    <ResponsiveContainer width="100%" height={height}>
      <AreaChart data={data}>
        <defs>
          <linearGradient id={`sp-${dataKey}-${color}`} x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor={color} stopOpacity={0.3} />
            <stop offset="100%" stopColor={color} stopOpacity={0} />
          </linearGradient>
        </defs>
        <Area type="monotone" dataKey={dataKey} stroke={color} strokeWidth={1.75} fill={`url(#sp-${dataKey}-${color})`} />
      </AreaChart>
    </ResponsiveContainer>
  );
}

// Export everything
Object.assign(window, {
  Avatar: function Avatar({ name = '', size = 32, className = '' }) {
    const initials = name.split(/\s+/).filter(Boolean).slice(0,2).map(s => s[0]).join('').toUpperCase() || '·';
    const hash = name.split('').reduce((s,c)=>s+c.charCodeAt(0),0);
    const palette = ['#635BFF','#4F46E5','#0EAF9E','#0066FF','#C75F00','#00A65A','#DF1B41'];
    const bg = palette[hash % palette.length];
    return (
      <div className={'rounded-full text-white font-bold flex items-center justify-center shrink-0 ' + className}
           style={{width:size, height:size, background:bg, fontSize: Math.max(10, size*0.38)}}>{initials}</div>
    );
  },
  ToastProvider, useToast,
  Button, IconBtn, Badge, AdqBadge, BandeiraBadge,
  Card, CardHeader, KpiCard,
  Input, Select, Toggle,
  Modal, useConfirm, Drawer, Tabs,
  Table, THead, TBody, TR, TH, TD,
  SearchBar, Empty, Skeleton, Pagination,
  Section, FilterBar, PageHeader, PactoLogo,
  Money, StatusDot, Sparkline,
  useState, useEffect, useRef, useMemo, useCallback
});
