
// ============================================================
// JuFlow — Shared UI Components
// ============================================================
const { useState, useEffect, useRef, useCallback } = React;
const U = window.JFUtils;

// ─── ICONS (safe wrapper around lucide-react UMD) ─────────
const _LR = window.LucideReact || window.lucideReact || {};
const Icon = ({ name, size = 18, color, strokeWidth = 2, style = {}, className = '' }) => {
  const Comp = _LR[name];
  if (!Comp) return <span style={{ display:'inline-block', width:size, height:size, ...style }} />;
  return <Comp size={size} color={color} strokeWidth={strokeWidth} style={style} className={className} />;
};

// ─── AVATAR ───────────────────────────────────────────────
const Avatar = ({ name, color, size = 36, src, style = {} }) => {
  const bg = color || '#0A1F44';
  const sz = size;
  return (
    <div style={{
      width: sz, height: sz, borderRadius: '50%',
      background: src ? 'transparent' : U.hexToRgba(bg, 0.15),
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontSize: sz * 0.36, fontWeight: 700, color: bg,
      border: `2px solid ${U.hexToRgba(bg, 0.25)}`,
      flexShrink: 0, overflow: 'hidden', ...style
    }}>
      {src
        ? <img src={src} style={{ width:'100%', height:'100%', objectFit:'cover' }} alt={name} />
        : U.initials(name)
      }
    </div>
  );
};

// ─── BADGE (status pill) ──────────────────────────────────
const Badge = ({ status, label, style = {} }) => {
  const colors = U.statusColor(status);
  return (
    <span style={{
      display:'inline-flex', alignItems:'center',
      padding:'2px 10px', borderRadius:20,
      fontSize:12, fontWeight:600,
      background:colors.bg, color:colors.text,
      border:`1px solid ${colors.border}`,
      ...style
    }}>
      {label || U.statusLabel(status)}
    </span>
  );
};

// ─── TAG CHIP ─────────────────────────────────────────────
const TAG_COLORS = {
  'VIP':          { bg:'#FFF7ED', text:'#C2410C', border:'#FED7AA' },
  'Aniversariante': { bg:'#FDF4FF', text:'#7E22CE', border:'#E9D5FF' },
  'Inadimplente': { bg:'#FEF2F2', text:'#B91C1C', border:'#FECACA' },
  'Regular':      { bg:'#F0FDF4', text:'#15803D', border:'#BBF7D0' },
};
const TagChip = ({ tag }) => {
  const c = TAG_COLORS[tag] || { bg:'#F3F4F6', text:'#374151', border:'#D1D5DB' };
  return (
    <span style={{
      display:'inline-flex', alignItems:'center', gap:4,
      padding:'2px 9px', borderRadius:20, fontSize:11, fontWeight:600,
      background:c.bg, color:c.text, border:`1px solid ${c.border}`,
    }}>
      {tag === 'VIP' && '★ '}{tag}
    </span>
  );
};

// ─── BUTTON ───────────────────────────────────────────────
const Button = ({ children, variant='primary', size='md', onClick, disabled, icon, style={}, type='button' }) => {
  const [hovered, setHovered] = useState(false);
  const sizes = { sm:'6px 12px', md:'9px 18px', lg:'12px 24px' };
  const fSizes = { sm:12, md:13, lg:14 };

  const variants = {
    primary:   { bg: hovered ? '#E55A20' : '#FF6B35', color:'#fff', border:'transparent', shadow: hovered ? '0 4px 14px rgba(255,107,53,.35)' : '0 2px 8px rgba(255,107,53,.25)' },
    secondary: { bg: hovered ? '#f0f4f8' : '#fff',    color:'#0A1F44', border:'#E2E8F0',  shadow: 'none' },
    ghost:     { bg: hovered ? '#f0f4f8' : 'transparent', color:'#0A1F44', border:'transparent', shadow:'none' },
    danger:    { bg: hovered ? '#DC2626' : '#EF4444', color:'#fff', border:'transparent', shadow:'none' },
    outline:   { bg:'transparent', color: hovered ? '#FF6B35' : '#0A1F44', border: hovered ? '#FF6B35' : '#CBD5E1', shadow:'none' },
  };
  const v = variants[variant] || variants.primary;

  return (
    <button
      type={type}
      onClick={onClick}
      disabled={disabled}
      onMouseEnter={() => setHovered(true)}
      onMouseLeave={() => setHovered(false)}
      style={{
        display:'inline-flex', alignItems:'center', justifyContent:'center', gap:6,
        padding: sizes[size], borderRadius:8,
        fontSize: fSizes[size], fontWeight:600,
        background: v.bg, color: v.color,
        border: `1px solid ${v.border}`,
        boxShadow: v.shadow,
        cursor: disabled ? 'not-allowed' : 'pointer',
        opacity: disabled ? 0.5 : 1,
        transition:'all .15s ease', outline:'none',
        whiteSpace:'nowrap',
        ...style
      }}
    >
      {icon && <Icon name={icon} size={fSizes[size]+2} color={v.color} />}
      {children}
    </button>
  );
};

// ─── INPUT ────────────────────────────────────────────────
const Input = ({ label, value, onChange, placeholder, type='text', icon, required, error, style={}, inputStyle={}, autoFocus, onKeyDown }) => {
  const [focused, setFocused] = useState(false);
  return (
    <div style={{ display:'flex', flexDirection:'column', gap:5, ...style }}>
      {label && <label style={{ fontSize:13, fontWeight:600, color:'#374151' }}>{label}{required && <span style={{color:'#EF4444'}}> *</span>}</label>}
      <div style={{ position:'relative' }}>
        {icon && <span style={{ position:'absolute', left:10, top:'50%', transform:'translateY(-50%)', pointerEvents:'none', display:'flex' }}>
          <Icon name={icon} size={15} color='#9CA3AF' />
        </span>}
        <input
          type={type}
          value={value}
          onChange={e => onChange && onChange(e.target.value)}
          placeholder={placeholder}
          autoFocus={autoFocus}
          onKeyDown={onKeyDown}
          onFocus={() => setFocused(true)}
          onBlur={() => setFocused(false)}
          style={{
            width:'100%', boxSizing:'border-box',
            padding: icon ? '9px 12px 9px 34px' : '9px 12px',
            borderRadius:8, fontSize:13,
            border:`1.5px solid ${error ? '#EF4444' : focused ? '#FF6B35' : '#E2E8F0'}`,
            outline:'none', color:'#0A1F44', background:'#fff',
            transition:'border-color .15s',
            ...inputStyle
          }}
        />
      </div>
      {error && <span style={{ fontSize:11, color:'#EF4444' }}>{error}</span>}
    </div>
  );
};

// ─── SELECT ───────────────────────────────────────────────
const Select = ({ label, value, onChange, options, placeholder, required, style={} }) => {
  const [focused, setFocused] = useState(false);
  return (
    <div style={{ display:'flex', flexDirection:'column', gap:5, ...style }}>
      {label && <label style={{ fontSize:13, fontWeight:600, color:'#374151' }}>{label}{required && <span style={{color:'#EF4444'}}> *</span>}</label>}
      <select
        value={value}
        onChange={e => onChange && onChange(e.target.value)}
        onFocus={() => setFocused(true)}
        onBlur={() => setFocused(false)}
        style={{
          padding:'9px 12px', borderRadius:8, fontSize:13,
          border:`1.5px solid ${focused ? '#FF6B35' : '#E2E8F0'}`,
          outline:'none', color:'#0A1F44', background:'#fff',
          cursor:'pointer', transition:'border-color .15s',
        }}
      >
        {placeholder && <option value=''>{placeholder}</option>}
        {options.map(opt => (
          <option key={opt.value} value={opt.value}>{opt.label}</option>
        ))}
      </select>
    </div>
  );
};

// ─── TEXTAREA ─────────────────────────────────────────────
const Textarea = ({ label, value, onChange, placeholder, rows=3, style={} }) => {
  const [focused, setFocused] = useState(false);
  return (
    <div style={{ display:'flex', flexDirection:'column', gap:5, ...style }}>
      {label && <label style={{ fontSize:13, fontWeight:600, color:'#374151' }}>{label}</label>}
      <textarea
        value={value}
        onChange={e => onChange && onChange(e.target.value)}
        placeholder={placeholder}
        rows={rows}
        onFocus={() => setFocused(true)}
        onBlur={() => setFocused(false)}
        style={{
          padding:'9px 12px', borderRadius:8, fontSize:13, resize:'vertical',
          border:`1.5px solid ${focused ? '#FF6B35' : '#E2E8F0'}`,
          outline:'none', color:'#0A1F44', background:'#fff',
          transition:'border-color .15s', fontFamily:'inherit',
        }}
      />
    </div>
  );
};

// ─── TABS ─────────────────────────────────────────────────
const Tabs = ({ tabs, activeTab, onTabChange, style={} }) => (
  <div style={{ display:'flex', gap:2, borderBottom:'2px solid #E2E8F0', ...style }}>
    {tabs.map(tab => (
      <button
        key={tab.id}
        onClick={() => onTabChange(tab.id)}
        style={{
          display:'flex', alignItems:'center', gap:6,
          padding:'10px 16px', fontSize:13, fontWeight:600,
          color: activeTab === tab.id ? '#FF6B35' : '#6B7280',
          borderBottom: activeTab === tab.id ? '2px solid #FF6B35' : '2px solid transparent',
          marginBottom:'-2px', background:'none', border:'none',
          cursor:'pointer', transition:'all .15s', whiteSpace:'nowrap',
        }}
      >
        {tab.icon && <Icon name={tab.icon} size={15} />}
        {tab.label}
        {tab.count !== undefined && (
          <span style={{
            padding:'1px 7px', borderRadius:20, fontSize:11,
            background: activeTab===tab.id ? '#FFF0EA' : '#F3F4F6',
            color: activeTab===tab.id ? '#FF6B35' : '#6B7280',
          }}>{tab.count}</span>
        )}
      </button>
    ))}
  </div>
);

// ─── MODAL ────────────────────────────────────────────────
const Modal = ({ open, onClose, title, children, width = 560, footer }) => {
  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
      onClick={e => { if (e.target === e.currentTarget) onClose(); }}
      style={{
        position:'fixed', inset:0, zIndex:1000,
        background:'rgba(10,31,68,.55)', backdropFilter:'blur(4px)',
        display:'flex', alignItems:'center', justifyContent:'center',
        padding:16,
      }}
    >
      <div style={{
        background:'#fff', borderRadius:16,
        width:'100%', maxWidth:width,
        maxHeight:'90vh', overflow:'hidden',
        display:'flex', flexDirection:'column',
        boxShadow:'0 24px 64px rgba(10,31,68,.18)',
        animation:'modalIn .2s ease',
      }}>
        {/* Header */}
        <div style={{
          display:'flex', alignItems:'center', justifyContent:'space-between',
          padding:'20px 24px', borderBottom:'1px solid #E2E8F0', flexShrink:0,
        }}>
          <h2 style={{ fontSize:17, fontWeight:700, color:'#0A1F44', margin:0 }}>{title}</h2>
          <button onClick={onClose} style={{
            width:32, height:32, borderRadius:8, border:'none',
            background:'#F3F4F6', cursor:'pointer', display:'flex',
            alignItems:'center', justifyContent:'center',
          }}>
            <Icon name="X" size={16} color="#6B7280" />
          </button>
        </div>
        {/* Body */}
        <div style={{ flex:1, overflow:'auto', padding:'24px' }}>
          {children}
        </div>
        {/* Footer */}
        {footer && (
          <div style={{
            padding:'16px 24px', borderTop:'1px solid #E2E8F0',
            display:'flex', justifyContent:'flex-end', gap:10, flexShrink:0,
          }}>
            {footer}
          </div>
        )}
      </div>
    </div>
  );
};

// ─── CONFIRM DIALOG ───────────────────────────────────────
const ConfirmDialog = ({ open, onClose, onConfirm, title, message, confirmLabel='Confirmar', danger=false }) => (
  <Modal open={open} onClose={onClose} title={title} width={400}
    footer={<>
      <Button variant="secondary" onClick={onClose}>Cancelar</Button>
      <Button variant={danger ? 'danger' : 'primary'} onClick={() => { onConfirm(); onClose(); }}>{confirmLabel}</Button>
    </>}
  >
    <p style={{ color:'#4B5563', fontSize:14, lineHeight:1.6, margin:0 }}>{message}</p>
  </Modal>
);

// ─── TOAST ────────────────────────────────────────────────
const Toast = ({ toasts }) => (
  <div style={{ position:'fixed', bottom:24, right:24, zIndex:9999, display:'flex', flexDirection:'column', gap:10, pointerEvents:'none' }}>
    {toasts.map(t => {
      const icons = { success:'CheckCircle', error:'XCircle', info:'Info', warning:'AlertTriangle' };
      const colors = {
        success: { bg:'#F0FDF4', border:'#86EFAC', icon:'#22C55E', text:'#15803D' },
        error:   { bg:'#FEF2F2', border:'#FCA5A5', icon:'#EF4444', text:'#B91C1C' },
        info:    { bg:'#EFF6FF', border:'#93C5FD', icon:'#3B82F6', text:'#1D4ED8' },
        warning: { bg:'#FEF9C3', border:'#FDE047', icon:'#EAB308', text:'#854D0E' },
      };
      const c = colors[t.type] || colors.success;
      return (
        <div key={t.id} style={{
          display:'flex', alignItems:'center', gap:10,
          padding:'12px 16px', borderRadius:10,
          background:c.bg, border:`1px solid ${c.border}`,
          boxShadow:'0 4px 16px rgba(0,0,0,.1)',
          minWidth:260, maxWidth:360, pointerEvents:'auto',
          animation:'toastIn .25s ease',
        }}>
          <Icon name={icons[t.type] || 'CheckCircle'} size={18} color={c.icon} />
          <span style={{ fontSize:13, fontWeight:500, color:c.text }}>{t.message}</span>
        </div>
      );
    })}
  </div>
);

// ─── METRIC CARD ──────────────────────────────────────────
const MetricCard = ({ title, value, subtitle, icon, color, trend, trendLabel }) => {
  const [hov, setHov] = useState(false);
  return (
    <div
      onMouseEnter={() => setHov(true)}
      onMouseLeave={() => setHov(false)}
      style={{
        background:'#fff', borderRadius:14, padding:'20px 22px',
        boxShadow: hov ? '0 8px 24px rgba(10,31,68,.10)' : '0 2px 8px rgba(10,31,68,.06)',
        transition:'all .2s ease', flex:1, minWidth:0,
      }}
    >
      <div style={{ display:'flex', alignItems:'flex-start', justifyContent:'space-between', marginBottom:14 }}>
        <span style={{ fontSize:13, fontWeight:600, color:'#6B7280' }}>{title}</span>
        <div style={{
          width:38, height:38, borderRadius:10,
          background: U.hexToRgba(color, 0.12),
          display:'flex', alignItems:'center', justifyContent:'center',
        }}>
          <Icon name={icon} size={18} color={color} />
        </div>
      </div>
      <div style={{ fontSize:28, fontWeight:800, color:'#0A1F44', letterSpacing:'-0.5px', marginBottom:6 }}>{value}</div>
      {(trend !== undefined || subtitle) && (
        <div style={{ display:'flex', alignItems:'center', gap:6 }}>
          {trend !== undefined && (
            <span style={{
              fontSize:11, fontWeight:700, color: trend >= 0 ? '#22C55E' : '#EF4444',
              display:'flex', alignItems:'center', gap:2,
            }}>
              <Icon name={trend >= 0 ? 'TrendingUp' : 'TrendingDown'} size={12} color={trend >= 0 ? '#22C55E' : '#EF4444'} />
              {Math.abs(trend)}%
            </span>
          )}
          <span style={{ fontSize:11, color:'#9CA3AF' }}>{trendLabel || subtitle}</span>
        </div>
      )}
    </div>
  );
};

// ─── SEARCH BAR ───────────────────────────────────────────
const SearchBar = ({ value, onChange, placeholder = 'Buscar...', style = {} }) => {
  const [focused, setFocused] = useState(false);
  return (
    <div style={{ position:'relative', ...style }}>
      <span style={{ position:'absolute', left:12, top:'50%', transform:'translateY(-50%)', pointerEvents:'none', display:'flex' }}>
        <Icon name="Search" size={15} color={focused ? '#FF6B35' : '#9CA3AF'} />
      </span>
      <input
        value={value}
        onChange={e => onChange(e.target.value)}
        placeholder={placeholder}
        onFocus={() => setFocused(true)}
        onBlur={() => setFocused(false)}
        style={{
          width:'100%', boxSizing:'border-box',
          padding:'9px 12px 9px 36px', borderRadius:10, fontSize:13,
          border:`1.5px solid ${focused ? '#FF6B35' : '#E2E8F0'}`,
          outline:'none', background:'#fff', color:'#0A1F44',
          transition:'border-color .15s',
        }}
      />
    </div>
  );
};

// ─── EMPTY STATE ──────────────────────────────────────────
const EmptyState = ({ icon, title, message, action }) => (
  <div style={{ display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', padding:'60px 24px', gap:12 }}>
    <div style={{
      width:64, height:64, borderRadius:20,
      background:'#F3F4F6', display:'flex', alignItems:'center', justifyContent:'center', marginBottom:4,
    }}>
      <Icon name={icon || 'Inbox'} size={28} color='#9CA3AF' />
    </div>
    <h3 style={{ fontSize:16, fontWeight:700, color:'#374151', margin:0 }}>{title}</h3>
    <p style={{ fontSize:13, color:'#9CA3AF', margin:0, textAlign:'center', maxWidth:280 }}>{message}</p>
    {action}
  </div>
);

// ─── SKELETON ─────────────────────────────────────────────
const Skeleton = ({ width = '100%', height = 16, radius = 6, style = {} }) => (
  <div style={{ width, height, borderRadius:radius, background:'#F3F4F6', ...style, animation:'pulse 1.5s ease-in-out infinite' }} />
);

// ─── PROGRESS BAR ─────────────────────────────────────────
const ProgressBar = ({ value, max, color = '#FF6B35', style = {} }) => {
  const pct = Math.min(100, Math.round((value / max) * 100));
  return (
    <div style={{ ...style }}>
      <div style={{ height:8, background:'#F3F4F6', borderRadius:99, overflow:'hidden' }}>
        <div style={{ height:'100%', width:`${pct}%`, background:color, borderRadius:99, transition:'width .4s ease' }} />
      </div>
    </div>
  );
};

// ─── DROPDOWN MENU ────────────────────────────────────────
const DropdownMenu = ({ trigger, items, align = 'right' }) => {
  const [open, setOpen] = useState(false);
  const ref = useRef(null);

  useEffect(() => {
    const handler = e => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, []);

  return (
    <div ref={ref} style={{ position:'relative', display:'inline-flex' }}>
      <div onClick={() => setOpen(o => !o)}>{trigger}</div>
      {open && (
        <div style={{
          position:'absolute', top:'calc(100% + 6px)',
          [align === 'right' ? 'right' : 'left']: 0,
          background:'#fff', borderRadius:10,
          boxShadow:'0 8px 32px rgba(10,31,68,.14)',
          border:'1px solid #E2E8F0',
          zIndex:500, minWidth:160, overflow:'hidden',
        }}>
          {items.map((item, i) => item === 'divider'
            ? <div key={i} style={{ height:1, background:'#E2E8F0', margin:'4px 0' }} />
            : (
              <button
                key={i}
                onClick={() => { item.onClick(); setOpen(false); }}
                style={{
                  display:'flex', alignItems:'center', gap:8,
                  width:'100%', padding:'9px 14px', fontSize:13, fontWeight:500,
                  color: item.danger ? '#EF4444' : '#374151',
                  background:'none', border:'none', cursor:'pointer',
                  textAlign:'left', transition:'background .1s',
                }}
                onMouseEnter={e => e.currentTarget.style.background='#F9FAFB'}
                onMouseLeave={e => e.currentTarget.style.background='none'}
              >
                {item.icon && <Icon name={item.icon} size={14} color={item.danger ? '#EF4444' : '#6B7280'} />}
                {item.label}
              </button>
            )
          )}
        </div>
      )}
    </div>
  );
};

// ─── EXPORT ───────────────────────────────────────────────
Object.assign(window, {
  Icon, Avatar, Badge, TagChip, Button, Input, Select, Textarea,
  Tabs, Modal, ConfirmDialog, Toast, MetricCard, SearchBar,
  EmptyState, Skeleton, ProgressBar, DropdownMenu,
});
