/* ============================================================
   Shared components: icons, plates, charts, drawer
   ============================================================ */
const { useState, useEffect, useRef } = React;

/* ---- Minimal line icons (stroke) --------------------------- */
function Icon({ name, size = 18, stroke = 1.6 }) {
  const p = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none',
    stroke: 'currentColor', strokeWidth: stroke, strokeLinecap: 'round', strokeLinejoin: 'round' };
  const paths = {
    home:    <><path d="M3 10.5 12 4l9 6.5" /><path d="M5 9.5V20h14V9.5" /><path d="M9.5 20v-5h5v5" /></>,
    money:   <><rect x="3" y="6" width="18" height="12" rx="2" /><circle cx="12" cy="12" r="2.4" /><path d="M6 12h.01M18 12h.01" /></>,
    box:     <><path d="M21 8 12 3 3 8l9 5 9-5Z" /><path d="M3 8v8l9 5 9-5V8" /><path d="M12 13v8" /></>,
    chat:    <><path d="M4 5h16v11H8l-4 3V5Z" /></>,
    plug:    <><path d="M9 7V3M15 7V3" /><path d="M7 7h10v4a5 5 0 0 1-10 0V7Z" /><path d="M12 16v5" /></>,
    table:   <><rect x="3" y="4" width="18" height="16" rx="2" /><path d="M3 9h18M9 9v11" /></>,
    percent: <><path d="M19 5 5 19" /><circle cx="7.5" cy="7.5" r="2.5" /><circle cx="16.5" cy="16.5" r="2.5" /></>,
    receipt: <><path d="M5 3v18l2-1.4L9 21l2-1.4L13 21l2-1.4L17 21l2-1.4V3l-2 1.4L15 3l-2 1.4L11 3 9 4.4 7 3 5 4.4Z" /><path d="M8 8h8M8 12h8M8 16h5" /></>,
    arrowUp: <><path d="M12 19V5M6 11l6-6 6 6" /></>,
    arrowDn: <><path d="M12 5v14M6 13l6 6 6-6" /></>,
    chevR:   <path d="m9 6 6 6-6 6" />,
    chevD:   <path d="m6 9 6 6 6-6" />,
    close:   <><path d="M6 6l12 12M18 6 6 18" /></>,
    check:   <path d="m5 12 5 5L20 7" />,
    alert:   <><path d="M12 3 2 20h20L12 3Z" /><path d="M12 10v4M12 17h.01" /></>,
    info:    <><circle cx="12" cy="12" r="9" /><path d="M12 11v5M12 8h.01" /></>,
    upload:  <><path d="M12 16V4M7 9l5-5 5 5" /><path d="M5 20h14" /></>,
    refresh: <><path d="M3 12a9 9 0 0 1 15-6.7L21 8" /><path d="M21 3v5h-5" /><path d="M21 12a9 9 0 0 1-15 6.7L3 16" /><path d="M3 21v-5h5" /></>,
    send:    <><path d="M22 2 11 13" /><path d="M22 2 15 22l-4-9-9-4 20-7Z" /></>,
    forward: <><path d="M15 17l5-5-5-5" /><path d="M20 12H9a5 5 0 0 0-5 5v2" /></>,
    pencil:  <><path d="M4 20h4L19 9l-4-4L4 16v4Z" /><path d="M14 6l4 4" /></>,
    eye:     <><path d="M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12Z" /><circle cx="12" cy="12" r="3" /></>,
    dot:     <circle cx="12" cy="12" r="3" />,
    sun:      <><circle cx="12" cy="12" r="4" /><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4" /></>,
    moon:     <path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8Z" />,
    briefcase:<><rect x="2" y="7" width="20" height="14" rx="2" /><path d="M16 7V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v2" /></>,
    download: <><path d="M12 4v12M7 12l5 5 5-5" /><path d="M5 20h14" /></>,
    file:     <><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6Z" /><path d="M14 2v6h6M10 13h4M10 17h4M8 9h1" /></>,
    building: <><path d="M3 21h18" /><path d="M5 21V5a1 1 0 0 1 1-1h7a1 1 0 0 1 1 1v16" /><path d="M14 9h4a1 1 0 0 1 1 1v11" /><path d="M8 8h.01M11 8h.01M8 12h.01M11 12h.01M8 16h.01M11 16h.01" /></>,
    key:      <><circle cx="8" cy="16" r="3" /><path d="M10.4 13.6 20 4" /><path d="M16.5 7.5 19 10" /></>,
    lock:     <><rect x="4" y="10" width="16" height="11" rx="2" /><path d="M8 10V7a4 4 0 0 1 8 0v3" /></>,
    copy:     <><rect x="9" y="9" width="12" height="12" rx="2" /><path d="M5 15H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v1" /></>,
    trash:    <><path d="M4 7h16" /><path d="M9 7V5a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2" /><path d="M6 7l1 13a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1l1-13" /><path d="M10 11v6M14 11v6" /></>,
    plus:     <><path d="M12 5v14M5 12h14" /></>,
    search:   <><circle cx="11" cy="11" r="7" /><path d="m21 21-4.3-4.3" /></>,
    ban:      <><circle cx="12" cy="12" r="9" /><path d="M5.6 5.6 18.4 18.4" /></>,
    login:    <><path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4" /><path d="M10 17l5-5-5-5" /><path d="M15 12H3" /></>,
    more:     <><circle cx="12" cy="5" r="1.5" /><circle cx="12" cy="12" r="1.5" /><circle cx="12" cy="19" r="1.5" /></>,
    shield:   <><path d="M12 3l8 3v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6l8-3Z" /><path d="m9 12 2 2 4-4" /></>,
    users:    <><path d="M16 19v-1a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v1" /><circle cx="9" cy="7" r="3" /><path d="M22 19v-1a4 4 0 0 0-3-3.8" /><path d="M16 4.2A4 4 0 0 1 16 11" /></>,
    clock:    <><circle cx="12" cy="12" r="9" /><path d="M12 7v5l3 2" /></>,
    monitor:  <><rect x="2" y="3" width="20" height="14" rx="2.5" /><path d="M8 21h8M12 17v4" /></>,
    iphone:   <><rect x="6" y="1" width="12" height="22" rx="3" /><path d="M9.5 4.5h5" strokeLinecap="round" strokeWidth="1.8" /></>,
  };
  return <svg {...p}>{paths[name] || null}</svg>;
}

/* ---- Выбор конкретного месяца (общий для десктопа и мобайла) ---- */
function MonthPicker({ year, month, onChange, className }) {
  const [open, setOpen] = useState(false);
  const [viewYear, setViewYear] = useState(year);
  const ref = useRef(null);

  useEffect(() => { setViewYear(year); }, [year]);
  useEffect(() => {
    if (!open) return;
    const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    const onKey = (e) => { if (e.key === 'Escape') setOpen(false); };
    document.addEventListener('mousedown', onDoc);
    document.addEventListener('keydown', onKey);
    return () => { document.removeEventListener('mousedown', onDoc); document.removeEventListener('keydown', onKey); };
  }, [open]);

  const pick = (m) => { onChange(viewYear, m); setOpen(false); };

  return (
    <div className={'month-pick-wrap' + (className ? ' ' + className : '')} ref={ref}>
      <button type="button" className={'month-pick' + (open ? ' open' : '')} onClick={() => setOpen(o => !o)}>
        <span className="num">{MONTHS_RU[month]} {year}</span>
        <span className="month-pick-chev"><Icon name="chevD" size={15} /></span>
      </button>
      {open && (
        <div className="month-pick-pop">
          <div className="month-pick-year">
            <button type="button" className="mp-nav" onClick={() => setViewYear(y => y - 1)} aria-label="Предыдущий год">
              <span style={{ transform: 'rotate(180deg)', display: 'inline-flex' }}><Icon name="chevR" size={16} /></span>
            </button>
            <span className="num mp-year-label">{viewYear}</span>
            <button type="button" className="mp-nav" onClick={() => setViewYear(y => y + 1)} aria-label="Следующий год">
              <Icon name="chevR" size={16} />
            </button>
          </div>
          <div className="month-pick-grid">
            {MONTHS_RU.map((mName, i) => (
              <button type="button" key={i}
                className={'mp-month' + (i === month && viewYear === year ? ' active' : '')}
                onClick={() => pick(i)}>
                {mName.slice(0, 3)}
              </button>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}

function Plate({ id, label, size }) {
  const p = PLATFORMS.find(x => x.id === id) || CABINETS.find(x => x.id === id);
  const cls = p?.cls || id;
  const glyph = p?.glyph || (id || '').slice(0,2).toUpperCase();
  const nm = label || p?.short || p?.name;
  return (
    <span className={'plate ' + cls} style={size === 'lg' ? { fontSize: 13.5, padding: '6px 12px 6px 9px' } : null}>
      <span className="glyph" style={size === 'lg' ? { width: 22, height: 22, fontSize: 11 } : null}>{glyph}</span>
      {nm}
    </span>
  );
}

function Delta({ value, suffix }) {
  if (value == null) return <span className="delta flat">–</span>;
  const up = value >= 0;
  return (
    <span className={'delta ' + (up ? 'up' : 'down')}>
      <Icon name={up ? 'arrowUp' : 'arrowDn'} size={13} stroke={2.2} />
      {fmtPct(Math.abs(value))}{suffix ? <span style={{ color: 'var(--ink-3)', fontWeight: 500 }}> {suffix}</span> : null}
    </span>
  );
}

/* ---- Area + line chart (SVG) ------------------------------- */
function AreaChart({ data, width = 560, height = 150, accent = 'var(--green)', highlightFrom = 0, showAxis = true, valueKey = 'v' }) {
  if (!data || data.length === 0) {
    return (
      <svg viewBox={`0 0 ${width} ${height}`} width="100%" style={{ display: 'block', overflow: 'visible' }}>
        <text x={width / 2} y={height / 2} fontSize="12" fill="var(--ink-3)" textAnchor="middle">Нет данных</text>
      </svg>
    );
  }
  const pad = { t: 14, r: 6, b: showAxis ? 22 : 6, l: 6 };
  const vals = data.map(d => typeof d === 'number' ? d : d[valueKey]);
  const max = Math.max(...vals), min = Math.min(...vals);
  const range = max - min || 1;
  const iw = width - pad.l - pad.r, ih = height - pad.t - pad.b;
  const x = (i) => pad.l + (i / (data.length - 1)) * iw;
  const y = (v) => pad.t + ih - ((v - min) / range) * ih;
  const pts = vals.map((v, i) => [x(i), y(v)]);
  const line = pts.map((p, i) => (i ? 'L' : 'M') + p[0].toFixed(1) + ' ' + p[1].toFixed(1)).join(' ');
  const area = line + ` L ${x(data.length - 1).toFixed(1)} ${(pad.t + ih).toFixed(1)} L ${pad.l} ${(pad.t + ih).toFixed(1)} Z`;
  const gid = 'g' + Math.random().toString(36).slice(2, 7);
  const last = pts[pts.length - 1];
  return (
    <svg viewBox={`0 0 ${width} ${height}`} width="100%" style={{ display: 'block', overflow: 'visible' }}>
      <defs>
        <linearGradient id={gid} x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor={accent} stopOpacity="0.16" />
          <stop offset="100%" stopColor={accent} stopOpacity="0" />
        </linearGradient>
      </defs>
      <path d={area} fill={`url(#${gid})`} />
      <path d={line} fill="none" stroke={accent} strokeWidth="2.2" strokeLinejoin="round" strokeLinecap="round" />
      {pts.map((p, i) => i >= highlightFrom && (
        <circle key={i} cx={p[0]} cy={p[1]} r={i === pts.length - 1 ? 3.6 : 2.2}
          fill={i === pts.length - 1 ? accent : 'var(--surface)'} stroke={accent} strokeWidth="1.6" />
      ))}
      <circle cx={last[0]} cy={last[1]} r="6" fill={accent} opacity="0.14" />
      {showAxis && data.map((d, i) => (i % Math.ceil(data.length / 8) === 0 || i === data.length - 1) && (
        <text key={i} x={x(i)} y={height - 4} fontSize="9.5" fill="var(--ink-3)" textAnchor="middle"
          fontFamily="var(--mono)">{typeof d === 'object' ? d.d : ''}</text>
      ))}
    </svg>
  );
}

/* ---- Mini sparkline ---------------------------------------- */
function Spark({ data, width = 132, height = 44, accent = 'var(--green)' }) {
  if (!data || data.length === 0) {
    return (
      <svg viewBox={`0 0 ${width} ${height}`} width={width} height={height} style={{ display: 'block' }}>
        <text x={width / 2} y={height / 2} fontSize="10" fill="var(--ink-3)" textAnchor="middle">Нет данных</text>
      </svg>
    );
  }
  const vals = data.map(d => typeof d === 'number' ? d : d.v);
  const max = Math.max(...vals), min = Math.min(...vals), range = max - min || 1;
  const x = (i) => (i / (vals.length - 1)) * (width - 4) + 2;
  const y = (v) => height - 4 - ((v - min) / range) * (height - 8);
  const line = vals.map((v, i) => (i ? 'L' : 'M') + x(i).toFixed(1) + ' ' + y(v).toFixed(1)).join(' ');
  const last = [x(vals.length - 1), y(vals[vals.length - 1])];
  return (
    <svg viewBox={`0 0 ${width} ${height}`} width={width} height={height} style={{ display: 'block' }}>
      <path d={line} fill="none" stroke={accent} strokeWidth="2" strokeLinejoin="round" strokeLinecap="round" />
      <circle cx={last[0]} cy={last[1]} r="2.6" fill={accent} />
    </svg>
  );
}

/* ---- Drawer ------------------------------------------------- */
function Drawer({ open, onClose, title, sub, children }) {
  useEffect(() => {
    const h = (e) => e.key === 'Escape' && onClose();
    if (open) window.addEventListener('keydown', h);
    return () => window.removeEventListener('keydown', h);
  }, [open, onClose]);
  if (!open) return null;
  return (
    <>
      <div className="overlay show" onClick={onClose} />
      <aside className="drawer show drawer-enter" aria-hidden={false}>
        <div className="drawer-head">
          <div style={{ flex: 1 }}>
            {sub && <div className="eyebrow" style={{ marginBottom: 4 }}>{sub}</div>}
            <div style={{ fontSize: 17, fontWeight: 600, letterSpacing: '-0.01em' }}>{title}</div>
          </div>
          <button className="iconbtn" onClick={onClose}><Icon name="close" size={18} /></button>
        </div>
        <div className="drawer-body">{children}</div>
      </aside>
    </>
  );
}

/* ---- Section header ---------------------------------------- */
function SectionHead({ icon, title, action }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 14 }}>
      {icon && <span style={{ color: 'var(--ink-2)' }}><Icon name={icon} size={18} /></span>}
      <span className="section-title">{title}</span>
      {action && <span style={{ marginLeft: 'auto' }}>{action}</span>}
    </div>
  );
}

Object.assign(window, { Icon, Plate, Delta, AreaChart, Spark, Drawer, SectionHead, useState, useEffect, useRef });
