/* GarageWiz — Admin: Business Settings, Door Pricing, Openers, Manufacturers */
(function () {
  const e = React.createElement;
  const { useState } = React;
  const Icon = window.Icon, Btn = window.Btn, Badge = window.Badge, Toggle = window.Toggle, Input = window.Input,
        Field = window.Field, SectionTitle = window.SectionTitle, Segmented = window.Segmented, Modal = window.Modal;

  function Card({ title, desc, children, foot }) {
    return e('div', { className: 'card', style: { padding: 24, marginBottom: 18 } },
      title ? e('div', { style: { marginBottom: 18 } },
        e('div', { className: 'display', style: { fontSize: 19, fontWeight: 600 } }, title),
        desc ? e('div', { className: 'muted', style: { fontSize: 13.5, marginTop: 3 } }, desc) : null,
      ) : null,
      children,
      foot || null,
    );
  }

  /* numeric setting row */
  function SetRow({ label, hint, value, onChange, suffix, prefix, step = 1 }) {
    return e('div', { style: { display: 'flex', alignItems: 'center', gap: 16, padding: '14px 0', borderBottom: '1px solid var(--line)' } },
      e('div', { className: 'grow' },
        e('div', { style: { fontWeight: 700, fontSize: 15 } }, label),
        hint ? e('div', { className: 'muted', style: { fontSize: 13 } }, hint) : null,
      ),
      e('div', { style: { position: 'relative', width: 130, flexShrink: 0 } },
        prefix ? e('span', { style: { position: 'absolute', left: 13, top: '50%', transform: 'translateY(-50%)', color: 'var(--ink-3)', fontWeight: 700 } }, prefix) : null,
        e('input', {
          type: 'number', value, step, onChange: ev => onChange(ev.target.value),
          style: { width: '100%', padding: '11px 13px', paddingLeft: prefix ? 26 : 13, paddingRight: suffix ? 30 : 13, borderRadius: 10, border: '1.5px solid var(--line-2)', fontSize: 15.5, fontWeight: 600, textAlign: 'right', outline: 'none', fontVariantNumeric: 'tabular-nums' },
        }),
        suffix ? e('span', { style: { position: 'absolute', right: 12, top: '50%', transform: 'translateY(-50%)', color: 'var(--ink-3)', fontWeight: 700 } }, suffix) : null,
      ),
    );
  }

  /* ===================== SETTINGS ===================== */
  function AdminSettings() {
    const app = window.useApp();
    const s = app.settings;
    const upd = (patch) => app.setSettings(Object.assign({}, s, patch));
    // live example
    const example = GW.priceFromSell(900, s, 'door');

    return e('div', null,
      e(SectionTitle, { eyebrow: 'Admin', title: 'Business Settings', sub: 'These values drive every price in the app. Changes take effect instantly.' }),
      e('div', { className: 'admin-2col', style: { display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 18, alignItems: 'start' } },
        e('div', null,
          e(Card, { title: 'Pricing formula', desc: 'Target margin and discount floor — applied globally across all categories.' },
            e(SetRow, { label: 'Target margin', hint: 'Customer price = cost ÷ (1 − this)', value: Math.round(s.targetMargin * 100), suffix: '%', onChange: v => upd({ targetMargin: Math.min(95, Math.max(0, Number(v))) / 100 }) }),
            e(SetRow, { label: 'Floor margin', hint: 'Lowest margin a rep can discount to', value: Math.round(s.floorMargin * 100), suffix: '%', onChange: v => upd({ floorMargin: Math.min(94, Math.max(0, Number(v))) / 100 }) }),
            e(SetRow, { label: 'Tax rate', hint: 'Added to supplier sell price for cost', value: Math.round(s.taxRate * 1000) / 10, suffix: '%', step: 0.5, onChange: v => upd({ taxRate: Math.max(0, Number(v)) / 100 }) }),
          ),
          e(Card, { title: 'Minimum profit floors', desc: 'Independent per category. Applied silently whenever the margin-based price would earn less than this dollar profit.' },
            e('div', { style: { display: 'flex', gap: 10, alignItems: 'center', background: 'var(--field)', borderRadius: 12, padding: '11px 14px', marginBottom: 6, fontSize: 12.5, color: 'var(--ink-2)' } },
              e(Icon, { name: 'info', size: 17, style: { flexShrink: 0, color: 'var(--blue)' } }),
              'Each module uses its own floor. Door installs carry the most labor; parts jobs the least.'),
            e(SetRow, { label: 'Doors', hint: 'New door installs — labor, overhead, truck roll, time on site', value: s.minProfitDoor, prefix: '$', step: 50, onChange: v => upd({ minProfitDoor: Math.max(0, Number(v)) }) }),
            e(SetRow, { label: 'Openers', hint: 'Standalone opener installs — faster, simpler', value: s.minProfitOpener, prefix: '$', step: 25, onChange: v => upd({ minProfitOpener: Math.max(0, Number(v)) }) }),
            e(SetRow, { label: 'Parts', hint: 'Parts & service jobs — quickest of the three', value: s.minProfitParts, prefix: '$', step: 25, onChange: v => upd({ minProfitParts: Math.max(0, Number(v)) }) }),
          ),
          e(Card, { title: 'Company & access' },
            e(Field, { label: 'Company name (header)', style: { marginBottom: 16 } }, e(Input, { value: s.companyName, onChange: ev => upd({ companyName: ev.target.value }) })),
            e(Field, { label: 'Dealer panel PIN (4 digits)', style: { marginBottom: 16 } }, e(Input, { value: s.dealerPin, maxLength: 4, onChange: ev => upd({ dealerPin: ev.target.value.replace(/\D/g, '').slice(0, 4) }) })),
            e(Field, { label: 'Special-order lead-time message' }, e('textarea', { value: s.leadTimeMsg, onChange: ev => upd({ leadTimeMsg: ev.target.value }), rows: 3, style: { width: '100%', padding: '12px 14px', borderRadius: 10, border: '1.5px solid var(--line-2)', fontFamily: 'var(--body)', fontSize: 14.5, resize: 'vertical', outline: 'none' } })),
          ),
        ),
        // live preview
        e('div', { style: { position: 'sticky', top: 90 } },
          e(Card, { title: 'Live example' },
            e('div', { className: 'muted', style: { fontSize: 13, marginBottom: 14 } }, 'On a $900 supplier-sell door:'),
            e('div', { style: { display: 'flex', flexDirection: 'column', gap: 2 } },
              [['Cost (incl. tax)', GW.fmtCents(example.cost)], ['Customer price', GW.fmt(example.price)], ['Gross profit', GW.fmt(example.profit)], ['Margin', GW.pct(example.margin)]].map((r, i) =>
                e('div', { key: i, style: { display: 'flex', justifyContent: 'space-between', padding: '11px 0', borderBottom: '1px solid var(--line)' } },
                  e('span', { style: { color: 'var(--ink-2)', fontSize: 14 } }, r[0]),
                  e('span', { className: 'display num', style: { fontWeight: 600, fontSize: 16, color: i === 1 ? 'var(--teal)' : i === 2 ? 'var(--good)' : 'var(--ink)' } }, r[1]),
                )),
            ),
            e('div', { style: { marginTop: 16, background: 'var(--good-bg)', color: '#15784A', borderRadius: 12, padding: '12px 14px', fontSize: 12.5, fontWeight: 600, display: 'flex', gap: 8 } },
              e(Icon, { name: 'check', size: 17, strokeWidth: 3 }), 'Settings auto-save & apply across all reps.'),
          ),
        ),
      ),
    );
  }
  window.AdminSettings = AdminSettings;

  /* ===================== DOOR PRICING ===================== */
  function AdminDoors() {
    const app = window.useApp();
    const [code, setCode] = useState('14');
    const model = GW.findModel(code);
    const cols = ["6'6/7'0", "7'6/8'0 4s", "7'6/8'0 5s", "9'0", "10'0", "11'0", "12'0", "14'0"];

    function editCell(wi, ci, v) {
      model.table[wi][ci] = Math.max(0, Math.round(Number(v) || 0));
      GW.saveModels();
      app.bump();
    }

    return e('div', null,
      e(SectionTitle, { eyebrow: 'Admin', title: 'Door Pricing', sub: 'Supplier SELL prices by width × height. Edit any cell — the configurator updates instantly.',
        right: e(Segmented, { value: code, onChange: setCode, options: GW.models.map(m => ({ value: m.code, label: m.name })) }),
      }),
      e('div', { className: 'card', style: { display: 'flex', alignItems: 'center', gap: 16, padding: '16px 20px', marginBottom: 16, flexWrap: 'wrap' } },
        e('div', { className: 'grow' },
          e('div', { style: { fontWeight: 700, fontSize: 15 } }, 'Pricing rule for ' + model.name + ' doors'),
          e('div', { className: 'muted', style: { fontSize: 13 } }, 'Overrides the global target margin for this model only. ' + GW.overrideLabel(model.override, app.settings) + '.'),
        ),
        e(window.OverrideControl, { value: model.override || null, settings: app.settings, onChange: ov => { model.override = ov; GW.saveModels(); app.bump(); } }),
      ),
      e('div', { className: 'card', style: { display: 'flex', alignItems: 'center', gap: 16, padding: '16px 20px', marginBottom: 16, flexWrap: 'wrap' } },
        e('div', { className: 'grow' },
          e('div', { style: { fontWeight: 700, fontSize: 15 } }, 'Minimum profit for ' + model.name + ' doors'),
          e('div', { className: 'muted', style: { fontSize: 13 } }, (model.minProfit != null)
            ? ('This tier floors at $' + Number(model.minProfit).toLocaleString() + ' profit — set a higher floor on premium tiers for a bigger upgrade jump.')
            : ('Using the global door minimum ($' + Number(app.settings.minProfitDoor).toLocaleString() + '). Set a value to give this tier its own floor.')),
        ),
        e('div', { style: { position: 'relative', width: 130 } },
          e('span', { style: { position: 'absolute', left: 12, top: '50%', transform: 'translateY(-50%)', color: 'var(--ink-3)', fontWeight: 700 } }, '$'),
          e('input', {
            type: 'number', value: model.minProfit == null ? '' : model.minProfit,
            placeholder: app.settings.minProfitDoor,
            onChange: ev => { const v = ev.target.value; model.minProfit = (v === '' ? null : Math.max(0, Number(v))); GW.saveModels(); app.bump(); },
            style: { width: '100%', padding: '9px 10px 9px 22px', borderRadius: 8, border: '1.5px solid var(--line-2)', fontWeight: 600, textAlign: 'right', outline: 'none', fontVariantNumeric: 'tabular-nums' },
          }),
        ),
      ),
      e('div', { className: 'card', style: { padding: 16, overflowX: 'auto' } },
        e('div', { style: { display: 'flex', alignItems: 'center', gap: 10, padding: '4px 8px 14px' } },
          e(Badge, { kind: model.badge }, model.badgeLabel),
          e('span', { className: 'muted', style: { fontSize: 13 } }, 'Model ' + model.code + ' — ' + model.desc),
        ),
        e('table', { className: 'price-table' },
          e('thead', null, e('tr', null,
            e('th', { style: { textAlign: 'left' } }, 'Width'),
            cols.map((c, i) => e('th', { key: i }, c)),
          )),
          e('tbody', null,
            GW.widths.map((w, wi) => e('tr', { key: w.ft },
              e('td', { style: { fontWeight: 700, whiteSpace: 'nowrap' } }, w.ft + ' ft', !w.std ? e('span', { className: 'badge badge-order', style: { marginLeft: 6, fontSize: 9.5, padding: '2px 6px' } }, 'SO') : null),
              model.table[wi].map((val, ci) => e('td', { key: ci },
                e('input', { type: 'number', value: val, onChange: ev => editCell(wi, ci, ev.target.value), className: 'price-cell' }),
              )),
            )),
          ),
        ),
      ),
    );
  }
  window.AdminDoors = AdminDoors;

  /* ===================== OPENERS ===================== */
  function AdminOpeners() {
    const app = window.useApp();
    const [edit, setEdit] = useState(null);
    const tierFor = (id) => { const t = GW.openerTiers.find(t => t.openerId === id); return t ? t.tier : null; };

    const TIERS = ['Good', 'Better', 'Best'];
    const openerForTier = (tier) => { const t = GW.openerTiers.find(t => t.tier === tier); return t ? t.openerId : ''; };
    const setTierOpener = (tier, openerId) => {
      let t = GW.openerTiers.find(t => t.tier === tier);
      if (!t) { t = { tier: tier, openerId: openerId, blurb: '' }; GW.openerTiers.push(t); }
      else t.openerId = openerId;
      GW.saveOpenerTiers(); app.bump();
    };
    const addOpener = () => {
      const brand = (GW.manufacturers && GW.manufacturers[0]) || 'LiftMaster';
      GW.openers.push({ id: 'NEW-' + Date.now().toString().slice(-4), brand: brand, type: 'Belt', desc: 'New opener', cost7: 0, cost8: 0, enabled: true, override: null, upsell: false });
      GW.saveOpeners(); app.bump();
    };
    const removeOpener = (o) => {
      if (!confirm('Remove ' + o.brand + ' ' + o.id + '?')) return;
      GW.openers = GW.openers.filter(x => x !== o);
      GW.openerTiers = GW.openerTiers.filter(t => t.openerId !== o.id);
      GW.saveOpeners(); GW.saveOpenerTiers(); app.bump();
    };

    return e('div', null,
      e(SectionTitle, { eyebrow: 'Admin', title: 'Openers', sub: 'Add, edit, or remove openers. Set pricing, descriptions, and which model is Good/Better/Best in the door flow.',
        right: e(Btn, { variant: 'primary', icon: 'plus', onClick: addOpener }, 'Add opener') }),

      // Good / Better / Best assignment
      e('div', { className: 'card', style: { padding: 20, marginBottom: 16 } },
        e('div', { style: { fontWeight: 700, fontSize: 15, marginBottom: 4 } }, 'Door-flow line-up'),
        e('div', { className: 'muted', style: { fontSize: 13, marginBottom: 14 } }, 'Pick which opener shows as Good / Better / Best when building a door.'),
        e('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: 14 } },
          TIERS.map(tier => e('div', { key: tier },
            e('div', { style: { fontSize: 12, fontWeight: 800, letterSpacing: '.04em', textTransform: 'uppercase', color: 'var(--ink-3)', marginBottom: 6 } }, tier),
            e('select', { value: openerForTier(tier), onChange: ev => setTierOpener(tier, ev.target.value), style: { width: '100%', padding: '10px 12px', borderRadius: 10, border: '1.5px solid var(--line-2)', background: '#fff', fontSize: 14, fontWeight: 600, outline: 'none', cursor: 'pointer' } },
              e('option', { value: '' }, '— none —'),
              GW.openers.map(o => e('option', { key: o.id, value: o.id }, o.brand + ' ' + o.id))),
          )),
        ),
      ),

      e('div', { className: 'card', style: { overflow: 'hidden' } },
        e('div', { className: 'table-head6' },
          ['Model', 'Type', '7ft', '8ft', 'Door-flow tier', ''].map((h, i) => e('div', { key: i, style: { textAlign: i >= 2 && i <= 3 ? 'right' : 'left' } }, h)),
        ),
        GW.openers.map((o, i) => e('div', { key: o.id, className: 'table-row6', style: { opacity: o.enabled ? 1 : .5 } },
          e('div', null,
            e('div', { style: { fontWeight: 700, fontSize: 15 } }, o.brand + ' ' + o.id),
            e('div', { className: 'muted', style: { fontSize: 12.5 } }, o.desc),
          ),
          e('div', null, e(Badge, { kind: 'start' }, o.type)),
          e('div', { className: 'num', style: { textAlign: 'right', fontWeight: 600 } }, o.single != null ? '—' : GW.fmtCents(o.cost7)),
          e('div', { className: 'num', style: { textAlign: 'right', fontWeight: 600 } }, o.single != null ? GW.fmtCents(o.single) : (o.cost8 != null ? GW.fmtCents(o.cost8) : '—')),
          e('div', null, tierFor(o.id) ? e('span', { className: 'badge badge-pop' }, tierFor(o.id)) : e('span', { className: 'muted', style: { fontSize: 13 } }, '—')),
          e('div', { style: { display: 'flex', alignItems: 'center', gap: 8, justifyContent: 'flex-end' } },
            e(Toggle, { on: o.enabled, onChange: v => { o.enabled = v; GW.saveOpeners(); app.bump(); }, label: 'enable' }),
            e('button', { onClick: () => setEdit(o), title: 'Edit', style: { border: 'none', background: 'var(--field)', borderRadius: 9, width: 34, height: 34, display: 'grid', placeItems: 'center', color: 'var(--ink-2)', cursor: 'pointer' } }, e(Icon, { name: 'edit', size: 17 })),
            e('button', { onClick: () => removeOpener(o), title: 'Remove', style: { border: 'none', background: 'var(--danger-bg)', color: 'var(--danger)', borderRadius: 9, width: 34, height: 34, display: 'grid', placeItems: 'center', cursor: 'pointer' } }, e(Icon, { name: 'trash', size: 16 })),
          ),
        )),
      ),
      e(Modal, { open: !!edit, onClose: () => setEdit(null), title: edit ? ('Edit ' + edit.brand + ' ' + edit.id) : '', width: 460 },
        edit ? e('div', { style: { display: 'flex', flexDirection: 'column', gap: 16 } },
          e('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 } },
            e(Field, { label: 'Brand' },
              e('select', { value: edit.brand, onChange: ev => { edit.brand = ev.target.value; GW.saveOpeners(); app.bump(); }, style: { width: '100%', padding: '10px 12px', borderRadius: 10, border: '1.5px solid var(--line-2)', background: '#fff', fontSize: 14, fontWeight: 600, outline: 'none', cursor: 'pointer' } },
                (GW.manufacturers || []).map(m => e('option', { key: m, value: m }, m)))),
            e(Field, { label: 'Type' },
              e('select', { value: edit.type, onChange: ev => { edit.type = ev.target.value; GW.saveOpeners(); app.bump(); }, style: { width: '100%', padding: '10px 12px', borderRadius: 10, border: '1.5px solid var(--line-2)', background: '#fff', fontSize: 14, fontWeight: 600, outline: 'none', cursor: 'pointer' } },
                ['Belt', 'Chain', 'Jackshaft'].map(t => e('option', { key: t, value: t }, t)))),
          ),
          e(Field, { label: 'Model number' }, e(Input, { value: edit.id, onChange: ev => { const old = edit.id; edit.id = ev.target.value; GW.openerTiers.forEach(t => { if (t.openerId === old) t.openerId = edit.id; }); GW.saveOpeners(); GW.saveOpenerTiers(); app.bump(); } })),
          e(Field, { label: 'Description' }, e(Input, { value: edit.desc, onChange: ev => { edit.desc = ev.target.value; GW.saveOpeners(); app.bump(); } })),
          edit.single != null
            ? e(Field, { label: 'Single price (jackshaft)' }, e(Input, { type: 'number', value: edit.single, onChange: ev => { edit.single = Number(ev.target.value); GW.saveOpeners(); app.bump(); } }))
            : e('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 } },
                e(Field, { label: '7ft cost' }, e(Input, { type: 'number', value: edit.cost7, onChange: ev => { edit.cost7 = Number(ev.target.value); GW.saveOpeners(); app.bump(); } })),
                e(Field, { label: '8ft cost' }, e(Input, { type: 'number', value: edit.cost8 == null ? '' : edit.cost8, onChange: ev => { edit.cost8 = ev.target.value === '' ? null : Number(ev.target.value); GW.saveOpeners(); app.bump(); } })),
              ),
          e(Field, { label: 'Pricing rule', hint: 'Overrides the global target margin for this opener' },
            e('div', { style: { display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' } },
              e(window.OverrideControl, { value: edit.override || null, settings: app.settings, onChange: ov => { edit.override = ov; GW.saveOpeners(); app.bump(); } }),
              e('span', { className: 'muted', style: { fontSize: 12.5 } }, GW.overrideLabel(edit.override, app.settings)),
            ),
          ),
          e(Field, { label: 'Offer as an upsell', hint: 'Feature this opener in bundles & door-flow recommendations' },
            e('div', { style: { display: 'flex', alignItems: 'center', gap: 12 } },
              e(Toggle, { on: !!edit.upsell, onChange: v => { edit.upsell = v; GW.saveOpeners(); app.bump(); }, label: 'Upsell ' + edit.id }),
              e('span', { className: 'muted', style: { fontSize: 12.5 } }, edit.upsell ? 'Featured as an upsell' : 'Not featured'),
            ),
          ),
          e(Btn, { variant: 'primary', block: true, onClick: () => setEdit(null) }, 'Done'),
        ) : null,
      ),
    );
  }
  window.AdminOpeners = AdminOpeners;

  /* ===================== MANUFACTURERS ===================== */
  function AdminManufacturers() {
    const app = window.useApp();
    const disabled = app.disabledMfrs || {};
    const toggle = (m) => { app.setDisabledMfrs(Object.assign({}, disabled, { [m]: !disabled[m] })); };

    const addMfr = () => {
      let name = 'New manufacturer', n = 1;
      while (GW.manufacturers.indexOf(name) >= 0) { name = 'New manufacturer ' + (++n); }
      GW.manufacturers.push(name); GW.saveManufacturers(); app.bump();
    };
    const rename = (idx, next) => {
      const old = GW.manufacturers[idx];
      next = next || '';
      // keep openers linked to the renamed brand
      GW.openers.forEach(o => { if (o.brand === old) o.brand = next; });
      GW.manufacturers[idx] = next;
      if (disabled[old]) { const d = Object.assign({}, disabled); delete d[old]; d[next] = true; app.setDisabledMfrs(d); }
      GW.saveManufacturers(); GW.saveOpeners(); app.bump();
    };
    const remove = (m) => {
      const count = GW.openers.filter(o => o.brand === m).length;
      if (count && !confirm('Remove ' + m + '? Its ' + count + ' opener model(s) will be deleted too.')) return;
      GW.openers = GW.openers.filter(o => o.brand !== m);
      GW.manufacturers = GW.manufacturers.filter(x => x !== m);
      if (disabled[m]) { const d = Object.assign({}, disabled); delete d[m]; app.setDisabledMfrs(d); }
      GW.saveManufacturers(); GW.saveOpeners(); app.bump();
    };

    return e('div', null,
      e(SectionTitle, { eyebrow: 'Admin', title: 'Manufacturers', sub: 'Add, rename or remove a manufacturer. Disable one to instantly hide all of its opener models from reps.',
        right: e(Btn, { variant: 'primary', icon: 'plus', onClick: addMfr }, 'Add manufacturer') }),
      e('div', { className: 'mfr-grid', style: { display: 'grid', gridTemplateColumns: 'repeat(auto-fill,minmax(300px,1fr))', gap: 18 } },
        GW.manufacturers.map((m, idx) => {
          const count = GW.openers.filter(o => o.brand === m).length;
          const off = disabled[m];
          return e('div', { key: idx, className: 'card', style: { padding: 22, display: 'flex', alignItems: 'center', gap: 16, opacity: off ? .6 : 1 } },
            e('div', { style: { width: 50, height: 50, borderRadius: 14, background: 'var(--field)', color: 'var(--teal)', display: 'grid', placeItems: 'center', flexShrink: 0 } }, e(Icon, { name: 'manufacturers', size: 26 })),
            e('div', { className: 'grow', style: { minWidth: 0 } },
              e('input', { value: m, onChange: ev => rename(idx, ev.target.value), style: { border: 'none', background: 'transparent', fontFamily: 'var(--display)', fontWeight: 600, fontSize: 18, width: '100%', outline: 'none', color: 'var(--ink)' } }),
              e('div', { className: 'muted', style: { fontSize: 13 } }, count + ' models · ' + (off ? 'Hidden' : 'Active')),
            ),
            e(Toggle, { on: !off, onChange: () => toggle(m), label: m }),
            e('button', { onClick: () => remove(m), title: 'Remove', style: { border: 'none', background: 'var(--danger-bg)', color: 'var(--danger)', borderRadius: 9, width: 34, height: 34, display: 'grid', placeItems: 'center', cursor: 'pointer', flexShrink: 0 } }, e(Icon, { name: 'trash', size: 16 })),
          );
        }),
      ),
    );
  }
  window.AdminManufacturers = AdminManufacturers;
})();
