/* Checkout */

function normalizePickupCity(value) {
  return String(value || '')
    .normalize('NFD')
    .replace(/[\u0300-\u036f]/g, '')
    .replace(/['`´’]/g, ' ')
    .replace(/[^a-zA-Z0-9]+/g, ' ')
    .trim()
    .replace(/\s+/g, ' ')
    .toLowerCase();
}

function countryIsItaly(value) {
  return ['it', 'italia', 'italy'].includes(String(value || '').trim().toLowerCase());
}

const Checkout = () => {
  const { t, lang } = useLang();
  const [items, setItems] = React.useState(CartStore.get().items);
  const [ready, setReady] = React.useState(false);
  const [loading, setLoading] = React.useState(false);
  const [serverError, setServerError] = React.useState('');
  const [discountTouched, setDiscountTouched] = React.useState(false);
  React.useEffect(() => CartStore.subscribe((state) => setItems(state.items)), []);

  const enriched = items.map((item) => {
    const config = normalizeConfig(item.config);
    return {
      ...item,
      config,
      unitPrice: calcPrice(config),
      stockResult: getVariantStockState(config.bodyColor, config.capColor)
    };
  });

  const hasUnavailable = enriched.some((item) => !canAddToCart(item.stockResult));
  const hasPreorder = enriched.some((item) => isPreorder(item.stockResult));

  const [form, setForm] = React.useState({
    email: '',
    firstName: '',
    lastName: '',
    address: '',
    address2: '',
    zip: '',
    city: '',
    country: CFG.shipping.countries[0],
    discount: '',
    paymentMethod: 'local_pickup',
    termsConsent: false,
    marketingConsent: false,
    website: ''
  });

  const set = (patch) => setForm((current) => ({ ...current, ...patch }));

  const subtotal = enriched.reduce((sum, item) => sum + item.unitPrice * (item.qty || 1), 0);
  const code = form.discount.trim().toUpperCase();
  const discount = CFG.pricing.discountCodes[code];
  const discountAmount = discount && discount.type === 'percent' ? Math.round(subtotal * (discount.value / 100)) : 0;
  const discountedSubtotal = Math.max(0, subtotal - discountAmount);
  const localPickup = CFG.localPickup || {};
  const localCities = localPickup.cities || [];
  const cityNormalized = normalizePickupCity(form.city);
  const postal = String(form.zip || '').replace(/\s+/g, '');
  const localPickupEligible = Boolean(localPickup.enabled && countryIsItaly(form.country) && localCities.some((zone) => {
    if (zone.cityNormalized !== cityNormalized) return false;
    if (zone.postalCode && postal && String(zone.postalCode).replace(/\s+/g, '') !== postal) return false;
    if (zone.postalCodePrefix && postal && !postal.startsWith(String(zone.postalCodePrefix))) return false;
    return true;
  }));
  const cardAvailable = Boolean(CFG.features && CFG.features.paymentsEnabled && CFG.features.paymentProvider);
  const selectedLocalPickup = form.paymentMethod === 'local_pickup';
  const paymentAvailable = selectedLocalPickup ? localPickupEligible : cardAvailable;
  const shipping = selectedLocalPickup ? 0 : enriched.length && discountedSubtotal < (CFG.pricing.freeShippingThresholdCents || 5000)
    ? CFG.pricing.shipping.standard.priceCents
    : 0;
  const total = discountedSubtotal + shipping;

  React.useEffect(() => {
    if (cardAvailable) return;
    if (form.paymentMethod !== 'local_pickup') set({ paymentMethod: 'local_pickup' });
  }, [cardAvailable, form.paymentMethod]);

  const submit = async (event) => {
    event.preventDefault();
    if (hasUnavailable || loading) return;
    if (!form.email || !form.firstName || !form.lastName || !form.zip || !form.city || (!selectedLocalPickup && !form.address)) {
      alert(t.checkout.alertFields);
      return;
    }
    if (!paymentAvailable) {
      alert(selectedLocalPickup ? t.checkout.localPickupDisabled : t.checkout.cardUnavailable);
      return;
    }
    if (!form.termsConsent) {
      alert(t.checkout.alertChecks);
      return;
    }
    setLoading(true);
    setServerError('');
    const payload = {
      form: {
        ...form,
        language: lang,
        privacyConsent: form.termsConsent,
        sourcePage: 'checkout'
      },
      items: enriched.map((item) => ({
        product: item.product,
        sku: item.sku,
        qty: item.qty,
        config: item.config
      }))
    };
    try {
      const response = await fetch('/api/orders', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload)
      });
      const result = await response.json();
      if (!response.ok || !result.ok) {
        throw new Error((result.error && result.error.message) || 'Order failed');
      }
      try { sessionStorage.setItem('tc_checkout_result', JSON.stringify(result)); } catch (e) {}
      if (result.payment && result.payment.url) {
        setReady(t.checkout.redirecting);
        window.location.href = result.payment.url;
        return;
      }
      CartStore.clear();
      navigate('/order-success?order=' + encodeURIComponent(result.orderNumber || ''));
    } catch (error) {
      setServerError(error.message);
    } finally {
      setLoading(false);
    }
  };

  if (!enriched.length) {
    return (
      <section className="section">
        <div className="container stack" style={{ gap: 18, alignItems: 'center', textAlign: 'center' }}>
          <div className="eyebrow">{t.checkout.eyebrow}</div>
          <h1 className="h-1">{t.cart.empty}</h1>
          <Link to="/configurator" className="btn btn-primary btn-lg btn-arrow">{t.common.configureYours}</Link>
        </div>
      </section>
    );
  }

  return (
    <section className="section">
      <div className="container">
        <div className="row-between wrap" style={{ marginBottom: 28, paddingBottom: 16, borderBottom: '1px solid var(--border)' }}>
          <div>
            <div className="eyebrow">{t.checkout.eyebrow}</div>
            <h1 className="h-1">{t.checkout.title}</h1>
          </div>
          <span className="mono-sm">{formatMoney(total, lang)}</span>
        </div>

        {hasUnavailable && (
          <div className="notice notice-danger" style={{ marginBottom: 20 }}>
            {t.checkout.unavailable} <Link to="/cart" style={{ textDecoration: 'underline' }}>{t.nav.cart}</Link>
          </div>
        )}

        <form className="checkout-grid" onSubmit={submit}>
          <div className="stack" style={{ gap: 28 }}>
            <CheckoutBlock n="01" title={t.checkout.contact}>
              <Field label={t.checkout.email}>
                <input
                  className="input"
                  type="email"
                  required
                  value={form.email}
                  placeholder={t.checkout.emailPlaceholder}
                  onChange={(event) => set({ email: event.target.value })}
                />
              </Field>
            </CheckoutBlock>

            <CheckoutBlock n="02" title={t.checkout.shipping}>
              <div className="grid cols-2">
                <Field label={t.checkout.firstName}>
                  <input className="input" required value={form.firstName} onChange={(event) => set({ firstName: event.target.value })} />
                </Field>
                <Field label={t.checkout.lastName}>
                  <input className="input" required value={form.lastName} onChange={(event) => set({ lastName: event.target.value })} />
                </Field>
              </div>
              <Field label={t.checkout.address}>
                <input className="input" required={!selectedLocalPickup} value={form.address} onChange={(event) => set({ address: event.target.value })} />
              </Field>
              <Field label={t.checkout.address2}>
                <input className="input" value={form.address2} onChange={(event) => set({ address2: event.target.value })} />
              </Field>
              <div className="grid cols-3">
                <Field label={t.checkout.zip}>
                  <input className="input" required value={form.zip} onChange={(event) => set({ zip: event.target.value })} />
                </Field>
                <Field label={t.checkout.city}>
                  <input className="input" required value={form.city} onChange={(event) => set({ city: event.target.value })} />
                </Field>
                <Field label={t.checkout.country}>
                  <select className="select" value={form.country} onChange={(event) => set({ country: event.target.value })}>
                    {CFG.shipping.countries.map((country) => <option key={country} value={country}>{country}</option>)}
                  </select>
                </Field>
              </div>
            </CheckoutBlock>

            <CheckoutBlock n="03" title={t.checkout.delivery}>
              <button type="button" className="choice selected">
                <div className="row-between">
                  <strong>{selectedLocalPickup ? (lang === 'en' ? localPickup.paymentNameEn : localPickup.paymentNameIt) : t.checkout.standardDelivery}</strong>
                  <span>{formatMoney(shipping, lang)}</span>
                </div>
                <p className="body-muted">
                  {selectedLocalPickup
                    ? (lang === 'en' ? localPickup.publicLabelEn : localPickup.publicLabelIt)
                    : t.checkout.standardDeliverySub
                    .replace('{min}', CFG.pricing.shipping.standard.minDays)
                    .replace('{max}', CFG.pricing.shipping.standard.maxDays)}
                </p>
              </button>
            </CheckoutBlock>

            <CheckoutBlock n="04" title={t.checkout.payment}>
              {cardAvailable && (
                <button
                  type="button"
                  className={'choice' + (form.paymentMethod === 'card' ? ' selected' : '')}
                  onClick={() => set({ paymentMethod: 'card' })}
                >
                  <div className="row-between">
                    <strong>{t.checkout.cardPayment}</strong>
                    {form.paymentMethod === 'card' && <span className="mono-sm">{t.common.selected}</span>}
                  </div>
                </button>
              )}
              <button
                type="button"
                className={'choice' + (selectedLocalPickup ? ' selected' : '') + (!localPickupEligible ? ' unavailable' : '')}
                onClick={() => set({ paymentMethod: 'local_pickup' })}
                disabled={!localPickupEligible}
              >
                <div className="row-between">
                  <strong>{lang === 'en' ? localPickup.paymentNameEn : localPickup.paymentNameIt}</strong>
                  {selectedLocalPickup && localPickupEligible && <span className="mono-sm">{t.common.selected}</span>}
                </div>
                <p className="body-muted">
                  {localPickupEligible
                    ? (lang === 'en' ? localPickup.publicLabelEn : localPickup.publicLabelIt)
                    : (lang === 'en' ? localPickup.disabledCopyEn : localPickup.disabledCopyIt)}
                </p>
              </button>
            </CheckoutBlock>

            <CheckoutBlock n="05" title={t.footer.legal}>
              <p className="notice">{t.checkout.accessoryDisclaimer}</p>
              {hasPreorder && <p className="notice">{t.checkout.preorderNotice}</p>}
              <CheckLabel
                checked={form.termsConsent}
                onChange={(value) => set({ termsConsent: value })}
                text={t.checkout.termsCheck}
                required
              />
              <CheckLabel
                checked={form.marketingConsent}
                onChange={(value) => set({ marketingConsent: value })}
                text={t.checkout.marketingCheck}
              />
              <input
                type="text"
                value={form.website}
                onChange={(event) => set({ website: event.target.value })}
                tabIndex="-1"
                autoComplete="off"
                className="hp-field"
                aria-hidden="true"
              />
            </CheckoutBlock>
          </div>

          <aside className="surface stack sticky-panel" style={{ padding: 22 }}>
            <div className="eyebrow">{t.checkout.orderSummary}</div>
            {enriched.map((item) => (
              <div key={item.id} className="row" style={{ alignItems: 'flex-start', paddingBottom: 12, borderBottom: '1px solid var(--border)' }}>
                <div style={{ width: 72, flex: '0 0 72px' }}>
                  <ProductPreview config={item.config} size="sm" animated={false} />
                </div>
                <div style={{ flex: 1 }}>
                  <strong>{item.product}</strong>
                  <div className="mono-sm">
                    {getColorLabel(item.config.bodyColor, lang)} / {getColorLabel(item.config.capColor, lang)} / x{item.qty || 1}
                  </div>
                  <StockBadge stockResult={item.stockResult} />
                </div>
                <strong>{formatMoney(item.unitPrice * (item.qty || 1), lang)}</strong>
              </div>
            ))}

            <div className="row">
              <input
                className="input"
                value={form.discount}
                placeholder={t.checkout.discountCode}
                onChange={(event) => set({ discount: event.target.value })}
              />
              <button className="btn btn-secondary" type="button" onClick={() => setDiscountTouched(true)}>
                {t.common.apply}
              </button>
            </div>
            {discountTouched && code && (
              <div className="mono-sm" style={{ color: discount ? 'var(--success)' : 'var(--danger)' }}>
                {discount ? `${t.checkout.discountApplied}: ${code}` : t.checkout.discountInvalid}
              </div>
            )}

            <SummaryRow k={t.cart.subtotal} v={formatMoney(subtotal, lang)} />
            {discountAmount > 0 && <SummaryRow k={t.checkout.discountApplied} v={'- ' + formatMoney(discountAmount, lang)} />}
            <SummaryRow k={t.cart.shipping} v={formatMoney(shipping, lang)} />
            <SummaryRow k={t.cart.vat} v={t.common.vatIncluded} />
            <SummaryRow k={t.cart.total} v={formatMoney(total, lang)} big />

            {hasPreorder && <p className="notice">{t.cart.preorderWarning}</p>}
            {serverError && <div className="notice notice-danger">{serverError}</div>}
            {ready && (
              <div className="notice">
                <strong>{t.checkout.readyTitle}</strong>
                <p className="body-muted" style={{ marginBottom: 0 }}>{ready === true ? t.checkout.readyBody : ready}</p>
              </div>
            )}

            {!paymentAvailable && (
              <p className="notice notice-danger">
                {selectedLocalPickup ? t.checkout.localPickupDisabled : t.checkout.cardUnavailable}
              </p>
            )}
            <button className="btn btn-primary btn-lg btn-block btn-arrow" type="submit" disabled={hasUnavailable || loading || !paymentAvailable}>
              {loading ? '...' : t.common.placeOrder}
            </button>
          </aside>
        </form>
      </div>
    </section>
  );
};

const CheckoutBlock = ({ n, title, children }) => (
  <section className="stack" style={{ gap: 14 }}>
    <div className="row">
      <span className="mono-sm">{n}</span>
      <h2 className="h-3">{title}</h2>
    </div>
    <div className="stack">{children}</div>
  </section>
);

const Field = ({ label, children }) => (
  <label>
    <span className="field-label">{label}</span>
    {children}
  </label>
);

const CheckLabel = ({ checked, onChange, text, required }) => (
  <label className="row" style={{ alignItems: 'flex-start' }}>
    <input
      type="checkbox"
      required={required}
      checked={checked}
      onChange={(event) => onChange(event.target.checked)}
      style={{ marginTop: 4 }}
    />
    <span>{text}</span>
  </label>
);

window.Checkout = Checkout;
window.Field = Field;
window.CheckLabel = CheckLabel;
