// =============================================================================
// Product.jsx — shared renderer for /products/*.html
//
// Each page supplies a plain data object (copy, usage, ingredient notes and the
// full INCI list). Price, name, category and availability are NOT hardcoded:
// they come from /api/store, the same source the storefront and the payment
// endpoint use, so a price edited in Admin shows here too.
//
// Add to bag writes the same cart shape index.html writes, to the same
// localStorage key, and fires the same event the nav badge listens for.
// =============================================================================

const CART_KEY = 'hws-cart-v1';

const addProductToCart = (p) => {
  let cart = [];
  try { cart = JSON.parse(localStorage.getItem(CART_KEY)) || []; } catch (e) { cart = []; }
  const i = cart.findIndex(it => it.id === p.id);
  if (i >= 0) cart[i] = { ...cart[i], qty: (cart[i].qty || 1) + 1 };
  else cart.push({ id: p.id, name: p.name, cat: p.cat, price: p.price, qty: 1, img: p.img });
  try {
    localStorage.setItem(CART_KEY, JSON.stringify(cart));
    window.dispatchEvent(new CustomEvent('hws-cart-changed', { detail: cart }));
  } catch (e) { /* private mode — the page still works, the bag just won't persist */ }
  return cart.reduce((s, it) => s + (it.qty || 1), 0);
};

// ── Full ingredient list, collapsed by default ───────────────────────────────
// Cosmetic INCI lists are long and in descending order of concentration. Nobody
// wants 30 Latin names above the fold, but the people who do want them really
// want them — so it is on the page, not in a PDF, one tap away.
const IngredientList = ({ inci }) => {
  const { useState } = React;
  const [open, setOpen] = useState(false);
  return (
    <div style={{
      border: '1.5px solid rgba(61,47,35,0.14)', borderRadius: 16,
      background: 'var(--paper-soft)', overflow: 'hidden',
    }}>
      <button
        type="button" onClick={() => setOpen(o => !o)} aria-expanded={open}
        style={{
          width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          gap: 12, padding: '18px 22px', background: 'transparent', border: 'none',
          cursor: 'pointer', textAlign: 'left', color: 'var(--brown)',
          fontFamily: 'var(--font-display)', fontSize: 17, letterSpacing: '0.06em',
          textTransform: 'uppercase', minHeight: 44,
        }}>
        <span>Full ingredients ({inci.length})</span>
        <span aria-hidden="true" style={{ transition: 'transform .2s', transform: open ? 'rotate(180deg)' : 'none' }}>
          <svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
            <polyline points="3,5 7,9 11,5" />
          </svg>
        </span>
      </button>
      {open && (
        <div style={{ padding: '0 22px 22px' }}>
          <p style={{ fontSize: 13, color: 'var(--brown-soft)', margin: '0 0 12px', lineHeight: 1.6 }}>
            INCI names, in descending order of concentration — the same list printed on the bottle.
          </p>
          <p style={{ fontSize: 14.5, lineHeight: 1.75, color: 'var(--brown)', margin: 0 }}>
            {inci.join(', ')}
          </p>
        </div>
      )}
    </div>
  );
};

// Product structured data is written from the same /api/store response the buy
// box uses, not baked into the HTML. Price and stock are the two fields most
// likely to be edited in Admin, and stale structured data is worse than none —
// Google will show a price that no longer exists. Google renders this page
// before extracting, so a script tag added here is read the same as a static one.
const writeProductLd = (p, storeOpen, meta) => {
  const origin = location.origin;
  const ld = {
    '@context': 'https://schema.org',
    '@type': 'Product',
    name: p.name,
    sku: p.id,
    description: (document.querySelector('meta[name="description"]') || {}).content || '',
    image: origin + '/assets/og/product-' + p.id + '.jpg',
    brand: { '@type': 'Brand', name: 'Hawaiian Style' },
    offers: {
      '@type': 'Offer',
      url: origin + location.pathname,
      priceCurrency: 'THB',
      price: String(p.price),
      availability: storeOpen
        ? 'https://schema.org/InStock'
        : 'https://schema.org/PreOrder',
      seller: { '@type': 'Organization', name: 'Sahatavesin Import Export Co., Ltd.' },
    },
  };
  let el = document.getElementById('hws-product-ld');
  if (!el) {
    el = document.createElement('script');
    el.type = 'application/ld+json';
    el.id = 'hws-product-ld';
    document.head.appendChild(el);
  }
  el.textContent = JSON.stringify(ld);
};

// ── Buy box: live price + availability from /api/store ───────────────────────
const BuyBox = ({ id, fallback }) => {
  const { useState, useEffect } = React;
  const [state, setState] = useState({ status: 'loading' });
  const [added, setAdded] = useState(0);

  useEffect(() => {
    let dead = false;
    fetch('/api/store')
      .then(r => r.ok ? r.json() : Promise.reject(new Error(r.status)))
      .then(d => {
        if (dead) return;
        const p = (d.products || []).find(x => x.id === id);
        const open = !!(d.settings && d.settings.store_open);
        setState({ status: 'ok', product: p || null, open });
        if (p) writeProductLd(p, open);
      })
      .catch(() => { if (!dead) setState({ status: 'error' }); });
    return () => { dead = true; };
  }, [id]);

  const box = (children) => (
    <div style={{
      background: 'var(--paper-soft)', border: '2px solid rgba(61,47,35,0.12)',
      borderRadius: 18, padding: '22px 24px', marginTop: 26,
    }}>{children}</div>
  );

  if (state.status === 'loading') {
    return box(<span style={{ color: 'var(--brown-soft)', fontSize: 15 }}>Checking price and availability…</span>);
  }

  // The catalogue is the source of truth for price; if it cannot be reached we
  // say so rather than showing a number that might be stale.
  if (state.status === 'error' || !state.product) {
    return box(
      <>
        <div style={{ fontWeight: 800, fontSize: 16, color: 'var(--brown)' }}>
          {state.status === 'error' ? 'Price unavailable right now' : 'Not currently on sale'}
        </div>
        <p style={{ fontSize: 14, color: 'var(--brown-soft)', margin: '8px 0 16px', lineHeight: 1.6 }}>
          {state.status === 'error'
            ? 'We could not reach the catalogue. Refresh, or find this bottle at any of our stockists.'
            : 'This one is not in the online shop at the moment. It may still be on the shelf near you.'}
        </p>
        <Pill variant="ghost" href="/#where-to-buy">Where to buy →</Pill>
      </>
    );
  }

  const p = state.product;
  return box(
    <>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 14, flexWrap: 'wrap' }}>
        <span style={{ fontFamily: 'var(--font-display)', fontSize: 34, color: 'var(--brown)', lineHeight: 1 }}>
          ฿{p.price}
        </span>
        <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--brown-soft)' }}>
          {p.cat}
        </span>
      </div>

      {state.open ? (
        <div style={{ marginTop: 18, display: 'flex', gap: 12, alignItems: 'center', flexWrap: 'wrap' }}>
          <Pill as="button" type="button" variant="sun"
            onClick={() => setAdded(addProductToCart(p))}>Add to bag +</Pill>
          {added > 0 && (
            <a href="/checkout" style={{ fontSize: 14, fontWeight: 700, color: 'var(--orange)' }}>
              {added} in your bag — checkout →
            </a>
          )}
        </div>
      ) : (
        <div style={{ marginTop: 18 }}>
          <p style={{ fontSize: 14.5, color: 'var(--brown-soft)', lineHeight: 1.6, margin: '0 0 14px' }}>
            <strong style={{ color: 'var(--brown)' }}>Online ordering opens very soon.</strong>{' '}
            In the meantime this bottle is on the shelf at our stockists and in our marketplace shops.
          </p>
          <Pill variant="ghost" href="/#where-to-buy">Where to buy →</Pill>
        </div>
      )}
    </>
  );
};

// ── Whole page ───────────────────────────────────────────────────────────────
const ProductPage = ({ product }) => {
  const p = product;
  return (
    <>
      <TopBar />
      <Nav cartCount={0} />

      <div style={{ maxWidth: 1160, margin: '0 auto', padding: '30px 24px 0' }}>
        <a href={p.backHref || '/#bestsellers'} style={{
          display: 'inline-flex', alignItems: 'center', gap: 8, textDecoration: 'none',
          fontFamily: 'var(--font-display)', fontSize: 14, letterSpacing: '0.08em',
          textTransform: 'uppercase', color: 'var(--brown-soft)',
        }}>← {p.backLabel || 'All products'}</a>
      </div>

      <header className="pd-top" style={{ maxWidth: 1160, margin: '0 auto', padding: '22px 24px 0' }}>
        <div className="pd-shot" style={{ background: p.gradient }}>
          <BottleShot src={p.img} alt={p.name} />
        </div>

        <div>
          <Eyebrow>{p.collection}</Eyebrow>
          <h1 style={{
            fontFamily: 'var(--font-display)', fontWeight: 400,
            fontSize: 'clamp(32px, 5vw, 56px)', lineHeight: 0.98,
            textTransform: 'uppercase', color: 'var(--brown)', margin: '14px 0 0',
          }}>{p.name}</h1>
          {p.script && (
            <div style={{
              fontFamily: 'var(--font-script)', color: 'var(--orange)', fontSize: 26,
              transform: 'rotate(-2deg)', transformOrigin: 'left center', margin: '10px 0 0',
            }}>{p.script}</div>
          )}
          <p style={{ fontSize: 17.5, lineHeight: 1.65, color: 'var(--brown-soft)', marginTop: 18 }}>
            {p.summary}
          </p>

          <div className="pd-facts">
            {p.facts.map(f => (
              <div key={f.k} className="pd-fact">
                <b>{f.v}</b><span>{f.k}</span>
              </div>
            ))}
          </div>

          <BuyBox id={p.id} />
        </div>
      </header>

      <main style={{ maxWidth: 860, margin: '0 auto', padding: '58px 24px 0' }} className="hws-prose">
        {p.sections.map((s, i) => (
          <section key={i} style={{ marginTop: i === 0 ? 0 : 44 }}>
            <h2 style={{ marginTop: 0 }}>{s.h}</h2>
            {(s.body || []).map((b, j) => <p key={j} dangerouslySetInnerHTML={{ __html: b }} />)}
            {s.list && (
              <ul>{s.list.map((it, j) => <li key={j} dangerouslySetInnerHTML={{ __html: it }} />)}</ul>
            )}
          </section>
        ))}

        <section style={{ marginTop: 46 }}>
          <h2 style={{ marginTop: 0 }}>What is in it</h2>
          <p>{p.inciIntro}</p>
          <div style={{ display: 'grid', gap: 12, marginTop: 20 }}>
            {p.highlights.map(h => (
              <div key={h.n} style={{
                display: 'grid', gridTemplateColumns: '190px 1fr', gap: 16,
                padding: '15px 18px', borderRadius: 13,
                border: '1.5px solid rgba(61,47,35,0.12)', background: 'var(--paper-soft)',
              }} className="pd-hl">
                <div style={{ fontWeight: 800, fontSize: 14.5, color: 'var(--brown)' }}>{h.n}</div>
                <div style={{ fontSize: 14.5, color: 'var(--brown-soft)', lineHeight: 1.6 }}
                     dangerouslySetInnerHTML={{ __html: h.d }} />
              </div>
            ))}
          </div>
          <div style={{ marginTop: 20 }}><IngredientList inci={p.inci} /></div>
        </section>

        <section style={{ marginTop: 46 }}>
          <h2 style={{ marginTop: 0 }}>Before you use it</h2>
          {p.cautions.map((c, i) => (
            <aside key={i} className="hws-callout" style={{
              marginTop: i === 0 ? 18 : 14,
              borderLeftColor: c.strong ? '#C8362C' : 'var(--orange)',
            }}>
              {c.title && <div className="hws-callout-h" style={{ color: c.strong ? '#C8362C' : 'var(--orange)' }}>{c.title}</div>}
              <div dangerouslySetInnerHTML={{ __html: c.html }} />
            </aside>
          ))}
        </section>

        {p.reading && p.reading.length > 0 && (
          <section style={{ marginTop: 52 }}>
            <Eyebrow>★ From Sun School</Eyebrow>
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(230px, 1fr))', gap: 14, marginTop: 14 }}>
              {p.reading.map(a => (
                <a key={a.href} href={a.href} style={{
                  background: 'var(--paper-soft)', border: '1.5px solid rgba(61,47,35,0.12)',
                  borderRadius: 15, padding: '18px 20px', textDecoration: 'none', color: 'var(--brown)',
                }}>
                  <div style={{ fontWeight: 800, fontSize: 15.5, lineHeight: 1.35 }}>{a.title}</div>
                  <div style={{ fontSize: 13, color: 'var(--brown-soft)', marginTop: 7 }}>{a.read} read →</div>
                </a>
              ))}
            </div>
          </section>
        )}
      </main>

      <div style={{ height: 64 }} />
      <Footer />
    </>
  );
};
