// The Fone Shop — Admin PWA (mobile-first)
// Tabs: Leads · Bookings · Shop(Services|Stock) · Settings
const { useState, useMemo, useEffect, useRef } = React;

// ========== DATA ==========

const LEADS = [
  { ref: 'FS-20260419-M3R8', name: 'Karen Willis', phone: '07891 234 556', email: 'karen.w@gmail.com',     device: 'iPhone 14', issue: 'Back glass cracked', channel: 'camera',    received: '11 min ago', starting: 75 },
  { ref: 'FS-20260419-H2J1', name: 'Mark T.',      phone: '07712 009 441', email: 'markt1988@outlook.com', device: 'Samsung Galaxy S22', issue: 'Screen replacement', channel: 'messenger', received: '38 min ago', starting: 120 },
  { ref: 'FS-20260419-Q9P4', name: 'Priya S.',     phone: '07900 771 229', email: 'priya.s@icloud.com',   device: 'MacBook Air M1', issue: 'Battery won\u2019t charge', channel: 'form', received: '1 h ago', starting: 135 },
  { ref: 'FS-20260419-X2Z7', name: 'Tom Walker',   phone: '07545 118 904', email: null,                    device: 'Nintendo Switch', issue: 'Joy-Con drift', channel: 'camera', received: '2 h ago', starting: 45 },
];

const BOOKINGS = [
  { ref: 'FS-20260418-A7K3', name: 'John Saunders', phone: '07812 556 014', email: 'j.saunders@btinternet.com', device: 'iPhone 13',   service: 'Screen repair',     status: 'in_progress',  due: 'Today 16:00', price: 89,  consumes: 'SCR-IP13-BLK' },
  { ref: 'FS-20260418-B2M1', name: 'Ellie Price',   phone: '07923 100 887', email: 'ellie.price@gmail.com',    device: 'iPad Air 4',  service: 'Battery swap',      status: 'ready',        due: 'Today 12:30', price: 110, consumes: 'BAT-IPAD-A4' },
  { ref: 'FS-20260418-C5H9', name: 'Marcus K.',     phone: '07455 220 913', email: 'marcusk@hotmail.co.uk',    device: 'PS5',         service: 'HDMI port repair',  status: 'in_progress',  due: 'Today 17:00', price: 70,  consumes: 'HDMI-PS5' },
  { ref: 'FS-20260417-D8L4', name: 'Sarah M.',      phone: '07700 900 122', email: 'sarahm@icloud.com',        device: 'iPhone 12',   service: 'Back glass',        status: 'collected',    due: 'Yesterday',   price: 55,  consumes: 'BCK-IP12' },
  { ref: 'FS-20260418-E3N6', name: 'Dev Patel',     phone: '07866 443 201', email: null,                       device: 'MacBook Pro', service: 'Keyboard repair',   status: 'waiting_part', due: 'Mon 21 Apr',  price: 195, consumes: 'KBD-MBP16' },
];

// SERVICES: what the shop sells. Each has variants (device-specific) or a flat price.
// Variants link to a stock SKU — completing the service consumes 1 from stock.
const SERVICES_SEED = [
  {
    id: 'screen', name: 'Screen repair', kind: 'variant',
    icon: 'screen', description: 'OEM-grade screen replacement, 12-month warranty.',
    variants: [
      { id: 'sv-ip15p', device: 'iPhone 15 Pro',   price: 189, sku: 'SCR-IP15P-TI', durationMin: 45 },
      { id: 'sv-ip14',  device: 'iPhone 14',        price: 129, sku: 'SCR-IP14-BLK', durationMin: 45 },
      { id: 'sv-ip13',  device: 'iPhone 13',        price: 89,  sku: 'SCR-IP13-BLK', durationMin: 40 },
      { id: 'sv-s22',   device: 'Samsung S22',      price: 120, sku: 'SCR-S22-BLK',  durationMin: 50 },
      { id: 'sv-ipa4',  device: 'iPad Air 4',       price: 135, sku: 'SCR-IPAD-A4',  durationMin: 60 },
    ],
  },
  {
    id: 'battery', name: 'Battery swap', kind: 'variant',
    icon: 'battery', description: 'Fresh cell, calibration, tested under load.',
    variants: [
      { id: 'bv-ip13',  device: 'iPhone 13',        price: 55,  sku: 'BAT-IP13',     durationMin: 30 },
      { id: 'bv-ipa4',  device: 'iPad Air 4',       price: 110, sku: 'BAT-IPAD-A4',  durationMin: 60 },
      { id: 'bv-mba',   device: 'MacBook Air M1',   price: 135, sku: 'BAT-MBA-M1',   durationMin: 90 },
    ],
  },
  {
    id: 'backglass', name: 'Back glass', kind: 'variant',
    icon: 'glass', description: 'Laser cut, UV-bonded. Same-day on iPhone 12+.',
    variants: [
      { id: 'gv-ip12',  device: 'iPhone 12',        price: 55,  sku: 'BCK-IP12', durationMin: 45 },
      { id: 'gv-ip14',  device: 'iPhone 14',        price: 75,  sku: 'BCK-IP14', durationMin: 45 },
    ],
  },
  {
    id: 'hdmi', name: 'HDMI port repair', kind: 'variant',
    icon: 'console', description: 'Console port micro-soldering.',
    variants: [
      { id: 'hv-ps5',   device: 'PS5',              price: 70,  sku: 'HDMI-PS5',     durationMin: 90 },
      { id: 'hv-xbox',  device: 'Xbox Series X',    price: 75,  sku: 'HDMI-XBXSX',   durationMin: 90 },
    ],
  },
  {
    id: 'diag', name: 'Diagnostic', kind: 'flat',
    icon: 'diag', description: '30-minute workup. Fee redeemed against any repair.',
    price: 15, durationMin: 30,
  },
  {
    id: 'water', name: 'Liquid damage', kind: 'flat',
    icon: 'water', description: 'Ultrasonic clean, board inspection, no-fix-no-fee.',
    price: 45, durationMin: 120,
  },
];

// STOCK: real parts. Cost = what the shop pays, not what it sells for.
const STOCK_SEED = [
  { sku: 'SCR-IP15P-TI', name: 'iPhone 15 Pro screen — Titanium', cost: 98,  qty: 2, min: 1, supplier: 'MobileSentrix', lastIn: '12 Apr', turn: 8 },
  { sku: 'SCR-IP14-BLK', name: 'iPhone 14 screen — Black',        cost: 62,  qty: 1, min: 2, supplier: 'MobileSentrix', lastIn: '02 Apr', turn: 14 },
  { sku: 'SCR-IP13-BLK', name: 'iPhone 13 screen — Black',        cost: 38,  qty: 4, min: 2, supplier: 'MobileSentrix', lastIn: '09 Apr', turn: 22 },
  { sku: 'SCR-S22-BLK',  name: 'Samsung S22 screen — Black',      cost: 55,  qty: 3, min: 1, supplier: 'ETrade',        lastIn: '08 Apr', turn: 6 },
  { sku: 'SCR-IPAD-A4',  name: 'iPad Air 4 screen',               cost: 72,  qty: 3, min: 1, supplier: 'iFixit',        lastIn: '01 Apr', turn: 3 },
  { sku: 'BAT-IP13',     name: 'iPhone 13 battery',               cost: 18,  qty: 6, min: 3, supplier: 'MobileSentrix', lastIn: '10 Apr', turn: 18 },
  { sku: 'BAT-IPAD-A4',  name: 'iPad Air 4 battery',              cost: 48,  qty: 2, min: 1, supplier: 'iFixit',        lastIn: '28 Mar', turn: 4 },
  { sku: 'BAT-MBA-M1',   name: 'MacBook Air M1 battery',          cost: 65,  qty: 0, min: 1, supplier: 'iFixit',        lastIn: '20 Mar', turn: 2 },
  { sku: 'BCK-IP12',     name: 'iPhone 12 back glass',            cost: 14,  qty: 5, min: 2, supplier: 'MobileSentrix', lastIn: '11 Apr', turn: 12 },
  { sku: 'BCK-IP14',     name: 'iPhone 14 back glass',            cost: 22,  qty: 3, min: 2, supplier: 'MobileSentrix', lastIn: '06 Apr', turn: 8 },
  { sku: 'HDMI-PS5',     name: 'PS5 HDMI port',                   cost: 9,   qty: 2, min: 1, supplier: 'AliExpress',    lastIn: '03 Apr', turn: 4 },
  { sku: 'HDMI-XBXSX',   name: 'Xbox Series X HDMI port',         cost: 11,  qty: 1, min: 1, supplier: 'AliExpress',    lastIn: '25 Mar', turn: 2 },
  { sku: 'KBD-MBP16',    name: 'MacBook Pro 16" keyboard',        cost: 72,  qty: 0, min: 1, supplier: 'iFixit',        lastIn: '—',      turn: 1 },
];

// ========== ATOMS ==========

const Eyebrow = ({ children, tone }) => (
  <div style={{
    fontSize: 10, fontWeight: 600, letterSpacing: '0.22em', textTransform: 'uppercase',
    color: tone === 'ember' ? '#FF6B1A' : '#86868b',
  }}>{children}</div>
);

const Mono = ({ children, style, ...rest }) => (
  <span style={{ fontFamily: 'JetBrains Mono, ui-monospace, monospace', fontVariantNumeric: 'tabular-nums', ...style }} {...rest}>{children}</span>
);

const StatusPill = ({ s }) => {
  const MAP = {
    in_progress:  { label: 'In progress',  color: '#ff9f0a' },
    ready:        { label: 'Ready',        color: '#30d158' },
    collected:    { label: 'Collected',    color: '#86868b' },
    waiting_part: { label: 'Waiting part', color: '#2997ff' },
  };
  const m = MAP[s] || MAP.in_progress;
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, padding: '3px 10px', borderRadius: 980, background: 'rgba(255,255,255,0.05)', boxShadow: 'inset 0 0 0 1px rgba(255,255,255,0.08)', fontSize: 12, color: '#fff' }}>
      <span style={{ width: 6, height: 6, borderRadius: '50%', background: m.color }} /> {m.label}
    </span>
  );
};

const ChannelIcon = ({ c }) => {
  const ICONS = {
    camera:    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z"/><circle cx="12" cy="13" r="3"/></svg>,
    messenger: <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 2C6.5 2 2 6.2 2 11.2c0 2.9 1.4 5.5 3.7 7.2V22l3.4-1.9c.9.3 1.9.4 2.9.4 5.5 0 10-4.2 10-9.3S17.5 2 12 2z"/><path d="M7 13l3-4 3 3 4-4"/></svg>,
    form:      <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><rect x="3" y="4" width="18" height="16" rx="2"/><path d="M7 9h10M7 13h10M7 17h6"/></svg>,
  };
  return <span style={{ color: '#86868b', display: 'inline-flex' }}>{ICONS[c]}</span>;
};

const ServiceIcon = ({ kind, size = 18, color = '#FF6B1A' }) => {
  const s = { width: size, height: size, color };
  switch (kind) {
    case 'screen':  return <svg {...s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="5" y="2" width="14" height="20" rx="2.5"/><path d="M11 18h2" /></svg>;
    case 'battery': return <svg {...s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="2" y="7" width="18" height="10" rx="2"/><path d="M22 11v2"/><path d="M6 11v2M10 10v4M14 10v4"/></svg>;
    case 'glass':   return <svg {...s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="5" y="2" width="14" height="20" rx="2.5"/><path d="M8 6l8 8M12 6l4 4"/></svg>;
    case 'console': return <svg {...s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M6 18h12a4 4 0 0 0 0-8H6a4 4 0 0 0 0 8z"/><circle cx="9" cy="14" r="1"/><circle cx="15" cy="13" r="1"/><path d="M16 15h-1"/></svg>;
    case 'diag':    return <svg {...s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M22 12h-4l-3 8-6-16-3 8H2"/></svg>;
    case 'water':   return <svg {...s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M12 2s6 7 6 12a6 6 0 0 1-12 0c0-5 6-12 6-12z"/></svg>;
    default:        return <svg {...s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8"><circle cx="12" cy="12" r="9"/></svg>;
  }
};

const SegmentedControl = ({ value, onChange, options }) => (
  <div style={{
    display: 'grid', gridTemplateColumns: `repeat(${options.length}, 1fr)`,
    gap: 2, padding: 3,
    background: '#0a0a0a', border: '1px solid #1a1a1a', borderRadius: 11,
  }}>
    {options.map(o => {
      const active = o.value === value;
      return (
        <button key={o.value} onClick={() => onChange(o.value)} style={{
          height: 34, background: active ? '#1d1d1f' : 'transparent',
          color: active ? '#fff' : '#86868b',
          border: 0, borderRadius: 9,
          font: '500 13px Inter', letterSpacing: '-0.011em',
          cursor: 'pointer',
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6,
          transition: 'background 180ms ease, color 180ms ease',
          boxShadow: active ? '0 1px 0 rgba(255,255,255,0.08) inset, 0 6px 14px rgba(0,0,0,0.5)' : 'none',
        }}>
          {o.label}
          {o.badge != null && (
            <span style={{
              minWidth: 18, height: 18, padding: '0 6px', borderRadius: 9,
              background: active ? '#FF6B1A' : '#2c2c2e',
              color: active ? '#000' : '#86868b',
              fontSize: 10, fontWeight: 600,
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            }}>{o.badge}</span>
          )}
        </button>
      );
    })}
  </div>
);

const StockBadge = ({ qty, min }) => {
  const tone = qty === 0 ? { c: '#ff453a', bg: 'rgba(255,69,58,0.12)', l: 'OUT' }
              : qty <= min ? { c: '#ff9f0a', bg: 'rgba(255,159,10,0.12)', l: 'LOW' }
              : { c: '#30d158', bg: 'rgba(48,209,88,0.1)', l: 'OK' };
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 6,
      padding: '3px 8px', borderRadius: 6, background: tone.bg,
      color: tone.c, fontSize: 10, fontWeight: 600, letterSpacing: '0.08em',
    }}>
      <Mono style={{ fontSize: 12 }}>{qty}</Mono> {tone.l}
    </span>
  );
};

const Field = ({ label, children }) => (
  <div>
    <div style={{ fontSize: 10, letterSpacing: '0.2em', color: '#86868b', marginBottom: 6, fontWeight: 600 }}>{label}</div>
    <div style={{ padding: '11px 12px', background: '#000', border: '1px solid #2c2c2e', borderRadius: 10 }}>
      {children}
    </div>
  </div>
);

const fieldInput = {
  width: '100%', background: 'transparent', border: 0, outline: 'none',
  color: '#fff', font: '14px Inter', letterSpacing: '-0.011em', padding: 0,
};

// Bottom sheet — thumb-friendly modal
const Sheet = ({ open, onClose, title, subtitle, children, actions }) => {
  if (!open) return null;
  return (
    <div onClick={onClose} style={{
      position: 'absolute', inset: 0, zIndex: 50,
      background: 'rgba(0,0,0,0.55)', backdropFilter: 'blur(12px)',
      display: 'flex', alignItems: 'flex-end',
      animation: 'fadeIn 220ms ease',
    }}>
      <div onClick={e => e.stopPropagation()} style={{
        width: '100%', background: '#0a0a0a',
        borderTop: '1px solid #2c2c2e',
        borderRadius: '22px 22px 0 0',
        padding: 16, maxHeight: '88%', overflow: 'auto',
        animation: 'slideUp 320ms cubic-bezier(0.25,0.1,0.25,1)',
        display: 'flex', flexDirection: 'column', gap: 14,
      }}>
        <div style={{ width: 36, height: 4, background: '#3a3a3c', borderRadius: 2, margin: '0 auto' }} />
        {(title || subtitle) && (
          <div>
            {subtitle && <Eyebrow>{subtitle}</Eyebrow>}
            {title && <div style={{ marginTop: 4, fontSize: 20, fontWeight: 600, letterSpacing: '-0.02em' }}>{title}</div>}
          </div>
        )}
        <div>{children}</div>
        {actions && <div style={{ display: 'flex', gap: 8 }}>{actions}</div>}
      </div>
    </div>
  );
};

const PrimaryButton = ({ children, disabled, tone = 'ember', onClick, flex = true }) => (
  <button onClick={onClick} disabled={disabled} style={{
    flex: flex ? 1 : 'none',
    height: 48,
    background: disabled ? '#1d1d1f' : tone === 'success' ? '#30d158' : '#FF6B1A',
    color: disabled ? '#86868b' : '#000',
    border: 0, borderRadius: 14,
    font: '600 15px Inter', letterSpacing: '-0.011em',
    cursor: disabled ? 'not-allowed' : 'pointer',
    display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8,
    transition: 'background 200ms ease, transform 120ms ease',
  }}>{children}</button>
);

const GhostButton = ({ children, onClick }) => (
  <button onClick={onClick} style={{
    height: 48, padding: '0 18px',
    background: 'transparent', color: '#86868b',
    border: 0, boxShadow: 'inset 0 0 0 1px #2c2c2e', borderRadius: 14,
    font: '500 14px Inter', cursor: 'pointer',
  }}>{children}</button>
);

const qbtn = (disabled) => ({
  width: 30, height: 30, borderRadius: 8,
  background: disabled ? '#0a0a0a' : '#1d1d1f',
  border: 0, color: disabled ? '#3a3a3c' : '#fff',
  cursor: disabled ? 'not-allowed' : 'pointer',
  font: '600 15px Inter', userSelect: 'none',
});

Object.assign(window, { Eyebrow, Mono, StatusPill, ChannelIcon, ServiceIcon,
  SegmentedControl, StockBadge, Field, fieldInput, Sheet, PrimaryButton, GhostButton, qbtn });
