/* ═══════════════════════════════════════════════════════════════════
   RateCardWizard.jsx — first-run WP Scope Estimator rate-card setup.
   ───────────────────────────────────────────────────────────────────
   Renders through the ONE config-driven WizardRunner (window.WPSB.Wizard.run,
   §6 #49) — NOT a bespoke step container, and NOT OnboardingWizard.jsx.
   Launched from the estimator's honest-empty CTA (design/Estimator.jsx) when an
   account has no commercial_profiles rate card yet.

   Honest-empty / Radical Transparency: NO pre-filled rates. Labels are suggested
   (Business, Starter…) but every NUMBER is entered by the agency — a placeholder
   rate is a false quote. onCommit builds a STRUCTURALLY-COMPLETE, estimator-safe
   rate_card (all 9 top-level keys; empty arrays for hosting/addon groups the agency
   can fill later in Edit-rates; identity-mult multipliers so the estimator never
   crashes), validates it against window.rateCardShapeMissing (mirrors the server
   validateRateCardShape), and PUTs /estimator/commercial-profile. A saved card IS
   the completion flag (the estimator re-fetches and flips empty→ready).

   Load AFTER WizardRunner.jsx + Estimator.jsx (uses window.WPSB.Wizard.run +
   window.rateCardShapeMissing). Registers window.RateCardWizard.
   ═══════════════════════════════════════════════════════════════════ */
(function () {
  const { useState } = React;
  const tx = (k, v, f) => (window.WPSB && window.WPSB.t) ? window.WPSB.t(k, v, f) : (f != null ? f : k);

  function api() {
    const apiBase = (window.WPSBD && window.WPSBD.apiBase) || 'https://api.wpsitebeam.io';
    const token = (window.WPSBD && window.WPSBD.getToken && window.WPSBD.getToken())
               || (window.WPSB && window.WPSB.getToken && window.WPSB.getToken()) || '';
    return { apiBase, token };
  }

  const num = v => { const n = Number(v); return isFinite(n) ? n : 0; };
  const slug = v => String(v || '').toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/^_+|_+$/g, '');

  /* ── Small field wrappers (v2 tokens; no hardcoded semantic hex) ── */
  function Field({ label, hint, children }) {
    return (
      <div className="field" style={{ margin: 0 }}>
        <label>{label}</label>
        {children}
        {hint && <div style={{ fontSize: '.68rem', color: 'var(--dim)', marginTop: 3 }}>{hint}</div>}
      </div>
    );
  }
  function NumInput({ value, onChange, placeholder, prefix, suffix }) {
    return (
      <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
        {prefix && <span className="mono" style={{ fontSize: '.72rem', color: 'var(--dim)' }}>{prefix}</span>}
        <input type="number" value={value} placeholder={placeholder || ''} min={0}
          onChange={e => onChange(e.target.value)} style={{ flex: 1, minWidth: 0 }}/>
        {suffix && <span className="mono" style={{ fontSize: '.72rem', color: 'var(--dim)' }}>{suffix}</span>}
      </div>
    );
  }

  /* ── Step 1: Basics ─────────────────────────────────────────────── */
  function BasicsStep({ ctx }) {
    const d = ctx.data;
    return (
      <div style={{ display: 'grid', gap: 14, maxWidth: 460 }}>
        <div className="box info" style={{ padding: '8px 12px', fontSize: '.78rem' }}>
          {tx('page.ratecardwizard.basics_intro_1', null, 'These are ')}
          <strong>{tx('page.ratecardwizard.basics_intro_strong', null, "your agency's own rates")}</strong>
          {tx('page.ratecardwizard.basics_intro_2', null, '. Nothing here is pre-filled — enter real numbers so every estimate is a real quote.')}
        </div>
        <Field label={tx('page.ratecardwizard.field_currency', null, 'Currency')}>
          <select value={d.currency} onChange={e => ctx.patch({ currency: e.target.value })}>
            {['USD', 'CAD', 'GBP', 'EUR', 'AUD'].map(c => <option key={c} value={c}>{c}</option>)}
          </select>
        </Field>
        <Field label={tx('page.ratecardwizard.field_hour_rate', null, 'Blended hourly rate')} hint={tx('page.ratecardwizard.field_hour_rate_hint', null, 'Your standard labor rate — drives prepaid hour blocks.')}>
          <NumInput value={d.hour_rate} onChange={v => ctx.patch({ hour_rate: v })} prefix="$" suffix="/hr"/>
        </Field>
        <Field label={tx('page.ratecardwizard.field_per_page', null, 'Per-page adder')} hint={tx('page.ratecardwizard.field_per_page_hint', null, "Added per content page beyond the tier's included pages.")}>
          <NumInput value={d.per_page_rate} onChange={v => ctx.patch({ per_page_rate: v })} prefix="$" suffix="/pg"/>
        </Field>
      </div>
    );
  }

  /* ── Step 2: Site types ─────────────────────────────────────────── */
  function SiteTypesStep({ ctx }) {
    const rows = ctx.data.site_types || [];
    const set = next => ctx.setData(Object.assign({}, ctx.data, { site_types: next }));
    const patchRow = (i, p) => set(rows.map((r, idx) => idx === i ? Object.assign({}, r, p) : r));
    const addRow = () => set(rows.concat([{ id: '', lbl: '', emoji: '🏢', rate: '' }]));
    const delRow = i => set(rows.filter((_, idx) => idx !== i));
    return (
      <div style={{ display: 'grid', gap: 10 }}>
        <div style={{ fontSize: '.8rem', color: 'var(--text-2)' }}>{tx('page.ratecardwizard.sitetypes_hint', null, 'Site categories you build, with a blended $/hr shown on each. Add at least one.')}</div>
        {rows.map((r, i) => (
          <div key={i} style={{ display: 'grid', gridTemplateColumns: '54px 1fr 130px 34px', gap: 8, alignItems: 'end' }}>
            <Field label={tx('page.ratecardwizard.field_icon', null, 'Icon')}><input value={r.emoji} onChange={e => patchRow(i, { emoji: e.target.value })} style={{ textAlign: 'center' }}/></Field>
            <Field label={tx('page.ratecardwizard.field_label', null, 'Label')}><input value={r.lbl} placeholder={tx('page.ratecardwizard.placeholder_business', null, 'Business')} onChange={e => patchRow(i, { lbl: e.target.value })}/></Field>
            <Field label={tx('page.ratecardwizard.field_blended_rate', null, 'Blended rate')}><NumInput value={r.rate} onChange={v => patchRow(i, { rate: v })} prefix="$" suffix="/hr"/></Field>
            <button className="btn btn-ghost btn-sm" onClick={() => delRow(i)} aria-label={tx('page.ratecardwizard.aria_remove_sitetype', null, 'Remove site type')} disabled={rows.length <= 1}><Icon name="x" size={12}/></button>
          </div>
        ))}
        <div><button className="btn btn-ghost btn-sm" onClick={addRow}><Icon name="plus" size={12}/>{tx('page.ratecardwizard.btn_add_sitetype', null, 'Add site type')}</button></div>
      </div>
    );
  }

  /* ── Step 3: Build tiers ────────────────────────────────────────── */
  function BuildTiersStep({ ctx }) {
    const rows = ctx.data.biz_tiers || [];
    const set = next => ctx.setData(Object.assign({}, ctx.data, { biz_tiers: next }));
    const patchRow = (i, p) => set(rows.map((r, idx) => idx === i ? Object.assign({}, r, p) : r));
    const addRow = () => set(rows.concat([{ id: '', lbl: '', priceMin: '', priceMax: '', care: '', pageMin: '', pageMax: '', hrsMin: '', hrsMax: '' }]));
    const delRow = i => set(rows.filter((_, idx) => idx !== i));
    return (
      <div style={{ display: 'grid', gap: 14 }}>
        <div style={{ fontSize: '.8rem', color: 'var(--text-2)' }}>{tx('page.ratecardwizard.buildtiers_hint', null, 'Your build tiers — price range, monthly care, and the page/hours band each covers. Add at least one.')}</div>
        {rows.map((r, i) => (
          <div key={i} className="card" style={{ padding: 12 }}>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 34px', gap: 8, alignItems: 'end', marginBottom: 8 }}>
              <Field label={tx('page.ratecardwizard.field_tier_name', null, 'Tier name')}><input value={r.lbl} placeholder={tx('page.ratecardwizard.placeholder_starter', null, 'Starter')} onChange={e => patchRow(i, { lbl: e.target.value })}/></Field>
              <button className="btn btn-ghost btn-sm" onClick={() => delRow(i)} aria-label={tx('page.ratecardwizard.aria_remove_tier', null, 'Remove tier')} disabled={rows.length <= 1}><Icon name="x" size={12}/></button>
            </div>
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 8 }}>
              <Field label={tx('page.ratecardwizard.field_price_min', null, 'Price min')}><NumInput value={r.priceMin} onChange={v => patchRow(i, { priceMin: v })} prefix="$"/></Field>
              <Field label={tx('page.ratecardwizard.field_price_max', null, 'Price max')}><NumInput value={r.priceMax} onChange={v => patchRow(i, { priceMax: v })} prefix="$"/></Field>
              <Field label={tx('page.ratecardwizard.field_care', null, 'Care / mo')}><NumInput value={r.care} onChange={v => patchRow(i, { care: v })} prefix="$"/></Field>
              <Field label={tx('page.ratecardwizard.field_pages_min', null, 'Pages min')}><NumInput value={r.pageMin} onChange={v => patchRow(i, { pageMin: v })}/></Field>
              <Field label={tx('page.ratecardwizard.field_pages_max', null, 'Pages max')}><NumInput value={r.pageMax} onChange={v => patchRow(i, { pageMax: v })}/></Field>
              <Field label={tx('page.ratecardwizard.field_hours_min', null, 'Hours min')}><NumInput value={r.hrsMin} onChange={v => patchRow(i, { hrsMin: v })}/></Field>
              <Field label={tx('page.ratecardwizard.field_hours_max', null, 'Hours max')}><NumInput value={r.hrsMax} onChange={v => patchRow(i, { hrsMax: v })}/></Field>
            </div>
          </div>
        ))}
        <div><button className="btn btn-ghost btn-sm" onClick={addRow}><Icon name="plus" size={12}/>{tx('page.ratecardwizard.btn_add_tier', null, 'Add build tier')}</button></div>
      </div>
    );
  }

  /* ── Step 4: Review ─────────────────────────────────────────────── */
  function ReviewStep({ ctx }) {
    const d = ctx.data;
    const st = (d.site_types || []).filter(r => r.lbl && num(r.rate) > 0);
    const bt = (d.biz_tiers || []).filter(r => r.lbl);
    return (
      <div style={{ display: 'grid', gap: 12, fontSize: '.84rem' }}>
        <div className="box info" style={{ padding: '8px 12px', fontSize: '.78rem' }}>
          {tx('page.ratecardwizard.review_intro_1', null, 'Hosting, care plans, and setup/monthly add-ons start empty — add them anytime from ')}
          <strong>{tx('page.ratecardwizard.review_intro_editrates', null, 'Edit rates')}</strong>
          {tx('page.ratecardwizard.review_intro_2', null, ". You can estimate right away with what's below.")}
        </div>
        <div><strong>{tx('page.ratecardwizard.review_basics_label', null, 'Basics:')}</strong> {d.currency} · ${num(d.hour_rate)}/hr · ${num(d.per_page_rate)}/page</div>
        <div><strong>{tx('page.ratecardwizard.review_sitetypes_label', { n: st.length }, 'Site types ({n}):')}</strong> {st.map(r => r.lbl + ' ($' + num(r.rate) + '/hr)').join(' · ') || '—'}</div>
        <div><strong>{tx('page.ratecardwizard.review_buildtiers_label', { n: bt.length }, 'Build tiers ({n}):')}</strong> {bt.map(r => r.lbl + ' ($' + num(r.priceMin) + '–$' + num(r.priceMax) + ')').join(' · ') || '—'}</div>
      </div>
    );
  }

  /* ── Build the estimator-safe rate_card from the wizard data bag ── */
  function buildRateCard(d) {
    return {
      currency: d.currency || 'USD',
      hour_rate: num(d.hour_rate),
      per_page_rate: num(d.per_page_rate),
      site_types: (d.site_types || []).filter(r => r.lbl && num(r.rate) > 0).map((r, i) => ({
        id: r.id || slug(r.lbl) || ('type' + i), lbl: r.lbl, emoji: r.emoji || '🏢', rate: num(r.rate),
      })),
      biz_tiers: (d.biz_tiers || []).filter(r => r.lbl).map((r, i) => {
        const pmin = num(r.priceMin), pmax = num(r.priceMax);
        return {
          id: r.id || slug(r.lbl) || ('tier' + i), lbl: r.lbl,
          basePrice: Math.round((pmin + pmax) / 2), priceMin: pmin, priceMax: pmax,
          care: num(r.care), pageMin: num(r.pageMin), pageMax: num(r.pageMax),
          hrsMin: num(r.hrsMin), hrsMax: num(r.hrsMax),
          pages: num(r.pageMin) + '–' + num(r.pageMax) + ' pages',
          hrs: num(r.hrsMin) + '–' + num(r.hrsMax) + ' hrs', desc: r.desc || '',
        };
      }),
      hosting_plans: { M: [], MWC: [], CARE_ONLY: [], CIVIC: [] },
      setup_addons: { business: [], civic: [] },
      monthly_addons: { base: [], civic_extra: [] },
      multipliers: {
        doc_load: [{ id: 'none', lbl: 'None', desc: 'No docs', mult: 1 }],
        complexity: [
          { id: 'standard', lbl: 'Standard', mult: 1 },
          { id: 'complex', lbl: 'Complex', mult: 1.25 },
          { id: 'high', lbl: 'High', mult: 1.5 },
        ],
        rush: [
          { id: 'standard', lbl: 'Standard', mult: 1 },
          { id: '2weeks', lbl: '2 Weeks', mult: 1.25 },
          { id: '1week', lbl: '1 Week', mult: 1.5 },
        ],
      },
    };
  }

  function wizardConfig(onDone, onCancel) {
    return {
      id: 'rate-card-setup',
      eyebrow: tx('page.ratecardwizard.wiz_eyebrow', null, 'WP Scope Estimator'),
      title: tx('page.ratecardwizard.wiz_title', null, 'Set up your rate card'),
      subtitle: tx('page.ratecardwizard.wiz_subtitle', null, "Your agency's own rates — nothing pre-filled."),
      stepVariant: 'numbered',
      finishLabel: tx('page.ratecardwizard.wiz_finish', null, 'Save rate card'),
      initialData: {
        currency: 'USD', hour_rate: '', per_page_rate: '',
        site_types: [{ id: 'business', lbl: 'Business', emoji: '🏢', rate: '' }],
        biz_tiers: [{ id: 'starter', lbl: 'Starter', priceMin: '', priceMax: '', care: '', pageMin: '', pageMax: '', hrsMin: '', hrsMax: '' }],
      },
      steps: [
        {
          key: 'basics', title: tx('page.ratecardwizard.step_basics_title', null, 'Basics'), subtitle: tx('page.ratecardwizard.step_basics_sub', null, 'Currency & labor rates'),
          validate: c => (num(c.data.hour_rate) > 0 ? true : tx('page.ratecardwizard.val_hour_rate', null, 'Enter your blended hourly rate (greater than 0).')),
          render: c => <BasicsStep ctx={c}/>,
        },
        {
          key: 'site-types', title: tx('page.ratecardwizard.step_sitetypes_title', null, 'Site types'), subtitle: tx('page.ratecardwizard.step_sitetypes_sub', null, 'Categories you build'),
          validate: c => ((c.data.site_types || []).some(r => r.lbl && num(r.rate) > 0) ? true : tx('page.ratecardwizard.val_sitetypes', null, 'Add at least one site type with a label and a rate greater than 0.')),
          render: c => <SiteTypesStep ctx={c}/>,
        },
        {
          key: 'build-tiers', title: tx('page.ratecardwizard.step_buildtiers_title', null, 'Build tiers'), subtitle: tx('page.ratecardwizard.step_buildtiers_sub', null, 'Price bands'),
          validate: c => {
            const rows = (c.data.biz_tiers || []).filter(r => r.lbl);
            if (!rows.length) return tx('page.ratecardwizard.val_tiers_none', null, 'Add at least one build tier with a name.');
            const bad = rows.find(r => !(num(r.priceMin) > 0) || num(r.priceMax) < num(r.priceMin));
            if (bad) return tx('page.ratecardwizard.val_tiers_price', null, 'Each tier needs a price min greater than 0 and a price max at or above the min.');
            return true;
          },
          render: c => <BuildTiersStep ctx={c}/>,
        },
        {
          key: 'review', title: tx('page.ratecardwizard.step_review_title', null, 'Review'), subtitle: tx('page.ratecardwizard.step_review_sub', null, 'Confirm & save'),
          render: c => <ReviewStep ctx={c}/>,
        },
      ],
      onCommit: async (data, helpers) => {
        const card = buildRateCard(data);
        const guard = window.rateCardShapeMissing;
        const missing = guard ? guard(card) : [];
        if (missing.length) throw new Error(tx('page.ratecardwizard.err_incomplete', { list: missing.join(', ') }, 'Rate card is incomplete: {list}'));
        const { apiBase, token } = api();
        let r, body;
        try {
          r = await fetch(apiBase + '/estimator/commercial-profile', {
            method: 'PUT',
            headers: { Authorization: 'Bearer ' + token, 'Content-Type': 'application/json' },
            body: JSON.stringify({ currency: card.currency, rate_card: card }),
          });
          body = await r.json().catch(() => ({}));
        } catch (e) {
          throw new Error(tx('page.ratecardwizard.err_network', null, 'Network error — rate card not saved. Try again.'));
        }
        if (!r.ok) {
          if (r.status === 403) throw new Error(tx('page.ratecardwizard.err_owner', null, 'Only the account owner can create the rate card. Ask your agency owner to complete setup.'));
          if (body && body.code === 'BAD_RATE_CARD') throw new Error(tx('page.ratecardwizard.err_validation', { detail: ((body.missing || []).join(', ') || tx('page.ratecardwizard.err_invalid_shape', null, 'invalid shape')) }, 'Rate card failed validation: {detail}'));
          throw new Error((body && body.error) || tx('page.ratecardwizard.err_save_http', { status: r.status }, 'Save failed (HTTP {status}).'));
        }
        if (window.wpsbToast) window.wpsbToast(tx('page.ratecardwizard.toast_saved', null, 'Rate card saved — estimating enabled'), 'ok');
        onDone && onDone();
        return { ok: true };
      },
      onExit: () => { onCancel && onCancel(); },
    };
  }

  /* Component wrapper: renders the config-driven Runner. */
  function RateCardWizard({ onDone, onCancel }) {
    const [cfg] = useState(() => wizardConfig(onDone, onCancel));
    const WZ = window.WPSB && window.WPSB.Wizard;
    if (!WZ || !WZ.run) {
      return (
        <div className="card" style={{ marginTop: 16, maxWidth: 560 }}>
          <div className="card-body" style={{ fontSize: '.84rem', color: 'var(--text-2)' }}>
            {tx('page.ratecardwizard.fallback_msg', null, 'The setup wizard failed to load. Reload the page and try again.')}
            <div style={{ marginTop: 10 }}><button className="btn btn-ghost btn-sm" onClick={() => onCancel && onCancel()}>{tx('page.ratecardwizard.btn_back', null, 'Back')}</button></div>
          </div>
        </div>
      );
    }
    return WZ.run(cfg);
  }

  window.RateCardWizard = RateCardWizard;
  console.log('[Estimator] RateCardWizard loaded (first-run rate-card setup via WizardRunner).');
})();
