/** @jsxImportSource preact */
import '@shopify/ui-extensions/preact';
import {useEffect, useState} from 'preact/hooks';

// Session-token-authenticated serve endpoint (NOT the App Proxy, the extension
// sandbox can't produce a proxy signature). Same payload shape as the proxy.
const API_URL = 'https://dynasort.immersiveecommerce.com/checkout-recommend.php';

// gid://shopify/Product/123... -> "123..."
export function numericGid(gid){
  const tail = String(gid || '').split('/').pop().split('?')[0];
  return /^\d+$/.test(tail) ? tail : '';
}

// Fetch the post-purchase recommendations once on mount. Any failure resolves
// to an empty product list, which renders as nothing, the block must never
// break or clutter the page it sits on.
// CX click beacon (plans/cx-tracking-jul-2026.md): best effort, keepalive so it
// survives the navigation to the product page. The sandbox has no page cookies,
// so post-purchase attribution is serve + click only.
function fireClickBeacon(serveId, productId, position){
  if (!serveId) return;
  shopify.sessionToken.get().then((token) => {
    const qs = new URLSearchParams({beacon: '1', e: 'click', serve_id: String(serveId), pid: String(productId), pos: String(position)});
    fetch(`${API_URL}?${qs.toString()}`, {headers: {Authorization: `Bearer ${token}`}, keepalive: true}).catch(() => {});
  }).catch(() => {});
}

function useRecs(params){
  const [state, setState] = useState({loading: true, products: [], heading: '', currency: 'USD', saleBadge: false, serveId: 0});
  useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        const token = await shopify.sessionToken.get();
        // No limit param: the server derives the card count (and enforces
        // min_to_render) from the placement's admin settings.
        const qs = new URLSearchParams();
        for (const key in params) {
          if (params[key] !== undefined && params[key] !== '') qs.set(key, params[key]);
        }
        const res = await fetch(`${API_URL}?${qs.toString()}`, {
          headers: {Authorization: `Bearer ${token}`},
        });
        const data = await res.json();
        if (cancelled) return;
        const badges = (data && data.settings && data.settings.fields && data.settings.fields.badges) || {};
        setState({
          loading: false,
          products: (data && data.products) || [],
          heading: pickHeading(data),
          currency: (data && data.currency) || 'USD',
          saleBadge: badges.sale === true,
          serveId: (data && data.serve_id) || 0,
        });
      } catch (err) {
        if (!cancelled) setState({loading: false, products: [], heading: '', currency: 'USD', saleBadge: false, serveId: 0});
      }
    })();
    return () => { cancelled = true; };
  }, []);
  return state;
}

// Merchant heading: per-placement settings locale override, else the placement
// default from the server ("Complete Your Order").
function pickHeading(data){
  const locales = (data && data.settings && data.settings.heading && data.settings.heading.locales) || {};
  let lang = 'en';
  try {
    const iso = shopify.localization?.language?.value?.isoCode;
    if (iso) lang = String(iso).toLowerCase();
  } catch (err) { /* default en */ }
  return locales[lang] || locales[lang.split('-')[0]] || (data && data.default_heading) || 'You may also like';
}

function storefrontBase(){
  try {
    return String(shopify.shop?.storefrontUrl || '').replace(/\/$/, '');
  } catch (err) {
    return '';
  }
}

function priceLabel(product, currency){
  const fmt = (n) => {
    try {
      return new Intl.NumberFormat(undefined, {style: 'currency', currency}).format(Number(n));
    } catch (err) {
      return `${currency} ${n}`;
    }
  };
  if (product.price_min === null || product.price_min === undefined) return '';
  if (product.price_max !== null && Number(product.price_max) > Number(product.price_min)) {
    return `From ${fmt(product.price_min)}`;
  }
  return fmt(product.price_min);
}

// The rendered block, shared by both targets; `params` decides the seed source
// (product_ids on the Thank you page, order_id on the Order status page).
export function RecsBlock({params}){
  const {loading, products, heading, currency, saleBadge, serveId} = useRecs(params);
  if (loading || products.length === 0) return null;
  const base = storefrontBase();
  return (
    <s-section heading={heading}>
      <s-grid gridTemplateColumns="repeat(auto-fill, minmax(130px, 1fr))" gap="base">
        {products.map((product, idx) => (
          <s-clickable key={product.id} href={`${base}${product.url}`} onClick={() => fireClickBeacon(serveId, product.id, idx + 1)}>
            <s-stack gap="small-200">
              {product.featured_image ? (
                <s-image src={product.featured_image} alt={product.title} />
              ) : null}
              <s-text>{product.title}</s-text>
              <s-stack direction="inline" gap="small-200">
                <s-text type="strong">{priceLabel(product, currency)}</s-text>
                {saleBadge && product.on_sale ? <s-badge tone="critical">Sale</s-badge> : null}
              </s-stack>
            </s-stack>
          </s-clickable>
        ))}
      </s-grid>
    </s-section>
  );
}
