// HOS — Admin / back-office panel
// Same brand palette, dense layout, real interactions on mock data.

/* ───────────── Mock back-office data ───────────── */

// Generate 30-day sales series with some natural waviness
const ADMIN_SALES_30D = (() => {
  const arr = [];
  const today = new Date();
  let base = 3200;
  for (let i = 29; i >= 0; i--) {
    const d = new Date(today); d.setDate(today.getDate() - i);
    // gentle sine + noise + weekend lift
    const wave = Math.sin(i * 0.42) * 900;
    const noise = (Math.random() - 0.4) * 1100;
    const weekend = (d.getDay() === 0 || d.getDay() === 6) ? 1200 : 0;
    const v = Math.max(900, Math.round(base + wave + noise + weekend));
    arr.push({ date: d, value: v });
  }
  return arr;
})();

const ADMIN_KPIS = (() => {
  const total = ADMIN_SALES_30D.reduce((s, d) => s + d.value, 0);
  const prevTotal = total * 0.83;
  const orders = 312;
  return [
    { id:'revenue', label:'Revenue (30d)',  value:`$${total.toLocaleString()}`, delta:+18.2, accent:'rose' },
    { id:'orders',  label:'Orders (30d)',   value: orders.toString(),            delta:+12.4, accent:'rose' },
    { id:'aov',     label:'Avg. order',     value:`$${Math.round(total/orders)}`, delta:+5.1,  accent:'rose' },
    { id:'cvr',     label:'Conversion',     value:'3.42%',                        delta:-0.6,  accent:'rose' },
  ];
})();

const ADMIN_ORDERS = [
  { id:'1208', customer:'Léa Bernard',     email:'lea.b@email.com',     total:248, status:'paid',      items:1, date:'2026-06-04 · 14:32', country:'FR', address:'12 Rue de Rivoli, 75001 Paris, France',          trackingNumber:'',               notes:'', lineItems:[{name:'Aurelie Silk Slip Dress',    color:'Blush',     size:'S',  qty:1, price:248, img:'https://images.unsplash.com/photo-1539109136881-3be0616acf4b?w=80&q=60'}] },
  { id:'1207', customer:'Imane Saadi',     email:'imane.s@email.com',   total:412, status:'paid',      items:2, date:'2026-06-04 · 11:08', country:'TN', address:'45 Avenue Habib Bourguiba, 1000 Tunis, Tunisia',  trackingNumber:'',               notes:'', lineItems:[{name:'Adèle Bias Maxi Dress',      color:'Champagne', size:'M',  qty:1, price:248, img:'https://images.unsplash.com/photo-1572804013309-59a88b7e92f1?w=80&q=60'},{name:'Solene Knot Top',color:'Ivory',size:'S',qty:1,price:164,img:'https://images.unsplash.com/photo-1515886657613-9f3515b0c78f?w=80&q=60'}] },
  { id:'1206', customer:'Sophie Tremblay', email:'sophie.t@email.com',  total:184, status:'shipped',   items:1, date:'2026-06-04 · 09:47', country:'CA', address:'220 Laurier Ave W, Ottawa ON K1P 5Z9, Canada',    trackingNumber:'DHL-4928374651', notes:'', lineItems:[{name:'Mireille Pleated Skirt',      color:'Blush',     size:'XS', qty:1, price:184, img:'https://images.unsplash.com/photo-1539109136881-3be0616acf4b?w=80&q=60'}] },
  { id:'1205', customer:'Camille Roy',     email:'camille.r@email.com', total:325, status:'fulfilled', items:1, date:'2026-06-03',          country:'FR', address:'8 Rue du Faubourg Saint-Antoine, 75011 Paris',   trackingNumber:'DHL-3817263540', notes:'Gift wrap requested.',  lineItems:[{name:'Margaux Tailored Blazer',     color:'Cocoa',     size:'M',  qty:1, price:325, img:'https://images.unsplash.com/photo-1515886657613-9f3515b0c78f?w=80&q=60'}] },
  { id:'1204', customer:'Olivia Park',     email:'olivia.p@email.com',  total:498, status:'paid',      items:2, date:'2026-06-03',          country:'CA', address:'1020 Burrard St, Vancouver BC V6Z 1Y5, Canada',   trackingNumber:'',               notes:'', lineItems:[{name:'Eloise Satin Slip',           color:'Ivory',     size:'S',  qty:1, price:268, img:'https://images.unsplash.com/photo-1539109136881-3be0616acf4b?w=80&q=60'},{name:'Romy Cropped Cardigan',color:'Blush',size:'XS',qty:1,price:230,img:'https://images.unsplash.com/photo-1572804013309-59a88b7e92f1?w=80&q=60'}] },
  { id:'1203', customer:'Yasmine Khaled',  email:'yasmine.k@email.com', total:168, status:'refunded',  items:1, date:'2026-06-02',          country:'TN', address:'15 Rue Ibn Khaldoun, 3000 Sfax, Tunisia',        trackingNumber:'DHL-2736451823', notes:'Return received 2026-06-01.', lineItems:[{name:'Romy Cropped Cardigan',   color:'Champagne', size:'M',  qty:1, price:168, img:'https://images.unsplash.com/photo-1515886657613-9f3515b0c78f?w=80&q=60'}] },
  { id:'1202', customer:'Anaïs Lemay',     email:'anais.l@email.com',   total:198, status:'shipped',   items:1, date:'2026-06-02',          country:'CA', address:'2100 Mackay St, Montréal QC H3G 2J1, Canada',    trackingNumber:'DHL-1837465029', notes:'', lineItems:[{name:'Lila Wide-Leg Trousers',      color:'Ivory',     size:'S',  qty:1, price:198, img:'https://images.unsplash.com/photo-1539109136881-3be0616acf4b?w=80&q=60'}] },
  { id:'1201', customer:'Margaux Petit',   email:'margaux.p@email.com', total:368, status:'fulfilled', items:1, date:'2026-06-01',          country:'FR', address:'3 Allée des Roses, 69001 Lyon, France',          trackingNumber:'DHL-0928374651', notes:'', lineItems:[{name:'Adèle Bias Maxi Dress',      color:'Blush',     size:'S',  qty:1, price:368, img:'https://images.unsplash.com/photo-1572804013309-59a88b7e92f1?w=80&q=60'}] },
  { id:'1200', customer:'Rim Ben Salah',   email:'rim.bs@email.com',    total:124, status:'fulfilled', items:1, date:'2026-06-01',          country:'TN', address:'7 Rue de Marseille, 5000 Monastir, Tunisia',     trackingNumber:'DHL-9182736450', notes:'', lineItems:[{name:'Solene Knot Top',           color:'Cocoa',     size:'XS', qty:1, price:124, img:'https://images.unsplash.com/photo-1515886657613-9f3515b0c78f?w=80&q=60'}] },
  { id:'1199', customer:'Juliette Marec',  email:'juliette.m@email.com',total:295, status:'fulfilled', items:1, date:'2026-05-31',          country:'FR', address:'18 Boulevard des Capucines, 75009 Paris, France', trackingNumber:'DHL-8273645019', notes:'', lineItems:[{name:'Celeste Linen Co-ord Set',  color:'Champagne', size:'M',  qty:1, price:295, img:'https://images.unsplash.com/photo-1539109136881-3be0616acf4b?w=80&q=60'}] },
];

const ADMIN_TICKETS = [
  { id:'T-309', customer:'Léa Bernard',     email:'lea.b@email.com',    subject:'Size exchange for Aurelie slip',      status:'open',    priority:'normal', date:'24 min ago',  unread:true,
    snippet:"Hi, I’d love to exchange the size S for M — the fit is beautiful but slightly small at the bust…",
    messages:[{ id:1, from:'customer', author:'Léa Bernard',      body:"Hi,\n\nI’d love to exchange the size S for M — the fit is beautiful but slightly small at the bust. Is it still possible to do an exchange?\n\nBest,\nLéa", date:'24 min ago' }] },
  { id:'T-308', customer:'Sophie Tremblay', email:'sophie.t@email.com', subject:'When will my order ship?',            status:'replied', priority:'normal', date:'1 h ago',     unread:false,
    snippet:"Hello, my order #1206 was placed two days ago and hasn’t shipped yet…",
    messages:[
      { id:1, from:'customer', author:'Sophie Tremblay',  body:"Hello,\n\nMy order #1206 was placed two days ago and hasn’t shipped yet — do you have an estimated dispatch date?\n\nThanks,\nSophie", date:'3 h ago' },
      { id:2, from:'team',     author:'House of Sheylas', body:"Hi Sophie,\n\nYour order has been picked and is being packed. You’ll receive a DHL tracking confirmation within 24 hours.\n\nWarmly,\nThe HOS Team", date:'1 h ago' }
    ]},
  { id:'T-307', customer:'Olivia Park',     email:'olivia.p@email.com', subject:'Combine two orders into one parcel?', status:'open',    priority:'low',    date:'3 h ago',     unread:true,
    snippet:"Hi team, I placed two orders this morning and was wondering if you could ship them together…",
    messages:[{ id:1, from:'customer', author:'Olivia Park', body:"Hi team,\n\nI placed two orders this morning and was wondering if you could ship them together to save on packaging?\n\nThanks!\nOlivia", date:'3 h ago' }] },
  { id:'T-306', customer:'Yasmine Khaled',  email:'yasmine.k@email.com',subject:'Refund question',                     status:'open',    priority:'high',   date:'Yesterday',   unread:true,
    snippet:"Hello, I returned the Romy cardigan a week ago — when can I expect the refund…",
    messages:[{ id:1, from:'customer', author:'Yasmine Khaled', body:"Hello,\n\nI returned the Romy cardigan a week ago — the carrier confirmed delivery on May 28. When can I expect the refund to appear on my card?\n\nBest,\nYasmine", date:'Yesterday · 09:14' }] },
  { id:'T-305', customer:'Press @ Vogue',   email:'press@vogue.fr',     subject:'Press loan request — Spring Bloom',  status:'replied', priority:'high',   date:'Yesterday',   unread:false,
    snippet:"Bonjour, we’d love to feature pieces from the Spring Bloom Édition in our April issue…",
    messages:[
      { id:1, from:'customer', author:'Vogue Press Team',  body:"Bonjour,\n\nWe’d love to feature pieces from the Spring Bloom Édition in our April issue. Could we arrange a press loan of 3–5 looks for a shoot on June 12?\n\nMerci,\nVogue FR", date:'Yesterday · 11:30' },
      { id:2, from:'team',     author:'House of Sheylas', body:"Bonjour,\n\nThank you — we’d be delighted to collaborate! Our PR team will follow up with loan agreement details by EOD.\n\nÀ bientôt,\nThe HOS Team", date:'Yesterday · 14:20' }
    ]},
  { id:'T-304', customer:'Rim Ben Salah',   email:'rim.bs@email.com',   subject:'Wholesale enquiry',                  status:'closed',  priority:'normal', date:'2 days ago',  unread:false,
    snippet:"Bonjour, je tiens une concept-store à Tunis — j’aimerais discuter d’une collaboration…",
    messages:[
      { id:1, from:'customer', author:'Rim Ben Salah',    body:"Bonjour,\n\nJe tiens une concept-store à Tunis — j’aimerais discuter d’une collaboration wholesale. Pouvez-vous partager vos conditions?\n\nCordialement,\nRim", date:'2 days ago · 10:00' },
      { id:2, from:'team',     author:'House of Sheylas', body:"Bonjour Rim,\n\nMerci pour votre intérêt! Notre équipe wholesale va vous contacter avec notre catalogue B2B et nos conditions.\n\nÀ très bientôt,\nHOS", date:'2 days ago · 15:00' }
    ]},
  { id:'T-303', customer:'Anaïs Lemay',     email:'anais.l@email.com',  subject:'Pricing in CAD',                     status:'replied', priority:'low',    date:'2 days ago',  unread:false,
    snippet:"Hello, do you offer prices in Canadian dollars for shipments to Canada?",
    messages:[
      { id:1, from:'customer', author:'Anaïs Lemay',      body:"Hello, do you offer prices in Canadian dollars for shipments to Canada? The USD conversion makes it a bit tricky to budget.", date:'2 days ago · 08:30' },
      { id:2, from:'team',     author:'House of Sheylas', body:"Hi Anaïs,\n\nAt the moment we invoice in USD, but your bank will convert at the daily rate. We’re exploring multi-currency support for later this year!\n\nThank you,\nHOS", date:'2 days ago · 11:00' }
    ]},
];

const ADMIN_TOP_PRODUCTS = [
  { id:'bs2', name:'Adèle Bias Maxi Dress',     sold:48, revenue:48*368 },
  { id:'na1', name:'Aurelie Silk Slip Dress',   sold:42, revenue:42*248 },
  { id:'bs1', name:'Margaux Tailored Blazer',   sold:31, revenue:31*325 },
  { id:'na4', name:'Sienna Wrap Blouse',        sold:28, revenue:28*148 },
  { id:'bs3', name:'Camille Cashmere Knit',     sold:24, revenue:24*285 },
];

const ADMIN_CHANNELS = [
  { name:'Direct',   pct:46, color:'#B86A78' },
  { name:'Instagram',pct:24, color:'#4A2D33' },
  { name:'Search',   pct:18, color:'#F6D6DA' },
  { name:'Other',    pct:12, color:'#F2E3DC' },
];

const ADMIN_COUNTRIES = [
  { code:'FR', name:'France',  pct:42 },
  { code:'CA', name:'Canada',  pct:31 },
  { code:'TN', name:'Tunisia', pct:14 },
  { code:'US', name:'United States', pct:8 },
  { code:'·',  name:'Other',   pct:5 },
];

/* ───────────── Admin state context ───────────── */
const AdminCtx = createContext(null);
function AdminProvider({ children }) {
  const { siteData, updateSiteData, resetSiteData } = useSiteData();
  const products = siteData.products;
  const categories = siteData.categories.map((category) => ({
    ...category,
    productCount: siteData.products.filter((product) => product.category === category.id).length,
  }));
  const [orders,     setOrders]     = useState(ADMIN_ORDERS);
  const [tickets,    setTickets]    = useState(ADMIN_TICKETS);
  const [toast,      setToast]      = useState(null);

  const flash = (msg, tone='success') => {
    setToast({ msg, tone, ts: Date.now() });
    setTimeout(() => setToast(null), 2400);
  };

  const saveProduct = (p) => {
    updateSiteData((current) => {
      const nextProducts = [...current.products];
      const index = nextProducts.findIndex((item) => item.id === p.id);
      if (index >= 0) {
        nextProducts[index] = { ...nextProducts[index], ...p };
      } else {
        nextProducts.unshift({ ...p, id: p.id || `new-${Date.now()}` });
      }
      return { ...current, products: nextProducts };
    });
    flash('Product saved');
  };
  const deleteProduct = (id) => {
    updateSiteData((current) => ({
      ...current,
      products: current.products.filter((product) => product.id !== id),
    }));
    flash('Product deleted','warn');
  };
  const adjustStock = (id, delta) => {
    updateSiteData((current) => ({
      ...current,
      products: current.products.map((product) =>
        product.id === id
          ? { ...product, stock: Math.max(0, (product.stock || 0) + delta) }
          : product
      ),
    }));
  };
  const setStock = (id, value) => {
    updateSiteData((current) => ({
      ...current,
      products: current.products.map((product) =>
        product.id === id ? { ...product, stock: Math.max(0, value) } : product
      ),
    }));
    flash('Stock updated');
  };
  const restock = (id, amount = 40) => {
    updateSiteData((current) => ({
      ...current,
      products: current.products.map((product) =>
        product.id === id ? { ...product, stock: (product.stock || 0) + amount } : product
      ),
    }));
    flash(`Restocked +${amount}`);
  };
  const saveCategory  = (c) => {
    updateSiteData((current) => {
      const nextCategories = [...current.categories];
      const index = nextCategories.findIndex((item) => item.id === c.id);
      const category = {
        ...c,
        id: c.id || `cat-${Date.now()}`,
        subcategories: c.subcategories || [],
      };
      if (index >= 0) nextCategories[index] = { ...nextCategories[index], ...category };
      else nextCategories.unshift(category);
      return { ...current, categories: nextCategories };
    });
    flash('Category saved');
  };
  const deleteCategory = (id) => {
    updateSiteData((current) => ({
      ...current,
      categories: current.categories.filter((category) => category.id !== id),
    }));
    flash('Category deleted','warn');
  };
  const savePages = (pages) => {
    updateSiteData((current) => ({ ...current, pages }));
    flash('Pages saved');
  };
  const saveContent = (key, value) => {
    updateSiteData((current) => ({ ...current, [key]: value }));
    flash('Content saved');
  };
  const saveSettings = (settings) => {
    updateSiteData((current) => ({ ...current, settings: { ...current.settings, ...settings } }));
    flash('Settings saved');
  };
  const updateOrderStatus = (id, status) => { setOrders(c => c.map(o => o.id === id ? {...o, status} : o)); flash('Order updated'); };
  const updateOrderField  = (id, patch)  => { setOrders(c => c.map(o => o.id === id ? {...o, ...patch} : o)); };
  const updateTicket      = (id, patch)  => { setTickets(c => c.map(t => t.id === id ? {...t, ...patch} : t)); };
  const addTicketMessage  = (id, msg)    => {
    setTickets(c => c.map(t => t.id === id
      ? { ...t, messages: [...(t.messages || []), msg], status: 'replied', unread: false }
      : t
    ));
    flash('Reply sent');
  };

  return (
    <AdminCtx.Provider value={{
      products, saveProduct, deleteProduct, adjustStock, setStock, restock,
      categories, saveCategory, deleteCategory,
      pages: siteData.pages,
      hero: siteData.hero,
      story: siteData.story,
      about: siteData.about,
      contact: siteData.contact,
      services: siteData.services,
      settings: siteData.settings,
      locations: siteData.locations,
      savePages, saveContent, saveSettings, resetSiteData,
      orders, updateOrderStatus, updateOrderField,
      tickets, updateTicket, addTicketMessage,
      flash, toast,
    }}>
      {children}
    </AdminCtx.Provider>
  );
}
const useAdmin = () => useContext(AdminCtx);

/* ───────────── Common admin pieces ───────────── */
function StatusPill({ status }) {
  const map = {
    paid:      { bg:'bg-blush',      text:'text-deep',    label:'Paid' },
    shipped:   { bg:'bg-champagne',  text:'text-deep',    label:'Shipped' },
    fulfilled: { bg:'bg-rose/15',    text:'text-rose',    label:'Fulfilled' },
    refunded:  { bg:'bg-deep/10',    text:'text-deep/70', label:'Refunded' },
    live:      { bg:'bg-rose/15',    text:'text-rose',    label:'Live' },
    draft:     { bg:'bg-deep/10',    text:'text-deep/70', label:'Draft' },
    open:      { bg:'bg-rose',       text:'text-ivory',   label:'Open' },
    replied:   { bg:'bg-champagne',  text:'text-deep',    label:'Replied' },
    closed:    { bg:'bg-deep/10',    text:'text-deep/60', label:'Closed' },
    high:      { bg:'bg-rose',       text:'text-ivory',   label:'High' },
    normal:    { bg:'bg-deep/10',    text:'text-deep/70', label:'Normal' },
    low:       { bg:'bg-blush-2',    text:'text-deep/70', label:'Low' },
  };
  const m = map[status] || { bg:'bg-deep/10', text:'text-deep/70', label:status };
  return (
    <span className={`inline-flex items-center font-sans text-[10px] tracking-widest-2 uppercase ${m.bg} ${m.text} px-2.5 py-1`}>
      {m.label}
    </span>
  );
}

function AdminCard({ children, className = '', accent = false }) {
  return (
    <div className={`bg-ivory border border-deep/10 ${accent ? 'shadow-soft' : ''} rounded-sm ${className}`}>
      {children}
    </div>
  );
}

function AdminToast() {
  const a = useAdmin();
  if (!a?.toast) return null;
  return (
    <div className="fixed bottom-6 right-6 z-[120] animate-slide-in-down">
      <div className={`px-5 py-3.5 shadow-card flex items-center gap-3 max-w-[320px]
        ${a.toast.tone === 'warn' ? 'bg-deep text-ivory' : 'bg-rose text-ivory'}`}>
        <span className="w-6 h-6 rounded-full bg-ivory/20 flex items-center justify-center">
          <I.check className="w-3.5 h-3.5"/>
        </span>
        <span className="font-sans text-[13px] tracking-wider-2">{a.toast.msg}</span>
      </div>
    </div>
  );
}

/* ───────────── Charts ───────────── */
function SalesChart({ data }) {
  const W = 720, H = 220, P = 28;
  const max = Math.max(...data.map(d => d.value)) * 1.15;
  const min = 0;
  const x = (i) => P + (i / (data.length - 1)) * (W - P*2);
  const y = (v) => H - P - ((v - min) / (max - min)) * (H - P*2);
  const points = data.map((d, i) => [x(i), y(d.value)]);
  const linePath = points.map((p, i) => `${i===0?'M':'L'} ${p[0]} ${p[1]}`).join(' ');
  const areaPath = `${linePath} L ${points[points.length-1][0]} ${H-P} L ${points[0][0]} ${H-P} Z`;

  const [hover, setHover] = useState(null);

  const days = data.map(d => d.date);
  const dayLabels = [0, 7, 14, 21, 29].map(i => ({
    x: x(i),
    label: days[i] ? days[i].toLocaleDateString('en', { day:'numeric', month:'short' }) : '',
  }));

  return (
    <div className="relative w-full">
      <svg viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="none" className="w-full h-[260px]">
        <defs>
          <linearGradient id="hosSalesGrad" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%"  stopColor="#B86A78" stopOpacity="0.32"/>
            <stop offset="100%" stopColor="#B86A78" stopOpacity="0"/>
          </linearGradient>
        </defs>
        {/* grid lines */}
        {[0.25, 0.5, 0.75].map(t => (
          <line key={t} x1={P} x2={W-P} y1={P + t*(H-P*2)} y2={P + t*(H-P*2)} stroke="#4A2D33" strokeOpacity="0.08" strokeDasharray="2 4"/>
        ))}
        {/* area */}
        <path d={areaPath} fill="url(#hosSalesGrad)"/>
        {/* line */}
        <path d={linePath} fill="none" stroke="#B86A78" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
        {/* hover marker */}
        {hover !== null && (
          <>
            <line x1={x(hover)} x2={x(hover)} y1={P} y2={H-P} stroke="#4A2D33" strokeOpacity=".25" strokeDasharray="2 3"/>
            <circle cx={x(hover)} cy={y(data[hover].value)} r="5" fill="#4A2D33" stroke="#FFF8F5" strokeWidth="2"/>
          </>
        )}
        {/* hit areas */}
        {data.map((d, i) => (
          <rect key={i} x={x(i) - (W-P*2)/(data.length*2)} y={P} width={(W-P*2)/data.length} height={H-P*2}
                fill="transparent" onMouseEnter={() => setHover(i)} onMouseLeave={() => setHover(null)} />
        ))}
        {/* x labels */}
        {dayLabels.map((l, i) => (
          <text key={i} x={l.x} y={H-6} textAnchor="middle" className="fill-deep/45" style={{font:'500 9px Outfit, sans-serif', letterSpacing:'.18em', textTransform:'uppercase'}}>
            {l.label}
          </text>
        ))}
      </svg>
      {hover !== null && (
        <div className="absolute top-4 right-4 bg-deep text-ivory px-4 py-2 shadow-card pointer-events-none">
          <div className="font-sans text-[9px] tracking-widest-2 uppercase text-ivory/60">
            {data[hover].date.toLocaleDateString('en', { weekday:'short', day:'numeric', month:'short' })}
          </div>
          <div className="font-display text-[22px] leading-none mt-0.5">${data[hover].value.toLocaleString()}</div>
        </div>
      )}
    </div>
  );
}

function DonutChart({ segments, size = 140 }) {
  const r = size/2 - 18;
  const c = 2 * Math.PI * r;
  let offset = 0;
  return (
    <svg viewBox={`0 0 ${size} ${size}`} className="block" style={{width:size, height:size}}>
      <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="#4A2D33" strokeOpacity=".08" strokeWidth="14"/>
      {segments.map((s, i) => {
        const len = (s.pct / 100) * c;
        const el = (
          <circle key={i} cx={size/2} cy={size/2} r={r} fill="none"
                  stroke={s.color} strokeWidth="14" strokeLinecap="butt"
                  strokeDasharray={`${len} ${c - len}`}
                  strokeDashoffset={-offset}
                  transform={`rotate(-90 ${size/2} ${size/2})`}/>
        );
        offset += len;
        return el;
      })}
    </svg>
  );
}

/* ───────────── Admin shell ───────────── */
function AdminShell({ children, active }) {
  const a = useAdmin();
  const auth = useAdminAuth();
  const [open, setOpen] = useState(false); // mobile sidebar
  const links = [
    { id:'home',       label:'Dashboard',  href:'#admin',           icon: AdminIcons.dash },
    { id:'products',   label:'Products',   href:'#admin/products',  icon: AdminIcons.bag,  count: a.products.length },
    { id:'categories', label:'Categories', href:'#admin/categories',icon: AdminIcons.grid, count: a.categories.length },
    { id:'content',    label:'Content',    href:'#admin/content',   icon: AdminIcons.edit, count: a.pages.length },
    { id:'inventory',  label:'Inventory',  href:'#admin/inventory', icon: AdminIcons.layers, count: a.products.filter(p => (p.stock||0) < 10).length, dot: a.products.some(p => (p.stock||0) < 10) },
    { id:'orders',     label:'Orders',     href:'#admin/orders',    icon: AdminIcons.box,  count: a.orders.length },
    { id:'tickets',    label:'Tickets',    href:'#admin/tickets',   icon: AdminIcons.chat, count: a.tickets.filter(t => t.unread).length, dot:true },
    { id:'analytics',  label:'Analytics',  href:'#admin/analytics', icon: AdminIcons.chart },
    { id:'settings',   label:'Settings',   href:'#admin/settings',  icon: AdminIcons.cog },
  ];

  return (
    <div className="admin-pro min-h-screen bg-ivory relative">
      {/* Sidebar */}
      <aside className={`fixed left-0 top-0 bottom-0 w-[240px] bg-ivory border-r border-deep/10 z-30 flex flex-col
                         ${open ? 'translate-x-0' : '-translate-x-full'} lg:translate-x-0 transition-transform duration-300`}>
        <div className="px-6 py-5 border-b border-deep/10 flex items-center justify-between">
          <a href="#admin" className="block leading-none">
            <span className="admin-wordmark block font-display text-deep text-[22px] tracking-[.18em]">{a.settings.brandMark}</span>
            <span className="block font-sans text-deep/55 text-[8px] tracking-widest-2 mt-1">ADMIN&nbsp;CONSOLE</span>
          </a>
          <button onClick={() => setOpen(false)} className="lg:hidden text-deep/60 hover:text-rose" aria-label="Close menu"><I.close className="w-5 h-5"/></button>
        </div>

        <nav className="flex-1 px-3 py-5 flex flex-col gap-0.5 overflow-y-auto">
          {links.map(l => {
            const isActive = active === l.id;
            return (
              <a key={l.id} href={l.href} onClick={() => setOpen(false)}
                 className={`flex items-center gap-3 px-3 py-2.5 rounded-sm transition-colors relative
                   ${isActive ? 'bg-blush text-deep' : 'text-deep/70 hover:bg-blush-2/60 hover:text-deep'}`}>
                {isActive && <span className="absolute left-0 top-1.5 bottom-1.5 w-0.5 bg-rose rounded-r"/>}
                <span className="w-[18px] h-[18px] flex items-center justify-center"><l.icon className="w-[18px] h-[18px]"/></span>
                <span className="font-sans text-[13px] tracking-wider-2 flex-1">{l.label}</span>
                {l.count !== undefined && l.count > 0 && (
                  <span className={`font-sans text-[10px] tracking-wider-2 px-1.5 py-0.5 rounded-sm
                    ${l.dot ? 'bg-rose text-ivory' : isActive ? 'bg-deep/10 text-deep' : 'bg-deep/5 text-deep/55'}`}>
                    {l.count}
                  </span>
                )}
              </a>
            );
          })}
        </nav>

        <div className="px-4 py-4 border-t border-deep/10 flex items-center gap-3">
          <div className="w-9 h-9 rounded-full bg-rose text-ivory flex items-center justify-center font-display text-[15px]">S</div>
          <div className="flex-1 min-w-0">
            <div className="font-serif text-deep text-[14px] leading-tight truncate">{a.settings.brandName}</div>
            <div className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/55 mt-0.5">Owner</div>
          </div>
          <button onClick={() => { auth.logout(); window.location.hash = '#admin'; }} title="Sign out" className="text-deep/55 hover:text-rose"><AdminIcons.exit className="w-4 h-4"/></button>
        </div>
      </aside>

      {/* Overlay for mobile */}
      {open && <div className="fixed inset-0 bg-deep/30 z-20 lg:hidden" onClick={() => setOpen(false)}/>}

      {/* Main */}
      <div className="lg:pl-[240px] min-h-screen flex flex-col">
        {/* Top bar */}
        <header className="sticky top-0 z-10 bg-ivory/95 backdrop-blur-md border-b border-deep/10">
          <div className="px-6 lg:px-8 h-[64px] flex items-center gap-4">
            <button onClick={() => setOpen(true)} className="lg:hidden text-deep" aria-label="Open menu"><I.menu className="w-5 h-5"/></button>
            <div className="font-sans text-[11px] tracking-widest-2 uppercase text-deep/55 hidden md:block">
              House of Sheylas · <span className="text-deep">Admin</span>
            </div>
            <div className="flex-1 max-w-[420px] ml-auto md:mx-auto">
              <div className="relative">
                <I.search className="w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-deep/50"/>
                <input
                  placeholder="Search products, orders, customers…"
                  className="w-full bg-blush-2/50 border border-transparent hover:border-deep/15 focus:border-deep focus:bg-ivory focus:outline-none transition-all rounded-sm pl-9 pr-3 py-2.5 font-sans text-[13px] tracking-wider-2 text-deep placeholder:text-deep/40"
                />
              </div>
            </div>
            <div className="flex items-center gap-2 md:gap-3">
              <button className="hidden md:inline-flex items-center gap-2 font-sans text-[11px] tracking-widest-2 uppercase text-deep/70 hover:text-rose">
                <AdminIcons.bell className="w-4 h-4"/> <span className="hidden xl:inline">Activity</span>
              </button>
              <a href="#admin/products/new" className="btn-sweep inline-flex items-center gap-2 bg-deep text-ivory font-sans text-[11px] tracking-widest-2 uppercase px-4 py-2.5 hover:bg-rose transition-colors">
                <I.plus className="w-3.5 h-3.5"/> New product
              </a>
            </div>
          </div>
        </header>

        <main className="flex-1 px-6 lg:px-8 py-6 lg:py-8">
          {children}
        </main>
      </div>

      <AdminToast/>
    </div>
  );
}

/* ───────────── Icons (admin-specific minimal set) ───────────── */
const AdminIcons = {
  dash:  (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" {...p}><rect x="3" y="3" width="8" height="10" rx="1"/><rect x="3" y="15" width="8" height="6" rx="1"/><rect x="13" y="3" width="8" height="6" rx="1"/><rect x="13" y="11" width="8" height="10" rx="1"/></svg>,
  bag:   (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" {...p}><path d="M5 8h14l-1 12H6L5 8Z"/><path d="M9 8a3 3 0 0 1 6 0"/></svg>,
  grid:  (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" {...p}><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg>,
  box:   (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" {...p}><path d="M3 7l9-4 9 4v10l-9 4-9-4V7Z"/><path d="M3 7l9 4 9-4M12 11v10"/></svg>,
  chat:  (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" {...p}><path d="M21 12a8 8 0 0 1-11.6 7.1L4 21l1.9-5.4A8 8 0 1 1 21 12Z"/></svg>,
  chart: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" {...p}><path d="M4 19V5M4 19h16M8 16l4-6 3 4 5-9"/></svg>,
  cog:   (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" {...p}><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 0 1-4 0v-.1a1.7 1.7 0 0 0-1.1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1A2 2 0 1 1 4.3 17l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 0 1 0-4h.1a1.7 1.7 0 0 0 1.5-1.1 1.7 1.7 0 0 0-.3-1.8l-.1-.1A2 2 0 1 1 7 4.3l.1.1a1.7 1.7 0 0 0 1.8.3H9a1.7 1.7 0 0 0 1-1.5V3a2 2 0 0 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1A2 2 0 1 1 19.7 7l-.1.1a1.7 1.7 0 0 0-.3 1.8V9a1.7 1.7 0 0 0 1.5 1H21a2 2 0 0 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1Z"/></svg>,
  bell:  (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" {...p}><path d="M18 16v-5a6 6 0 0 0-12 0v5l-2 2h16l-2-2Z"/><path d="M9 19a3 3 0 0 0 6 0"/></svg>,
  exit:  (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" {...p}><path d="M9 21H4V3h5"/><path d="m16 17 5-5-5-5M21 12H9"/></svg>,
  trash: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" {...p}><path d="M4 7h16M10 11v6M14 11v6M5 7l1 13h12l1-13M9 7V4h6v3"/></svg>,
  edit:  (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" {...p}><path d="M11 4H4v16h16v-7"/><path d="M19 3.5a2.1 2.1 0 0 1 3 3L12 16l-4 1 1-4 10-9.5Z"/></svg>,
  dots:  (p) => <svg viewBox="0 0 24 24" fill="currentColor" {...p}><circle cx="5" cy="12" r="1.5"/><circle cx="12" cy="12" r="1.5"/><circle cx="19" cy="12" r="1.5"/></svg>,
  upload:(p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" {...p}><path d="M21 15v4H3v-4"/><path d="m17 9-5-5-5 5"/><path d="M12 4v12"/></svg>,
  filter:(p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" {...p}><path d="M3 5h18l-7 9v6l-4-2v-4L3 5Z"/></svg>,
  layers:(p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" {...p}><path d="M12 3 3 8l9 5 9-5-9-5Z"/><path d="m3 13 9 5 9-5M3 18l9 5 9-5" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  alert: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" {...p}><path d="M12 3 2 20h20L12 3Z" strokeLinejoin="round"/><path d="M12 10v4M12 17h.01" strokeLinecap="round"/></svg>,
  trend: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" {...p}><path d="M3 17l6-6 4 4 8-8M21 7v5M21 7h-5" strokeLinecap="round" strokeLinejoin="round"/></svg>,
};

/* ───────────── Page: Dashboard ───────────── */
function AdminDashboard() {
  const a = useAdmin();
  return (
    <div className="space-y-6">
      <PageHeading title="Dashboard" sub="A snapshot of how the House is doing right now."/>

      {/* KPIs */}
      <div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
        {ADMIN_KPIS.map(k => (
          <AdminCard key={k.id} className="p-5">
            <div className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/55">{k.label}</div>
            <div className="font-display text-deep text-[36px] leading-none mt-2.5">{k.value}</div>
            <div className={`mt-2 inline-flex items-center gap-1 font-sans text-[11px] tracking-wider-2
              ${k.delta >= 0 ? 'text-rose' : 'text-deep/60'}`}>
              <span>{k.delta >= 0 ? '↑' : '↓'}</span>
              <span>{Math.abs(k.delta)}%</span>
              <span className="text-deep/45">vs previous</span>
            </div>
          </AdminCard>
        ))}
      </div>

      {/* Sales chart + channels */}
      <div className="grid lg:grid-cols-3 gap-4">
        <AdminCard className="lg:col-span-2 p-5">
          <div className="flex items-center justify-between mb-3">
            <div>
              <div className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/55">Revenue · Last 30 days</div>
              <div className="font-display text-deep text-[28px] leading-none mt-1.5">${ADMIN_SALES_30D.reduce((s,d)=>s+d.value,0).toLocaleString()}</div>
            </div>
            <div className="hidden md:flex items-center gap-2">
              {['7d','30d','90d','12m'].map((r, i) => (
                <button key={r} className={`font-sans text-[10px] tracking-widest-2 uppercase px-3 py-1.5 ${i===1 ? 'bg-deep text-ivory' : 'text-deep/60 hover:text-deep border border-deep/10'}`}>
                  {r}
                </button>
              ))}
            </div>
          </div>
          <SalesChart data={ADMIN_SALES_30D}/>
        </AdminCard>

        {/* Channels donut */}
        <AdminCard className="p-5">
          <div className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/55 mb-3">Traffic sources</div>
          <div className="flex items-center gap-5">
            <DonutChart segments={ADMIN_CHANNELS}/>
            <ul className="flex-1 space-y-2.5">
              {ADMIN_CHANNELS.map(c => (
                <li key={c.name} className="flex items-center justify-between">
                  <span className="flex items-center gap-2 font-sans text-[12px] text-deep/75 tracking-wider-2">
                    <span className="w-2.5 h-2.5 rounded-full" style={{background:c.color}}/>
                    {c.name}
                  </span>
                  <span className="font-display text-deep text-[16px]">{c.pct}%</span>
                </li>
              ))}
            </ul>
          </div>
        </AdminCard>
      </div>

      {/* Top products + recent orders + tickets */}
      <div className="grid lg:grid-cols-3 gap-4">
        {/* Top products */}
        <AdminCard className="p-5">
          <div className="flex items-center justify-between mb-4">
            <div className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/55">Top products</div>
            <a href="#admin/products" className="ulink font-sans text-[10px] tracking-widest-2 uppercase text-deep/55 hover:text-rose">View all</a>
          </div>
          <ul className="space-y-3">
            {ADMIN_TOP_PRODUCTS.map((p, i) => {
              const full = ALL_PRODUCTS.find(x => x.id === p.id);
              return (
                <li key={p.id} className="flex items-center gap-3">
                  <span className="font-display text-rose text-[18px] w-5 leading-none">0{i+1}</span>
                  <div className="w-10 h-12 bg-blush-2 overflow-hidden flex-none">
                    {full && <img src={full.img} alt="" className="w-full h-full object-cover"/>}
                  </div>
                  <div className="flex-1 min-w-0">
                    <div className="font-serif text-deep text-[14px] leading-tight truncate">{p.name}</div>
                    <div className="font-sans text-[10px] tracking-wider-2 text-deep/55 mt-0.5">{p.sold} sold</div>
                  </div>
                  <div className="font-sans text-[12px] text-deep tracking-wider-2">${p.revenue.toLocaleString()}</div>
                </li>
              );
            })}
          </ul>
        </AdminCard>

        {/* Recent orders */}
        <AdminCard className="p-5 lg:col-span-2">
          <div className="flex items-center justify-between mb-4">
            <div className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/55">Recent orders</div>
            <a href="#admin/orders" className="ulink font-sans text-[10px] tracking-widest-2 uppercase text-deep/55 hover:text-rose">View all</a>
          </div>
          <table className="w-full">
            <thead>
              <tr className="text-left font-sans text-[10px] tracking-widest-2 uppercase text-deep/45 border-b border-deep/10">
                <th className="py-2 pr-3 font-medium">Order</th>
                <th className="py-2 pr-3 font-medium">Customer</th>
                <th className="py-2 pr-3 font-medium hidden md:table-cell">Date</th>
                <th className="py-2 pr-3 font-medium">Status</th>
                <th className="py-2 font-medium text-right">Total</th>
              </tr>
            </thead>
            <tbody>
              {a.orders.slice(0, 6).map(o => (
                <tr key={o.id} className="border-b border-deep/5 last:border-b-0 hover:bg-blush-2/40 transition-colors">
                  <td className="py-3 pr-3 font-sans text-[13px] text-deep tracking-wider-2">
                    <a href={`#admin/orders/${o.id}`} className="hover:text-rose">#{o.id}</a>
                  </td>
                  <td className="py-3 pr-3 font-serif text-deep text-[14px]">{o.customer}</td>
                  <td className="py-3 pr-3 font-sans text-[12px] text-deep/55 tracking-wider-2 hidden md:table-cell">{o.date}</td>
                  <td className="py-3 pr-3"><StatusPill status={o.status}/></td>
                  <td className="py-3 font-sans text-[13px] text-deep tracking-wider-2 text-right">${o.total}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </AdminCard>
      </div>

      {/* Tickets + Geography */}
      <div className="grid lg:grid-cols-3 gap-4">
        <AdminCard className="p-5 lg:col-span-2">
          <div className="flex items-center justify-between mb-4">
            <div className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/55">Latest tickets</div>
            <a href="#admin/tickets" className="ulink font-sans text-[10px] tracking-widest-2 uppercase text-deep/55 hover:text-rose">Go to inbox</a>
          </div>
          <ul className="divide-y divide-deep/5">
            {a.tickets.slice(0, 4).map(t => (
              <li key={t.id} className="py-3 flex items-start gap-3">
                <span className={`w-2 h-2 rounded-full mt-2.5 ${t.unread ? 'bg-rose' : 'bg-deep/15'}`}/>
                <div className="flex-1 min-w-0">
                  <div className="flex items-center gap-2 mb-0.5">
                    <span className="font-serif text-deep text-[15px]">{t.customer}</span>
                    <span className="font-sans text-[10px] tracking-wider-2 text-deep/45">· {t.date}</span>
                  </div>
                  <a href={`#admin/tickets/${t.id}`} className="font-sans text-[13px] text-deep/80 hover:text-rose tracking-wider-2 block">{t.subject}</a>
                  <div className="font-sans text-[12px] text-deep/55 mt-1 truncate">{t.snippet}</div>
                </div>
                <StatusPill status={t.status}/>
              </li>
            ))}
          </ul>
        </AdminCard>

        <AdminCard className="p-5">
          <div className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/55 mb-4">By country</div>
          <ul className="space-y-3">
            {ADMIN_COUNTRIES.map(c => (
              <li key={c.code}>
                <div className="flex items-center justify-between mb-1.5">
                  <span className="font-sans text-[12px] text-deep/75 tracking-wider-2">{c.name}</span>
                  <span className="font-display text-deep text-[15px]">{c.pct}%</span>
                </div>
                <div className="h-1 bg-deep/5 rounded-full overflow-hidden">
                  <div className="h-full bg-rose rounded-full transition-all duration-700" style={{width:`${c.pct}%`}}/>
                </div>
              </li>
            ))}
          </ul>
        </AdminCard>
      </div>

      {/* Inventory health */}
      <AdminCard className="p-5">
        <div className="flex items-center justify-between mb-4">
          <div className="flex items-center gap-2">
            <span className="w-7 h-7 rounded-full bg-rose/15 text-rose flex items-center justify-center"><AdminIcons.layers className="w-4 h-4"/></span>
            <div className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/55">Inventory health</div>
          </div>
          <a href="#admin/inventory" className="ulink font-sans text-[10px] tracking-widest-2 uppercase text-deep/55 hover:text-rose">Manage stock</a>
        </div>
        {(() => {
          const units = a.products.reduce((s,p) => s + (p.stock||0), 0);
          const value = a.products.reduce((s,p) => s + (p.stock||0)*(p.price||0), 0);
          const low = a.products.filter(p => (p.stock||0) > 0 && (p.stock||0) < 10);
          const out = a.products.filter(p => (p.stock||0) === 0).length;
          return (
            <div className="grid md:grid-cols-4 gap-4">
              {[
                ['Units in stock', units.toLocaleString()],
                ['Inventory value', `$${value.toLocaleString()}`],
                ['Low stock', low.length, low.length>0],
                ['Out of stock', out, out>0],
              ].map(([label, val, warn]) => (
                <div key={label} className="bg-blush-2/40 p-4">
                  <div className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/55">{label}</div>
                  <div className={`font-display text-[26px] leading-none mt-2 ${warn ? 'text-rose' : 'text-deep'}`}>{val}</div>
                </div>
              ))}
              {low.length > 0 && (
                <div className="md:col-span-4 flex flex-wrap items-center gap-2 pt-1">
                  <span className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/45">Running low:</span>
                  {low.slice(0,5).map(p => (
                    <a key={p.id} href="#admin/inventory" className="inline-flex items-center gap-2 border border-deep/10 hover:border-rose hover:text-rose transition-colors px-2.5 py-1.5">
                      <span className="font-serif text-[13px] text-deep">{p.name}</span>
                      <span className="font-sans text-[11px] text-rose tracking-wider-2">{p.stock} left</span>
                    </a>
                  ))}
                </div>
              )}
            </div>
          );
        })()}
      </AdminCard>
    </div>
  );
}

function PageHeading({ title, sub, actions }) {
  return (
    <div className="flex flex-col md:flex-row md:items-end md:justify-between gap-3 mb-2">
      <div>
        <h1 className="font-display text-deep leading-[1.05]" style={{fontSize:'clamp(28px, 3vw, 44px)'}}>{title}</h1>
        {sub && <p className="font-sans text-[13px] text-deep/55 tracking-wider-2 mt-1.5">{sub}</p>}
      </div>
      {actions && <div className="flex items-center gap-2">{actions}</div>}
    </div>
  );
}

/* ───────────── Page: Products list ───────────── */
function AdminProductsPage() {
  const a = useAdmin();
  const [filter, setFilter] = useState('all');
  const [q, setQ] = useState('');

  const rows = useMemo(() => {
    let arr = a.products;
    if (filter !== 'all') arr = arr.filter(p => p.status === filter);
    if (q) arr = arr.filter(p => p.name.toLowerCase().includes(q.toLowerCase()));
    return arr;
  }, [a.products, filter, q]);

  return (
    <div className="space-y-6">
      <PageHeading
        title="Products"
        sub={`${a.products.length} pieces in the catalog`}
        actions={
          <a href="#admin/products/new" className="btn-sweep inline-flex items-center gap-2 bg-deep text-ivory font-sans text-[11px] tracking-widest-2 uppercase px-4 py-2.5 hover:bg-rose transition-colors">
            <I.plus className="w-3.5 h-3.5"/> Add product
          </a>
        }
      />

      <AdminCard className="overflow-hidden">
        {/* Toolbar */}
        <div className="flex flex-col md:flex-row md:items-center gap-3 p-4 border-b border-deep/10">
          <div className="flex items-center gap-1.5 flex-1">
            {[['all','All'], ['live','Live'], ['draft','Drafts']].map(([k, l]) => (
              <button key={k} onClick={() => setFilter(k)}
                      className={`font-sans text-[11px] tracking-widest-2 uppercase px-3 py-1.5 rounded-sm transition-all
                        ${filter===k ? 'bg-deep text-ivory' : 'text-deep/60 hover:text-deep border border-deep/10'}`}>
                {l}
              </button>
            ))}
          </div>
          <div className="relative w-full md:w-[260px]">
            <I.search className="w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-deep/45"/>
            <input value={q} onChange={e => setQ(e.target.value)} placeholder="Search products…"
                   className="w-full bg-blush-2/40 border border-transparent hover:border-deep/15 focus:border-deep focus:bg-ivory focus:outline-none transition-all pl-9 pr-3 py-2 font-sans text-[12px] tracking-wider-2 text-deep placeholder:text-deep/40"/>
          </div>
        </div>

        {/* Table */}
        <div className="overflow-x-auto">
          <table className="w-full min-w-[760px]">
            <thead>
              <tr className="text-left font-sans text-[10px] tracking-widest-2 uppercase text-deep/45 border-b border-deep/10">
                <th className="py-3 px-4 font-medium">Product</th>
                <th className="py-3 px-4 font-medium">Category</th>
                <th className="py-3 px-4 font-medium">Price</th>
                <th className="py-3 px-4 font-medium">Stock</th>
                <th className="py-3 px-4 font-medium">Status</th>
                <th className="py-3 px-4 font-medium text-right">Actions</th>
              </tr>
            </thead>
            <tbody>
              {rows.map(p => (
                <tr key={p.id} className="border-b border-deep/5 last:border-b-0 hover:bg-blush-2/30 transition-colors">
                  <td className="py-3 px-4">
                    <a href={`#admin/products/${p.id}`} className="flex items-center gap-3 group">
                      <div className="w-10 h-12 bg-blush-2 overflow-hidden flex-none">
                        <img src={p.img} alt="" className="w-full h-full object-cover"/>
                      </div>
                      <div className="min-w-0">
                        <div className="font-serif text-deep text-[15px] leading-tight group-hover:text-rose transition-colors">{p.name}</div>
                        <div className="font-sans text-[10px] tracking-wider-2 text-deep/45 mt-0.5">{p.id}</div>
                      </div>
                    </a>
                  </td>
                  <td className="py-3 px-4 font-sans text-[12px] text-deep/70 tracking-wider-2 capitalize">{p.category}</td>
                  <td className="py-3 px-4 font-sans text-[13px] text-deep tracking-wider-2">${p.price}</td>
                  <td className="py-3 px-4">
                    <div className="flex items-center gap-2">
                      <span className={`font-sans text-[13px] tracking-wider-2 ${p.stock < 10 ? 'text-rose' : 'text-deep'}`}>{p.stock}</span>
                      {p.stock < 10 && <span className="font-sans text-[9px] tracking-widest-2 uppercase text-rose">Low</span>}
                    </div>
                  </td>
                  <td className="py-3 px-4"><StatusPill status={p.status}/></td>
                  <td className="py-3 px-4 text-right">
                    <div className="inline-flex items-center gap-1">
                      <a href={`#admin/products/${p.id}`} className="w-8 h-8 inline-flex items-center justify-center text-deep/55 hover:bg-blush hover:text-deep rounded-sm transition-colors" title="Edit">
                        <AdminIcons.edit className="w-4 h-4"/>
                      </a>
                      <button onClick={() => a.deleteProduct(p.id)} className="w-8 h-8 inline-flex items-center justify-center text-deep/55 hover:bg-blush hover:text-rose rounded-sm transition-colors" title="Delete">
                        <AdminIcons.trash className="w-4 h-4"/>
                      </button>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
          {rows.length === 0 && (
            <div className="py-16 text-center">
              <div className="font-display text-deep text-[28px] leading-none">Nothing here</div>
              <p className="font-sans text-[13px] text-deep/55 tracking-wider-2 mt-2">No products match your filters.</p>
            </div>
          )}
        </div>

        <div className="px-4 py-3 border-t border-deep/10 font-sans text-[11px] tracking-wider-2 text-deep/55 flex items-center justify-between">
          <span>{rows.length} of {a.products.length} pieces</span>
          <div className="flex items-center gap-2">
            <button className="px-3 py-1.5 border border-deep/10 hover:border-deep/30 transition-colors">Prev</button>
            <span>1 / 1</span>
            <button className="px-3 py-1.5 border border-deep/10 hover:border-deep/30 transition-colors">Next</button>
          </div>
        </div>
      </AdminCard>
    </div>
  );
}

/* ───────────── Variant / media editors ───────────── */
function ColorComposer({ onAdd }) {
  const [duo, setDuo]   = useState(false);
  const [a, setA]       = useState('#B86A78');
  const [b, setB]       = useState('#2A4C7D');
  const [name, setName] = useState('');
  const add = () => {
    const color = duo
      ? { name: name.trim() || 'Two-tone', hex: a, hex2: b }
      : { name: name.trim() || a.toUpperCase(), hex: a };
    onAdd(color);
    setName('');
  };
  const preview = { background: duo ? `linear-gradient(135deg, ${a} 0 50%, ${b} 50% 100%)` : a };
  return (
    <div className="border border-deep/12 rounded-sm p-3.5 bg-blush-2/30">
      <div className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/55 mb-3">Create a colour</div>
      <div className="flex items-center gap-3 flex-wrap">
        <span className="w-10 h-10 rounded-full border border-deep/15 flex-none shadow-soft" style={preview}/>
        <label className="inline-flex flex-col gap-1">
          <span className="font-sans text-[9px] tracking-widest-2 uppercase text-deep/50">Colour</span>
          <input type="color" value={a} onChange={e => setA(e.target.value)} className="w-11 h-9 rounded cursor-pointer border border-deep/15 bg-transparent p-0.5"/>
        </label>
        {duo && (
          <label className="inline-flex flex-col gap-1">
            <span className="font-sans text-[9px] tracking-widest-2 uppercase text-deep/50">Second</span>
            <input type="color" value={b} onChange={e => setB(e.target.value)} className="w-11 h-9 rounded cursor-pointer border border-deep/15 bg-transparent p-0.5"/>
          </label>
        )}
        <button type="button" onClick={() => setDuo(d => !d)}
                className={`self-end font-sans text-[10px] tracking-widest-2 uppercase px-3 py-2 border transition-colors
                  ${duo ? 'bg-deep text-ivory border-deep' : 'border-deep/15 text-deep/65 hover:border-deep'}`}>
          Two-tone
        </button>
        <input value={name} onChange={e => setName(e.target.value)} placeholder="Name (optional)" className="admin-input !w-[150px] !py-2 self-end"/>
        <button type="button" onClick={add}
                className="self-end font-sans text-[10px] tracking-widest-2 uppercase bg-deep text-ivory px-4 py-2.5 hover:bg-rose transition-colors inline-flex items-center gap-1.5">
          <I.plus className="w-3.5 h-3.5"/> Add
        </button>
      </div>
      {duo && (
        <p className="font-sans text-[11px] text-deep/55 mt-2.5">
          Split swatch — half <span className="text-deep">{a.toUpperCase()}</span>, half <span className="text-deep">{b.toUpperCase()}</span>.
        </p>
      )}
    </div>
  );
}

function TagEditor({ tags, onChange }) {
  const [input, setInput] = useState('');
  const presets = ['New','Just in','Limited','Bestseller','Most loved','Restocked','Back soon','Exclusive'];
  const addTag = (t) => {
    const v = (t || '').trim();
    if (!v || tags.some(x => x.toLowerCase() === v.toLowerCase())) { setInput(''); return; }
    onChange([...tags, v]); setInput('');
  };
  return (
    <div>
      {tags.length > 0 && (
        <div className="flex flex-wrap gap-2 mb-2.5">
          {tags.map((t, i) => (
            <span key={i} className="inline-flex items-center gap-2 bg-deep text-ivory font-sans text-[10px] tracking-widest-2 uppercase pl-2.5 pr-2 py-1.5">
              {i === 0 && <span className="w-1.5 h-1.5 rounded-full bg-rose" title="Badge"/>}
              {t}
              <button type="button" onClick={() => onChange(tags.filter((_, j) => j !== i))} className="opacity-70 hover:opacity-100"><I.close className="w-3 h-3"/></button>
            </span>
          ))}
        </div>
      )}
      <div className="flex items-center gap-2">
        <input value={input} onChange={e => setInput(e.target.value)}
               onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); addTag(input); } }}
               placeholder="Type a tag, press Enter…" className="admin-input"/>
        <button type="button" onClick={() => addTag(input)} className="flex-none font-sans text-[10px] tracking-widest-2 uppercase bg-deep text-ivory px-4 py-2.5 hover:bg-rose transition-colors">Add</button>
      </div>
      <div className="flex flex-wrap gap-1.5 mt-2.5">
        {presets.filter(p => !tags.some(t => t.toLowerCase() === p.toLowerCase())).map(p => (
          <button key={p} type="button" onClick={() => addTag(p)} className="font-sans text-[10px] tracking-wider-2 uppercase text-deep/60 hover:text-rose border border-deep/12 hover:border-rose px-2.5 py-1.5 transition-colors">+ {p}</button>
        ))}
      </div>
      <p className="font-sans text-[11px] text-deep/45 mt-2">The first tag shows as the badge on the storefront.</p>
    </div>
  );
}

function ImageUploader({ value, onChange }) {
  const inputRef = useRef(null);
  const [drag, setDrag] = useState(false);
  const isData = typeof value === 'string' && value.startsWith('data:');
  const readFile = (file) => {
    if (!file || !file.type.startsWith('image/')) return;
    const fr = new FileReader();
    fr.onload = () => onChange(fr.result);
    fr.readAsDataURL(file);
  };
  return (
    <>
      <div
        onClick={() => inputRef.current && inputRef.current.click()}
        onDragOver={e => { e.preventDefault(); setDrag(true); }}
        onDragLeave={() => setDrag(false)}
        onDrop={e => { e.preventDefault(); setDrag(false); readFile(e.dataTransfer.files[0]); }}
        className={`group mt-3 relative aspect-[3/4] overflow-hidden bg-blush-2 cursor-pointer transition-all
          ${drag ? 'ring-2 ring-rose ring-offset-2 ring-offset-ivory' : ''}`}>
        {value && <img src={value} alt="" className="w-full h-full object-cover"/>}
        <div className={`absolute inset-0 flex flex-col items-center justify-center gap-2 text-center px-4 transition-all
          ${value ? 'opacity-0 group-hover:opacity-100 bg-deep/45 text-ivory' : 'text-deep/65'}`}>
          <AdminIcons.upload className="w-6 h-6"/>
          <div className="font-sans text-[11px] tracking-widest-2 uppercase">{drag ? 'Drop to upload' : value ? 'Replace image' : 'Click or drop image'}</div>
          <div className="font-sans text-[10px] tracking-wider-2 opacity-70">PNG · JPG · WEBP</div>
        </div>
      </div>
      <input ref={inputRef} type="file" accept="image/*" className="hidden" onChange={e => readFile(e.target.files[0])}/>
      <input value={isData ? '' : (value || '')} onChange={e => onChange(e.target.value)} className="admin-input mt-3" placeholder="…or paste an image URL"/>
      {isData && <div className="font-sans text-[10px] tracking-wider-2 text-deep/45 mt-1.5">Uploaded file attached ✓</div>}
    </>
  );
}

/* ───────────── Page: Product form (new / edit) ───────────── */
function AdminProductFormPage({ productId }) {
  const a = useAdmin();
  const editing = productId && productId !== 'new';
  const existing = editing ? a.products.find(p => p.id === productId) : null;

  const [form, setForm] = useState(() => {
    if (existing) return { ...existing, tags: existing.tags || (existing.tag ? [existing.tag] : []) };
    return {
      name: '', price: 0, category: 'dresses', stock: 20, status: 'draft',
      description: '', img: IMG('photo-1539109136881-3be0616acf4b', 700),
      colors: [SW.blush, SW.ivory], tags: ['New'], tag: 'New',
    };
  });
  const set = (k, v) => setForm(f => ({...f, [k]: v}));
  const setTags = (tags) => setForm(f => ({...f, tags, tag: tags[0] || ''}));

  const onSave = (e) => {
    e.preventDefault();
    a.saveProduct(form);
    window.location.hash = '#admin/products';
  };

  return (
    <div className="space-y-6">
      <PageHeading
        title={editing ? form.name || 'Edit product' : 'New product'}
        sub={editing ? `Editing ${existing?.id || productId}` : 'Add a new piece to the House catalog.'}
        actions={
          <>
            <a href="#admin/products" className="font-sans text-[11px] tracking-widest-2 uppercase text-deep/60 hover:text-deep px-4 py-2.5">Cancel</a>
            <button onClick={onSave} className="btn-sweep inline-flex items-center gap-2 bg-deep text-ivory font-sans text-[11px] tracking-widest-2 uppercase px-4 py-2.5 hover:bg-rose transition-colors">
              <I.check className="w-3.5 h-3.5"/> Save product
            </button>
          </>
        }
      />

      <form onSubmit={onSave} className="grid lg:grid-cols-3 gap-5">
        {/* Main form */}
        <div className="lg:col-span-2 space-y-5">
          <AdminCard className="p-6">
            <SectionTitle>Basics</SectionTitle>
            <div className="grid md:grid-cols-2 gap-5 mt-4">
              <Field label="Name">
                <input value={form.name} onChange={e => set('name', e.target.value)} className="admin-input" placeholder="Aurelie Silk Slip Dress"/>
              </Field>
              <Field label="Internal ID">
                <input value={form.id || ''} onChange={e => set('id', e.target.value)} className="admin-input" placeholder="auto" disabled={editing}/>
              </Field>
              <Field label="Category">
                <select value={form.category} onChange={e => set('category', e.target.value)} className="admin-input">
                  {a.categories.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
                </select>
              </Field>
            </div>
            <Field label="Tags" className="mt-5">
              <TagEditor tags={form.tags || []} onChange={setTags}/>
            </Field>
          </AdminCard>

          <AdminCard className="p-6">
            <SectionTitle>Description</SectionTitle>
            <textarea value={form.description || ''} onChange={e => set('description', e.target.value)} rows={6}
                      className="admin-input mt-4 leading-relaxed"
                      placeholder="Tell the story of this piece — fabric, fit, the woman it’s for…"/>
          </AdminCard>

          <AdminCard className="p-6">
            <SectionTitle>Pricing &amp; inventory</SectionTitle>
            <div className="grid md:grid-cols-3 gap-5 mt-4">
              <Field label="Price (USD)">
                <div className="relative">
                  <span className="absolute left-3 top-1/2 -translate-y-1/2 text-deep/45 font-sans text-[13px]">$</span>
                  <input type="number" min="0" value={form.price} onChange={e => set('price', +e.target.value)} className="admin-input pl-7"/>
                </div>
              </Field>
              <Field label="Compare at">
                <div className="relative">
                  <span className="absolute left-3 top-1/2 -translate-y-1/2 text-deep/45 font-sans text-[13px]">$</span>
                  <input type="number" min="0" value={form.compareAt || ''} onChange={e => set('compareAt', +e.target.value || undefined)} className="admin-input pl-7" placeholder="—"/>
                </div>
              </Field>
              <Field label="Stock">
                <input type="number" min="0" value={form.stock} onChange={e => set('stock', +e.target.value)} className="admin-input"/>
              </Field>
            </div>
          </AdminCard>

          <AdminCard className="p-6">
            <SectionTitle>Variants</SectionTitle>
            <Field label="Colours" className="mt-4">
              {/* Selected colours — removable chips */}
              {(form.colors || []).length > 0 && (
                <div className="flex flex-wrap gap-2 mb-3">
                  {(form.colors || []).map((c, i) => (
                    <span key={i} className="inline-flex items-center gap-2 pl-1.5 pr-2 py-1.5 border border-deep/15 rounded-sm bg-ivory">
                      <span className="w-5 h-5 rounded-full" style={swatchStyle(c)}/>
                      <span className="font-sans text-[11px] tracking-wider-2 text-deep">{c.name}</span>
                      <button type="button" onClick={() => set('colors', (form.colors || []).filter((_, j) => j !== i))} className="text-deep/45 hover:text-rose"><I.close className="w-3.5 h-3.5"/></button>
                    </span>
                  ))}
                </div>
              )}
              {/* Quick add from the house palette */}
              <div className="flex flex-wrap items-center gap-1.5 mb-3">
                <span className="font-sans text-[9px] tracking-widest-2 uppercase text-deep/45 mr-1">Palette</span>
                {Object.values(SW).map(c => {
                  const active = (form.colors || []).some(x => x.name === c.name);
                  return (
                    <button key={c.name} type="button" title={c.name}
                            onClick={() => {
                              const next = active ? (form.colors || []).filter(x => x.name !== c.name) : [...(form.colors || []), c];
                              set('colors', next);
                            }}
                            className={`w-7 h-7 rounded-full transition-all ${active ? 'ring-2 ring-offset-2 ring-offset-ivory ring-deep' : 'opacity-80 hover:opacity-100 hover:scale-105'}`}
                            style={swatchStyle(c)}/>
                  );
                })}
              </div>
              {/* Custom colour + two-tone composer */}
              <ColorComposer onAdd={(c) => set('colors', [...(form.colors || []), c])}/>
            </Field>
            <Field label="Sizes" className="mt-5">
              <div className="flex gap-2">
                {SIZES.map(s => {
                  const active = (form.sizes || SIZES).includes(s);
                  return (
                    <button key={s} type="button" onClick={() => {
                      const curr = form.sizes || SIZES;
                      const next = curr.includes(s) ? curr.filter(x => x !== s) : [...curr, s];
                      set('sizes', next);
                    }}
                            className={`w-10 h-10 font-sans text-[12px] tracking-wider-2 transition-all
                              ${active ? 'bg-deep text-ivory' : 'border border-deep/15 text-deep/65 hover:border-deep'}`}>
                      {s}
                    </button>
                  );
                })}
              </div>
            </Field>
          </AdminCard>
        </div>

        {/* Sidebar */}
        <div className="space-y-5">
          <AdminCard className="p-5">
            <SectionTitle>Status</SectionTitle>
            <div className="mt-3 flex gap-2">
              {['live','draft'].map(s => (
                <button key={s} type="button" onClick={() => set('status', s)}
                        className={`flex-1 font-sans text-[11px] tracking-widest-2 uppercase px-3 py-2 transition-all
                          ${form.status === s ? (s === 'live' ? 'bg-rose text-ivory' : 'bg-deep text-ivory') : 'border border-deep/15 text-deep/60 hover:border-deep'}`}>
                  {s}
                </button>
              ))}
            </div>
            <p className="font-sans text-[11px] text-deep/55 leading-relaxed mt-3">
              {form.status === 'live' ? 'This piece is live on the storefront.' : 'Save as a draft. Customers won’t see it.'}
            </p>
          </AdminCard>

          <AdminCard className="p-5">
            <SectionTitle>Image</SectionTitle>
            <ImageUploader value={form.img} onChange={(v) => set('img', v)}/>
          </AdminCard>

          <AdminCard className="p-5">
            <SectionTitle>Preview</SectionTitle>
            <div className="mt-3">
              <div className="relative overflow-hidden bg-blush-2 aspect-[3/4]">
                <img src={form.img} alt="" className="absolute inset-0 w-full h-full object-cover"/>
                {form.tag && (
                  <span className="absolute top-2 left-2 bg-ivory/90 text-deep text-[9px] tracking-widest-2 uppercase px-2 py-1">{form.tag}</span>
                )}
              </div>
              <div className="pt-3">
                <div className="font-serif text-deep text-[17px] leading-tight">{form.name || 'Untitled piece'}</div>
                <div className="mt-1.5 flex items-center justify-between">
                  <span className="font-sans text-[12px] text-deep/65 tracking-wider-2">${form.price || 0}</span>
                  {(form.colors || []).length > 0 && (
                    <div className="flex items-center gap-1.5">
                      {(form.colors || []).slice(0, 5).map((c, i) => (
                        <span key={i} className="w-3.5 h-3.5 rounded-full" title={c.name} style={swatchStyle(c)}/>
                      ))}
                    </div>
                  )}
                </div>
              </div>
            </div>
          </AdminCard>
        </div>
      </form>
    </div>
  );
}

function SectionTitle({ children }) {
  return <div className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/55">{children}</div>;
}
function Field({ label, children, className = '' }) {
  return (
    <label className={`block ${className}`}>
      <span className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/60">{label}</span>
      <div className="mt-1.5">{children}</div>
    </label>
  );
}

/* ───────────── Page: Categories ───────────── */
function AdminCategoriesPage() {
  const a = useAdmin();
  const [editing, setEditing] = useState(null); // category being edited (or 'new')

  return (
    <div className="space-y-6">
      <PageHeading
        title="Categories"
        sub="Organise the wardrobe."
        actions={
          <button onClick={() => setEditing({ id: '', name: '', count: '0 pieces', img: IMG('photo-1572804013309-59a88b7e92f1', 700), status: 'live' })}
                  className="btn-sweep inline-flex items-center gap-2 bg-deep text-ivory font-sans text-[11px] tracking-widest-2 uppercase px-4 py-2.5 hover:bg-rose transition-colors">
            <I.plus className="w-3.5 h-3.5"/> New category
          </button>
        }
      />

      <div className="grid md:grid-cols-2 lg:grid-cols-3 gap-5">
        {a.categories.map(c => (
          <AdminCard key={c.id} className="overflow-hidden">
            <div className="relative aspect-[16/10] bg-blush-2 overflow-hidden">
              <img src={c.img} alt={c.name} className="w-full h-full object-cover img-zoom"/>
              <div className="absolute top-3 left-3"><StatusPill status={c.status || 'live'}/></div>
            </div>
            <div className="p-5">
              <div className="flex items-start justify-between gap-3">
                <div>
                  <h3 className="font-display text-deep text-[24px] leading-none">{c.name}</h3>
                  <div className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/55 mt-2">{c.productCount} pieces</div>
                </div>
                <div className="flex items-center gap-1">
                  <button onClick={() => setEditing(c)} className="w-8 h-8 inline-flex items-center justify-center text-deep/55 hover:bg-blush hover:text-deep transition-colors"><AdminIcons.edit className="w-4 h-4"/></button>
                  <button onClick={() => a.deleteCategory(c.id)} className="w-8 h-8 inline-flex items-center justify-center text-deep/55 hover:bg-blush hover:text-rose transition-colors"><AdminIcons.trash className="w-4 h-4"/></button>
                </div>
              </div>
            </div>
          </AdminCard>
        ))}
      </div>

      {editing && <CategoryDrawer cat={editing} onClose={() => setEditing(null)} onSave={(c) => { a.saveCategory(c); setEditing(null); }}/>}
    </div>
  );
}

function CategoryDrawer({ cat, onClose, onSave }) {
  const [form, setForm] = useState({...cat});
  const set = (k, v) => setForm(f => ({...f, [k]: v}));
  const subcategoryValue = (form.subcategories || []).map((item) => item.name).join(', ');
  return (
    <div className="fixed inset-0 z-[110]">
      <div className="absolute inset-0 bg-deep/30" onClick={onClose}/>
      <aside className="absolute right-0 top-0 bottom-0 w-full sm:w-[440px] bg-ivory shadow-lift flex flex-col animate-slide-in-right">
        <div className="flex items-center justify-between px-6 py-4 border-b border-deep/10">
          <div className="font-display text-deep text-[22px]">{cat.name || 'New category'}</div>
          <button onClick={onClose} className="w-9 h-9 rounded-full hover:bg-blush flex items-center justify-center"><I.close className="w-5 h-5"/></button>
        </div>
        <div className="flex-1 overflow-y-auto p-6 space-y-5">
          <Field label="Name"><input value={form.name} onChange={e => set('name', e.target.value)} className="admin-input"/></Field>
          <Field label="Slug / ID"><input value={form.id || ''} onChange={e => set('id', e.target.value.toLowerCase().replace(/\s+/g,'-'))} className="admin-input" placeholder="dresses"/></Field>
          <Field label="Image URL"><input value={form.img || ''} onChange={e => set('img', e.target.value)} className="admin-input"/></Field>
          <Field label="Subcategories">
            <textarea
              value={subcategoryValue}
              onChange={e =>
                set(
                  'subcategories',
                  e.target.value
                    .split(',')
                    .map((value) => value.trim())
                    .filter(Boolean)
                    .map((name) => ({
                      id: name.toLowerCase().replace(/\s+/g, '-'),
                      name,
                      href: `#shop/${name.toLowerCase().replace(/\s+/g, '-')}`,
                    }))
                )
              }
              rows={3}
              className="admin-input"
              placeholder="New In, Occasion, Evening"
            />
          </Field>
          <div className="relative aspect-[16/10] bg-blush-2 overflow-hidden">
            <img src={form.img} alt="" className="w-full h-full object-cover"/>
          </div>
          <Field label="Status">
            <div className="flex gap-2">
              {['live','draft'].map(s => (
                <button key={s} type="button" onClick={() => set('status', s)}
                        className={`flex-1 font-sans text-[11px] tracking-widest-2 uppercase px-3 py-2 transition-all
                          ${form.status === s ? (s === 'live' ? 'bg-rose text-ivory' : 'bg-deep text-ivory') : 'border border-deep/15 text-deep/60 hover:border-deep'}`}>
                  {s}
                </button>
              ))}
            </div>
          </Field>
        </div>
        <div className="p-5 border-t border-deep/10 flex items-center gap-3">
          <button onClick={onClose} className="font-sans text-[11px] tracking-widest-2 uppercase text-deep/60 hover:text-deep px-4 py-2.5">Cancel</button>
          <button onClick={() => onSave(form)} className="btn-sweep flex-1 inline-flex items-center justify-center gap-2 bg-deep text-ivory font-sans text-[11px] tracking-widest-2 uppercase px-4 py-2.5 hover:bg-rose transition-colors">
            <I.check className="w-3.5 h-3.5"/> Save category
          </button>
        </div>
      </aside>
    </div>
  );
}

/* ───────────── Page: Orders list ───────────── */
const ORDERS_PAGE_SIZE = 8;
function AdminOrdersPage() {
  const a = useAdmin();
  const [statusF, setStatusF] = useState('all');
  const [q, setQ] = useState('');
  const [sort, setSort] = useState({ col:'date', dir:'desc' });
  const [page, setPage] = useState(1);

  const toggleSort = (col) => {
    setSort(s => s.col === col ? { col, dir: s.dir === 'asc' ? 'desc' : 'asc' } : { col, dir: 'desc' });
    setPage(1);
  };

  const filtered = useMemo(() => {
    let arr = [...a.orders];
    if (statusF !== 'all') arr = arr.filter(o => o.status === statusF);
    if (q.trim()) arr = arr.filter(o =>
      o.customer.toLowerCase().includes(q.toLowerCase()) ||
      o.email.toLowerCase().includes(q.toLowerCase()) ||
      o.id.includes(q.replace('#',''))
    );
    const { col, dir } = sort;
    arr.sort((x, y) => {
      const av = x[col], bv = y[col];
      if (col === 'total') return dir === 'asc' ? av - bv : bv - av;
      return dir === 'asc' ? String(av).localeCompare(String(bv)) : String(bv).localeCompare(String(av));
    });
    return arr;
  }, [a.orders, statusF, q, sort]);

  const totalPages = Math.max(1, Math.ceil(filtered.length / ORDERS_PAGE_SIZE));
  const rows = filtered.slice((page - 1) * ORDERS_PAGE_SIZE, page * ORDERS_PAGE_SIZE);

  const exportCSV = () => {
    const head = ['Order','Customer','Email','Country','Date','Items','Status','Total'];
    const lines = [head.join(','), ...a.orders.map(o =>
      [`#${o.id}`, `"${o.customer}"`, o.email, o.country, `"${o.date}"`, o.items, o.status, o.total].join(',')
    )];
    const blob = new Blob([lines.join('\n')], { type:'text/csv' });
    const url = URL.createObjectURL(blob);
    const el = document.createElement('a'); el.href = url; el.download = 'orders.csv'; el.click();
    URL.revokeObjectURL(url);
  };

  const SortTh = ({ col, children, right }) => {
    const active = sort.col === col;
    return (
      <th onClick={() => toggleSort(col)}
          className={`py-3 px-4 font-medium cursor-pointer select-none hover:text-deep transition-colors ${right ? 'text-right' : ''}`}>
        <span className="inline-flex items-center gap-1">
          {children}
          <span className={`text-rose transition-opacity ${active ? 'opacity-100' : 'opacity-0'}`}>
            {sort.dir === 'asc' ? '↑' : '↓'}
          </span>
        </span>
      </th>
    );
  };

  return (
    <div className="space-y-6">
      <PageHeading
        title="Orders"
        sub={`${a.orders.length} orders this period`}
        actions={
          <button onClick={exportCSV}
                  className="inline-flex items-center gap-2 font-sans text-[11px] tracking-widest-2 uppercase text-deep/70 hover:text-rose border border-deep/15 hover:border-rose transition-colors px-4 py-2.5">
            <AdminIcons.upload className="w-3.5 h-3.5"/> Export CSV
          </button>
        }
      />

      {/* KPI cards — click to filter */}
      <div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
        {(['paid','shipped','fulfilled','refunded']).map(s => {
          const subset = a.orders.filter(o => o.status === s);
          const rev = subset.reduce((acc, o) => acc + o.total, 0);
          const active = statusF === s;
          return (
            <AdminCard key={s}
                       className={`p-4 cursor-pointer transition-all hover:shadow-soft ${active ? 'ring-1 ring-rose' : ''}`}
                       onClick={() => { setStatusF(f => f === s ? 'all' : s); setPage(1); }}>
              <div className="flex items-center justify-between mb-2">
                <div className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/55 capitalize">{s}</div>
                <StatusPill status={s}/>
              </div>
              <div className="font-display text-deep text-[30px] leading-none">{subset.length}</div>
              <div className="font-sans text-[11px] tracking-wider-2 text-deep/55 mt-1.5">${rev.toLocaleString()}</div>
            </AdminCard>
          );
        })}
      </div>

      <AdminCard className="overflow-hidden">
        {/* Toolbar */}
        <div className="flex flex-col md:flex-row md:items-center gap-3 p-4 border-b border-deep/10">
          <div className="flex items-center gap-1.5 flex-1 overflow-x-auto">
            {[['all','All'],['paid','Paid'],['shipped','Shipped'],['fulfilled','Fulfilled'],['refunded','Refunded']].map(([k, l]) => (
              <button key={k} onClick={() => { setStatusF(k); setPage(1); }}
                      className={`whitespace-nowrap font-sans text-[11px] tracking-widest-2 uppercase px-3 py-1.5 transition-all
                        ${statusF===k ? 'bg-deep text-ivory' : 'text-deep/60 hover:text-deep border border-deep/10'}`}>
                {l}
                {k !== 'all' && (
                  <span className="ml-1.5 opacity-55">({a.orders.filter(o => o.status === k).length})</span>
                )}
              </button>
            ))}
          </div>
          <div className="relative w-full md:w-[280px]">
            <I.search className="w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-deep/45"/>
            <input value={q} onChange={e => { setQ(e.target.value); setPage(1); }}
                   placeholder="Customer, email, or #order…"
                   className="w-full bg-blush-2/40 border border-transparent hover:border-deep/15 focus:border-deep focus:bg-ivory focus:outline-none transition-all pl-9 pr-3 py-2 font-sans text-[12px] tracking-wider-2 text-deep placeholder:text-deep/40"/>
          </div>
        </div>

        {/* Table */}
        <div className="overflow-x-auto">
          <table className="w-full min-w-[800px]">
            <thead>
              <tr className="text-left font-sans text-[10px] tracking-widest-2 uppercase text-deep/45 border-b border-deep/10">
                <SortTh col="id">Order</SortTh>
                <SortTh col="customer">Customer</SortTh>
                <th className="py-3 px-4 font-medium">Country</th>
                <SortTh col="date">Date</SortTh>
                <th className="py-3 px-4 font-medium">Items</th>
                <SortTh col="status">Status</SortTh>
                <SortTh col="total" right>Total</SortTh>
              </tr>
            </thead>
            <tbody>
              {rows.map(o => (
                <tr key={o.id}
                    className="border-b border-deep/5 last:border-b-0 hover:bg-blush-2/30 transition-colors cursor-pointer group"
                    onClick={() => window.location.hash = `#admin/orders/${o.id}`}>
                  <td className="py-3.5 px-4 font-sans text-[13px] text-deep tracking-wider-2 font-medium group-hover:text-rose transition-colors">
                    #{o.id}
                  </td>
                  <td className="py-3.5 px-4">
                    <div className="font-serif text-deep text-[15px] leading-tight">{o.customer}</div>
                    <div className="font-sans text-[11px] text-deep/50 mt-0.5 truncate max-w-[180px]">{o.email}</div>
                  </td>
                  <td className="py-3.5 px-4 font-sans text-[12px] text-deep/70 tracking-wider-2">{o.country}</td>
                  <td className="py-3.5 px-4 font-sans text-[12px] text-deep/55 tracking-wider-2 whitespace-nowrap">{o.date}</td>
                  <td className="py-3.5 px-4 font-sans text-[13px] text-deep tracking-wider-2">{o.items}</td>
                  <td className="py-3.5 px-4"><StatusPill status={o.status}/></td>
                  <td className="py-3.5 px-4 font-sans text-[14px] text-deep tracking-wider-2 text-right font-medium">
                    ${o.total.toLocaleString()}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
          {rows.length === 0 && (
            <div className="py-16 text-center">
              <div className="font-display text-deep text-[28px] leading-none">No orders found</div>
              <p className="font-sans text-[13px] text-deep/55 tracking-wider-2 mt-2">Adjust your filters or search term.</p>
            </div>
          )}
        </div>

        {/* Pagination + summary */}
        <div className="px-4 py-3 border-t border-deep/10 font-sans text-[11px] tracking-wider-2 text-deep/55 flex items-center justify-between gap-4 flex-wrap">
          <span>
            {filtered.length} order{filtered.length !== 1 ? 's' : ''}
            {filtered.length > 0 && <> · <span className="text-deep">${filtered.reduce((s,o)=>s+o.total,0).toLocaleString()}</span> total</>}
          </span>
          <div className="flex items-center gap-2">
            <button disabled={page <= 1} onClick={() => setPage(p => p-1)}
                    className="px-3 py-1.5 border border-deep/10 hover:border-deep/30 transition-colors disabled:opacity-30 disabled:cursor-not-allowed">←</button>
            <span>Page {page} / {totalPages}</span>
            <button disabled={page >= totalPages} onClick={() => setPage(p => p+1)}
                    className="px-3 py-1.5 border border-deep/10 hover:border-deep/30 transition-colors disabled:opacity-30 disabled:cursor-not-allowed">→</button>
          </div>
        </div>
      </AdminCard>
    </div>
  );
}

/* ───────────── Page: Order detail ───────────── */
function AdminOrderDetailPage({ orderId }) {
  const a = useAdmin();
  const o = a.orders.find(x => x.id === orderId) || a.orders[0];
  const [tracking, setTracking] = useState(o?.trackingNumber || '');
  const [notes,    setNotes]    = useState(o?.notes || '');
  const [noteSaved, setNoteSaved] = useState(false);

  useEffect(() => {
    setTracking(o?.trackingNumber || '');
    setNotes(o?.notes || '');
    setNoteSaved(false);
  }, [o?.id]);

  const statuses = ['paid','shipped','fulfilled'];
  const reached  = statuses.indexOf(o.status === 'refunded' ? 'paid' : o.status);
  const shippingCost = o.total > 200 ? 0 : 12;

  const saveTracking = () => { a.updateOrderField(o.id, { trackingNumber: tracking }); a.flash('Tracking saved'); };
  const saveNotes    = () => {
    a.updateOrderField(o.id, { notes });
    setNoteSaved(true);
    setTimeout(() => setNoteSaved(false), 2200);
  };

  const customerOrders   = a.orders.filter(x => x.email === o.email);
  const customerLifetime = customerOrders.reduce((s, x) => s + x.total, 0);

  return (
    <div className="space-y-6">
      {/* Breadcrumb */}
      <div className="flex items-center gap-2 font-sans text-[11px] tracking-widest-2 uppercase text-deep/55">
        <a href="#admin/orders" className="hover:text-rose">Orders</a><span>/</span>
        <span className="text-deep">#{o.id}</span>
      </div>

      <PageHeading
        title={`Order #${o.id}`}
        sub={`Placed ${o.date} · ${o.country}`}
        actions={
          <>
            <button onClick={() => window.print()}
                    className="font-sans text-[11px] tracking-widest-2 uppercase text-deep/60 hover:text-rose border border-deep/15 hover:border-rose transition-colors px-3 py-2.5">
              Print
            </button>
            <select value={o.status} onChange={e => a.updateOrderStatus(o.id, e.target.value)} className="admin-input !w-auto">
              {['paid','shipped','fulfilled','refunded'].map(s => <option key={s}>{s}</option>)}
            </select>
          </>
        }
      />

      <div className="grid lg:grid-cols-3 gap-5">
        {/* Left — items, timeline, tracking */}
        <div className="lg:col-span-2 space-y-5">

          {/* Line items */}
          <AdminCard className="p-6">
            <SectionTitle>Items ({o.items})</SectionTitle>
            <ul className="mt-4 divide-y divide-deep/8">
              {(o.lineItems || []).map((item, i) => (
                <li key={i} className="py-4 flex items-center gap-4">
                  <div className="w-14 h-16 bg-blush-2 overflow-hidden flex-none">
                    {item.img && <img src={item.img} alt={item.name} className="w-full h-full object-cover"/>}
                  </div>
                  <div className="flex-1 min-w-0">
                    <div className="font-serif text-deep text-[15px] leading-tight">{item.name}</div>
                    <div className="font-sans text-[11px] tracking-wider-2 text-deep/55 mt-1">
                      {item.color} · Size {item.size} · Qty {item.qty}
                    </div>
                  </div>
                  <div className="font-sans text-[14px] text-deep tracking-wider-2 font-medium">
                    ${(item.price * item.qty).toLocaleString()}
                  </div>
                </li>
              ))}
            </ul>
            <div className="mt-5 border-t border-deep/10 pt-4 space-y-2.5">
              {[
                ['Subtotal', `$${(o.total - shippingCost).toLocaleString()}`],
                ['Shipping', shippingCost === 0 ? 'Free' : `$${shippingCost}`],
                ['Tax', '$0'],
              ].map(([l, v]) => (
                <div key={l} className="flex items-center justify-between font-sans text-[13px] text-deep/65">
                  <span>{l}</span><span>{v}</span>
                </div>
              ))}
              <div className="flex items-center justify-between pt-3 border-t border-deep/10">
                <span className="font-sans text-[11px] tracking-widest-2 uppercase text-deep/60">Total</span>
                <span className="font-display text-deep text-[28px] leading-none">${o.total.toLocaleString()}</span>
              </div>
            </div>
          </AdminCard>

          {/* Fulfillment timeline — reacts to status dropdown */}
          <AdminCard className="p-6">
            <SectionTitle>Fulfillment timeline</SectionTitle>
            <ol className="mt-5 space-y-5">
              {[
                { key:'paid',      label:'Payment received',        sub: o.date },
                { key:'shipped',   label:'Parcel handed to carrier', sub: o.trackingNumber ? `Tracking: ${o.trackingNumber}` : 'No tracking yet' },
                { key:'fulfilled', label:'Delivered to customer',    sub: '—' },
              ].map(({ key, label, sub }, i) => {
                const done = i <= reached && o.status !== 'refunded';
                return (
                  <li key={key} className="flex items-start gap-4">
                    <span className={`w-7 h-7 rounded-full flex items-center justify-center flex-none mt-0.5 transition-colors
                      ${done ? 'bg-rose text-ivory' : 'bg-deep/8 text-deep/35'}`}>
                      {done ? <I.check className="w-4 h-4"/> : <span className="font-sans text-[10px]">{i+1}</span>}
                    </span>
                    <div className="flex-1 pt-0.5">
                      <div className={`font-serif text-[15px] leading-tight ${done ? 'text-deep' : 'text-deep/35'}`}>{label}</div>
                      <div className="font-sans text-[11px] tracking-wider-2 text-deep/45 mt-1">{done ? sub : 'Pending'}</div>
                    </div>
                  </li>
                );
              })}
              {o.status === 'refunded' && (
                <li className="flex items-start gap-4">
                  <span className="w-7 h-7 rounded-full bg-deep/10 text-deep/55 flex items-center justify-center mt-0.5">
                    <I.minus className="w-4 h-4"/>
                  </span>
                  <div className="pt-0.5">
                    <div className="font-serif text-deep text-[15px]">Order refunded</div>
                    <div className="font-sans text-[11px] tracking-wider-2 text-deep/45 mt-1">Closed</div>
                  </div>
                </li>
              )}
            </ol>
          </AdminCard>

          {/* Tracking number */}
          <AdminCard className="p-6">
            <SectionTitle>Tracking number</SectionTitle>
            <div className="mt-4 flex items-end gap-3">
              <Field label="Carrier reference" className="flex-1">
                <input value={tracking} onChange={e => setTracking(e.target.value)}
                       placeholder="e.g. DHL-4928374651"
                       className="admin-input"
                       onKeyDown={e => e.key === 'Enter' && saveTracking()}/>
              </Field>
              <button onClick={saveTracking}
                      className="btn-sweep inline-flex items-center gap-2 bg-deep text-ivory font-sans text-[11px] tracking-widest-2 uppercase px-4 py-2.5 hover:bg-rose transition-colors flex-none">
                <I.check className="w-3.5 h-3.5"/> Save
              </button>
            </div>
            {o.trackingNumber && (
              <p className="mt-2.5 font-sans text-[12px] text-deep/55 tracking-wider-2">
                Active: <span className="text-deep font-medium">{o.trackingNumber}</span>
              </p>
            )}
          </AdminCard>
        </div>

        {/* Right sidebar */}
        <div className="space-y-5">
          {/* Customer card — real lifetime from orders data */}
          <AdminCard className="p-5">
            <SectionTitle>Customer</SectionTitle>
            <div className="mt-3 flex items-center gap-3">
              <div className="w-10 h-10 rounded-full bg-rose text-ivory flex items-center justify-center font-display text-[15px] flex-none">
                {o.customer.charAt(0)}
              </div>
              <div className="min-w-0">
                <div className="font-serif text-deep text-[16px] leading-tight">{o.customer}</div>
                <a href={`mailto:${o.email}`} className="font-sans text-[11px] text-deep/55 hover:text-rose truncate block">{o.email}</a>
              </div>
            </div>
            <div className="mt-4 grid grid-cols-2 gap-2 text-center">
              <div className="bg-blush-2/50 py-3">
                <div className="font-display text-deep text-[20px] leading-none">{customerOrders.length}</div>
                <div className="font-sans text-[9px] tracking-widest-2 uppercase text-deep/55 mt-1">Orders</div>
              </div>
              <div className="bg-blush-2/50 py-3">
                <div className="font-display text-deep text-[17px] leading-none">${customerLifetime.toLocaleString()}</div>
                <div className="font-sans text-[9px] tracking-widest-2 uppercase text-deep/55 mt-1">Lifetime</div>
              </div>
            </div>
            <a href={`mailto:${o.email}`}
               className="mt-3 w-full inline-flex items-center justify-center gap-2 font-sans text-[11px] tracking-widest-2 uppercase text-deep/65 hover:text-rose py-2.5 border border-dashed border-deep/20 hover:border-rose transition-all">
              Email customer
            </a>
          </AdminCard>

          {/* Shipping address */}
          <AdminCard className="p-5">
            <SectionTitle>Shipping address</SectionTitle>
            <div className="mt-3 font-sans text-[13px] text-deep/75 leading-relaxed whitespace-pre-line">
              {o.customer}{'\n'}{o.address || '—'}
            </div>
            <div className="mt-3 font-sans text-[11px] tracking-wider-2 text-deep/55">
              Method: {o.trackingNumber ? 'DHL Express' : 'Standard shipping'}
            </div>
          </AdminCard>

          {/* Internal notes — saves to order state */}
          <AdminCard className="p-5">
            <SectionTitle>Internal notes</SectionTitle>
            <textarea rows={4} value={notes} onChange={e => setNotes(e.target.value)}
                      placeholder="Private note — visible to admin only…"
                      className="admin-input mt-3 leading-relaxed text-[13px]"/>
            <button onClick={saveNotes}
                    className={`mt-2.5 w-full font-sans text-[11px] tracking-widest-2 uppercase py-2.5 border transition-all
                      ${noteSaved ? 'bg-rose text-ivory border-rose' : 'border-deep/15 text-deep/60 hover:border-rose hover:text-rose'}`}>
              {noteSaved ? '✓ Saved' : 'Save note'}
            </button>
          </AdminCard>
        </div>
      </div>
    </div>
  );
}

/* ───────────── Page: Tickets (inbox) ───────────── */
function AdminTicketsPage({ ticketId }) {
  const a = useAdmin();
  const [statusF,   setStatusF]   = useState('all');
  const [searchQ,   setSearchQ]   = useState('');
  const [replyMode, setReplyMode] = useState('reply'); // 'reply' | 'note'
  const [reply,     setReply]     = useState('');

  const filtered = useMemo(() => {
    let arr = a.tickets;
    if (statusF !== 'all') arr = arr.filter(t => t.status === statusF);
    if (searchQ.trim()) arr = arr.filter(t =>
      t.customer.toLowerCase().includes(searchQ.toLowerCase()) ||
      t.subject.toLowerCase().includes(searchQ.toLowerCase()) ||
      (t.email || '').toLowerCase().includes(searchQ.toLowerCase())
    );
    return arr;
  }, [a.tickets, statusF, searchQ]);

  const selected = a.tickets.find(t => t.id === ticketId) || filtered[0] || a.tickets[0];

  useEffect(() => {
    if (selected?.unread) a.updateTicket(selected.id, { unread: false });
    setReply('');
    setReplyMode('reply');
  }, [selected?.id]);

  const send = () => {
    if (!reply.trim()) return;
    const msg = {
      id:     Date.now(),
      from:   replyMode === 'note' ? 'note' : 'team',
      author: replyMode === 'note' ? 'Internal note' : 'House of Sheylas',
      body:   reply.trim(),
      date:   'Just now',
    };
    if (replyMode === 'note') {
      a.updateTicket(selected.id, { messages: [...(selected.messages || []), msg] });
      a.flash('Note added');
    } else {
      a.addTicketMessage(selected.id, msg);
    }
    setReply('');
  };

  const unreadCount = a.tickets.filter(t => t.unread).length;
  const openCount   = a.tickets.filter(t => t.status === 'open').length;

  return (
    <div className="space-y-5">
      <PageHeading
        title="Support inbox"
        sub={`${unreadCount} unread · ${openCount} open · ${a.tickets.length} total`}
      />

      <AdminCard className="overflow-hidden">
        <div className="grid lg:grid-cols-12" style={{minHeight:700}}>

          {/* Left — ticket list */}
          <div className="lg:col-span-4 xl:col-span-3 border-r border-deep/10 flex flex-col">
            {/* Status filters */}
            <div className="p-3 border-b border-deep/10 flex items-center gap-1 overflow-x-auto">
              {[['all','All'],['open','Open'],['replied','Replied'],['closed','Closed']].map(([k, l]) => (
                <button key={k} onClick={() => setStatusF(k)}
                        className={`whitespace-nowrap font-sans text-[10px] tracking-widest-2 uppercase px-2.5 py-1.5 transition-all
                          ${statusF===k ? 'bg-deep text-ivory' : 'text-deep/55 hover:text-deep border border-deep/10'}`}>
                  {l}
                  {k !== 'all' && <span className="ml-1 opacity-55">({a.tickets.filter(t => t.status === k).length})</span>}
                </button>
              ))}
            </div>
            {/* Search */}
            <div className="p-3 border-b border-deep/10">
              <div className="relative">
                <I.search className="w-3.5 h-3.5 absolute left-3 top-1/2 -translate-y-1/2 text-deep/40"/>
                <input value={searchQ} onChange={e => setSearchQ(e.target.value)}
                       placeholder="Search tickets…"
                       className="w-full bg-blush-2/40 border border-transparent hover:border-deep/15 focus:border-deep focus:bg-ivory focus:outline-none transition-all pl-9 pr-3 py-2 font-sans text-[11px] tracking-wider-2 text-deep placeholder:text-deep/40"/>
              </div>
            </div>
            {/* List */}
            <ul className="flex-1 overflow-y-auto divide-y divide-deep/8">
              {filtered.length === 0 ? (
                <li className="py-14 text-center">
                  <p className="font-sans text-[12px] text-deep/40 tracking-wider-2">Nothing matches.</p>
                </li>
              ) : filtered.map(t => (
                <li key={t.id}>
                  <a href={`#admin/tickets/${t.id}`}
                     className={`block px-4 py-3.5 hover:bg-blush-2/40 transition-colors relative
                       ${selected?.id === t.id ? 'bg-blush-2/60' : ''}`}>
                    {selected?.id === t.id && <span className="absolute left-0 top-3 bottom-3 w-0.5 bg-rose rounded-r"/>}
                    <div className="flex items-center justify-between gap-2 mb-1">
                      <span className={`font-serif text-deep text-[14px] truncate ${t.unread ? 'font-medium' : ''}`}>{t.customer}</span>
                      <span className="font-sans text-[10px] tracking-wider-2 text-deep/45 flex-none whitespace-nowrap">{t.date}</span>
                    </div>
                    <div className={`font-sans text-[12px] tracking-wider-2 truncate ${t.unread ? 'text-deep' : 'text-deep/65'}`}>
                      {t.unread && <span className="inline-block w-1.5 h-1.5 bg-rose rounded-full mr-2 align-middle"/>}
                      {t.subject}
                    </div>
                    <div className="flex items-center gap-2 mt-2">
                      <StatusPill status={t.status}/>
                      {t.priority !== 'normal' && <StatusPill status={t.priority}/>}
                    </div>
                  </a>
                </li>
              ))}
            </ul>
          </div>

          {/* Right — conversation thread */}
          <div className="lg:col-span-8 xl:col-span-9 flex flex-col">
            {selected ? (
              <>
                {/* Thread header */}
                <div className="px-6 py-4 border-b border-deep/10 flex items-start justify-between gap-4">
                  <div className="flex-1 min-w-0">
                    <div className="font-display text-deep text-[22px] leading-tight truncate">{selected.subject}</div>
                    <div className="font-sans text-[11px] tracking-wider-2 text-deep/55 mt-1">
                      {selected.customer}
                      {selected.email && <> · <a href={`mailto:${selected.email}`} className="hover:text-rose">{selected.email}</a></>}
                      {' · '}#{selected.id} · {selected.date}
                    </div>
                  </div>
                  <div className="flex items-center gap-2 flex-none mt-1">
                    <select value={selected.priority}
                            onChange={e => a.updateTicket(selected.id, { priority: e.target.value })}
                            className="admin-input !w-auto !py-1.5 text-[11px]">
                      <option value="low">Low</option>
                      <option value="normal">Normal</option>
                      <option value="high">High</option>
                    </select>
                    <StatusPill status={selected.status}/>
                  </div>
                </div>

                {/* Messages */}
                <div className="flex-1 overflow-y-auto p-6 space-y-6 bg-ivory/50">
                  {(selected.messages || []).map((msg, i) => {
                    const isNote = msg.from === 'note';
                    const isTeam = msg.from === 'team';
                    return (
                      <div key={msg.id || i} className={`flex gap-3 ${isTeam ? 'justify-end' : ''}`}>
                        {!isTeam && (
                          <div className={`w-9 h-9 rounded-full flex items-center justify-center font-display text-[14px] flex-none
                            ${isNote ? 'bg-champagne/70 text-deep' : 'bg-blush text-deep'}`}>
                            {isNote ? '✎' : selected.customer.charAt(0)}
                          </div>
                        )}
                        <div className={`flex-1 max-w-[600px]`}>
                          <div className={`flex items-baseline gap-2 flex-wrap ${isTeam ? 'justify-end' : ''}`}>
                            <span className="font-serif text-deep text-[15px]">{msg.author}</span>
                            <span className="font-sans text-[11px] tracking-wider-2 text-deep/45">· {msg.date}</span>
                            {isNote && (
                              <span className="font-sans text-[9px] tracking-widest-2 uppercase bg-champagne text-deep px-2 py-0.5">Note</span>
                            )}
                          </div>
                          <div className={`p-4 mt-2 font-sans text-[14px] text-deep/85 leading-relaxed whitespace-pre-wrap
                            ${isNote ? 'bg-champagne/25 border border-deep/8' : isTeam ? 'bg-rose/10' : 'bg-blush-2/60'}`}>
                            {msg.body}
                          </div>
                        </div>
                        {isTeam && (
                          <div className="w-9 h-9 rounded-full bg-rose text-ivory flex items-center justify-center font-display text-[14px] flex-none">S</div>
                        )}
                      </div>
                    );
                  })}
                </div>

                {/* Composer */}
                {selected.status !== 'closed' ? (
                  <div className="border-t border-deep/10 p-4">
                    {/* Mode tabs */}
                    <div className="flex items-center gap-1.5 mb-3">
                      {[['reply','Reply to customer'],['note','Internal note']].map(([k, l]) => (
                        <button key={k} type="button" onClick={() => setReplyMode(k)}
                                className={`font-sans text-[10px] tracking-widest-2 uppercase px-3 py-1.5 transition-all
                                  ${replyMode===k ? (k==='note' ? 'bg-champagne text-deep' : 'bg-deep text-ivory') : 'border border-deep/10 text-deep/55 hover:text-deep'}`}>
                          {l}
                        </button>
                      ))}
                    </div>
                    <textarea value={reply} onChange={e => setReply(e.target.value)} rows={4}
                              placeholder={replyMode === 'note' ? 'Private note — only visible to admins…' : 'Type your reply to the customer…'}
                              className={`admin-input leading-relaxed text-[14px] ${replyMode === 'note' ? '!bg-champagne/15' : ''}`}/>
                    <div className="mt-3 flex items-center justify-between gap-3 flex-wrap">
                      {replyMode === 'reply' && (
                        <div className="flex items-center gap-1.5 flex-wrap">
                          {['Hi,', 'Thank you for reaching out', 'Best, HOS team'].map(t => (
                            <button key={t} onClick={() => setReply(r => (r ? r+'\n' : '')+t)}
                                    className="font-sans text-[10px] tracking-wider-2 text-deep/55 hover:text-rose border border-deep/10 px-2.5 py-1.5">
                              ✦ {t}
                            </button>
                          ))}
                        </div>
                      )}
                      <div className="flex items-center gap-2 ml-auto">
                        <button onClick={() => a.updateTicket(selected.id, { status:'closed' })}
                                className="font-sans text-[11px] tracking-widest-2 uppercase text-deep/60 hover:text-rose px-3 py-2.5">
                          Close ticket
                        </button>
                        <button onClick={send} disabled={!reply.trim()}
                                className="btn-sweep inline-flex items-center gap-2 bg-deep text-ivory font-sans text-[11px] tracking-widest-2 uppercase px-4 py-2.5 hover:bg-rose transition-colors disabled:opacity-40 disabled:cursor-not-allowed">
                          {replyMode === 'note' ? 'Add note' : <>Send reply <I.arrowR className="w-3.5 h-3.5"/></>}
                        </button>
                      </div>
                    </div>
                  </div>
                ) : (
                  <div className="border-t border-deep/10 p-4 flex items-center justify-between">
                    <span className="font-sans text-[12px] text-deep/50 tracking-wider-2">This ticket is closed.</span>
                    <button onClick={() => a.updateTicket(selected.id, { status:'open' })}
                            className="font-sans text-[11px] tracking-widest-2 uppercase text-deep/60 hover:text-rose border border-deep/15 hover:border-rose transition-colors px-4 py-2.5">
                      Reopen
                    </button>
                  </div>
                )}
              </>
            ) : (
              <div className="flex-1 flex flex-col items-center justify-center text-center px-8">
                <div className="font-display text-deep text-[32px]">Inbox zero.</div>
                <p className="font-sans text-[13px] text-deep/55 tracking-wider-2 mt-2">Nothing here right now.</p>
              </div>
            )}
          </div>
        </div>
      </AdminCard>
    </div>
  );
}

/* ───────────── Page: Analytics ───────────── */
function AdminAnalyticsPage() {
  // simple bar chart for top categories revenue
  const catRevenue = useMemo(() => {
    const m = {};
    ADMIN_TOP_PRODUCTS.forEach(p => {
      const prod = ALL_PRODUCTS.find(x => x.id === p.id);
      const cat = prod?.category || 'misc';
      m[cat] = (m[cat] || 0) + p.revenue;
    });
    // include some baseline for other cats
    ['dresses','tops','sets','bottoms','accessories'].forEach(c => { if (!m[c]) m[c] = 2400 + Math.random()*4000; });
    const arr = Object.entries(m).map(([cat, rev]) => ({ cat, rev: Math.round(rev) })).sort((a,b) => b.rev - a.rev);
    return arr;
  }, []);
  const maxRev = Math.max(...catRevenue.map(c => c.rev));

  return (
    <div className="space-y-6">
      <PageHeading title="Analytics" sub="Where revenue is flowing and where to look next."/>

      <div className="grid lg:grid-cols-3 gap-4">
        <AdminCard className="p-5 lg:col-span-2">
          <div className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/55 mb-2">Revenue · Last 30 days</div>
          <SalesChart data={ADMIN_SALES_30D}/>
        </AdminCard>

        <AdminCard className="p-5">
          <div className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/55 mb-4">Traffic sources</div>
          <div className="flex flex-col items-center gap-4">
            <DonutChart segments={ADMIN_CHANNELS} size={160}/>
            <ul className="w-full space-y-2">
              {ADMIN_CHANNELS.map(c => (
                <li key={c.name} className="flex items-center justify-between">
                  <span className="flex items-center gap-2 font-sans text-[12px] text-deep/70 tracking-wider-2">
                    <span className="w-2.5 h-2.5 rounded-full" style={{background:c.color}}/>
                    {c.name}
                  </span>
                  <span className="font-display text-deep text-[15px]">{c.pct}%</span>
                </li>
              ))}
            </ul>
          </div>
        </AdminCard>
      </div>

      <div className="grid lg:grid-cols-2 gap-4">
        <AdminCard className="p-5">
          <div className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/55 mb-5">Revenue by category</div>
          <ul className="space-y-4">
            {catRevenue.map(c => (
              <li key={c.cat}>
                <div className="flex items-center justify-between mb-1.5">
                  <span className="font-serif text-deep text-[15px] capitalize">{c.cat}</span>
                  <span className="font-sans text-[12px] text-deep tracking-wider-2">${c.rev.toLocaleString()}</span>
                </div>
                <div className="h-2 bg-deep/5 rounded-full overflow-hidden">
                  <div className="h-full bg-rose rounded-full transition-all duration-700" style={{width:`${(c.rev/maxRev)*100}%`}}/>
                </div>
              </li>
            ))}
          </ul>
        </AdminCard>

        <AdminCard className="p-5">
          <div className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/55 mb-5">By country</div>
          <ul className="space-y-4">
            {ADMIN_COUNTRIES.map(c => (
              <li key={c.code} className="flex items-center gap-4">
                <span className="font-display text-rose text-[20px] w-10">{c.code}</span>
                <div className="flex-1">
                  <div className="flex items-center justify-between mb-1.5">
                    <span className="font-serif text-deep text-[15px]">{c.name}</span>
                    <span className="font-sans text-[12px] text-deep tracking-wider-2">{c.pct}%</span>
                  </div>
                  <div className="h-2 bg-deep/5 rounded-full overflow-hidden">
                    <div className="h-full bg-rose rounded-full transition-all duration-700" style={{width:`${c.pct*2}%`}}/>
                  </div>
                </div>
              </li>
            ))}
          </ul>
        </AdminCard>
      </div>
    </div>
  );
}

/* ───────────── Page: Settings ───────────── */
function AdminContentPage() {
  const a = useAdmin();
  const [pages, setPages] = useState(a.pages);
  const [hero, setHero] = useState(a.hero);
  const [story, setStory] = useState(a.story);
  const [about, setAbout] = useState(a.about);
  const [contact, setContact] = useState(a.contact);
  const [services, setServices] = useState(a.services.map((service) => service.title).join(', '));

  return (
    <div className="space-y-6">
      <PageHeading title="Content" sub="Manage page structure, text blocks, section images, and service links." />

      <AdminCard className="p-6">
        <SectionTitle>Pages</SectionTitle>
        <div className="mt-4 space-y-4">
          {pages.map((page, index) => (
            <div key={page.id} className="grid md:grid-cols-4 gap-3">
              <input value={page.id} disabled className="admin-input" />
              <input value={page.title} onChange={e => setPages(curr => curr.map((item, itemIndex) => itemIndex === index ? { ...item, title: e.target.value } : item))} className="admin-input" />
              <input value={page.href} onChange={e => setPages(curr => curr.map((item, itemIndex) => itemIndex === index ? { ...item, href: e.target.value } : item))} className="admin-input" />
              <select value={page.status} onChange={e => setPages(curr => curr.map((item, itemIndex) => itemIndex === index ? { ...item, status: e.target.value } : item))} className="admin-input">
                <option value="live">live</option>
                <option value="draft">draft</option>
              </select>
            </div>
          ))}
        </div>
        <button onClick={() => a.savePages(pages)} className="btn-sweep mt-5 inline-flex items-center gap-2 bg-deep text-ivory font-sans text-[11px] tracking-widest-2 uppercase px-4 py-2.5 hover:bg-rose transition-colors">
          <I.check className="w-3.5 h-3.5" /> Save pages
        </button>
      </AdminCard>

      <div className="grid lg:grid-cols-2 gap-5">
        <AdminCard className="p-6 space-y-4">
          <SectionTitle>Hero</SectionTitle>
          <Field label="Eyebrow"><input value={hero.eyebrow} onChange={e => setHero({ ...hero, eyebrow: e.target.value })} className="admin-input" /></Field>
          <Field label="Title"><input value={hero.title} onChange={e => setHero({ ...hero, title: e.target.value })} className="admin-input" /></Field>
          <Field label="Accent"><input value={hero.accent} onChange={e => setHero({ ...hero, accent: e.target.value })} className="admin-input" /></Field>
          <Field label="Description"><textarea rows={5} value={hero.description} onChange={e => setHero({ ...hero, description: e.target.value })} className="admin-input" /></Field>
          <button onClick={() => a.saveContent('hero', hero)} className="btn-sweep inline-flex items-center gap-2 bg-deep text-ivory font-sans text-[11px] tracking-widest-2 uppercase px-4 py-2.5 hover:bg-rose transition-colors">
            <I.check className="w-3.5 h-3.5" /> Save hero
          </button>
        </AdminCard>

        <AdminCard className="p-6 space-y-4">
          <SectionTitle>Brand story</SectionTitle>
          <Field label="Heading"><input value={story.title} onChange={e => setStory({ ...story, title: e.target.value })} className="admin-input" /></Field>
          <Field label="Accent"><input value={story.accent} onChange={e => setStory({ ...story, accent: e.target.value })} className="admin-input" /></Field>
          <Field label="Ending"><input value={story.end} onChange={e => setStory({ ...story, end: e.target.value })} className="admin-input" /></Field>
          <Field label="Body"><textarea rows={5} value={story.body} onChange={e => setStory({ ...story, body: e.target.value })} className="admin-input" /></Field>
          <Field label="Primary image"><input value={story.imagePrimary} onChange={e => setStory({ ...story, imagePrimary: e.target.value })} className="admin-input" /></Field>
          <Field label="Secondary image"><input value={story.imageSecondary} onChange={e => setStory({ ...story, imageSecondary: e.target.value })} className="admin-input" /></Field>
          <button onClick={() => a.saveContent('story', story)} className="btn-sweep inline-flex items-center gap-2 bg-deep text-ivory font-sans text-[11px] tracking-widest-2 uppercase px-4 py-2.5 hover:bg-rose transition-colors">
            <I.check className="w-3.5 h-3.5" /> Save story
          </button>
        </AdminCard>

        <AdminCard className="p-6 space-y-4">
          <SectionTitle>About page</SectionTitle>
          <Field label="Eyebrow"><input value={about.eyebrow} onChange={e => setAbout({ ...about, eyebrow: e.target.value })} className="admin-input" /></Field>
          <Field label="Title"><input value={about.title} onChange={e => setAbout({ ...about, title: e.target.value })} className="admin-input" /></Field>
          <Field label="Accent"><input value={about.accent} onChange={e => setAbout({ ...about, accent: e.target.value })} className="admin-input" /></Field>
          <Field label="Subtitle"><textarea rows={5} value={about.subtitle} onChange={e => setAbout({ ...about, subtitle: e.target.value })} className="admin-input" /></Field>
          <button onClick={() => a.saveContent('about', about)} className="btn-sweep inline-flex items-center gap-2 bg-deep text-ivory font-sans text-[11px] tracking-widest-2 uppercase px-4 py-2.5 hover:bg-rose transition-colors">
            <I.check className="w-3.5 h-3.5" /> Save about
          </button>
        </AdminCard>

        <AdminCard className="p-6 space-y-4">
          <SectionTitle>Contact & services</SectionTitle>
          <Field label="Contact subtitle"><textarea rows={5} value={contact.subtitle} onChange={e => setContact({ ...contact, subtitle: e.target.value })} className="admin-input" /></Field>
          <Field label="Response time"><input value={contact.responseTime} onChange={e => setContact({ ...contact, responseTime: e.target.value })} className="admin-input" /></Field>
          <Field label="Service links">
            <textarea rows={4} value={services} onChange={e => setServices(e.target.value)} className="admin-input" placeholder="Shipping & Returns, Order Tracking, Size Guide" />
          </Field>
          <button onClick={() => {
            a.saveContent('contact', contact);
            a.saveContent('services', services.split(',').map((title, index) => ({ id: `service-${index + 1}`, title: title.trim(), href: '#contact' })).filter((item) => item.title));
          }} className="btn-sweep inline-flex items-center gap-2 bg-deep text-ivory font-sans text-[11px] tracking-widest-2 uppercase px-4 py-2.5 hover:bg-rose transition-colors">
            <I.check className="w-3.5 h-3.5" /> Save contact
          </button>
        </AdminCard>
      </div>
    </div>
  );
}

function AdminSettingsPage() {
  const a = useAdmin();
  const [form, setForm] = useState({
    brandName:       a.settings.brandName        || '',
    brandMark:       a.settings.brandMark        || '',
    brandTagline:    a.settings.brandTagline     || '',
    contact:         a.settings.supportEmail     || '',
    pressEmail:      a.settings.pressEmail       || '',
    phone:           a.settings.phone            || '',
    currency:        a.settings.currency         || 'USD',
    welcomeCode:     a.settings.newsletterCode   || '',
    replyTo:         a.settings.newsletterReplyTo || '',
    autoReply:       a.settings.autoReply        || 'Thank you for writing to us. We typically reply within 48 hours.',
    instagramHandle: a.settings.instagramHandle  || '',
    instagramUrl:    a.settings.instagramUrl     || '',
    tiktokUrl:       a.settings.tiktokUrl        || '',
    pinterestUrl:    a.settings.pinterestUrl     || '',
    adminUsername:   a.settings.adminUsername    || '',
    adminPassword:   a.settings.adminPassword    || '',
  });
  const set = (k, v) => setForm(f => ({...f, [k]: v}));
  const [showPw, setShowPw] = useState(false);

  const defaultLocations = [
    { id:'loc-1', city:'Paris',   role:'Studio',     note:'' },
    { id:'loc-2', city:'Canada',  role:'Operations', note:'' },
    { id:'loc-3', city:'Tunisia', role:'Atelier',    note:'' },
  ];
  const [locations, setLocations] = useState(
    (a.locations && a.locations.length > 0) ? a.locations : defaultLocations
  );
  const updateLoc = (i, patch) => setLocations(ls => ls.map((l, idx) => idx === i ? {...l, ...patch} : l));
  const addLoc    = () => setLocations(ls => [...ls, { id:`loc-${Date.now()}`, city:'', role:'', note:'' }]);
  const removeLoc = (i) => setLocations(ls => ls.filter((_, idx) => idx !== i));

  const saveAll = () => {
    a.saveSettings({
      brandName:        form.brandName,
      brandMark:        form.brandMark,
      brandTagline:     form.brandTagline,
      supportEmail:     form.contact,
      pressEmail:       form.pressEmail,
      phone:            form.phone,
      currency:         form.currency,
      newsletterCode:   form.welcomeCode,
      newsletterReplyTo: form.replyTo,
      autoReply:        form.autoReply,
      instagramHandle:  form.instagramHandle,
      instagramUrl:     form.instagramUrl,
      tiktokUrl:        form.tiktokUrl,
      pinterestUrl:     form.pinterestUrl,
      adminUsername:    form.adminUsername,
      adminPassword:    form.adminPassword,
    });
    a.saveContent('locations', locations);
  };

  return (
    <div className="space-y-6">
      <PageHeading
        title="Settings"
        sub="Brand details, social links, automations, and admin access."
        actions={
          <button onClick={saveAll}
                  className="btn-sweep inline-flex items-center gap-2 bg-deep text-ivory font-sans text-[11px] tracking-widest-2 uppercase px-4 py-2.5 hover:bg-rose transition-colors">
            <I.check className="w-3.5 h-3.5"/> Save all settings
          </button>
        }
      />

      <div className="grid lg:grid-cols-2 gap-5">
        {/* Brand */}
        <AdminCard className="p-6 space-y-4">
          <SectionTitle>Brand</SectionTitle>
          <Field label="Display name"><input value={form.brandName} onChange={e => set('brandName', e.target.value)} className="admin-input"/></Field>
          <Field label="Wordmark (short)"><input value={form.brandMark} onChange={e => set('brandMark', e.target.value)} className="admin-input"/></Field>
          <Field label="Tagline"><input value={form.brandTagline} onChange={e => set('brandTagline', e.target.value)} className="admin-input"/></Field>
          <Field label="Support email"><input type="email" value={form.contact} onChange={e => set('contact', e.target.value)} className="admin-input"/></Field>
          <Field label="Press email"><input type="email" value={form.pressEmail} onChange={e => set('pressEmail', e.target.value)} className="admin-input"/></Field>
          <Field label="Phone"><input type="tel" value={form.phone} onChange={e => set('phone', e.target.value)} className="admin-input"/></Field>
          <Field label="Default currency">
            <select value={form.currency} onChange={e => set('currency', e.target.value)} className="admin-input">
              {['USD','EUR','CAD','TND','GBP'].map(c => <option key={c}>{c}</option>)}
            </select>
          </Field>
        </AdminCard>

        {/* Social */}
        <AdminCard className="p-6 space-y-4">
          <SectionTitle>Social &amp; online presence</SectionTitle>
          <Field label="Instagram handle"><input value={form.instagramHandle} onChange={e => set('instagramHandle', e.target.value)} className="admin-input" placeholder="@roudaina"/></Field>
          <Field label="Instagram URL"><input value={form.instagramUrl} onChange={e => set('instagramUrl', e.target.value)} className="admin-input" placeholder="https://instagram.com/…"/></Field>
          <Field label="TikTok URL"><input value={form.tiktokUrl} onChange={e => set('tiktokUrl', e.target.value)} className="admin-input" placeholder="https://tiktok.com/@…"/></Field>
          <Field label="Pinterest URL"><input value={form.pinterestUrl} onChange={e => set('pinterestUrl', e.target.value)} className="admin-input" placeholder="https://pinterest.com/…"/></Field>
        </AdminCard>

        {/* Newsletter */}
        <AdminCard className="p-6 space-y-4">
          <SectionTitle>Newsletter</SectionTitle>
          <Field label="Welcome discount code"><input value={form.welcomeCode} onChange={e => set('welcomeCode', e.target.value)} className="admin-input" placeholder="WELCOME10"/></Field>
          <Field label="From name"><input value={`${form.brandName || 'Brand'} team`} readOnly className="admin-input opacity-60"/></Field>
          <Field label="Reply-to email"><input type="email" value={form.replyTo} onChange={e => set('replyTo', e.target.value)} className="admin-input"/></Field>
        </AdminCard>

        {/* Auto-reply */}
        <AdminCard className="p-6 space-y-4">
          <SectionTitle>Customer auto-reply</SectionTitle>
          <textarea rows={5} value={form.autoReply} onChange={e => set('autoReply', e.target.value)} className="admin-input leading-relaxed"/>
          <p className="font-sans text-[12px] text-deep/55 leading-relaxed">Sent automatically when a customer contacts you. Keep it warm and concise.</p>
        </AdminCard>

        {/* Locations — editable */}
        <AdminCard className="p-6 space-y-4">
          <div className="flex items-center justify-between">
            <SectionTitle>Locations</SectionTitle>
            <button onClick={addLoc}
                    className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/55 hover:text-rose inline-flex items-center gap-1">
              <I.plus className="w-3 h-3"/> Add
            </button>
          </div>
          <ul className="space-y-2.5 mt-1">
            {locations.map((loc, i) => (
              <li key={loc.id} className="grid grid-cols-[1fr_1fr_auto] gap-2 items-center">
                <input value={loc.city} onChange={e => updateLoc(i, { city: e.target.value })}
                       placeholder="City" className="admin-input !py-2"/>
                <input value={loc.role} onChange={e => updateLoc(i, { role: e.target.value })}
                       placeholder="Role (Studio, Atelier…)" className="admin-input !py-2"/>
                <button onClick={() => removeLoc(i)} title="Remove"
                        className="text-deep/35 hover:text-rose transition-colors p-1">
                  <AdminIcons.trash className="w-4 h-4"/>
                </button>
              </li>
            ))}
          </ul>
        </AdminCard>

        {/* Admin access */}
        <AdminCard className="p-6 space-y-4">
          <SectionTitle>Admin access</SectionTitle>
          <div className="bg-deep/5 border border-deep/10 px-4 py-3 font-sans text-[12px] text-deep/60 leading-relaxed">
            Credentials stored locally (localStorage). For production security use Supabase Auth at <a href="/admin" className="text-rose underline">/admin</a>.
          </div>
          <Field label="Username">
            <input value={form.adminUsername} onChange={e => set('adminUsername', e.target.value)} className="admin-input"/>
          </Field>
          <Field label="Password">
            <div className="relative">
              <input type={showPw ? 'text' : 'password'} value={form.adminPassword}
                     onChange={e => set('adminPassword', e.target.value)} className="admin-input pr-10"/>
              <button type="button" onClick={() => setShowPw(v => !v)}
                      className="absolute right-3 top-1/2 -translate-y-1/2 text-deep/40 hover:text-deep">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" className="w-4 h-4">
                  {showPw
                    ? <><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94"/><path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19"/><line x1="1" y1="1" x2="23" y2="23"/></>
                    : <><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></>
                  }
                </svg>
              </button>
            </div>
          </Field>
          <button onClick={() => { if (window.confirm('Reset all CMS data to defaults?')) a.resetSiteData(); }}
                  className="w-full font-sans text-[11px] tracking-widest-2 uppercase text-rose border border-rose/30 hover:bg-rose hover:text-ivory transition-colors px-4 py-2.5">
            Reset CMS data to defaults
          </button>
        </AdminCard>
      </div>
    </div>
  );
}

/* ───────────── Page: Inventory ───────────── */
function stockState(n) {
  if (!n || n <= 0) return 'out';
  if (n < 10) return 'low';
  if (n < 20) return 'fair';
  return 'healthy';
}
function StockPill({ n }) {
  const s = stockState(n);
  const map = {
    out:     { bg:'bg-deep',       text:'text-ivory',   label:'Out of stock' },
    low:     { bg:'bg-rose',       text:'text-ivory',   label:'Low' },
    fair:    { bg:'bg-champagne',  text:'text-deep',    label:'Fair' },
    healthy: { bg:'bg-rose/15',    text:'text-rose',    label:'In stock' },
  };
  const m = map[s];
  return <span className={`inline-flex items-center font-sans text-[10px] tracking-widest-2 uppercase ${m.bg} ${m.text} px-2.5 py-1`}>{m.label}</span>;
}

function StepperStock({ value, onMinus, onPlus, onSet }) {
  return (
    <div className="inline-flex items-center border border-deep/15">
      <button onClick={onMinus} className="w-8 h-8 flex items-center justify-center hover:bg-blush transition-colors text-deep/70" aria-label="Decrease"><I.minus className="w-3.5 h-3.5"/></button>
      <input
        value={value}
        onChange={e => { const v = parseInt(e.target.value.replace(/\D/g,''),10); onSet(Number.isFinite(v) ? v : 0); }}
        className={`w-12 text-center font-sans text-[13px] tracking-wider-2 bg-transparent outline-none ${value < 10 ? 'text-rose' : 'text-deep'}`}
        inputMode="numeric"
      />
      <button onClick={onPlus} className="w-8 h-8 flex items-center justify-center hover:bg-blush transition-colors text-deep/70" aria-label="Increase"><I.plus className="w-3.5 h-3.5"/></button>
    </div>
  );
}

function AdminInventoryPage() {
  const a = useAdmin();
  const [filter, setFilter] = useState('all'); // all | low | out | healthy
  const [q, setQ] = useState('');
  const [sort, setSort] = useState('stock'); // stock | value | name

  const stats = useMemo(() => {
    const units = a.products.reduce((s,p) => s + (p.stock||0), 0);
    const value = a.products.reduce((s,p) => s + (p.stock||0) * (p.price||0), 0);
    const low   = a.products.filter(p => stockState(p.stock) === 'low').length;
    const out   = a.products.filter(p => stockState(p.stock) === 'out').length;
    return { units, value, low, out };
  }, [a.products]);

  // Units in stock by category — simple bar viz
  const byCat = useMemo(() => {
    const m = {};
    a.products.forEach(p => { m[p.category] = (m[p.category]||0) + (p.stock||0); });
    const arr = Object.entries(m).map(([cat, units]) => ({ cat, units })).sort((x,y) => y.units - x.units);
    const max = Math.max(1, ...arr.map(c => c.units));
    return { arr, max };
  }, [a.products]);

  const lowList = useMemo(
    () => a.products.filter(p => stockState(p.stock) === 'low' || stockState(p.stock) === 'out')
                    .sort((x,y) => (x.stock||0) - (y.stock||0)),
    [a.products]
  );

  const rows = useMemo(() => {
    let arr = [...a.products];
    if (filter !== 'all') arr = arr.filter(p => stockState(p.stock) === filter);
    if (q) arr = arr.filter(p => p.name.toLowerCase().includes(q.toLowerCase()));
    arr.sort((x,y) => {
      if (sort === 'value') return ((y.stock||0)*(y.price||0)) - ((x.stock||0)*(x.price||0));
      if (sort === 'name')  return x.name.localeCompare(y.name);
      return (x.stock||0) - (y.stock||0); // low first
    });
    return arr;
  }, [a.products, filter, q, sort]);

  const restockAllLow = () => {
    lowList.forEach(p => a.restock(p.id, 40));
  };

  return (
    <div className="space-y-6">
      <PageHeading
        title="Inventory"
        sub="Follow stock levels, catch low runners early, and restock in a click."
        actions={
          lowList.length > 0 && (
            <button onClick={restockAllLow} className="btn-sweep inline-flex items-center gap-2 bg-deep text-ivory font-sans text-[11px] tracking-widest-2 uppercase px-4 py-2.5 hover:bg-rose transition-colors">
              <AdminIcons.upload className="w-3.5 h-3.5"/> Restock all low
            </button>
          )
        }
      />

      {/* KPIs */}
      <div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
        {[
          { label:'Units in stock', value: stats.units.toLocaleString(), foot:`${a.products.length} active SKUs` },
          { label:'Inventory value', value:`$${stats.value.toLocaleString()}`, foot:'At current retail' },
          { label:'Low stock', value: stats.low, foot:'Under 10 left', warn: stats.low > 0 },
          { label:'Out of stock', value: stats.out, foot:'Needs restock', warn: stats.out > 0 },
        ].map(k => (
          <AdminCard key={k.label} className="p-5">
            <div className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/55">{k.label}</div>
            <div className={`font-display text-[36px] leading-none mt-2.5 ${k.warn ? 'text-rose' : 'text-deep'}`}>{k.value}</div>
            <div className="mt-2 font-sans text-[11px] tracking-wider-2 text-deep/45">{k.foot}</div>
          </AdminCard>
        ))}
      </div>

      {/* Low-stock alert + stock by category */}
      <div className="grid lg:grid-cols-3 gap-4">
        <AdminCard className="lg:col-span-2 p-5">
          <div className="flex items-center justify-between mb-4">
            <div className="flex items-center gap-2">
              <span className={`w-7 h-7 rounded-full flex items-center justify-center ${lowList.length ? 'bg-rose/15 text-rose' : 'bg-deep/5 text-deep/40'}`}>
                <AdminIcons.alert className="w-4 h-4"/>
              </span>
              <div className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/55">Needs attention</div>
            </div>
            <span className="font-sans text-[11px] tracking-wider-2 text-deep/45">{lowList.length} item{lowList.length===1?'':'s'}</span>
          </div>
          {lowList.length === 0 ? (
            <div className="py-10 text-center">
              <div className="font-display text-deep text-[26px] leading-none">All stocked up.</div>
              <p className="font-sans text-[13px] text-deep/55 tracking-wider-2 mt-2">Nothing is running low right now.</p>
            </div>
          ) : (
            <ul className="divide-y divide-deep/5">
              {lowList.slice(0, 5).map(p => (
                <li key={p.id} className="py-3 flex items-center gap-3">
                  <div className="w-10 h-12 bg-blush-2 overflow-hidden flex-none">
                    <img src={p.img} alt="" className="w-full h-full object-cover"/>
                  </div>
                  <div className="flex-1 min-w-0">
                    <div className="font-serif text-deep text-[15px] leading-tight truncate">{p.name}</div>
                    <div className="font-sans text-[10px] tracking-wider-2 text-deep/50 mt-0.5 capitalize">{p.category}</div>
                  </div>
                  <div className="text-right">
                    <div className={`font-display text-[20px] leading-none ${(p.stock||0)===0 ? 'text-deep' : 'text-rose'}`}>{p.stock||0}</div>
                    <div className="font-sans text-[9px] tracking-widest-2 uppercase text-deep/45 mt-1">left</div>
                  </div>
                  <button onClick={() => a.restock(p.id, 40)} className="font-sans text-[10px] tracking-widest-2 uppercase text-ivory bg-deep hover:bg-rose transition-colors px-3 py-2 flex-none">
                    Restock
                  </button>
                </li>
              ))}
            </ul>
          )}
        </AdminCard>

        <AdminCard className="p-5">
          <div className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/55 mb-4">Units by category</div>
          <ul className="space-y-3.5">
            {byCat.arr.map(c => (
              <li key={c.cat}>
                <div className="flex items-center justify-between mb-1.5">
                  <span className="font-serif text-deep text-[15px] capitalize">{c.cat}</span>
                  <span className="font-sans text-[12px] text-deep tracking-wider-2">{c.units}</span>
                </div>
                <div className="h-1.5 bg-deep/5 rounded-full overflow-hidden">
                  <div className="h-full bg-rose rounded-full transition-all duration-700" style={{width:`${(c.units/byCat.max)*100}%`}}/>
                </div>
              </li>
            ))}
          </ul>
        </AdminCard>
      </div>

      {/* Inventory table */}
      <AdminCard className="overflow-hidden">
        <div className="flex flex-col md:flex-row md:items-center gap-3 p-4 border-b border-deep/10">
          <div className="flex items-center gap-1.5 flex-1 overflow-x-auto">
            {[['all','All'],['low','Low'],['out','Out'],['healthy','In stock']].map(([k, l]) => (
              <button key={k} onClick={() => setFilter(k)}
                      className={`whitespace-nowrap font-sans text-[11px] tracking-widest-2 uppercase px-3 py-1.5 transition-all
                        ${filter===k ? 'bg-deep text-ivory' : 'text-deep/60 hover:text-deep border border-deep/10'}`}>
                {l}
              </button>
            ))}
          </div>
          <div className="flex items-center gap-2">
            <select value={sort} onChange={e => setSort(e.target.value)} className="admin-input !w-auto !py-2 text-[12px]">
              <option value="stock">Sort: Lowest stock</option>
              <option value="value">Sort: Stock value</option>
              <option value="name">Sort: Name</option>
            </select>
            <div className="relative w-full md:w-[220px]">
              <I.search className="w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-deep/45"/>
              <input value={q} onChange={e => setQ(e.target.value)} placeholder="Search products…"
                     className="w-full bg-blush-2/40 border border-transparent hover:border-deep/15 focus:border-deep focus:bg-ivory focus:outline-none transition-all pl-9 pr-3 py-2 font-sans text-[12px] tracking-wider-2 text-deep placeholder:text-deep/40"/>
            </div>
          </div>
        </div>

        <div className="overflow-x-auto">
          <table className="w-full min-w-[820px]">
            <thead>
              <tr className="text-left font-sans text-[10px] tracking-widest-2 uppercase text-deep/45 border-b border-deep/10">
                <th className="py-3 px-4 font-medium">Product</th>
                <th className="py-3 px-4 font-medium">Category</th>
                <th className="py-3 px-4 font-medium">Price</th>
                <th className="py-3 px-4 font-medium">On hand</th>
                <th className="py-3 px-4 font-medium">Status</th>
                <th className="py-3 px-4 font-medium text-right">Stock value</th>
                <th className="py-3 px-4 font-medium text-right">Restock</th>
              </tr>
            </thead>
            <tbody>
              {rows.map(p => (
                <tr key={p.id} className="border-b border-deep/5 last:border-b-0 hover:bg-blush-2/30 transition-colors">
                  <td className="py-3 px-4">
                    <a href={`#admin/products/${p.id}`} className="flex items-center gap-3 group">
                      <div className="w-10 h-12 bg-blush-2 overflow-hidden flex-none">
                        <img src={p.img} alt="" className="w-full h-full object-cover"/>
                      </div>
                      <div className="min-w-0">
                        <div className="font-serif text-deep text-[15px] leading-tight group-hover:text-rose transition-colors truncate max-w-[200px]">{p.name}</div>
                        <div className="font-sans text-[10px] tracking-wider-2 text-deep/45 mt-0.5">{p.id}</div>
                      </div>
                    </a>
                  </td>
                  <td className="py-3 px-4 font-sans text-[12px] text-deep/70 tracking-wider-2 capitalize">{p.category}</td>
                  <td className="py-3 px-4 font-sans text-[13px] text-deep tracking-wider-2">${p.price}</td>
                  <td className="py-3 px-4">
                    <StepperStock
                      value={p.stock||0}
                      onMinus={() => a.adjustStock(p.id, -1)}
                      onPlus={() => a.adjustStock(p.id, +1)}
                      onSet={(v) => a.setStock(p.id, v)}
                    />
                  </td>
                  <td className="py-3 px-4"><StockPill n={p.stock}/></td>
                  <td className="py-3 px-4 font-sans text-[13px] text-deep tracking-wider-2 text-right">${((p.stock||0)*(p.price||0)).toLocaleString()}</td>
                  <td className="py-3 px-4 text-right">
                    <button onClick={() => a.restock(p.id, 40)} className="font-sans text-[10px] tracking-widest-2 uppercase text-deep/70 hover:text-rose border border-deep/10 hover:border-rose transition-colors px-3 py-2">
                      +40
                    </button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
          {rows.length === 0 && (
            <div className="py-16 text-center">
              <div className="font-display text-deep text-[28px] leading-none">Nothing here</div>
              <p className="font-sans text-[13px] text-deep/55 tracking-wider-2 mt-2">No products match your filters.</p>
            </div>
          )}
        </div>

        <div className="px-4 py-3 border-t border-deep/10 font-sans text-[11px] tracking-wider-2 text-deep/55 flex items-center justify-between">
          <span>{rows.length} of {a.products.length} SKUs</span>
          <span>{stats.units.toLocaleString()} units · ${stats.value.toLocaleString()} value</span>
        </div>
      </AdminCard>
    </div>
  );
}

/* ───────────── Admin router ───────────── */
function AdminRouter({ subPath }) {
  const [head, ...rest] = (subPath || '').split('/');
  if (!head)              return <AdminShell active="home"><AdminDashboard/></AdminShell>;
  if (head === 'products') {
    if (rest[0] === 'new')       return <AdminShell active="products"><AdminProductFormPage productId="new"/></AdminShell>;
    if (rest[0])                 return <AdminShell active="products"><AdminProductFormPage productId={rest[0]}/></AdminShell>;
    return <AdminShell active="products"><AdminProductsPage/></AdminShell>;
  }
  if (head === 'categories') return <AdminShell active="categories"><AdminCategoriesPage/></AdminShell>;
  if (head === 'content')    return <AdminShell active="content"><AdminContentPage/></AdminShell>;
  if (head === 'inventory')  return <AdminShell active="inventory"><AdminInventoryPage/></AdminShell>;
  if (head === 'orders') {
    if (rest[0]) return <AdminShell active="orders"><AdminOrderDetailPage orderId={rest[0]}/></AdminShell>;
    return <AdminShell active="orders"><AdminOrdersPage/></AdminShell>;
  }
  if (head === 'tickets')   return <AdminShell active="tickets"><AdminTicketsPage ticketId={rest[0]}/></AdminShell>;
  if (head === 'analytics') return <AdminShell active="analytics"><AdminAnalyticsPage/></AdminShell>;
  if (head === 'settings')  return <AdminShell active="settings"><AdminSettingsPage/></AdminShell>;
  return <AdminShell active="home"><AdminDashboard/></AdminShell>;
}

function AdminApp({ subPath }) {
  return (
    <AdminProvider>
      <AdminRouter subPath={subPath}/>
    </AdminProvider>
  );
}

Object.assign(window, { AdminApp });
