/* linked.market — Marked items + Send-to-Vendor flow */
(function () {
const { useState, useEffect } = React;
const h = React.createElement;
const { naira, VENDORS, PRODUCTS, vendorOf } = window.LM_DATA;
const { Icon, Avatar, ImageBlock, VendorStrip, VMark, Badge } = window;

/* group marked items by vendor → [{ vendor, items:[{p,qty,variant}] }] */
function groupMarked(markedMap) {
  const groups = {};
  PRODUCTS.forEach(p => {
    const m = markedMap[p.id];
    if (!m) return;
    (groups[p.vendor] ||= { vendor: VENDORS[p.vendor], items: [] }).items.push({ p, ...m });
  });
  return Object.values(groups);
}
const groupTotal = (g) => g.items.reduce((s, it) => s + it.p.price * it.qty, 0);
const variantStr = (variant) => variant ? Object.values(variant).join(' · ') : '';

/* ---------- qty stepper ---------- */
function Qty({ v, onDelta }) {
  return h('div', { className: 'qty' },
    h('button', { onClick: () => onDelta(-1), disabled: v <= 1 }, h(Icon, { name: 'minus' })),
    h('span', { className: 'v' }, v),
    h('button', { onClick: () => onDelta(1) }, h(Icon, { name: 'plus' })),
  );
}

/* ---------- marked row ---------- */
function MarkedRow({ it, onOpen, onDelta, onRemove }) {
  const { p } = it;
  return h('div', { className: 'mrow' },
    h(ImageBlock, { duo: p.duo, glyph: p.glyph, className: 'mthumb', style: { cursor: 'pointer' }, onClick: () => onOpen(p) }),
    h('div', { style: { flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column' } },
      h('div', { style: { display: 'flex', justifyContent: 'space-between', gap: 10 } },
        h('div', { className: 'mname', onClick: () => onOpen(p), style: { cursor: 'pointer' } }, p.name),
        h('button', { className: 'icon-btn', style: { width: 30, height: 30, marginTop: -4, marginRight: -6 }, onClick: () => onRemove(p.id) },
          h(Icon, { name: 'x' })),
      ),
      variantStr(it.variant) && h('div', { className: 'mvar' }, variantStr(it.variant)),
      h('div', { style: { flex: 1 } }),
      h('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginTop: 8 } },
        h('span', { className: 'mprice price' }, naira(p.price)),
        h(Qty, { v: it.qty, onDelta }),
      ),
    ),
  );
}

/* ---------- empty state ---------- */
function EmptyMarked({ onBrowse }) {
  return h('div', { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center', padding: '64px 32px' } },
    h('div', { style: { width: 88, height: 88, borderRadius: 24, background: 'var(--bg-sunk)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--ink-4)', marginBottom: 22 } },
      h(Icon, { name: 'bookmark', style: { width: 36, height: 36 } })),
    h('h2', { className: 't-display', style: { fontSize: 24 } }, 'Nothing marked yet'),
    h('p', { style: { fontSize: 14.5, color: 'var(--ink-2)', marginTop: 10, maxWidth: 280, lineHeight: 1.55 } },
      'Tap the marker on any product to collect it here. Group your finds by vendor, then send in one message.'),
    h('button', { className: 'btn btn-primary btn-md', style: { marginTop: 22 }, onClick: onBrowse }, 'Start browsing'),
  );
}

/* ============================== MOBILE ============================== */
function MarkedMobile(props) {
  const { markedMap, onOpen, onDelta, onRemove, onSendGroup, onBrowse } = props;
  const groups = groupMarked(markedMap);
  const count = Object.keys(markedMap).length;

  return h('div', { className: 'screen-fade' },
    h('div', { className: 'mtop', style: { paddingBottom: 6 } },
      h('div', null,
        h('h1', { className: 't-display', style: { fontSize: 24 } }, 'Your bag'),
        count > 0 && h('div', { style: { fontSize: 13, color: 'var(--ink-3)', marginTop: 2 } },
          h('span', { className: 'price' }, count), count === 1 ? ' item' : ' items', ' from ', h('span', { className: 'price' }, groups.length), groups.length === 1 ? ' vendor' : ' vendors')),
    ),
    count === 0 ? h(EmptyMarked, { onBrowse }) :
      h('div', { style: { padding: '14px 16px 110px', display: 'flex', flexDirection: 'column', gap: 18 } },
        groups.map(g => h('div', { className: 'mgroup', key: g.vendor.handle },
          h('div', { className: 'ghead' },
            h(VendorStrip, { vendor: g.vendor, size: 30 }),
            h('span', { style: { marginLeft: 'auto', fontSize: 12.5, color: 'var(--ink-3)' } }, g.vendor.response)),
          g.items.map(it => h(MarkedRow, { key: it.p.id, it, onOpen, onRemove, onDelta: (d) => onDelta(it.p.id, d) })),
          h('div', { className: 'gfoot' },
            h('div', null,
              h('div', { style: { fontSize: 11.5, color: 'var(--ink-3)' } }, 'Subtotal'),
              h('div', { className: 'price', style: { fontSize: 17, fontWeight: 600 } }, naira(groupTotal(g)))),
            h('button', { className: 'btn btn-primary btn-md', onClick: () => onSendGroup(g) },
              h(Icon, { name: 'send' }), 'Send'),
          ),
        )),
        h('p', { style: { fontSize: 12, color: 'var(--ink-3)', textAlign: 'center', lineHeight: 1.5, padding: '0 24px' } },
          'linked.market doesn’t handle payment. You’ll arrange that directly with each vendor.'),
      ),
  );
}

/* ============================== DESKTOP ============================== */
function MarkedDesktop(props) {
  const { markedMap, onOpen, onDelta, onRemove, onSendGroup, onBrowse } = props;
  const groups = groupMarked(markedMap);
  const count = Object.keys(markedMap).length;
  const grand = groups.reduce((s, g) => s + groupTotal(g), 0);

  if (count === 0) return h('div', { className: 'screen-fade', style: { maxWidth: 1140, margin: '0 auto' } }, h(EmptyMarked, { onBrowse }));

  return h('div', { className: 'screen-fade', style: { maxWidth: 1140, margin: '0 auto', padding: '36px 40px 64px' } },
    h('h1', { className: 't-display', style: { fontSize: 34 } }, 'Your bag'),
    h('div', { style: { fontSize: 14, color: 'var(--ink-3)', marginTop: 6, marginBottom: 28 } },
      h('span', { className: 'price' }, count), count === 1 ? ' item' : ' items', ' across ', h('span', { className: 'price' }, groups.length), ' vendors · each sends as its own message'),
    h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 332px', gap: 28, alignItems: 'start' } },
      // left: groups
      h('div', { style: { display: 'flex', flexDirection: 'column', gap: 20 } },
        groups.map(g => h('div', { className: 'mgroup', key: g.vendor.handle },
          h('div', { className: 'ghead' },
            h(VendorStrip, { vendor: g.vendor, size: 32 }),
            h('span', { style: { marginLeft: 'auto', fontSize: 12.5, color: 'var(--ink-3)' } }, 'Replies in ', g.vendor.response),
            h('button', { className: 'btn btn-primary btn-sm', style: { marginLeft: 14 }, onClick: () => onSendGroup(g) },
              h(Icon, { name: 'send' }), 'Send to @' + g.vendor.handle)),
          g.items.map(it => h(MarkedRow, { key: it.p.id, it, onOpen, onRemove, onDelta: (d) => onDelta(it.p.id, d) })),
        ))),
      // right: summary
      h('div', { className: 'card', style: { padding: 22, position: 'sticky', top: 26 } },
        h('div', { className: 'eyebrow' }, 'Summary'),
        h('div', { style: { display: 'flex', flexDirection: 'column', gap: 11, margin: '16px 0' } },
          groups.map(g => h('div', { key: g.vendor.handle, style: { display: 'flex', justifyContent: 'space-between', fontSize: 14 } },
            h('span', { style: { color: 'var(--ink-2)' } }, '@' + g.vendor.handle),
            h('span', { className: 'price', style: { fontWeight: 600 } }, naira(groupTotal(g)))))),
        h('div', { style: { height: 1, background: 'var(--line)', margin: '6px 0 14px' } }),
        h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' } },
          h('span', { style: { fontSize: 14, color: 'var(--ink-2)' } }, 'Estimated total'),
          h('span', { className: 'price t-display', style: { fontSize: 24 } }, naira(grand))),
        h('p', { style: { fontSize: 12, color: 'var(--ink-3)', marginTop: 14, lineHeight: 1.5 } },
          'A guide only — confirm final pricing and delivery with each vendor. Payment happens off-platform in v1.'),
      ),
    ),
  );
}

/* ============================== SEND FLOW (sheet / modal) ============================== */
const CHANNELS = [
  { id: 'whatsapp',  icon: 'chat',    bg: '#1FA855', name: 'WhatsApp',          sub: 'Opens chat with your list pre-filled' },
  { id: 'instagram', icon: 'camera',  bg: '#C13584', name: 'Instagram DM',      sub: 'Copies the message, opens your DMs' },
  { id: 'link',      icon: 'linkico', bg: 'var(--accent)', name: 'Vendor link', sub: 'Open the store’s own site' },
];

function SendFlow({ ctx, visible, device, onClose }) {
  const [channel, setChannel] = useState('whatsapp');
  const [stage, setStage] = useState('choose');
  useEffect(() => { if (ctx) { setStage('choose'); setChannel('whatsapp'); } }, [ctx && ctx.vendor.handle, visible]);
  if (!ctx) return null;
  const { vendor, items } = ctx;
  const total = items.reduce((s, it) => s + it.p.price * it.qty, 0);
  const ch = CHANNELS.find(c => c.id === channel);

  const inner = stage === 'choose'
    ? h(React.Fragment, null,
        h('div', { style: { display: 'flex', alignItems: 'center', gap: 11, padding: '4px 0 16px' } },
          h(Avatar, { name: vendor.name, color: vendor.avatar, size: 42 }),
          h('div', { style: { flex: 1, lineHeight: 1.25 } },
            h('div', { style: { fontSize: 12, color: 'var(--ink-3)' } }, 'Send your list to'),
            h('div', { style: { display: 'flex', alignItems: 'center', gap: 5, fontWeight: 600, fontSize: 16 } }, vendor.name, vendor.verified && h(VMark))),
          device === 'desktop' && h('button', { className: 'icon-btn', onClick: onClose }, h(Icon, { name: 'x' })),
        ),
        // message preview
        h('div', { className: 'eyebrow', style: { marginBottom: 8 } }, 'Message preview'),
        h('div', { className: 'msgprev' },
          items.length === 0
            ? h('div', { style: { color: 'var(--ink)', fontWeight: 500 } }, 'Hi ', vendor.name, ', I came across your store on linked.market and I’d love to know more about what you have available.')
            : h(React.Fragment, null,
                h('div', { style: { color: 'var(--ink)', fontWeight: 500, paddingBottom: 4 } }, 'Hi ', vendor.name, ', I’d like these from your linked.market store:'),
                items.map(it => h('div', { className: 'ln', key: it.p.id },
                  h('span', { className: 'price', style: { color: 'var(--ink-3)', minWidth: 22 } }, '×' + it.qty),
                  h('span', { style: { flex: 1 } }, h('b', null, it.p.name), variantStr(it.variant) ? '  (' + variantStr(it.variant) + ')' : ''),
                  h('span', { className: 'price', style: { color: 'var(--ink-2)' } }, naira(it.p.price * it.qty)))),
                h('div', { className: 'ln', style: { fontWeight: 600 } },
                  h('span', { style: { flex: 1, color: 'var(--ink)' } }, 'Estimated total'),
                  h('span', { className: 'price', style: { color: 'var(--ink)' } }, naira(total)))),
        ),
        // channels
        h('div', { className: 'eyebrow', style: { margin: '18px 0 8px' } }, 'Send via'),
        h('div', { style: { display: 'flex', flexDirection: 'column', gap: 9 } },
          CHANNELS.map(c => h('div', { key: c.id, className: 'channel' + (channel === c.id ? ' on' : ''), onClick: () => setChannel(c.id) },
            h('div', { className: 'cico', style: { background: c.bg } }, h(Icon, { name: c.icon })),
            h('div', { style: { flex: 1, minWidth: 0 } }, h('div', { className: 'ct' }, c.name), h('div', { className: 'cs' }, c.sub)),
            h('div', { className: 'cradio' }),
          ))),
        h('button', { className: 'btn btn-primary btn-lg btn-block', style: { marginTop: 18 }, onClick: () => setStage('sent') },
          h(Icon, { name: 'send' }), 'Open ' + ch.name),
        h('p', { style: { fontSize: 11.5, color: 'var(--ink-3)', textAlign: 'center', marginTop: 12, lineHeight: 1.5 } },
          'You’ll finish the conversation with the vendor directly. linked.market never takes a cut.'),
      )
    : h('div', { className: 'confirm' },
        h('div', { className: 'ring2' }, h(Icon, { name: 'check' })),
        h('h2', { className: 't-display', style: { fontSize: 24 } }, 'Your list is on its way'),
        h('p', { style: { fontSize: 14.5, color: 'var(--ink-2)', marginTop: 10, maxWidth: 300, lineHeight: 1.55 } },
          ch.name + ' is opening with your ' + (items.length ? items.length + '-item message' : 'message') + ' to ', h('b', { style: { color: 'var(--ink)' } }, '@' + vendor.handle), '. They usually reply in ', vendor.response, '.'),
        h('div', { style: { display: 'flex', gap: 10, marginTop: 24, width: '100%' } },
          h('button', { className: 'btn btn-secondary btn-md', style: { flex: 1 }, onClick: () => setStage('choose') }, 'Back'),
          h('button', { className: 'btn btn-primary btn-md', style: { flex: 1 }, onClick: onClose }, 'Done')),
      );

  if (device === 'desktop') {
    return h('div', { className: 'modal' + (visible ? ' show' : ''), onClick: onClose },
      h('div', { className: 'card', onClick: e => e.stopPropagation(), style: { padding: 26 } }, inner));
  }
  return h(React.Fragment, null,
    h('div', { className: 'scrim' + (visible ? ' show' : ''), onClick: onClose }),
    h('div', { className: 'sheet' + (visible ? ' show' : '') },
      h('div', { className: 'grip' }),
      h('div', { style: { padding: '8px 20px 28px', overflowY: 'auto' } }, inner),
    ),
  );
}

Object.assign(window, { MarkedMobile, MarkedDesktop, SendFlow });
})();
