// Import List Modal — paste content from anywhere, AI turns it into a
// structured list.
//
// Three input modes:
//   • Paste text   — anything: AI response, freeform notes, markdown
//   • Paste CSV    — spreadsheet rows (we send raw, AI parses)
//   • Paste URL    — server fetches the page, strips HTML, AI summarises
//
// Plus an "Upload file" affordance that reads .csv/.txt/.tsv/.md client-side
// and feeds it into the appropriate textarea.
//
// Flow: pick mode → paste/upload content → Analyze → preview tree →
// Save (calls window.MR.aiAssistant's list builder pattern via a passed
// onCreate handler) OR Discard.

(function () {
  const e = React.createElement;
  const { useState, useRef, useEffect } = React;

  const TABS = [
    { k: 'text', label: 'Paste text', hint: 'Notes, an AI response, a markdown checklist — anything.' },
    { k: 'csv',  label: 'CSV / Spreadsheet', hint: 'Paste rows from Excel, Google Sheets, Numbers. Headers in row 1 help.' },
    { k: 'url',  label: 'From a URL', hint: 'Paste a link to a Babylist, Amazon registry, blog post — we\'ll fetch it.' },
  ];

  function packCatalog(products) {
    return (products || [])
      .filter(p => p && p.id && p.name)
      .slice(0, 250)
      .map(p => ({
        id: p.id, brand: p.brand || '', name: p.name || '',
        price: p.price != null ? Number(p.price) : null,
        category: p.category || p.subcategory || '',
      }));
  }

  function readContext() {
    const ctx = {};
    try {
      // User-scoped app blob — read from the active signed-in user's
      // bucket. Falling back to the unscoped legacy key would risk
      // pulling a previous user's profile/kids data on a shared browser
      // (the bug fixed across the codebase).
      const uid = (window.MR && window.MR.user && window.MR.user.current
        ? (window.MR.user.current().session && window.MR.user.current().session.user && window.MR.user.current().session.user.id) || null
        : null);
      const raw = localStorage.getItem('parentstack-v1:' + (uid || 'guest'));
      if (raw) {
        const ps = JSON.parse(raw) || {};
        const profile = ps.profile || {};
        if (Array.isArray(profile.kids) && profile.kids.length) {
          ctx.kids = profile.kids.map(k => ({
            name: k.name, birthday: k.birthday,
          }));
        }
      }
    } catch {}
    return ctx;
  }

  // Stats for the preview banner.
  function specStats(spec) {
    let items = 0, matched = 0, placeholders = 0, groups = 0, shortlists = 0;
    const walk = (arr) => (arr || []).forEach(c => {
      if (!c) return;
      if (c.kind === 'item') { items++; if (c.productId) matched++; else placeholders++; }
      else if (c.kind === 'group') { groups++; walk(c.children); }
      else if (c.kind === 'shortlist') { shortlists++; walk(c.children); }
    });
    walk(spec.children);
    return { items, matched, placeholders, groups, shortlists };
  }

  function renderTree(children, depth) {
    if (!Array.isArray(children) || children.length === 0) return null;
    return e('ul', { className: 'imp-tree imp-tree--d' + depth },
      children.map((c, i) => {
        if (!c) return null;
        if (c.kind === 'item') {
          return e('li', { key: i, className: 'imp-tree-item' + (c.productId ? ' imp-tree-item--matched' : ' imp-tree-item--placeholder') },
            e('span', { className: 'imp-tree-dot' }),
            e('span', { className: 'imp-tree-name' }, c.name || 'Item'),
            c.brand && e('span', { className: 'imp-tree-brand' }, c.brand),
            c.price != null && e('span', { className: 'imp-tree-price' }, 'A$' + c.price),
            !c.productId && e('span', { className: 'imp-tree-tag' }, 'placeholder')
          );
        }
        return e('li', { key: i, className: 'imp-tree-group imp-tree-group--' + c.kind },
          e('div', { className: 'imp-tree-grouphead' },
            e('span', { className: 'imp-tree-groupicon' }, c.kind === 'shortlist' ? '◧' : '▸'),
            e('span', { className: 'imp-tree-groupname' }, c.name || 'Group'),
            c.kind === 'shortlist' && e('span', { className: 'imp-tree-tag imp-tree-tag--shortlist' },
              c.quantityNeeded && c.quantityNeeded > 1 ? 'pick ' + c.quantityNeeded : 'pick one')
          ),
          renderTree(c.children, depth + 1)
        );
      })
    );
  }

  // Build the actual list using the same helper the AI sidebar uses.
  // Also passes through `sourceUrl` from each item so the enrichment
  // pass can fetch product details after the list is created.
  async function buildListFromSpec(spec) {
    if (!window.MR || !window.MR.nodes) return { ok: false, error: 'Data layer not ready' };
    const rootRes = await window.MR.nodes.createRoot({
      name: spec.name || 'Imported list', kind: 'private',
      description: spec.description || '',
    });
    if (!rootRes.ok) return { ok: false, error: rootRes.reason || 'Could not create list' };
    const root = rootRes.root;
    const insertChildren = async (parentId, items) => {
      for (let i = 0; i < items.length; i++) {
        const c = items[i] || {};
        if (c.kind === 'item') {
          if (c.productId) {
            await window.MR.nodes.addChild({
              parentId, rootId: root.id, type: 'item',
              productId: c.productId, name: c.name || '', position: i,
              picked: !!c.picked, status: c.status || 'want',
            });
          } else {
            await window.MR.nodes.addChild({
              parentId, rootId: root.id, type: 'item',
              name: c.name || 'Item', position: i,
              custom: {
                name: c.name || 'Item', brand: c.brand || '',
                price: c.price != null ? Number(c.price) : null, currency: 'AUD',
                description: c.description || '', placeholder: true,
                // Preserve the URL the AI extracted from the source content;
                // the enrichment pass will use it to fetch product details.
                sourceUrl: (typeof c.sourceUrl === 'string' && c.sourceUrl) ? c.sourceUrl : '',
              },
              picked: !!c.picked, status: c.status || 'want',
            });
          }
        } else {
          const inferredQty = c.kind === 'shortlist'
            ? (Number.isFinite(c.quantityNeeded) && c.quantityNeeded > 0 ? Math.floor(c.quantityNeeded) : 1)
            : 0;
          const r = await window.MR.nodes.addChild({
            parentId, rootId: root.id, type: 'slot',
            name: c.name || 'Group',
            slotKind: c.kind === 'shortlist' ? 'shortlist' : 'group',
            position: i, blurb: c.blurb || null,
            quantityNeeded: inferredQty,
          });
          if (r.ok && Array.isArray(c.children) && c.children.length) {
            await insertChildren(r.node.id, c.children);
          }
        }
      }
    };
    if (Array.isArray(spec.children)) await insertChildren(root.id, spec.children);
    return { ok: true, root };
  }

  // Count items with URLs in a spec tree (recursive).
  function countItemsWithUrls(spec) {
    let n = 0;
    const walk = (arr) => (arr || []).forEach(c => {
      if (!c) return;
      if (c.kind === 'item') { if (c.sourceUrl) n++; }
      else if (c.kind === 'group' || c.kind === 'shortlist') walk(c.children);
    });
    walk(spec.children);
    return n;
  }

  function ImportListModal({ open, onClose, products, gated }) {
    // Pro gate — same status hook as the AI sidebar uses.
    const proStatus = window.ProGate && window.ProGate.useStatus
      ? window.ProGate.useStatus().status : 'approved';
    const isPro = proStatus === 'approved';

    const [tab, setTab]         = useState('text');
    const [text, setText]       = useState('');
    const [csv, setCsv]         = useState('');
    const [url, setUrl]         = useState('');
    const [busy, setBusy]       = useState(false);
    const [err, setErr]         = useState('');
    const [reply, setReply]     = useState(null);
    const [created, setCreated] = useState(false);
    const fileRef = useRef(null);

    useEffect(() => {
      if (!open) {
        // Reset state when modal closes
        setTab('text'); setText(''); setCsv(''); setUrl('');
        setBusy(false); setErr(''); setReply(null); setCreated(false);
      }
    }, [open]);

    useEffect(() => {
      if (!open) return;
      const onKey = (ev) => { if (ev.key === 'Escape') onClose(); };
      window.addEventListener('keydown', onKey);
      const prev = document.body.style.overflow;
      document.body.style.overflow = 'hidden';
      return () => {
        window.removeEventListener('keydown', onKey);
        document.body.style.overflow = prev;
      };
    }, [open, onClose]);

    const hasContent = (tab === 'text' && text.trim())
                    || (tab === 'csv'  && csv.trim())
                    || (tab === 'url'  && url.trim());

    const analyse = async () => {
      setBusy(true); setErr(''); setReply(null);
      const body = { catalog: packCatalog(products), context: readContext() };
      if (tab === 'text') body.text = text.trim();
      if (tab === 'csv')  body.csv  = csv.trim();
      if (tab === 'url')  body.url  = url.trim();
      const headers = { 'Content-Type': 'application/json' };
      try {
        const c = window.MR && window.MR.supabase;
        if (c) {
          const { data } = await c.auth.getSession();
          const tk = data && data.session && data.session.access_token;
          if (tk) headers['Authorization'] = 'Bearer ' + tk;
        }
      } catch {}
      try {
        const r = await fetch('/api/import-list', {
          method: 'POST',
          headers,
          body: JSON.stringify(body),
        });
        const data = await r.json();
        if (data.ok && data.list) {
          setReply({ list: data.list, summary: data.summary || '' });
        } else {
          setErr(data.error || 'Could not parse that content.');
        }
      } catch (ex) {
        setErr('Network error: ' + (ex.message || ex));
      } finally {
        setBusy(false);
      }
    };

    const save = async () => {
      if (!reply || !reply.list) return;
      setBusy(true);
      const run = async () => {
        const res = await buildListFromSpec(reply.list);
        if (!res.ok || !res.root) {
          setErr(res.error || 'Could not create the list');
          setBusy(false);
          return;
        }
        setCreated(true);
        // If the spec has items with URLs, kick off an enrichment pass
        // in the background. We DON'T await it — the user navigates to
        // the list immediately and sees items "fill in" as fetches return.
        // Progress is reported via a globally-handled toast (saved-toast)
        // so it follows the user across pages.
        const urlsToFetch = countItemsWithUrls(reply.list);
        if (urlsToFetch > 0 && window.MR.enrich) {
          // Show initial toast — handled by the global showToast
          if (typeof window.__mr_showToast === 'function') {
            window.__mr_showToast(`Enriching ${urlsToFetch} item${urlsToFetch === 1 ? '' : 's'}…`);
          }
          // Run async — refetch the root first to get the persisted
          // sourceUrls, then enrich.
          (async () => {
            try {
              const fresh = await window.MR.nodes.fetchMyRoots();
              const root = fresh.ok && fresh.roots.find(r => r.id === res.root.id);
              if (!root) return;
              const result = await window.MR.enrich.enrichRoot(root, {
                onProgress: ({ done, total }) => {
                  if (typeof window.__mr_showToast === 'function') {
                    window.__mr_showToast(`Enriching items… ${done}/${total}`);
                  }
                },
              });
              if (typeof window.__mr_showToast === 'function') {
                const msg = result.failed > 0
                  ? `Enriched ${result.succeeded}/${result.total} items (${result.failed} couldn't be fetched)`
                  : `Enriched ${result.succeeded} item${result.succeeded === 1 ? '' : 's'} ✓`;
                window.__mr_showToast(msg);
              }
              // Force a refresh of the list page so the user sees updates.
              if (typeof window.__mr_refreshRoot === 'function') {
                window.__mr_refreshRoot();
              }
            } catch (e) {
              console.warn('[import] enrichment threw', e);
            }
          })();
        }
        setTimeout(() => {
          try { location.hash = '#list/' + res.root.id; } catch {}
          onClose();
        }, 700);
      };
      if (typeof gated === 'function') gated(run)();
      else run();
    };

    const onFileChange = (ev) => {
      const f = ev.target && ev.target.files && ev.target.files[0];
      if (!f) return;
      const reader = new FileReader();
      reader.onload = () => {
        const content = String(reader.result || '');
        // Detect CSV vs text by file extension
        const name = (f.name || '').toLowerCase();
        if (name.endsWith('.csv') || name.endsWith('.tsv')) {
          setTab('csv');
          setCsv(content);
        } else {
          setTab('text');
          setText(content);
        }
      };
      reader.readAsText(f);
      ev.target.value = '';
    };

    if (!open) return null;

    return e(React.Fragment, null,
      e('div', { className: 'imp-scrim', onClick: onClose, 'aria-hidden': true }),
      e('div', { className: 'imp-modal', role: 'dialog', 'aria-label': 'Import a list' },
        e('button', { type: 'button', className: 'imp-close', onClick: onClose, 'aria-label': 'Close' },
          e('svg', { width: 18, height: 18, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 2, strokeLinecap: 'round' },
            e('path', { d: 'M6 6 L18 18 M18 6 L6 18' })
          )
        ),
        e('header', { className: 'imp-head' },
          e('div', { className: 'imp-eyebrow' }, '✦ Import list'),
          e('h2', { className: 'imp-title' }, 'Bring a list in from anywhere'),
          e('p', { className: 'imp-sub' },
            'Paste a response from another AI, a spreadsheet, notes — or a URL. The AI organizes it into groups, picks-of, and catalog matches.'
          )
        ),

        !isPro ? e('div', { className: 'imp-body' },
          e(window.ProGate.UpgradePanel, {
            status: proStatus,
            onRefresh: () => window.MR.pro && window.MR.pro.getMyStatus(),
          })
        ) :
        !reply && e('div', { className: 'imp-body' },
          e('div', { className: 'imp-tabs', role: 'tablist' },
            TABS.map(t => e('button', {
              key: t.k, type: 'button', role: 'tab',
              'aria-selected': tab === t.k,
              className: 'imp-tab' + (tab === t.k ? ' is-on' : ''),
              onClick: () => setTab(t.k),
            }, t.label))
          ),
          e('div', { className: 'imp-tabbody' },
            e('div', { className: 'imp-hint' }, (TABS.find(t => t.k === tab) || {}).hint),
            tab === 'text' && e('textarea', {
              className: 'imp-textarea',
              placeholder: "Paste anything — an AI response, a markdown checklist, freeform notes…\n\nExample:\n# Hospital bag\n- Diapers (3-pack newborn)\n- Wipes\n- Cot sheets × 2\n- Nappies — Pampers Pure or Honest\n…",
              value: text,
              onChange: (ev) => setText(ev.target.value),
              rows: 14,
            }),
            tab === 'csv' && e('textarea', {
              className: 'imp-textarea imp-textarea--mono',
              placeholder: 'Paste CSV or TSV rows. Headers in the first row help:\n\nItem,Brand,Price,Status\nStroller,Bugaboo Fox 5,1899,Loved\nCot,IKEA Sniglar,99,Have\n…',
              value: csv,
              onChange: (ev) => setCsv(ev.target.value),
              rows: 14,
            }),
            tab === 'url' && e('div', { className: 'imp-urlfield' },
              e('input', {
                type: 'url',
                className: 'imp-input',
                placeholder: 'https://www.babylist.com/list/…',
                value: url,
                onChange: (ev) => setUrl(ev.target.value),
                autoFocus: true,
              }),
              e('p', { className: 'imp-urlhint' },
                'Works best with public list pages, blog posts, registry exports. Pages behind login or aggressive anti-bot blocks may not load — paste the text directly if so.'
              )
            )
          ),

          // File upload — works for any tab; reads .csv/.tsv into CSV, .txt/.md into text
          e('div', { className: 'imp-uploadrow' },
            e('button', {
              type: 'button', className: 'imp-upload',
              onClick: () => fileRef.current && fileRef.current.click(),
            },
              e('svg', { width: 12, height: 12, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round' },
                e('path', { d: 'M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4' }),
                e('path', { d: 'M17 8 L12 3 L7 8' }),
                e('path', { d: 'M12 3 L12 15' })
              ),
              e('span', null, 'Or upload a file (.csv, .tsv, .txt, .md)')
            ),
            e('input', {
              ref: fileRef,
              type: 'file',
              accept: '.csv,.tsv,.txt,.md,text/csv,text/plain',
              style: { display: 'none' },
              onChange: onFileChange,
            })
          ),

          err && e('div', { className: 'imp-error' }, '⚠ ' + err),

          e('div', { className: 'imp-actions' },
            e('button', { type: 'button', className: 'btn btn-ghost', onClick: onClose, style: { width: 'auto', padding: '10px 18px' } },
              e('span', null, 'Cancel')
            ),
            e('button', {
              type: 'button',
              className: 'btn',
              onClick: analyse,
              disabled: busy || !hasContent,
              style: { width: 'auto', padding: '10px 22px' },
            },
              busy
                ? e(React.Fragment, null,
                    e('span', { className: 'ai-thinking-dot' }), e('span', { className: 'ai-thinking-dot' }), e('span', { className: 'ai-thinking-dot' }),
                    e('span', { style: { marginLeft: 8 } }, 'Analysing…')
                  )
                : e(React.Fragment, null,
                    e('span', null, '✦ Analyse content'),
                    e('span', { className: 'arrow' }, '→')
                  )
            )
          )
        ),

        // Preview phase
        reply && reply.list && e('div', { className: 'imp-body imp-body--preview' },
          (function () {
            const s = specStats(reply.list);
            return e('div', { className: 'imp-preview-stats' },
              e('span', null, s.items + ' item' + (s.items === 1 ? '' : 's')),
              s.matched > 0 && e('span', { className: 'imp-stat-pill imp-stat-pill--matched' }, s.matched + ' from catalog'),
              s.placeholders > 0 && e('span', { className: 'imp-stat-pill imp-stat-pill--placeholder' }, s.placeholders + ' placeholder' + (s.placeholders === 1 ? '' : 's')),
              s.groups > 0 && e('span', { className: 'imp-stat-pill' }, s.groups + ' group' + (s.groups === 1 ? '' : 's')),
              s.shortlists > 0 && e('span', { className: 'imp-stat-pill' }, s.shortlists + ' decision' + (s.shortlists === 1 ? '' : 's')),
            );
          })(),
          e('div', { className: 'imp-preview' },
            e('div', { className: 'imp-preview-title' }, reply.list.name),
            reply.list.description && e('div', { className: 'imp-preview-desc' }, reply.list.description),
            reply.summary && e('div', { className: 'imp-preview-summary' },
              e('span', { className: 'imp-preview-summary-icon' }, '✦'),
              e('span', null, reply.summary)
            ),
            e('div', { className: 'imp-preview-tree' }, renderTree(reply.list.children, 0))
          ),
          err && e('div', { className: 'imp-error' }, '⚠ ' + err),
          e('div', { className: 'imp-actions' },
            e('button', { type: 'button', className: 'btn btn-ghost', onClick: () => setReply(null), style: { width: 'auto', padding: '10px 18px' } },
              e('span', null, '← Edit input')
            ),
            e('button', {
              type: 'button', className: 'btn',
              onClick: save, disabled: busy || created,
              style: { width: 'auto', padding: '10px 22px' },
            },
              busy
                ? e('span', null, created ? '✓ Created — opening it' : 'Creating…')
                : e(React.Fragment, null,
                    e('span', null, 'Save as list'),
                    e('span', { className: 'arrow' }, '→')
                  )
            )
          )
        )
      )
    );
  }

  window.ImportListModal = ImportListModal;
})();
