/* =========================================================
   Tappt — CEO Console (owner-only command centre)
   Gated to the founder handle. Overview KPIs, users, card
   fulfilment (batch code generator), feedback, Pro members,
   payouts/Stripe. Reads real Supabase data where possible,
   demo fallback otherwise. Loaded after app-dash.jsx.
   ========================================================= */
const { useState: ceoUse, useEffect: ceoEffect } = React;

const CEO_HANDLES = ['maxxharland', 'max', 'tappt'];  // who can see the console
window.isCEO = function (user) { return user && CEO_HANDLES.indexOf((user.handle || '').toLowerCase()) !== -1; };

function genCode() {
  var A = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';   // no ambiguous chars
  var s = ''; for (var i = 0; i < 6; i++) s += A[Math.floor(Math.random() * A.length)];
  return s;
}

/* 50 single-rule influencer gift codes — live in Shopify (DiscountCodeNode 1878886809938),
   £27.50 fixed off all products, once-per-customer, 50-use global cap. Influencer pays
   ~£2.47 for the card + £2.50 shipping = ~£4.97. Map each code to who you DM'd it to below. */
const INFLUENCER_CODES = ['TPT-K7M2','TPT-Q4X9','TPT-A2N6','TPT-W8R3','TPT-J5P1','TPT-H9C4','TPT-T3V7','TPT-M6B2','TPT-Z1K8','TPT-Y4D5','TPT-N7F3','TPT-R2H9','TPT-C5L6','TPT-X8J1','TPT-P3W4','TPT-B6Q7','TPT-V9M2','TPT-K1T5','TPT-D4Z8','TPT-G7N3','TPT-L2C6','TPT-F5R9','TPT-H8J1','TPT-J3B4','TPT-Q6P7','TPT-W9K2','TPT-A4V5','TPT-T7D8','TPT-M1H3','TPT-Z5N6','TPT-Y8L9','TPT-N2J1','TPT-R6F4','TPT-C9W7','TPT-X3Q2','TPT-P7B5','TPT-B1M8','TPT-V4T3','TPT-K8Z6','TPT-D2C9','TPT-G5X1','TPT-L9H4','TPT-F3N7','TPT-H6R2','TPT-J1V5','TPT-Q4D8','TPT-W7L3','TPT-A9P6','TPT-T2K4','TPT-M5B7'];

function CEOConsole({ user, toast, onClose }) {
  const MI2 = window.MI;
  const [tab, setTab] = ceoUse('overview');
  const [stats, setStats] = ceoUse(null);
  const [users, setUsers] = ceoUse(null);
  const [refs, setRefs] = ceoUse(null);
  const [batch, setBatch] = ceoUse([]);
  const [qty, setQty] = ceoUse(25);
  const [orders, setOrders] = ceoUse(null);
  // influencer gift-code tracking (CEO-only, persisted locally). { code: {name, handle, sent, redeemed} }
  const INFL_KEY = 'tappt_infl_codes_v1';
  const [infl, setInfl] = ceoUse(function () { try { return JSON.parse(localStorage.getItem(INFL_KEY)) || {}; } catch (e) { return {}; } });
  const [pgOpen, setPgOpen] = ceoUse(false);
  const [pregens, setPregens] = ceoUse(null);
  const reloadPregens = () => { if (window.TapptDB && window.TapptDB.available() && window.TapptDB.listPregen) { window.TapptDB.listPregen().then(setPregens); } };
  ceoEffect(() => { reloadPregens(); }, []);
  const setInflField = (code, field, val) => {
    setInfl((prev) => {
      const next = Object.assign({}, prev);
      next[code] = Object.assign({}, next[code], { [field]: val });
      try { localStorage.setItem(INFL_KEY, JSON.stringify(next)); } catch (e) {}
      return next;
    });
  };
  const inflExport = () => {
    const rows = [['code', 'checkout_url', 'name', 'handle', 'sent']].concat(
      INFLUENCER_CODES.map((c) => {
        const r = infl[c] || {};
        return [c, 'https://tappt.io/#shop', (r.name || '').replace(/,/g, ' '), (r.handle || '').replace(/,/g, ' '), r.sent ? 'yes' : 'no'];
      })
    );
    const csv = rows.map((r) => r.join(',')).join('\n');
    const a = document.createElement('a');
    a.href = 'data:text/csv;charset=utf-8,' + encodeURIComponent(csv);
    a.download = 'tappt-influencer-codes.csv'; a.click();
    toast && toast('CSV downloaded');
  };

  ceoEffect(() => {
    if (!window.TapptDB || !window.TapptDB.available() || !window.TapptDB.client) return;
    const sb = window.TapptDB.client;
    (async () => {
      try {
        const pc = await sb.from('profiles').select('id,handle,name,pro,created_at,avatar', { count: 'exact' }).order('created_at', { ascending: false }).limit(100);
        const cc = await sb.from('cards').select('claimed', { count: 'exact', head: true });
        const cClaimed = await sb.from('cards').select('id', { count: 'exact', head: true }).eq('claimed', true);
        const tipsAgg = await sb.from('tips').select('amount');
        // real referral commissions land in referral_payouts (Shopify order webhook writes them);
        // normalise to the shape the render expects (commission/item/buyer_email/status/created_at)
        const refAgg = await sb.from('referral_payouts').select('referrer,referrer_handle,buyer_email,amount,status,created_at').order('created_at', { ascending: false }).limit(200);
        setRefs((refAgg.data || []).map((r) => ({
          referrer: r.referrer_handle || r.referrer,
          buyer_email: r.buyer_email,
          item: 'card',
          amount: parseFloat(r.amount) || 0,
          commission: parseFloat(r.amount) || 0,
          status: r.status,
          created_at: r.created_at,
        })));
        try { const ord = await window.TapptDB.listAllOrders(200); if (ord) setOrders(ord); } catch (e) {}
        const rows = pc.data || [];
        const proCount = rows.filter((r) => r.pro).length;
        setUsers(rows);
        setStats({
          users: pc.count != null ? pc.count : rows.length,
          pro: proCount,
          cards: cc.count || 0,
          claimed: cClaimed.count || 0,
          tips: (tipsAgg.data || []).reduce((s, t) => s + (parseFloat(t.amount) || 0), 0),
        });
      } catch (e) { setStats(null); }
    })();
  }, []);

  // demo dataset — "6 months from now" projection for the founder (@maxxharland)
  const DEMO_NAMES = ['Sofia Marchetti','Daniel Osei','Mia Chen','Jayden Brooks','Amara Okafor','Leo Petrov','Priya Kaur','Tom Hayes','Zara Ali','Noah Webb','Ines Costa','Kai Tanaka'];
  const DEMO = (function(){
    var users = 14820, pro = 1240, claimed = 9630;
    var ulist = DEMO_NAMES.map(function(n,i){ return { id:'d'+i, name:n, handle:n.toLowerCase().replace(/[^a-z]/g,'').slice(0,10), pro: i<5, avatar:null, created_at:new Date(Date.now()-i*86400000*3).toISOString() }; });
    var refs = [];
    var rs=['paid','paid','approved','pending','pending','paid','pending','approved'];
    for (var i=0;i<22;i++){ refs.push({ referrer:'d'+(i%6), buyer_email: DEMO_NAMES[i%DEMO_NAMES.length].split(' ')[0].toLowerCase()+'@gmail.com', item: i%4===0?'pro':'card', amount: i%4===0?7:29.97, commission: i%4===0?2:5, status: rs[i%rs.length], created_at:new Date(Date.now()-i*86400000*2).toISOString() }); }
    return { users:users, pro:pro, claimed:claimed, cards:11200, tips:8470, ulist:ulist, refs:refs };
  })();
  const isDemoCEO = (user.handle === 'maxxharland');

  // demo fallback so the console always looks alive
  const live = stats || { users: 1, pro: 0, cards: 0, claimed: 0, tips: 0 };
  const useDemo = isDemoCEO || (live.users <= 1 && live.claimed === 0);
  const s = useDemo ? DEMO : live;
  const mrr = s.pro * 7.99;            // £7.99/mo Pro
  const cardRev = s.claimed * 29.97;
  const fee = s.tips * 0.06;        // blended platform fee on tips
  const gbp = (n) => '£' + Math.round(n).toLocaleString('en-GB');

  const mint = () => {
    const codes = [];
    for (let i = 0; i < Math.max(1, Math.min(500, qty)); i++) codes.push(genCode());
    setBatch(codes);
    toast && toast(codes.length + ' codes minted');
  };
  const exportCsv = () => {
    const rows = [['code', 'encode_url']].concat(batch.map((c) => [c, 'tappt.io/c/' + c]));
    const csv = rows.map((r) => r.join(',')).join('\n');
    try { const a = document.createElement('a'); a.href = URL.createObjectURL(new Blob([csv], { type: 'text/csv' })); a.download = 'tappt-card-codes.csv'; a.click(); } catch (e) {}
    toast && toast('CSV downloaded');
  };

  const TABS = [['overview', 'Overview', 'chart'], ['users', 'Users', 'users'], ['orders', 'Orders', 'box'], ['fulfil', 'Cards', 'card'], ['influencer', 'Influencer', 'gift'], ['pro', 'Pro', 'crown'], ['payouts', 'Payouts', 'dollar'], ['money', 'Money', 'wallet'], ['feedback', 'Feedback', 'star']];
  const orderList = orders || [];
  // real lifetime card revenue from the orders table when we have it; else the claimed-count estimate
  const realCardRev = orderList.length ? orderList.filter((o) => o.status !== 'cancelled').reduce((sum, o) => sum + (parseFloat(o.total) || 29.97), 0) : null;
  const refList = useDemo ? DEMO.refs : (refs || []);
  const userList = useDemo ? DEMO.ulist : (users || []);
  const refOwed = refList.filter((r) => r.status !== 'paid' && r.status !== 'void').reduce((s, r) => s + (parseFloat(r.commission) || 0), 0);
  const refPaid = refList.filter((r) => r.status === 'paid').reduce((s, r) => s + (parseFloat(r.commission) || 0), 0);

  return (
    <div className="ceo-overlay">
      <div className="ceo-top">
        <div className="ceo-brand">{MI2.bolt ? MI2.bolt({ width: 16, height: 16 }) : '⚡'} <b>Tappt CEO</b></div>
        <button className="ceo-close" onClick={onClose}>{MI2.close ? MI2.close({ width: 18, height: 18 }) : '✕'}</button>
      </div>
      <div className="ceo-tabs">
        {TABS.map(([id, lb, ic]) => <button key={id} className={'ceo-tab' + (tab === id ? ' on' : '')} onClick={() => setTab(id)}>{MI2[ic] ? MI2[ic]({ width: 16, height: 16 }) : null}<span>{lb}</span></button>)}
      </div>
      <div className="ceo-body">
        {tab === 'overview' && (
          <React.Fragment>
            <div className="ceo-kpis">
              <div className="ceo-kpi hero"><div className="ck-l">MRR</div><div className="ck-v">{gbp(mrr)}</div><div className="ck-s">{s.pro} Pro members</div></div>
              <div className="ceo-kpi"><div className="ck-l">Users</div><div className="ck-v">{s.users.toLocaleString()}</div></div>
              <div className="ceo-kpi"><div className="ck-l">Cards claimed</div><div className="ck-v">{s.claimed}</div></div>
              <div className="ceo-kpi"><div className="ck-l">Card revenue</div><div className="ck-v">{gbp(cardRev)}</div></div>
              <div className="ceo-kpi"><div className="ck-l">Tips processed</div><div className="ck-v">{gbp(s.tips)}</div></div>
              <div className="ceo-kpi"><div className="ck-l">Platform fees</div><div className="ck-v">{gbp(fee + cardRev * 0.0 + mrr)}</div></div>
            </div>
            <div className="ceo-note">{stats ? 'Live from Supabase · refreshed on open' : 'Offline — showing placeholder figures'}</div>
          </React.Fragment>
        )}

        {tab === 'users' && (
          <div className="ceo-list">
            {userList.length === 0 && <div className="ceo-empty">No users yet — they'll appear here as people sign up.</div>}
            {userList.map((u) => (
              <div className="ceo-userrow" key={u.id}>
                <span className="ceo-av" style={{ background: 'linear-gradient(135deg,#6B8299,#3a4f63)' }}>{u.avatar ? <img src={u.avatar} alt="" /> : (u.name || u.handle || '?').charAt(0).toUpperCase()}</span>
                <div className="ceo-uinfo"><div className="ceo-uname">{u.name || u.handle}{u.pro && <span className="ceo-protag">PRO</span>}</div><div className="ceo-uhandle">@{u.handle}</div></div>
                <div className="ceo-udate">{u.created_at ? new Date(u.created_at).toLocaleDateString(undefined, { day: 'numeric', month: 'short' }) : ''}</div>
              </div>
            ))}
          </div>
        )}

        {tab === 'fulfil' && (
          <React.Fragment>
            <div className="ceo-section-h">Card fulfilment</div>
            <p className="ceo-p">Mint a batch of unique codes, export the CSV, and encode each chip with its <b>tappt.io/c/&lt;code&gt;</b> URL before shipping. Codes activate on first tap — no need to pre-register them.</p>
            <div className="ceo-mint">
              <label className="ceo-qty">Quantity<input type="number" min="1" max="500" value={qty} onChange={(e) => setQty(parseInt(e.target.value || '1', 10))} /></label>
              <button className="ceo-btn" onClick={mint}>{MI2.refresh ? MI2.refresh({ width: 15, height: 15 }) : ''} Mint codes</button>
            </div>
            {batch.length > 0 && (
              <React.Fragment>
                <div className="ceo-batch-head"><span>{batch.length} codes</span><button className="ceo-link" onClick={exportCsv}>{MI2.ext ? MI2.ext({ width: 14, height: 14 }) : ''} Export CSV</button></div>
                <div className="ceo-codes">{batch.map((c) => <span className="ceo-code" key={c}>tappt.io/c/{c}</span>)}</div>
              </React.Fragment>
            )}
          </React.Fragment>
        )}

        {tab === 'influencer' && (() => {
          const sentCount = INFLUENCER_CODES.filter((c) => infl[c] && infl[c].sent).length;
          return (
            <React.Fragment>
              <div className="ceo-section-h">Influencer gift codes · {sentCount}/50 sent</div>
              <button className="pg-launch" onClick={() => setPgOpen(true)}>{MI2.sparkles ? MI2.sparkles({ width: 16, height: 16 }) : '✨'} Build a profile for an influencer</button>
              {pregens && pregens.length > 0 && (
                <div className="ceo-pregen-wrap">
                  <div className="ceo-subh">Generated profiles · {pregens.filter((p) => p.claimed).length}/{pregens.length} claimed</div>
                  <div className="ceo-pregen-list">
                    {pregens.map((p) => (
                      <div className="ceo-pregen-row" key={p.token}>
                        <div className="ceo-pregen-info">
                          <div className="ceo-pregen-name">{p.name || '@' + p.handle}<span className={'ceo-pregen-badge' + (p.claimed ? ' claimed' : '')}>{p.claimed ? 'Claimed' : 'Unclaimed'}</span></div>
                          <div className="ceo-pregen-handle">tappt.io/{p.handle}</div>
                        </div>
                        <div className="ceo-pregen-acts">
                          <button className="ceo-pregen-act" title="Edit profile" onClick={() => setPgOpen(p.token)}>{MI2.edit ? MI2.edit({ width: 15, height: 15 }) : '✎'}</button>
                          <a className="ceo-pregen-act" href={'https://tappt.io/p/' + p.token} target="_blank" rel="noopener" title="Preview">{MI2.ext ? MI2.ext({ width: 15, height: 15 }) : '↗'}</a>
                          <button className="ceo-pregen-act" title="Copy claim link" onClick={() => { try { navigator.clipboard.writeText('https://app.tappt.io/login?claimprofile=' + p.token); toast && toast('Claim link copied'); } catch (e) {} }}>{MI2.link ? MI2.link({ width: 15, height: 15 }) : '🔗'}</button>
                        </div>
                      </div>
                    ))}
                  </div>
                </div>
              )}
              <p className="ceo-p">50 unique codes — each gives <b>£27.50 off</b> a card (they pay ~<b>£2.47</b> + £2.50 shipping ≈ <b>£4.97</b>). Once-per-customer, 50-use cap total, so a leak can't be farmed. DM a code per influencer and log who it went to. They redeem at <b>tappt.io/#shop</b> → enter the code at checkout.</p>
              <div className="ceo-batch-head"><span>{sentCount} of 50 assigned</span><button className="ceo-link" onClick={inflExport}>{MI2.ext ? MI2.ext({ width: 14, height: 14 }) : ''} Export CSV</button></div>
              <div className="ceo-infl-list">
                {INFLUENCER_CODES.map((c, i) => {
                  const r = infl[c] || {};
                  return (
                    <div className={'ceo-infl-row' + (r.sent ? ' is-sent' : '')} key={c}>
                      <div className="ceo-infl-top">
                        <button className="ceo-infl-code" onClick={() => { try { navigator.clipboard.writeText(c); toast && toast('Copied ' + c); } catch (e) {} }} title="Copy code">{c}</button>
                        <label className="ceo-infl-sent"><input type="checkbox" checked={!!r.sent} onChange={(e) => setInflField(c, 'sent', e.target.checked)} /> Sent</label>
                      </div>
                      <div className="ceo-infl-fields">
                        <input className="ceo-infl-in" placeholder="Name" value={r.name || ''} onChange={(e) => setInflField(c, 'name', e.target.value)} />
                        <input className="ceo-infl-in" placeholder="@handle" value={r.handle || ''} onChange={(e) => setInflField(c, 'handle', e.target.value)} />
                      </div>
                    </div>
                  );
                })}
              </div>
            </React.Fragment>
          );
        })()}

        {tab === 'pro' && (
          <div className="ceo-list">
            <div className="ceo-section-h">Pro members · {gbp(mrr)} MRR</div>
            {userList.filter((u) => u.pro).length === 0 && <div className="ceo-empty">No Pro members yet. They'll show here once Stripe subscriptions go live.</div>}
            {userList.filter((u) => u.pro).map((u) => (
              <div className="ceo-userrow" key={u.id}><span className="ceo-av" style={{ background: 'linear-gradient(135deg,#E8C75A,#b8902a)' }}>{(u.name || u.handle || '?').charAt(0).toUpperCase()}</span><div className="ceo-uinfo"><div className="ceo-uname">{u.name || u.handle}</div><div className="ceo-uhandle">@{u.handle} · £7/mo</div></div></div>
            ))}
          </div>
        )}

        {tab === 'payouts' && (
          <React.Fragment>
            <div className="ceo-section-h">Referral payouts</div>
            <div className="ceo-kpis" style={{ marginBottom: 16 }}>
              <div className="ceo-kpi hero"><div className="ck-l">Owed to referrers</div><div className="ck-v">{gbp(refOwed)}</div><div className="ck-s">{refList.filter((r) => r.status !== 'paid').length} pending</div></div>
              <div className="ceo-kpi"><div className="ck-l">Paid out</div><div className="ck-v">{gbp(refPaid)}</div></div>
              <div className="ceo-kpi"><div className="ck-l">Referrals</div><div className="ck-v">{refList.length}</div></div>
            </div>
            <div className="ceo-list">
              {refList.length === 0 && <div className="ceo-empty">No referrals yet. When someone buys via a user's referral link, the commission owed shows here to track &amp; pay out.</div>}
              {refList.map((r, i) => (
                <div className="ceo-userrow" key={i}>
                  <span className="ceo-av" style={{ background: 'linear-gradient(135deg,#8AFF6B,#1a7a3a)' }}>{MI2.dollar ? MI2.dollar({ width: 16, height: 16 }) : '£'}</span>
                  <div className="ceo-uinfo"><div className="ceo-uname">{gbp(r.commission)} · {r.item}</div><div className="ceo-uhandle">{r.buyer_email || 'buyer'} · {r.created_at ? new Date(r.created_at).toLocaleDateString(undefined, { day: 'numeric', month: 'short' }) : ''}</div></div>
                  <span className={'ceo-refstatus st-' + (r.status || 'pending')}>{r.status || 'pending'}</span>
                </div>
              ))}
            </div>
            <div className="ceo-stripe-note">{MI2.lock ? MI2.lock({ width: 13, height: 13 }) : ''} Referrals log automatically when Stripe/Shopify orders carry a <b>?ref=</b> code. Mark as paid here once sent (or auto-pay via Stripe Connect later).</div>
          </React.Fragment>
        )}

        {tab === 'money' && (
          <React.Fragment>
            <div className="ceo-money-row"><span>Referral payouts owed</span><b>{gbp(refOwed)}</b></div>
            <div className="ceo-section-h">Money</div>
            <div className="ceo-money-row"><span>Pro subscriptions (MRR)</span><b>{gbp(mrr)}</b></div>
            <div className="ceo-money-row"><span>Card sales (lifetime)</span><b>{gbp(realCardRev != null ? realCardRev : cardRev)}</b></div>
            <div className="ceo-money-row"><span>Tips processed</span><b>{gbp(s.tips)}</b></div>
            <div className="ceo-money-row"><span>Platform fee on tips <span style={{ color: 'var(--fg-3)', fontSize: 11 }}>(10% free / 4% Pro)</span></span><b>{gbp(fee)}</b></div>
            <div className="ceo-money-row total"><span>Est. monthly revenue</span><b>{gbp(mrr + fee)}</b></div>
            <div className="ceo-stripe-note">{MI2.lock ? MI2.lock({ width: 13, height: 13 }) : ''} Connect Stripe to see live payouts, balance &amp; subscription events here. (Stripe wiring is the next build.)</div>
          </React.Fragment>
        )}

        {tab === 'orders' && (
          <div className="ceo-list">
            <div className="ceo-section-h">Orders{realCardRev != null ? ' · ' + gbp(realCardRev) + ' lifetime' : ''}</div>
            {orderList.length === 0 && <div className="ceo-empty">No orders yet. Card purchases flow in here from Shopify (via the orders webhook) the moment someone checks out.</div>}
            {orderList.map((o, i) => (
              <div className="ceo-order" key={o.id || i}>
                <span className={'ceo-order-badge st-' + o.status}>{o.status === 'placed' ? 'Processing' : o.status === 'shipped' ? 'Shipped' : o.status === 'delivered' ? 'Delivered' : 'Cancelled'}</span>
                <div className="ceo-order-meta">
                  <div className="ceo-order-t">{o.productTitle}{o.orderNo ? ' · #' + o.orderNo : ''}</div>
                  <div className="ceo-order-s">{o.email || 'guest'}{o.ref ? ' · ref @' + o.ref : ''}{o.createdAt ? ' · ' + new Date(o.createdAt).toLocaleDateString('en-GB') : ''}</div>
                </div>
                <b className="ceo-order-amt">{o.total != null ? gbp(parseFloat(o.total) || 0) : '£29.97'}</b>
              </div>
            ))}
          </div>
        )}

        {tab === 'feedback' && (
          <div className="ceo-list">
            <div className="ceo-section-h">Feedback</div>
            <div className="ceo-empty">In-app feedback &amp; low ratings will collect here once the feedback table is wired. (The "Are you enjoying Tappt?" prompt routes low ratings to feedback.)</div>
          </div>
        )}
      </div>
      {pgOpen && window.PregenGenerator && <window.PregenGenerator key={typeof pgOpen === 'string' ? pgOpen : 'new'} editToken={typeof pgOpen === 'string' ? pgOpen : null} toast={toast} onClose={() => { setPgOpen(false); reloadPregens(); }} />}
    </div>
  );
}
window.CEOConsole = CEOConsole;
