// Search step — side-by-side: keyword search vs personalized search
// Search bar lives inside each column (like the real rainbowshops.com header search).

function StepSearch({ state, setState }) {
  const persona = window.PERSONAS.find(p => p.id === state.persona) || window.PERSONAS[0];
  const favorites = state.favorites || [];

  const [query, setQuery] = React.useState(SCRIPTED_QUERIES[0].q);

  const keywordResults = React.useMemo(() => {
    // Scripted keyword override — mirrors what rainbowshops.com actually returns:
    // literal "top" matches that ignore the "going out" + budget intent.
    const scripted = SCRIPTED_QUERIES.find(s => s.q === query);
    if (scripted && scripted.keywordResults) return scripted.keywordResults;
    // Alpha: literal word match against product name. Typos & semantic queries return 0.
    const words = query.toLowerCase().replace(/[$]/g, '').split(/\s+/).filter(w => w.length > 2);
    if (!words.length) return [];
    return window.PRODUCTS.filter(p => {
      const n = (p.name + ' ' + p.type).toLowerCase();
      return words.every(w => n.includes(w));
    }).sort((a, b) => a.sku.localeCompare(b.sku)).slice(0, 6);
  }, [query]);

  const favWeights = window.buildFavWeights ? window.buildFavWeights(favorites) : null;
  const personalizedResults = React.useMemo(() => {
    // Malachyte: resolve scripted query to its aliases (typo fix + semantic intent),
    // apply any budget cap, then rank against the persona vector.
    const scripted = SCRIPTED_QUERIES.find(s => s.q === query);
    // Curated per-persona result set (overrides ranking for a specific visitor).
    if (scripted && scripted.personaResults && scripted.personaResults[persona.id]) {
      return scripted.personaResults[persona.id]
        .map(id => window.PRODUCTS.find(p => p.id === id))
        .filter(Boolean)
        .slice(0, 6);
    }
    const aliases = scripted ? scripted.aliases : [query.toLowerCase()];
    if (!aliases.length) return [];
    let pool = window.PRODUCTS.filter(p => {
      const n = (p.name + ' ' + p.type).toLowerCase();
      return aliases.some(a => n.includes(a));
    });
    if (scripted && scripted.maxPrice) pool = pool.filter(p => p.price <= scripted.maxPrice);
    let ranked = window.rankProducts(pool, persona, favWeights);
    // Lead-boost: pull the strongest going-out top cues to the front (matched by name).
    if (scripted && scripted.boostTerms) {
      const score = (p) => {
        const n = (p.name + ' ' + p.type).toLowerCase();
        let best = scripted.boostTerms.length;
        scripted.boostTerms.forEach((t, i) => { if (n.includes(t) && i < best) best = i; });
        return best;
      };
      ranked = [...ranked].sort((a, b) => score(a) - score(b));
    }
    return ranked.slice(0, 6);
  }, [query, persona, favWeights]);

  return (
    <div className="sbs-shell">
      <div className="sbs-grid">
        <SearchColumn mode="alpha" query={query} setQuery={setQuery} results={keywordResults} persona={persona} />
        <SearchColumn mode="malachyte" query={query} setQuery={setQuery} results={personalizedResults} persona={persona} favWeights={favWeights} />
      </div>
    </div>
  );
}

const SCRIPTED_QUERIES = [
  { q: 'something to wear to a summer wedding',    intent: 'semantic', aliases: ['maxi dress', 'midi dress', 'jumpsuit', 'satin'],
    // usr_2093 (denim) — lead the personalized results with summer-dressy denim, not the plain cami jumpsuit.
    personaResults: {
      denim: [
        'denim-tie-back-halter-neck-skater-dress-tan-753',
        'open-tie-back-sweetheart-denim-dress-light-wash-754',
        'metallic-keyhole-halter-neck-denim-dress-blue-denim-103',
        'halter-neck-cutout-zip-back-denim-mini-dress-light-wash-186',
        'denim-faux-wrap-front-detail-mini-dress-light-wash-66',
        'strapless-tiered-denim-romper-light-wash-145',
      ],
    },
    keywordResults: [
      { id: 'kw-wed-a0', name: 'Plus Size Tiered Ruffle Hem Side Ruched Halter Dress - yellow', type: 'Dress', price: 5.99, orig: 9.99, sale: true, cats: [], img: 'assets/kw-wed-a0.png' },
      { id: 'kw-wed-a1', name: 'Plus Size Beaded Halter Neck Side Slit Maxi Dress - black', type: 'Maxi Dress', price: 19.97, orig: null, sale: false, cats: [], img: 'assets/kw-wed-a1.png' },
      { id: 'kw-wed-a2', name: 'Plus Size Beaded Halter Neck Side Slit Maxi Dress - brown', type: 'Maxi Dress', price: 19.97, orig: null, sale: false, cats: [], img: 'assets/kw-wed-a2.png' },
      { id: 'kw-wed-a3', name: 'Plus Size Side Ruched Faux Wrap Low Open Back Dress - black', type: 'Dress', price: 5.99, orig: 9.99, sale: true, cats: [], img: 'assets/kw-wed-a3.png' },
      { id: 'kw-wed-b0', name: 'Plus Size Side Ruched Faux Wrap Low Open Back Dress - lavender', type: 'Dress', price: 5.99, orig: 9.99, sale: true, cats: [], img: 'assets/kw-wed-b0.png' },
      { id: 'kw-wed-b2', name: 'Plus Size Tie Waist Back Detail Midi Halter Dress - blue', type: 'Midi Dress', price: 6.99, orig: null, sale: false, cats: [], img: 'assets/kw-wed-b2.png' },
      { id: 'kw-wed-b3', name: 'Sleeveless Smocked Midi Dress - pink', type: 'Midi Dress', price: 24.97, orig: null, sale: false, cats: [], img: 'assets/kw-wed-b3.png' },
      { id: 'kw-wed-c1', name: 'Plus Size Lace Up Side Sheath Dress - chambray', type: 'Dress', price: 11.99, orig: null, sale: false, cats: [], img: 'assets/kw-wed-c1.png' },
    ] },
  { q: 'cute going out top under $20',            intent: 'combo',
    aliases: ['halter top', 'grommet', 'bustier', 'corset', 'tube top', 'one shoulder', 'crop top', 'cami'],
    boostTerms: ['grommet halter', 'halter', 'bustier', 'corset', 'tube top', 'one shoulder', 'mesh', 'rhinestone'],
    maxPrice: 20,
    keywordResults: [
      { id: 'kw-go-0', name: 'Plus Size Bow Money Graphic Short Sleeve Crop Top - black', type: 'Crop Top', price: 12.99, orig: null, sale: false, cats: [], img: 'assets/kw-goingout-0.png' },
      { id: 'kw-go-1', name: 'Plus Size Tie Front Off The Shoulder Top - pink', type: 'Top', price: 9.99, orig: null, sale: false, cats: [], img: 'assets/kw-goingout-1.png' },
      { id: 'kw-go-2', name: 'Plus Size Tie Front Off The Shoulder Top - green', type: 'Top', price: 9.99, orig: null, sale: false, cats: [], img: 'assets/kw-goingout-2.png' },
      { id: 'kw-go-3', name: 'Plus Size Tie Front Off The Shoulder Top - black', type: 'Top', price: 9.99, orig: null, sale: false, cats: [], img: 'assets/kw-goingout-3.png' },
    ] },
];

function SearchColumn({ mode, query, setQuery, results, persona, favWeights }) {
  const isMal = mode === 'malachyte';
  const handleImgErr = (e) => { e.target.src = window.PRODUCT_FALLBACK; };
  const [open, setOpen] = React.useState(false);

  const pick = (q) => { setQuery(q); setOpen(false); };
  const scripted = SCRIPTED_QUERIES.find(s => s.q === query);

  return (
    <div className={`sbs-col sbs-col--${mode}`}>
      <div className="sbs-col__head">
        <span className="sbs-col__tag">{isMal ? 'AFTER' : 'BEFORE'}</span>
        {isMal
          ? <img src="assets/malachyte-logo-gradient.png" alt="Malachyte" className="sbs-col__logo sbs-col__logo--mal" />
          : <span className="sbs-col__brandline"><img src="assets/rainbow-logo.jpeg" alt="Rainbow Shops" className="sbs-col__logo sbs-col__logo--wiha" /><span className="rainbow-wordmark">RAINBOW</span></span>}
        <span className="sbs-col__caption">{isMal ? 'Personalized search' : 'Keyword match'}</span>
      </div>

      <div className="sbs-col__viewport">
        <div className="demo-urlbar">
          <div className="demo-urlbar__dots"><span /><span /><span /></div>
          <div className="demo-urlbar__url">
            rainbowshops.com/search?q={encodeURIComponent(query)}{isMal ? ' · personalized by malachyte' : ''}
          </div>
        </div>

        <WihaChrome />

        <div className="wiha-plp-root">
          <div className={`search-bar-row ${open ? 'is-active' : ''}`}>
            <button className="search-bar-trigger" onClick={() => setOpen(o => !o)}>
              <span className={`search-bar-trigger-text ${!query ? 'is-placeholder' : ''}`}>
                {query || 'Search Rainbow…'}
              </span>
              <span className="search-bar-trigger-caret">▾</span>
            </button>

            {open && (
              <div className="search-bar-menu">
                <div className="search-bar-menu-eye">SCRIPTED QUERIES</div>
                {SCRIPTED_QUERIES.map(s => (
                  <button
                    key={s.q}
                    className={`search-bar-menu-item ${s.q === query ? 'is-selected' : ''}`}
                    onClick={() => pick(s.q)}
                  >
                    <span className="search-bar-menu-item-q">{s.q}</span>
                    <span className={`search-bar-menu-item-intent search-bar-menu-item-intent--${s.intent}`}>{s.intent}</span>
                  </button>
                ))}
              </div>
            )}
          </div>

          <div className="search-head">
            <div className="search-head__eye">
              {isMal ? 'PERSONALIZED RESULTS' : 'KEYWORD RESULTS'}
            </div>
            <h2 className="search-head__title">
              {results.length} matches for "{query}"
            </h2>
            <p className="search-head__note">
              {isMal
                ? `Resolved to ${(scripted?.aliases || []).slice(0, 3).join(' + ') || 'intent vector'}${scripted?.maxPrice ? ` · ≤ $${scripted.maxPrice}` : ''} — ranked for ${persona.userId}.`
                : results.length
                  ? `Returned in catalog order. No persona signal applied.`
                  : `No products match those exact words. Keyword search can't handle typos, occasions, or budgets.`}
            </p>
          </div>

          <div className="wiha-grid">
            {results.map((p, i) => (
              <ProductCard
                key={p.id}
                product={p}
                index={i}
                mode={mode}
                persona={persona}
                favWeights={favWeights}
                isFav={false}
                onFav={() => {}}
                onImgErr={handleImgErr}
              />
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { StepSearch });
