/* Configurator */

const Configurator = () => {
  const { t, lang } = useLang();
  const [config, setConfig] = React.useState(() => {
    try {
      const raw = sessionStorage.getItem('tc_draft');
      return raw ? normalizeConfig(JSON.parse(raw)) : { ...DEFAULT_CONFIG };
    } catch (e) {
      return { ...DEFAULT_CONFIG };
    }
  });
  const [step, setStep] = React.useState(0);
  const [added, setAdded] = React.useState(false);

  React.useEffect(() => {
    try { sessionStorage.setItem('tc_draft', JSON.stringify(config)); } catch (e) {}
  }, [config]);

  const set = (patch) => setConfig((current) => normalizeConfig({ ...current, ...patch }));
  const stockResult = getVariantStockState(config.bodyColor, config.capColor);
  const price = calcPrice(config);
  const steps = t.configurator.steps;
  const addDisabled = !canAddToCart(stockResult);

  const addToCart = () => {
    if (addDisabled) return;
    const device = CFG.devices.find((item) => item.id === config.device) || CFG.devices[0];
    const payload = {
      product: t.product.title.replace('{device}', device.displayName),
      sku: device.sku,
      config,
      unitPrice: price,
      qty: config.qty || 1
    };
    let editId = '';
    try { editId = sessionStorage.getItem('tc_edit_item') || ''; } catch (e) {}
    if (editId) {
      CartStore.update(editId, payload);
      try { sessionStorage.removeItem('tc_edit_item'); } catch (e) {}
    } else {
      CartStore.add(payload);
    }
    setAdded(true);
    window.setTimeout(() => navigate('/cart'), 700);
  };

  return (
    <section className="section">
      <div className="container">
        <div className="row-between wrap" style={{ marginBottom: 24, paddingBottom: 16, borderBottom: '1px solid var(--border)' }}>
          <div>
            <div className="eyebrow">{t.configurator.title}</div>
            <h1 className="h-2">{steps[step]}</h1>
          </div>
          <div className="mono-sm">
            {t.configurator.step} {String(step + 1).padStart(2, '0')} / 06 · {formatMoney(price, lang)}
          </div>
        </div>

        <div className="config-grid">
          <aside className="stack sticky-panel" style={{ gap: 14 }}>
            <ProductPreview config={config} size="xl" />
            <div className="grid cols-3">
              <PreviewChip label={t.configurator.hardBody} value={getColorLabel(config.bodyColor, lang)} />
              <PreviewChip label={t.configurator.softCap} value={getColorLabel(config.capColor, lang)} />
              <PreviewChip label={t.configurator.customText} value={config.customText || t.configurator.noText} />
            </div>
            <StockBadge stockResult={stockResult} />
          </aside>

          <div className="stack" style={{ gap: 26 }}>
            <div className="step-tabs">
              {steps.map((label, index) => (
                <button
                  key={label}
                  type="button"
                  className={'step-tab' + (index === step ? ' active' : '')}
                  onClick={() => setStep(index)}
                >
                  {String(index + 1).padStart(2, '0')} · {label}
                </button>
              ))}
            </div>

            <div className="fade-in">
              {step === 0 && <StepDevice config={config} set={set} />}
              {step === 1 && <StepBodyColor config={config} set={set} />}
              {step === 2 && <StepCapColor config={config} set={set} />}
              {step === 3 && <StepText config={config} set={set} />}
              {step === 4 && <StepSymbols config={config} set={set} />}
              {step === 5 && <StepReview config={config} stockResult={stockResult} price={price} />}
            </div>

            {isPreorder(stockResult) && (
              <div className="notice">{t.configurator.preorderNote}</div>
            )}

            {step === 5 && addDisabled && (
              <NotifyMeForm config={config} stockResult={stockResult} />
            )}

            <div className="row-between wrap" style={{ paddingTop: 22, borderTop: '1px solid var(--border)' }}>
              <button
                type="button"
                className="btn btn-secondary"
                disabled={step === 0}
                onClick={() => setStep((current) => Math.max(0, current - 1))}
              >
                {t.common.back}
              </button>
              <span className="mono-sm">{String(step + 1).padStart(2, '0')} / 06</span>
              {step < 5 ? (
                <button type="button" className="btn btn-primary btn-arrow" onClick={() => setStep((current) => Math.min(5, current + 1))}>
                  {t.common.next}
                </button>
              ) : (
                <button type="button" className="btn btn-primary btn-arrow" disabled={addDisabled} onClick={addToCart}>
                  {t.common.addToCart} · {formatMoney(price, lang)}
                </button>
              )}
            </div>
          </div>
        </div>
      </div>

      {added && (
        <div style={{ position: 'fixed', inset: 0, zIndex: 90, background: 'var(--overlay)', display: 'grid', placeItems: 'center', padding: 20 }}>
          <div className="surface stack" style={{ padding: 28, maxWidth: 380, textAlign: 'center' }}>
            <div className="eyebrow">{t.configurator.added}</div>
            <p className="body-muted">{t.configurator.addedSub}</p>
          </div>
        </div>
      )}
    </section>
  );
};

const PreviewChip = ({ label, value }) => (
  <div className="surface-plain" style={{ padding: 12 }}>
    <div className="mono-sm">{label}</div>
    <strong style={{ display: 'block', marginTop: 4 }}>{value}</strong>
  </div>
);

const StepShell = ({ n, title, sub, children }) => (
  <div className="stack" style={{ gap: 18 }}>
    <div>
      <div className="mono-sm">{n}</div>
      <h2 className="h-2">{title}</h2>
      {sub && <p className="body-muted">{sub}</p>}
    </div>
    {children}
  </div>
);

const StepDevice = ({ config, set }) => {
  const { t } = useLang();
  const live = getLiveDevices();
  return (
    <StepShell n="01" title={t.configurator.step1.title} sub={t.configurator.step1.sub}>
      <div className="stack">
        {live.map((device) => (
          <button
            type="button"
            key={device.id}
            className={'choice' + (config.device === device.id ? ' selected' : '')}
            onClick={() => set({ device: device.id })}
          >
            <div className="row-between">
              <span className="tag tag-dot">{t.configurator.step1.live}</span>
              {config.device === device.id && <span className="mono-sm">{t.common.selected}</span>}
            </div>
            <h3 className="h-3" style={{ marginTop: 12 }}>{device.displayName}</h3>
            <p className="body-muted">{t.product.designedFor.replace('{device}', device.displayName)}</p>
          </button>
        ))}
        <Link to="/compatibility" className="choice">
          <div className="row-between">
            <span className="tag">{t.configurator.step1.requestOnly}</span>
          </div>
          <h3 className="h-3" style={{ marginTop: 12 }}>{t.nav.compatibility}</h3>
          <p className="body-muted">{t.configurator.step1.requestSub}</p>
        </Link>
      </div>
    </StepShell>
  );
};

const StepBodyColor = ({ config, set }) => {
  const { t, lang } = useLang();
  return (
    <StepShell n="02" title={t.configurator.step2.title} sub={t.configurator.step2.sub}>
      <div className="swatch-grid">
        {BODY_COLORS.map((color) => {
          const state = getVariantStockState(color.key, config.capColor);
          const disabled = !canAddToCart(state);
          const render = renderBody(color.key, color);
          const finishExtra = (CFG.pricing.finishesCents && CFG.pricing.finishesCents[color.type]) || 0;
          return (
            <button
              key={color.key}
              type="button"
              className={'swatch' + (config.bodyColor === color.key ? ' selected' : '') + (disabled ? ' unavailable' : '')}
              style={{ background: render.swatch }}
              onClick={() => set({ bodyColor: color.key })}
            >
              <span className="swatch-label">
                <span>
                  <span>{getColorLabel(color.key, lang)}</span>
                  <span className="price-extra">{finishExtra > 0 ? '+' + formatMoney(finishExtra, lang) : t.common.noExtra}</span>
                </span>
                <span>{t.stock[getStockLabelKey(state)].label}</span>
              </span>
            </button>
          );
        })}
      </div>
    </StepShell>
  );
};

const StepCapColor = ({ config, set }) => {
  const { t, lang } = useLang();
  return (
    <StepShell n="03" title={t.configurator.step3.title} sub={t.configurator.step3.sub}>
      <div className="swatch-grid">
        {CAP_COLORS.map((color) => {
          const state = getVariantStockState(config.bodyColor, color.key);
          const disabled = !canAddToCart(state);
          return (
            <button
              key={color.key}
              type="button"
              className={'swatch' + (config.capColor === color.key ? ' selected' : '') + (disabled ? ' unavailable' : '')}
              style={{ background: `radial-gradient(circle at 28% 22%, ${shadeHex(color.hex, 32)}, ${color.hex})` }}
              onClick={() => set({ capColor: color.key })}
            >
              <span className="swatch-label">
                <span>{getColorLabel(color.key, lang)}</span>
                <span>{t.stock[getStockLabelKey(state)].label}</span>
              </span>
            </button>
          );
        })}
      </div>
    </StepShell>
  );
};

const StepText = ({ config, set }) => {
  const { t, lang } = useLang();
  const max = CFG.limits.customTextMax;
  const remaining = max - String(config.customText || '').length;
  const suggestions = ['TITAN', 'DAILY', '2026', 'JM', 'GOLD', ''];
  return (
    <StepShell n="04" title={t.configurator.step4.title} sub={t.configurator.step4.sub}>
      <div>
        <label className="field-label">{t.configurator.step4.label}</label>
        <input
          className="input"
          value={config.customText || ''}
          maxLength={max}
          placeholder={t.configurator.step4.placeholder}
          onChange={(event) => set({ customText: event.target.value.toUpperCase() })}
        />
        <div className="row-between wrap" style={{ marginTop: 8 }}>
          <span className="mono-sm">{t.configurator.step4.hint}</span>
          <span className="mono-sm">{remaining} {t.common.remaining}</span>
        </div>
      </div>
      <div>
        <div className="field-label">{t.configurator.step4.suggestions}</div>
        <div className="row wrap">
          {suggestions.map((item, index) => (
            <button
              key={index}
              type="button"
              className={'btn btn-sm ' + ((config.customText || '') === item ? 'btn-primary' : 'btn-secondary')}
              onClick={() => set({ customText: item })}
            >
              {item || t.common.none}
            </button>
          ))}
        </div>
      </div>
      <p className="notice">{t.configurator.step4.surcharge.replace('{price}', '+' + formatMoney(CFG.pricing.customTextExtraCents, lang))}</p>
    </StepShell>
  );
};

const StepSymbols = ({ config, set }) => {
  const { t, lang } = useLang();
  const selected = config.symbols || [];
  const toggle = (symbol) => {
    if (selected.includes(symbol)) {
      set({ symbols: selected.filter((item) => item !== symbol) });
      return;
    }
    if (selected.length < CFG.limits.symbolsMax) {
      set({ symbols: selected.concat(symbol) });
    }
  };

  return (
    <StepShell n="05" title={t.configurator.step5.title} sub={t.configurator.step5.sub}>
      <div className="symbol-grid">
        {SYMBOLS.map((symbol) => (
          <button
            key={symbol}
            type="button"
            className={'symbol-btn' + (selected.includes(symbol) ? ' selected' : '')}
            onClick={() => toggle(symbol)}
          >
            {symbol}
          </button>
        ))}
      </div>
      <div className="row-between wrap">
        <span className="mono-sm">{t.common.selected}: {selected.length} / {CFG.limits.symbolsMax}</span>
        <span className="mono-sm">{t.configurator.step5.surcharge.replace('{price}', '+' + formatMoney(CFG.pricing.symbolExtraCents, lang))}</span>
      </div>
      <p className="notice">{t.configurator.step5.warning}</p>
    </StepShell>
  );
};

const StepReview = ({ config, stockResult, price }) => {
  const { t, lang } = useLang();
  const device = CFG.devices.find((item) => item.id === config.device) || CFG.devices[0];
  const eta = getProductionEta(stockResult);
  const breakdown = calcPriceBreakdown(config);
  return (
    <StepShell n="06" title={t.configurator.step6.title} sub={t.configurator.step6.sub}>
      <div className="surface-plain" style={{ padding: 18 }}>
        <SpecRow k={t.configurator.step6.device} v={device.displayName} />
        <SpecRow k={t.configurator.step6.body} v={getColorLabel(config.bodyColor, lang)} />
        <SpecRow k={t.configurator.step6.cap} v={getColorLabel(config.capColor, lang)} />
        <SpecRow k={t.configurator.step6.text} v={config.customText || t.common.none} />
        <SpecRow k={t.configurator.step6.symbols} v={(config.symbols || []).length ? config.symbols.join(' ') : t.common.none} />
        <SpecRow k={t.configurator.step6.production} v={`${eta.min}-${eta.max} ${t.common.days}`} />
        <SpecRow k={t.common.from} v={formatMoney(breakdown.base, lang)} />
        {breakdown.finish > 0 && <SpecRow k={getColorLabel(config.bodyColor, lang)} v={'+' + formatMoney(breakdown.finish, lang)} />}
        {breakdown.text > 0 && <SpecRow k={t.configurator.step4.label} v={'+' + formatMoney(breakdown.text, lang)} />}
        {breakdown.symbols > 0 && <SpecRow k={t.configurator.step5.title} v={'+' + formatMoney(breakdown.symbols, lang)} />}
        <SpecRow k={t.configurator.step6.total} v={formatMoney(price, lang)} />
      </div>
      <div className="row wrap">
        <span className="mono-sm">{t.configurator.stockStatus}</span>
        <StockBadge stockResult={stockResult} />
      </div>
      <p className="notice">{t.configurator.step6.returnNote}</p>
    </StepShell>
  );
};

const NotifyMeForm = ({ config, stockResult }) => {
  const { t, lang } = useLang();
  const [email, setEmail] = React.useState('');
  const [backInStockConsent, setBackInStockConsent] = React.useState(false);
  const [marketingConsent, setMarketingConsent] = React.useState(false);
  const [website, setWebsite] = React.useState('');
  const [loading, setLoading] = React.useState(false);
  const [done, setDone] = React.useState(false);
  const [error, setError] = React.useState('');

  const submit = async (event) => {
    event.preventDefault();
    if (loading) return;
    setLoading(true);
    setError('');
    const request = {
      email,
      language: lang,
      config,
      stockState: getStockLabelKey(stockResult),
      backInStockConsent,
      marketingConsent,
      website
    };
    const result = await submitRecord('/api/notify', request);
    setLoading(false);
    if (result.ok) setDone(true);
    else setError(result.error || t.common.requestFailed);
  };

  return (
    <form className="surface-plain stack" style={{ padding: 18 }} onSubmit={submit}>
      <div>
        <h3 className="h-3">{t.configurator.notify.title}</h3>
        <p className="body-muted">{done ? t.configurator.notify.done : t.configurator.notify.sub}</p>
      </div>
      {error && <p className="notice notice-danger" role="alert">{error}</p>}
      <p className="mono-sm">
        {t.configurator.notify.summary}: {getColorLabel(config.bodyColor, lang)} / {getColorLabel(config.capColor, lang)}
      </p>
      <label>
        <span className="field-label">{t.configurator.notify.email}</span>
        <input className="input" type="email" required value={email} onChange={(event) => setEmail(event.target.value)} />
      </label>
      <CheckLabel
        checked={backInStockConsent}
        onChange={setBackInStockConsent}
        text={t.configurator.notify.consent}
        required
      />
      <CheckLabel
        checked={marketingConsent}
        onChange={setMarketingConsent}
        text={t.configurator.notify.marketing}
      />
      <input
        type="text"
        value={website}
        onChange={(event) => setWebsite(event.target.value)}
        tabIndex="-1"
        autoComplete="off"
        className="hp-field"
        aria-hidden="true"
      />
      <button className="btn btn-secondary" type="submit" disabled={loading}>
        {loading ? '...' : t.configurator.notify.button}
      </button>
    </form>
  );
};

window.Configurator = Configurator;
