// ============================================
// MariusVPN — UI primitives
// Exposes: Card, Button, IconButton, Badge, Toggle, Toast, ToastHost,
//   Modal, Sheet, ProgressBar, Skeleton, Logo, Field, Spinner, Copy
// ============================================

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

// ---------- Logo ----------
const Logo = ({ size = 28, withText = true, className = '' }) => (
  <div className={`flex items-center gap-2 ${className}`}>
    <div className="relative" style={{ width: size, height: size }}>
      <svg viewBox="0 0 32 32" width={size} height={size}>
        <defs>
          <linearGradient id="logoGrad" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor="#22D3EE" />
            <stop offset="100%" stopColor="#0891B2" />
          </linearGradient>
        </defs>
        <path d="M16 2 L28 6 V14 C28 22 16 30 16 30 C16 30 4 22 4 14 V6 Z"
              fill="url(#logoGrad)" />
        <path d="M11 19 V12 L16 17 L21 12 V19" fill="none" stroke="#0B0E14" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/>
      </svg>
    </div>
    {withText && (
      <div className="leading-tight">
        <div className="font-semibold text-m-text tracking-tight" style={{ fontSize: Math.max(14, size * 0.58) }}>
          Marius<span className="text-m-accent">VPN</span>
        </div>
      </div>
    )}
  </div>
);

// ---------- Card ----------
const Card = ({ className = '', children, padding = 'p-5', as: As = 'div', ...rest }) => (
  <As
    className={`bg-m-card border border-white/5 rounded-2xl shadow-card ${padding} ${className}`}
    {...rest}
  >
    {children}
  </As>
);

// ---------- Button ----------
const Button = ({
  children, variant = 'primary', size = 'md', icon, iconRight, loading, disabled,
  fullWidth = false, className = '', as: As = 'button', ...rest
}) => {
  const sizes = {
    sm: 'h-9 px-3.5 text-[13px] gap-1.5 rounded-xl',
    md: 'h-11 px-4 text-sm gap-2 rounded-xl',
    lg: 'h-12 px-5 text-[15px] gap-2 rounded-xl font-medium',
  };
  const variants = {
    primary:  'bg-m-accent text-m-bg hover:brightness-110 active:brightness-95 font-medium shadow-glow disabled:bg-m-line2 disabled:text-m-mute disabled:shadow-none',
    secondary:'bg-white/[0.06] text-m-text hover:bg-white/[0.10] border border-white/5',
    ghost:    'text-m-text hover:bg-white/[0.06]',
    danger:   'bg-m-err/15 text-m-err hover:bg-m-err/25 border border-m-err/30',
    gold:     'bg-m-gold text-m-bg hover:brightness-110 font-medium',
    outline:  'border border-white/10 text-m-text hover:bg-white/[0.05]',
  };
  const cls = `inline-flex items-center justify-center transition-all duration-150 active:scale-[0.98]
    disabled:cursor-not-allowed disabled:active:scale-100
    ${sizes[size]} ${variants[variant]} ${fullWidth ? 'w-full' : ''} ${className}`;
  return (
    <As className={cls} disabled={disabled || loading} {...rest}>
      {loading ? <Spinner size={size === 'sm' ? 14 : 16} /> : icon && <Icon name={icon} size={size === 'sm' ? 14 : 16} />}
      {children}
      {iconRight && <Icon name={iconRight} size={size === 'sm' ? 14 : 16} />}
    </As>
  );
};

const IconButton = ({ icon, size = 'md', variant = 'ghost', className = '', dot = false, ...rest }) => {
  const dims = size === 'sm' ? 'w-9 h-9' : 'w-10 h-10';
  const variants = {
    ghost: 'bg-white/[0.04] hover:bg-white/[0.08] border border-white/5',
    solid: 'bg-m-card border border-white/5 hover:bg-m-card-hi',
  };
  return (
    <button className={`relative grid place-items-center rounded-xl text-m-text transition ${dims} ${variants[variant]} ${className}`} {...rest}>
      <Icon name={icon} size={18} />
      {dot && <span className="absolute top-2.5 right-2.5 w-1.5 h-1.5 rounded-full bg-m-accent shadow-glow" />}
    </button>
  );
};

// ---------- Badge ----------
const Badge = ({ children, tone = 'neutral', size = 'md', icon, className = '' }) => {
  const tones = {
    neutral: 'bg-white/[0.06] text-m-mute border-white/5',
    accent:  'bg-m-accent/15 text-m-accent border-m-accent/30',
    ok:      'bg-m-ok/15 text-m-ok border-m-ok/30',
    err:     'bg-m-err/15 text-m-err border-m-err/30',
    gold:    'bg-m-gold/15 text-m-gold border-m-gold/30',
    warn:    'bg-m-gold/15 text-m-gold border-m-gold/30',
  };
  const sizes = { sm: 'h-5 px-2 text-[10px] gap-1', md: 'h-6 px-2.5 text-[11px] gap-1.5' };
  return (
    <span className={`inline-flex items-center rounded-full border font-medium tracking-wide uppercase ${tones[tone]} ${sizes[size]} ${className}`}>
      {icon && <Icon name={icon} size={11} />}
      {children}
    </span>
  );
};

// ---------- Toggle ----------
const Toggle = ({ checked, onChange, disabled = false, size = 'md' }) => {
  const dims = size === 'sm' ? { w: 40, h: 24, k: 18 } : { w: 48, h: 28, k: 22 };
  return (
    <button
      role="switch"
      aria-checked={checked}
      disabled={disabled}
      onClick={() => !disabled && onChange?.(!checked)}
      className={`relative rounded-full transition-colors duration-200 disabled:opacity-50 ${checked ? 'bg-m-accent' : 'bg-white/10'}`}
      style={{ width: dims.w, height: dims.h }}
    >
      <span
        className="absolute top-1/2 -translate-y-1/2 rounded-full bg-white shadow transition-all duration-200"
        style={{
          width: dims.k,
          height: dims.k,
          left: checked ? dims.w - dims.k - 3 : 3,
        }}
      />
    </button>
  );
};

// ---------- ProgressBar ----------
const ProgressBar = ({ value, max = 100, tone, height = 6, className = '' }) => {
  const pct = Math.min(100, Math.max(0, (value / max) * 100));
  // Auto-tone: cyan → gold → red as it approaches max
  let auto = 'bg-gradient-to-r from-m-accent to-cyan-300';
  if (pct >= 90) auto = 'bg-gradient-to-r from-m-err to-rose-400';
  else if (pct >= 75) auto = 'bg-gradient-to-r from-m-gold to-amber-300';
  const toneClass = tone || auto;
  return (
    <div className={`w-full rounded-full bg-white/[0.06] overflow-hidden ${className}`} style={{ height }}>
      <div
        className={`h-full rounded-full transition-all duration-500 ${toneClass}`}
        style={{ width: `${pct}%` }}
      />
    </div>
  );
};

// ---------- Skeleton ----------
const Skeleton = ({ className = 'h-4 w-full', rounded = 'rounded-md' }) => (
  <div className={`skeleton ${rounded} ${className}`} />
);

// ---------- Spinner ----------
const Spinner = ({ size = 16, className = '' }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" className={`animate-spin ${className}`}>
    <circle cx="12" cy="12" r="9" stroke="currentColor" strokeWidth="2.5" fill="none" opacity="0.2" />
    <path d="M21 12a9 9 0 0 0-9-9" stroke="currentColor" strokeWidth="2.5" fill="none" strokeLinecap="round" />
  </svg>
);

// ---------- Field (input wrapper) ----------
const Field = ({ label, hint, error, children, className = '' }) => (
  <label className={`block ${className}`}>
    {label && <div className="text-[12px] uppercase tracking-wider text-m-dim mb-2">{label}</div>}
    {children}
    {hint && !error && <div className="text-[11px] text-m-dim mt-1.5">{hint}</div>}
    {error && <div className="text-[11px] text-m-err mt-1.5">{error}</div>}
  </label>
);

const Input = ({ className = '', ...rest }) => (
  <input
    className={`w-full h-11 px-4 bg-m-bg2 border border-white/5 rounded-xl text-m-text text-sm
      placeholder:text-m-dim outline-none transition
      focus:border-m-accent/40 focus:bg-m-bg2 focus:shadow-[0_0_0_3px_rgba(34,211,238,0.10)]
      ${className}`}
    {...rest}
  />
);

const Select = ({ className = '', children, ...rest }) => (
  <select
    className={`w-full h-11 px-4 bg-m-bg2 border border-white/5 rounded-xl text-m-text text-sm
      outline-none transition focus:border-m-accent/40
      ${className}`}
    {...rest}
  >
    {children}
  </select>
);

// ---------- Copy field ----------
const CopyField = ({ value, mono = true, className = '' }) => {
  const [copied, setCopied] = useState(false);
  const onCopy = () => {
    navigator.clipboard?.writeText(value);
    setCopied(true);
    setTimeout(() => setCopied(false), 1400);
  };
  return (
    <div className={`flex items-center gap-2 bg-m-bg2 border border-white/5 rounded-xl pl-3.5 pr-1 py-1 ${className}`}>
      <div className={`flex-1 min-w-0 truncate text-sm ${mono ? 'font-mono' : ''} text-m-text`}>{value}</div>
      <button
        onClick={onCopy}
        className={`h-8 px-3 rounded-lg text-xs font-medium inline-flex items-center gap-1.5 transition
          ${copied ? 'bg-m-ok/20 text-m-ok' : 'bg-white/[0.07] text-m-text hover:bg-white/[0.13]'}`}
      >
        <Icon name={copied ? 'check' : 'copy'} size={13} />
        {copied ? 'Скопировано' : 'Копировать'}
      </button>
    </div>
  );
};

// ---------- Modal ----------
const Modal = ({ open, onClose, title, children, footer, maxWidth = 'max-w-md', dismissible = true }) => {
  useEffect(() => {
    if (!open) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    const onKey = (e) => e.key === 'Escape' && dismissible && onClose?.();
    document.addEventListener('keydown', onKey);
    return () => {
      document.body.style.overflow = prev;
      document.removeEventListener('keydown', onKey);
    };
  }, [open, dismissible, onClose]);
  if (!open) return null;
  return (
    <div className="fixed inset-0 z-[120] flex items-center justify-center p-4 fade-in"
         onClick={(e) => e.target === e.currentTarget && dismissible && onClose?.()}>
      <div className="absolute inset-0 bg-black/70 backdrop-blur-md" />
      <div className={`relative w-full ${maxWidth} bg-m-card border border-white/8 rounded-2xl shadow-lift slide-up overflow-hidden`}>
        {title && (
          <div className="flex items-center justify-between px-5 py-4 border-b border-white/5">
            <div className="font-medium text-m-text">{title}</div>
            {dismissible && (
              <button onClick={onClose} className="w-8 h-8 rounded-full bg-white/[0.07] hover:bg-white/[0.13] grid place-items-center text-m-text transition">
                <Icon name="close" size={14} />
              </button>
            )}
          </div>
        )}
        <div className="px-5 py-5">{children}</div>
        {footer && <div className="px-5 py-4 border-t border-white/5 bg-m-bg2/40">{footer}</div>}
      </div>
    </div>
  );
};

// ---------- Bottom Sheet (mobile) / side drawer (desktop) ----------
const Sheet = ({ open, onClose, title, children, side = 'auto' }) => {
  useEffect(() => {
    if (!open) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    const onKey = (e) => e.key === 'Escape' && onClose?.();
    document.addEventListener('keydown', onKey);
    return () => { document.body.style.overflow = prev; document.removeEventListener('keydown', onKey); };
  }, [open, onClose]);
  if (!open) return null;
  return (
    <div className="fixed inset-0 z-[110] fade-in">
      <div className="absolute inset-0 bg-black/65 backdrop-blur-md" onClick={onClose} />
      {/* Mobile: bottom; Desktop: right */}
      <aside
        className={`absolute bg-m-card border-white/8 shadow-lift overflow-hidden
          inset-x-0 bottom-0 rounded-t-2xl border-t max-h-[88vh]
          md:left-auto md:right-4 md:top-4 md:bottom-4 md:inset-x-auto md:w-[460px]
          md:rounded-2xl md:border md:max-h-none
          sheet-in flex flex-col`}
      >
        {/* mobile drag handle */}
        <div className="md:hidden flex justify-center pt-2 pb-1">
          <div className="w-10 h-1 rounded-full bg-white/15" />
        </div>
        {title && (
          <div className="flex items-center justify-between px-5 py-3 md:py-4 border-b border-white/5">
            <div className="font-medium text-m-text">{title}</div>
            <button onClick={onClose} className="w-8 h-8 rounded-full bg-white/[0.07] hover:bg-white/[0.13] grid place-items-center text-m-text transition">
              <Icon name="close" size={14} />
            </button>
          </div>
        )}
        <div className="flex-1 overflow-y-auto px-5 py-5">{children}</div>
      </aside>
    </div>
  );
};

// ---------- Toast ----------
const ToastCtx = createContext(null);
const useToast = () => useContext(ToastCtx);

const ToastHost = ({ children }) => {
  const [toasts, setToasts] = useState([]);
  const push = useCallback((t) => {
    const id = Math.random().toString(36).slice(2);
    setToasts((arr) => [...arr, { id, tone: 'neutral', ...t }]);
    setTimeout(() => setToasts((arr) => arr.filter((x) => x.id !== id)), t.duration || 3000);
  }, []);
  const ctx = useMemo(() => ({
    show: push,
    success: (msg) => push({ tone: 'ok', msg }),
    error:   (msg) => push({ tone: 'err', msg }),
    info:    (msg) => push({ tone: 'accent', msg }),
  }), [push]);
  return (
    <ToastCtx.Provider value={ctx}>
      {children}
      <div className="fixed top-4 right-4 z-[200] flex flex-col gap-2 max-w-sm">
        {toasts.map((t) => (
          <div
            key={t.id}
            className={`slide-up px-4 py-3 rounded-xl border backdrop-blur bg-m-card/95 shadow-lift text-sm flex items-start gap-2.5
              ${t.tone === 'ok'  ? 'border-m-ok/30 text-m-ok' :
                t.tone === 'err' ? 'border-m-err/30 text-m-err' :
                t.tone === 'accent' ? 'border-m-accent/30 text-m-accent' :
                'border-white/8 text-m-text'}`}
          >
            <Icon name={t.tone === 'ok' ? 'check' : t.tone === 'err' ? 'close' : 'bell'} size={16} className="mt-0.5 shrink-0" />
            <div className="flex-1">{t.msg}</div>
          </div>
        ))}
      </div>
    </ToastCtx.Provider>
  );
};

// ---------- ScreenHeader ----------
const ScreenHeader = ({ title, subtitle, right, onBack }) => (
  <header className="flex items-start justify-between gap-4 mb-5 md:mb-6">
    <div className="min-w-0">
      {onBack && (
        <button onClick={onBack} className="text-m-dim hover:text-m-text inline-flex items-center gap-1 text-[13px] mb-2 transition">
          <Icon name="chevR" size={14} className="rotate-180" /> Назад
        </button>
      )}
      <h1 className="text-[22px] md:text-[26px] font-semibold text-m-text tracking-tight">{title}</h1>
      {subtitle && <p className="text-sm text-m-mute mt-1">{subtitle}</p>}
    </div>
    {right && <div className="flex items-center gap-2 shrink-0">{right}</div>}
  </header>
);

// ---------- KV Row (a label/value row for lists) ----------
const KV = ({ label, value, mono = false, className = '' }) => (
  <div className={`flex items-baseline justify-between gap-4 py-2 ${className}`}>
    <div className="text-[13px] text-m-mute">{label}</div>
    <div className={`text-[13px] text-m-text ${mono ? 'font-mono' : ''}`}>{value}</div>
  </div>
);

// expose
Object.assign(window, {
  Logo, Card, Button, IconButton, Badge, Toggle, ProgressBar, Skeleton, Spinner,
  Field, Input, Select, CopyField,
  Modal, Sheet, ToastHost, useToast,
  ScreenHeader, KV,
});
