/* ------------------------------------------------------------------ *
 *  Composants UI réutilisables
 * ------------------------------------------------------------------ */

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

function Segmented({ options, value, onChange, dense = false }) {
  return (
    <div className="inline-flex p-1 bg-ink-100 rounded-xl">
      {options.map((o) => {
        const active = o.id === value;
        return (
          <button key={o.id}
            onClick={() => onChange(o.id)}
            className={`seg-btn relative ${dense ? 'px-3 py-1.5 text-sm' : 'px-4 py-2 text-[13.5px]'} rounded-lg font-medium
                        ${active ? 'bg-white text-ink-900 shadow-card' : 'text-ink-500 hover:text-ink-800'}`}>
            {o.label}
          </button>
        );
      })}
    </div>
  );
}

function SelectCard({ title, sub, hint, active, onClick, icon }) {
  return (
    <button onClick={onClick}
      className={`group text-left w-full p-4 rounded-2xl border transition
                  ${active
                    ? 'border-brand-500 bg-white shadow-pop ring-1 ring-brand-500/20'
                    : 'border-ink-200 bg-white hover:border-ink-300 shadow-card'}`}>
      <div className="flex items-start justify-between gap-3">
        <div>
          <div className="flex items-center gap-2">
            {icon && <span className="text-ink-400">{icon}</span>}
            <div className="font-semibold text-ink-900 text-[15px]">{title}</div>
          </div>
          {sub && <div className="text-[12.5px] text-ink-500 mt-0.5">{sub}</div>}
          {hint && <div className="text-[11.5px] text-ink-400 mt-1.5">{hint}</div>}
        </div>
        <div className={`w-4 h-4 rounded-full border-2 mt-0.5
                        ${active ? 'border-brand-500 bg-brand-500' : 'border-ink-300 bg-white'}`}>
          {active && <span className="block w-full h-full rounded-full ring-2 ring-white"></span>}
        </div>
      </div>
    </button>
  );
}

function KpiCard({ label, value, sub, tone = 'default', icon, helper }) {
  const tones = {
    default: 'bg-white border-ink-200',
    brand: 'bg-gradient-to-br from-brand-500 to-brand-700 text-white border-transparent',
    success: 'bg-white border-emerald-200',
    warn: 'bg-white border-amber-200',
    danger: 'bg-white border-rose-200'
  };
  const valueTones = {
    default: 'text-ink-900',
    brand: 'text-white',
    success: 'text-emerald-700',
    warn: 'text-amber-700',
    danger: 'text-rose-700'
  };
  const subTones = {
    default: 'text-ink-500',
    brand: 'text-brand-100',
    success: 'text-emerald-600',
    warn: 'text-amber-600',
    danger: 'text-rose-600'
  };
  return (
    <div className={`relative p-5 rounded-2xl border shadow-card ${tones[tone]}`}>
      <div className="flex items-center justify-between">
        <div className={`text-[12px] uppercase tracking-[0.08em] font-medium ${tone === 'brand' ? 'text-brand-100' : 'text-ink-500'}`}>
          {label}
        </div>
        {icon && <div className={tone === 'brand' ? 'text-brand-100' : 'text-ink-400'}>{icon}</div>}
      </div>
      <div className={`mt-3 text-[30px] leading-none font-semibold tnum ${valueTones[tone]}`}>
        {value}
      </div>
      {sub && <div className={`mt-2 text-[12.5px] ${subTones[tone]}`}>{sub}</div>}
      {helper &&
        <div className={`mt-3 text-[11.5px] leading-snug border-t pt-2.5 ${tone === 'brand' ? 'border-white/20 text-brand-100' : 'border-ink-100 text-ink-500'}`}>
          {helper}
        </div>
      }
    </div>
  );
}

function NumberInput({ value, onChange, min = 0, max, step = 1, suffix, prefix, warn, className, ariaLabel }) {
  const [local, setLocal] = useState(String(value ?? ''));
  useEffect(() => { setLocal(String(value ?? '')); }, [value]);
  return (
    <span className={`inline-flex items-center gap-1 ${className || ''}`}>
      {prefix && <span className="text-ink-400 text-[12px]">{prefix}</span>}
      <input
        type="number"
        aria-label={ariaLabel}
        className={`cell-input ${warn ? 'warn' : ''}`}
        value={local}
        min={min}
        max={max}
        step={step}
        onChange={(e) => {
          setLocal(e.target.value);
          const n = parseFloat(e.target.value);
          onChange(isFinite(n) ? n : 0);
        }}
        onBlur={() => setLocal(String(value ?? ''))}
      />
      {suffix && <span className="text-ink-400 text-[12px]">{suffix}</span>}
    </span>
  );
}

const Icon = {
  chart:   (p = {}) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M3 3v18h18" /><path d="M7 14l4-4 4 3 5-7" /></svg>,
  savings: (p = {}) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 3v3" /><path d="M3 12h3" /><path d="M18 12h3" /><circle cx="12" cy="13" r="7" /><path d="M9.5 13.5l2 2 3.5-4" /></svg>,
  clock:   (p = {}) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="12" cy="12" r="9" /><path d="M12 7v5l3 2" /></svg>,
  flow:    (p = {}) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M3 12h12" /><path d="M11 8l4 4-4 4" /><path d="M21 4v16" /></svg>,
  euro:    (p = {}) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M19 4.5A8 8 0 1 0 19 19.5" /><path d="M3 10h12" /><path d="M3 14h12" /></svg>,
  chair:   (p = {}) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M4 11h16" /><path d="M6 11V7a3 3 0 0 1 6 0v4" /><path d="M5 11l-1 7" /><path d="M19 11l1 7" /><path d="M8 18h8" /></svg>,
  spark:   (p = {}) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 3v4" /><path d="M12 17v4" /><path d="M3 12h4" /><path d="M17 12h4" /><path d="M5.6 5.6l2.8 2.8" /><path d="M15.6 15.6l2.8 2.8" /><path d="M5.6 18.4l2.8-2.8" /><path d="M15.6 8.4l2.8-2.8" /></svg>,
  doc:     (p = {}) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z" /><path d="M14 3v5h5" /><path d="M8 13h8" /><path d="M8 17h5" /></svg>,
  warn:    (p = {}) => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M10.3 3.7L1.7 18a2 2 0 0 0 1.7 3h17.2a2 2 0 0 0 1.7-3L13.7 3.7a2 2 0 0 0-3.4 0z" /><path d="M12 9v4" /><path d="M12 17h.01" /></svg>,
  check:   (p = {}) => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M4 12l5 5L20 6" /></svg>,
  printer: (p = {}) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M6 9V3h12v6" /><rect x="3" y="9" width="18" height="9" rx="2" /><path d="M6 14h12v7H6z" /></svg>,
  user:    (p = {}) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="12" cy="8" r="4" /><path d="M4 21a8 8 0 0 1 16 0" /></svg>,
  copy:    (p = {}) => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="9" y="9" width="12" height="12" rx="2" /><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" /></svg>,
  close:   (p = {}) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M6 6l12 12" /><path d="M18 6L6 18" /></svg>,
  plus:    (p = {}) => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 5v14" /><path d="M5 12h14" /></svg>,
  minus:   (p = {}) => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M5 12h14" /></svg>,
  info:    (p = {}) => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="12" cy="12" r="9" /><path d="M12 8h.01" /><path d="M11 12h1v4h1" /></svg>,
  camera:  (p = {}) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg>,
  heart:   (p = {}) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg>
};

function useDarkMode() {
  const [dark, setDark] = useState(() => document.documentElement.classList.contains('dark'));
  useEffect(() => {
    const obs = new MutationObserver(() => {
      setDark(document.documentElement.classList.contains('dark'));
    });
    obs.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
    return () => obs.disconnect();
  }, []);
  function toggle() {
    const next = !dark;
    document.documentElement.classList.toggle('dark', next);
    localStorage.setItem('simuprint-theme', next ? 'dark' : 'light');
  }
  return [dark, toggle];
}

function DarkModeToggle() {
  const [dark, toggle] = useDarkMode();
  return (
    <button
      onClick={toggle}
      title={dark ? 'Mode jour' : 'Mode nuit'}
      aria-label={dark ? 'Activer le mode jour' : 'Activer le mode nuit'}
      className="w-8 h-8 rounded-lg border border-ink-200 bg-white hover:bg-ink-100 text-ink-400 hover:text-ink-700 grid place-items-center transition shadow-card">
      {dark ? (
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <circle cx="12" cy="12" r="4"/>
          <path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"/>
        </svg>
      ) : (
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
        </svg>
      )}
    </button>
  );
}

function Wordmark() {
  const { t } = useLang();
  const isLab = window.location.pathname.includes('/labo');
  const [leaving, setLeaving] = useState(false);

  /* XOR: true = currently showing lab (green) state */
  const showLab = isLab !== leaving;

  const purpleFrom = '#5B3DF5', purpleTo = '#3B22B0';
  const greenFrom  = '#22C55E', greenTo  = '#15803D';

  function handleClick() {
    setLeaving(true);
    setTimeout(() => { window.location.href = isLab ? '/' : '/labo/'; }, 520);
  }

  return (
    <button
      onClick={handleClick}
      title={isLab ? 'Simuprint Cabinet' : 'Simuprint Lab'}
      style={{ background: 'none', border: 'none', padding: 0, cursor: 'pointer' }}
      className="flex items-center gap-2.5"
    >
      <div style={{ position: 'relative', width: 32, height: 32, borderRadius: 8,
                    boxShadow: '0 12px 32px -8px rgba(91,61,245,0.18), 0 4px 12px -2px rgba(15,16,36,0.06)' }}>
        <div style={{ position: 'absolute', inset: 0, borderRadius: 8,
                      background: `linear-gradient(135deg, ${purpleFrom}, ${purpleTo})`,
                      opacity: showLab ? 0 : 1, transition: 'opacity 0.5s ease' }}/>
        <div style={{ position: 'absolute', inset: 0, borderRadius: 8,
                      background: `linear-gradient(135deg, ${greenFrom}, ${greenTo})`,
                      opacity: showLab ? 1 : 0, transition: 'opacity 0.5s ease' }}/>
        <div style={{ position: 'relative', zIndex: 1, display: 'grid', placeItems: 'center', height: '100%' }}>
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
            <path d="M5 8l7-4 7 4-7 4z" />
            <path d="M5 12l7 4 7-4" />
            <path d="M5 16l7 4 7-4" />
          </svg>
        </div>
      </div>
      <div className="leading-tight">
        <div className="font-semibold text-[15px] text-ink-900 tracking-tight" style={{ display: 'flex', alignItems: 'center' }}>
          Simuprint
          <span style={{
            display: 'inline-block',
            maxWidth: showLab ? '52px' : '0px',
            opacity: showLab ? 1 : 0,
            overflow: 'hidden',
            transition: 'max-width 0.45s ease, opacity 0.35s ease, padding-left 0.45s ease',
            color: '#15803D',
            paddingLeft: showLab ? '3px' : '0px',
            fontWeight: 700,
          }}>.lab</span>
        </div>
        <div className="text-[11px] text-ink-500 -mt-0.5">
          {showLab ? t('wordmark.sub.lab') : t('wordmark.sub')}
        </div>
      </div>
    </button>
  );
}

function printPdf() {
  const isIOS = /iP(ad|hone|od)/.test(navigator.userAgent) ||
                (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);

  if (isIOS) {
    const msgs = {
      fr: 'Sur iOS, appuyez sur le bouton Partager ↗ de Safari puis « Imprimer ».',
      en: "On iOS, tap Safari's Share ↗ button then \"Print\".",
      es: 'En iOS, toca Compartir ↗ en Safari y luego "Imprimir".',
      it: 'Su iOS, tocca Condividi ↗ in Safari poi "Stampa".',
      de: 'Auf iOS, tippe auf Teilen ↗ in Safari, dann "Drucken".',
    };
    const lang = localStorage.getItem('simuprint-lang') || 'fr';
    const toastEl = document.createElement('div');
    Object.assign(toastEl.style, {
      position: 'fixed', bottom: '24px', left: '50%', transform: 'translateX(-50%)',
      background: '#1A1B36', color: '#EEF0F8', borderRadius: '14px',
      padding: '14px 20px', fontSize: '13px', lineHeight: '1.5',
      zIndex: '9999', boxShadow: '0 8px 32px rgba(0,0,0,.28)',
      textAlign: 'center', width: 'min(320px, calc(100vw - 32px))',
    });
    toastEl.textContent = msgs[lang] || msgs.fr;
    document.body.appendChild(toastEl);
    setTimeout(() => {
      toastEl.style.transition = 'opacity .3s';
      toastEl.style.opacity = '0';
      setTimeout(() => toastEl.remove(), 300);
    }, 6000);
    return;
  }

  const wasDark = document.documentElement.classList.contains('dark');
  if (wasDark) document.documentElement.classList.remove('dark');
  function restore() {
    if (wasDark) document.documentElement.classList.add('dark');
    window.removeEventListener('afterprint', restore);
  }
  if (wasDark) window.addEventListener('afterprint', restore);
  window.print();
  if (wasDark) setTimeout(restore, 1000);
}

Object.assign(window, {
  Segmented, SelectCard, KpiCard, NumberInput, Icon, Wordmark,
  useDarkMode, DarkModeToggle, printPdf,
});
