// v-wire.jsx — wiring-truth layer: data classification tags, session model,
// last-sync/refresh model, staff invites, media assets, audit rows, Mustard Seed registry.

// ─── Wiring classification ───────────────────────────────────────────
// Every surface is honestly labelled by what backs it in production:
// live    — reads/writes a validated Supabase table/RPC
// partial — live read or validated write exists, rest is local
// local   — sample/local data only, no DB contract yet
// pending — contract not built; control shown disabled
// soon    — future scope (Mustard Seed)
const WIRE_KIND = {
  live:    { tone:'green', dot:true,  label:'Live · DB',        title:'Backed by a validated Supabase table/RPC' },
  partial: { tone:'blue',  dot:true,  label:'Partial · live read', title:'Live read validated; remainder local until contract lands' },
  local:   { tone:'grey',  dot:false, label:'Local demo',       title:'Sample data — no database contract yet' },
  pending: { tone:'amber', dot:false, label:'Pending contract', title:'Disabled until a backend contract exists and is validated' },
  soon:    { tone:'amber', dot:false, label:'Coming soon',      title:'Future scope — not live yet' },
};
function Wire({ kind='local', style={} }) {
  const k = WIRE_KIND[kind] || WIRE_KIND.local;
  return (
    <span title={k.title} style={{ cursor:'help', display:'inline-flex', ...style }}>
      <Pill tone={k.tone} dot={k.dot} style={{ fontSize:9.5, padding:'2px 8px', letterSpacing:'0.05em', textTransform:'uppercase' }}>{k.label}</Pill>
    </span>
  );
}

// ─── Session model (Supabase-Auth-aware UI states) ───────────────────
// phase: restoring → signedout | signedin | expired
const SESSION_KEY = 'lasso_vendor_session_v1';
const ROLES = {
  owner:   { name:'Marco Bellini', init:'MB', label:'Owner',   email:'marco@fireanddough.co.uk', access:'Full access' },
  manager: { name:'Priya Shah',    init:'PS', label:'Manager', email:'priya@fireanddough.co.uk', access:'Menu · orders · campaigns · insights' },
  staff:   { name:'Tom Okafor',    init:'TO', label:'Staff',   email:'tom@fireanddough.co.uk',   access:'Orders only' },
};
// Which pages each role can open. Enforced in UI; production mirrors this with RLS.
const ROLE_PAGES = {
  owner:   null, // all
  manager: ['overview','map','menu','orders','insights','campaigns','rewards','trail','team','ops'],
  staff:   ['orders','menu'],
};
function roleCanSee(role, page) {
  const allow = ROLE_PAGES[role];
  return !allow || allow.includes(page);
}
function readSession() {
  try { return JSON.parse(localStorage.getItem(SESSION_KEY) || 'null'); } catch(e){ return null; }
}
function useSession() {
  const [phase, setPhase] = React.useState('signedout');
  const [sess, setSess] = React.useState(null);
  React.useEffect(()=>{
    const t = setTimeout(()=>{
      const s = readSession();
      if (s && s.role && ROLES[s.role]) { setSess(s); setPhase('signedin'); }
      else setPhase('signedout');
    }, 650); // session-restore state is a real state — show it
    return ()=>clearTimeout(t);
  }, []);
  const signIn = (role) => {
    const r = ROLES[role] || ROLES.owner;
    const s = { role: ROLES[role]?role:'owner', email:r.email, name:r.name, init:r.init, signedInAt:Date.now() };
    localStorage.setItem(SESSION_KEY, JSON.stringify(s));
    setSess(s); setPhase('signedin');
  };
  const signOut = () => { localStorage.removeItem(SESSION_KEY); setSess(null); setPhase('signedout'); };
  const expire  = () => { setPhase('expired'); };
  const restore = () => { setPhase('signedin'); };
  return { phase, sess, signIn, signOut, expire, restore };
}

// ─── Last-sync / refresh model ───────────────────────────────────────
// Realtime is not implemented — the honest model is "last updated + refresh".
function LastSync({ onRefresh, label='Updated' }) {
  const [at, setAt] = React.useState(Date.now());
  const [busy, setBusy] = React.useState(false);
  const [, tick] = React.useState(0);
  React.useEffect(()=>{ const t=setInterval(()=>tick(x=>x+1), 5000); return ()=>clearInterval(t); }, []);
  const secs = Math.max(0, Math.round((Date.now()-at)/1000));
  const ago = secs<8 ? 'just now' : secs<60 ? `${secs}s ago` : `${Math.round(secs/60)}m ago`;
  const refresh = () => {
    if (busy) return;
    setBusy(true);
    setTimeout(()=>{ setAt(Date.now()); setBusy(false); onRefresh && onRefresh(); }, 700);
  };
  return (
    <span style={{ display:'inline-flex', alignItems:'center', gap:8 }}>
      <span style={{ fontFamily:'var(--font-mono)', fontSize:10.5, color:'var(--warm-stone)', whiteSpace:'nowrap' }}>{label} {ago}</span>
      <button onClick={refresh} title="Fetch latest from Supabase" style={{ display:'inline-flex', alignItems:'center', gap:5, padding:'4px 10px', borderRadius:9, border:'1px solid var(--soft-line)', background:'var(--bg-surface)', cursor:'pointer', fontFamily:'var(--font-display)', fontWeight:700, fontSize:11, color:'var(--fg-primary)' }}>
        <span style={{ display:'inline-flex', animation: busy?'v-spin 800ms linear infinite':'none' }}><I.refresh c="var(--brand-orange)" s={12}/></span>
        {busy?'Refreshing…':'Refresh'}
      </button>
    </span>
  );
}

// ─── Staff invites (public.lasso_vendor_staff_invites) ───────────────
// Invite creation is browser-validated. Email delivery + accept flow have no
// contract yet — shown as pending, never implied to work.
const STAFF_INVITES = [
  { id:'inv-9d42', email:'sofia.r@outlook.com',  role:'Manager', sent:'2 days ago', status:'pending' },
  { id:'inv-8c17', email:'jake.kitchen@gmail.com', role:'Staff', sent:'6 days ago', status:'pending' },
  { id:'inv-7b03', email:'old.hire@yahoo.co.uk', role:'Staff',  sent:'31 days ago', status:'expired' },
];

// ─── Media assets (private bucket lasso-media, vendor-scoped paths) ──
// Upload/update/delete policies are validated. Archive + moderation have no
// contract yet — controls render disabled with a pending tag.
const MEDIA_ASSETS = [
  { id:'md1', name:'pepperoni-storm-hero.jpg', kind:'Item photo',  size:'412 KB', path:'fd-2841/menu/pepperoni-storm-hero.jpg', status:'live',       linked:'Smoky Pepperoni Storm' },
  { id:'md2', name:'family-feast-bundle.jpg',  kind:'Item photo',  size:'388 KB', path:'fd-2841/menu/family-feast-bundle.jpg',  status:'live',       linked:'Family Feast Bundle' },
  { id:'md3', name:'storefront-night.jpg',     kind:'Storefront',  size:'1.2 MB', path:'fd-2841/brand/storefront-night.jpg',    status:'live',       linked:'Storefront profile' },
  { id:'md4', name:'loaded-fries-close.jpg',   kind:'Item photo',  size:'509 KB', path:'fd-2841/menu/loaded-fries-close.jpg',   status:'processing', linked:null },
];

// ─── Onboarding / application status (vendor account) ────────────────
const ONBOARD_STEPS = [
  { id:'app',   label:'Application submitted',       state:'done',    wire:'live',    note:'Stored in vendor application table' },
  { id:'biz',   label:'Business details confirmed',  state:'done',    wire:'live',    note:'Company no. · address · cuisine' },
  { id:'menu',  label:'Menu imported',               state:'done',    wire:'live',    note:'15 items across 5 categories' },
  { id:'bank',  label:'Payout account added',        state:'done',    wire:'live',    note:'Barclays Business ···4821' },
  { id:'docs',  label:'Document & payout verification', state:'pending', wire:'pending', note:'Admin review flow not built yet — status will update here' },
];

// ─── Audit activity (read-only; rows exist only for real mutations) ──
const AUDIT_ROWS = [
  { when:'14:32 today', actor:'Marco Bellini', action:'Order status → completed', target:'#4814 · Chris D.', kind:'orders' },
  { when:'13:05 today', actor:'Priya Shah',    action:'Campaign paused',           target:'Wolverton Win-Back', kind:'campaigns' },
  { when:'11:48 today', actor:'Marco Bellini', action:'Staff invite created',      target:'sofia.r@outlook.com · Manager', kind:'team' },
  { when:'Yesterday',   actor:'Marco Bellini', action:'Media uploaded',            target:'loaded-fries-close.jpg', kind:'media' },
  { when:'Yesterday',   actor:'Priya Shah',    action:'Menu item availability off', target:'Garden Veg Stonebake', kind:'menu' },
  { when:'2 days ago',  actor:'Marco Bellini', action:'Campaign created',          target:'Pepperoni First Bite · Bletchley', kind:'campaigns' },
];

// ─── Mustard Seed — future POS / inventory platform (vendor-only) ────
const MS_AREAS = [
  { id:'register', label:'Register',        icon:'grid' },
  { id:'pos',      label:'POS terminal',    icon:'zap' },
  { id:'inventory',label:'Inventory & stock', icon:'layers' },
  { id:'recipes',  label:'Recipes & COGS',  icon:'utensils' },
  { id:'suppliers',label:'Suppliers',       icon:'truck' },
  { id:'po',       label:'Purchase orders', icon:'receipt' },
  { id:'barcode',  label:'Barcode & labels',icon:'tag' },
  { id:'cash',     label:'Cash drawer',     icon:'pound' },
];

function MustardSeedModal({ area, onClose }) {
  return (
    <div onClick={onClose} style={{ position:'fixed', inset:0, zIndex:950, background:'rgba(12,8,6,0.55)', backdropFilter:'blur(6px)', display:'flex', alignItems:'center', justifyContent:'center', animation:'v-fade 180ms ease-out' }}>
      <div onClick={e=>e.stopPropagation()} style={{ width:480, maxWidth:'calc(100vw - 48px)', background:'var(--dark-chocolate)', color:'var(--dust-cream)', borderRadius:22, border:'1px solid rgba(255,255,255,0.14)', boxShadow:'0 40px 90px -20px rgba(0,0,0,0.8)', padding:'30px 30px 26px', animation:'v-pop 240ms var(--ease-out)', position:'relative' }}>
        <button onClick={onClose} style={{ position:'absolute', top:16, right:16, width:32, height:32, borderRadius:10, border:'1px solid rgba(255,255,255,0.14)', background:'rgba(255,255,255,0.06)', cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center' }}><I.x c="#B6A595" s={15}/></button>
        <div style={{ display:'flex', alignItems:'center', gap:14, marginBottom:18 }}>
          <div style={{ width:52, height:52, borderRadius:15, background:'linear-gradient(135deg,#E0992A,#B8741A)', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0, boxShadow:'0 10px 24px -8px rgba(224,153,42,0.6)' }}>
            <I.droplet c="#fff" s={24} f/>
          </div>
          <div>
            <div style={{ fontFamily:'var(--font-display)', fontWeight:900, fontSize:20, letterSpacing:'-0.01em' }}>Mustard Seed is coming soon</div>
            <div style={{ fontFamily:'var(--font-body)', fontSize:12, color:'#9F8979', marginTop:3 }}>{area ? `${area} lives in Mustard Seed` : 'Back-of-house platform for Lasso vendors'}</div>
          </div>
        </div>
        <p style={{ margin:'0 0 14px', fontFamily:'var(--font-body)', fontSize:13.5, lineHeight:1.6, color:'#D8CCC0' }}>
          Mustard Seed is the register, POS and inventory platform we're building alongside Lasso. Register, stock, recipes, suppliers, purchase orders, cash drawer and terminal controls are <strong style={{ color:'var(--dust-cream)' }}>not live yet</strong> — nothing here shows real numbers until they are.
        </p>
        <div style={{ display:'flex', gap:10, alignItems:'flex-start', padding:'12px 14px', background:'rgba(46,139,78,0.12)', border:'1px solid rgba(46,139,78,0.3)', borderRadius:12, marginBottom:20 }}>
          <I.check c="#5B8F6E" s={16}/>
          <span style={{ fontFamily:'var(--font-body)', fontSize:12.5, lineHeight:1.5, color:'#D8CCC0' }}>Your Lasso delivery orders, menu visibility and this vendor dashboard keep working as normal today.</span>
        </div>
        <Btn kind="accent" full onClick={onClose}>Back to the dashboard</Btn>
      </div>
    </div>
  );
}

Object.assign(window, {
  WIRE_KIND, Wire, SESSION_KEY, ROLES, ROLE_PAGES, roleCanSee, readSession, useSession,
  LastSync, STAFF_INVITES, MEDIA_ASSETS, ONBOARD_STEPS, AUDIT_ROWS, MS_AREAS, MustardSeedModal,
});
