// Main app — orchestrates the flow + admin pricing
const { useState: useS, useMemo: useM, useEffect: useE } = React;

const STEPS = [
  { id: 'client',   label: 'Vendor & Customer', sub: 'Contacts + site' },
  { id: 'cabinets', label: 'Cabinets',          sub: 'Specs + toe kick' },
  { id: 'review',   label: 'Review',            sub: 'Confirm order' },
  { id: 'done',     label: 'Work Order',        sub: 'Send or print' },
];

const todayISO = () => new Date().toISOString().slice(0, 10);

const blankData = () => ({
  vendorName: '', vendorContact: '', vendorPhone: '', vendorEmail: '', vendorPO: '',
  clientName: '', clientPhone: '', clientEmail: '',
  preferredContact: 'Phone',
  address: '', installNeeded: 'Yes', homeType: 'Single fam.',
  accessNotes: '',
  dateReceived: todayISO(), completionRequested: '',
  timeframe: '1mo',
  cabinets: [],
  toeKick: { heightU: 'in', depthU: 'in', setbackU: 'in', thickness: '3/4"' },
  specialInstructions: '',
});

const DEFAULT_TWEAKS = /*EDITMODE-BEGIN*/{
  "companyName": "Precision Cabinets LLC",
  "companyInitial": "P",
  "tagline": "Restore · Refinish · Recreate"
}/*EDITMODE-END*/;

const PRICING_STORAGE_KEY = 'cabinet_intake_pricing_v1';

function loadPricing() {
  try {
    const raw = localStorage.getItem(PRICING_STORAGE_KEY);
    if (!raw) return DEFAULT_PRICING;
    const saved = JSON.parse(raw);
    // Merge so new keys from updates are picked up
    const merged = { ...DEFAULT_PRICING };
    for (const k of Object.keys(saved)) {
      if (merged[k]) merged[k] = { ...merged[k], price: saved[k].price };
    }
    return merged;
  } catch { return DEFAULT_PRICING; }
}

function savePricing(pricing) {
  try {
    const slim = {};
    for (const [k, v] of Object.entries(pricing)) slim[k] = { price: v.price };
    localStorage.setItem(PRICING_STORAGE_KEY, JSON.stringify(slim));
  } catch {}
}

function App() {
  const [step, setStep] = useS(0);
  const [data, setData] = useS(blankData);
  const [tweaks, setTweaks] = useTweaks(DEFAULT_TWEAKS);
  const [pricing, setPricingRaw] = useS(loadPricing);
  const [adminOpen, setAdminOpen] = useS(false);
  const [vendors, setVendorsRaw] = useS(loadVendors);
  const [activeVendor, setActiveVendor] = useS(null);

  const setVendors = (v) => { setVendorsRaw(v); saveVendors(v); };

  // On mount: detect ?vendor= in URL and apply
  useE(() => {
    const slug = getVendorFromURL();
    if (!slug) return;
    const allVendors = loadVendors();
    const v = allVendors.find(x => x.slug === slug);
    if (v) {
      setActiveVendor(v);
      setData(prev => applyVendorToData(prev, v));
    }
  }, []);

  const applyVendorCode = (v) => {
    setActiveVendor(v);
    setData(prev => applyVendorToData(prev, v));
    // Update URL without reloading
    try {
      const url = new URL(window.location.href);
      url.searchParams.set('vendor', v.slug);
      window.history.replaceState({}, '', url.toString());
    } catch {}
  };

  const clearVendor = () => {
    setActiveVendor(null);
    try {
      const url = new URL(window.location.href);
      url.searchParams.delete('vendor');
      url.searchParams.delete('v');
      window.history.replaceState({}, '', url.pathname);
    } catch {}
  };

  const setPricing = (p) => { setPricingRaw(p); savePricing(p); };
  const resetPricing = () => { if (confirm('Reset all prices to defaults?')) { setPricingRaw(DEFAULT_PRICING); savePricing(DEFAULT_PRICING); } };

  const reset = () => {
    let next = blankData();
    if (activeVendor) next = applyVendorToData(next, activeVendor);
    setData(next);
    setStep(0);
  };

  const estimate = useM(() => computeEstimate(data, pricing), [data, pricing]);

  const canAdvance = () => {
    if (step === 0) return data.vendorName && data.clientName && data.address;
    if (step === 1) return (data.cabinets || []).length > 0;
    return true;
  };

  return (
    <div className="app">
      <aside className="rail no-print">
        <div className="brand">
          <div className="brand-mark" style={{ fontStyle: 'italic' }}>{tweaks.companyInitial || 'P'}</div>
          <div style={{ flex: 1 }}>
            <div className="brand-name">{tweaks.companyName}</div>
            <div className="brand-sub">{tweaks.tagline}</div>
          </div>
          <button className="rail-admin-btn" onClick={() => setAdminOpen(true)} title="Admin · Pricing">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
              <rect x="3" y="11" width="18" height="11" rx="2"/>
              <path d="M7 11V7a5 5 0 0 1 10 0v4"/>
            </svg>
          </button>
        </div>

        <div className="steps">
          {STEPS.map((s, i) => (
            <button key={s.id}
              className={'step' + (step === i ? ' active' : '') + (step > i ? ' done' : '')}
              onClick={() => { if (i <= step || canAdvance()) setStep(i); }}>
              <div className="step-num">{step > i ? <Icon.Check/> : String(i + 1).padStart(2, '0')}</div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div className="step-label">{s.label}</div>
                <div className="step-sub">{s.sub}</div>
              </div>
            </button>
          ))}
        </div>

        <RailEstimate data={data} estimate={estimate}/>
      </aside>

      <main className="main">
        {activeVendor && step === 0 && (
          <VendorBanner vendor={activeVendor} onSwitchToOpen={clearVendor}/>
        )}
        {!activeVendor && step === 0 && vendors.length > 0 && (
          <VendorCodeEntry vendors={vendors} onPick={applyVendorCode}/>
        )}
        {step === 0 && <ClientStep data={data} setData={setData}/>}
        {step === 1 && <CabinetsStep data={data} setData={setData} onProceed={() => setStep(2)}/>}
        {step === 2 && <ReviewStep data={data} estimate={estimate}/>}
        {step === 3 && <SubmittedStep data={data} estimate={estimate} onReset={reset}/>}

        {step !== 1 && step < 3 && (
          <div className="nav-foot no-print">
            <button className="btn ghost" onClick={() => setStep(Math.max(0, step - 1))} disabled={step === 0}>
              <Icon.ArrowL/> Back
            </button>
            <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
              {!canAdvance() && step === 0 && (<span style={{ fontSize: 12, color: 'var(--ink-faint)' }}>Vendor, customer, and address required</span>)}
              <button className="btn primary lg" onClick={() => setStep(step + 1)} disabled={!canAdvance()}>
                {step === 2 ? 'Submit & create work order' : 'Continue'} <Icon.ArrowR/>
              </button>
            </div>
          </div>
        )}
        {step === 1 && (
          <div className="nav-foot no-print" style={{ justifyContent: 'flex-start' }}>
            <button className="btn ghost" onClick={() => setStep(0)}><Icon.ArrowL/> Back</button>
          </div>
        )}
      </main>

      {adminOpen && (
        <AdminScreen pricing={pricing} setPricing={setPricing}
          vendors={vendors} setVendors={setVendors}
          onClose={() => setAdminOpen(false)}
          onReset={resetPricing}/>
      )}

      <TweaksPanel title="Tweaks">
        <TweakSection title="Brand">
          <TweakText label="Company name" value={tweaks.companyName} onChange={(v) => setTweaks({ companyName: v })}/>
          <TweakText label="Brand initial" value={tweaks.companyInitial} onChange={(v) => setTweaks({ companyInitial: v.slice(0, 2) })}/>
          <TweakText label="Tagline" value={tweaks.tagline} onChange={(v) => setTweaks({ tagline: v })}/>
        </TweakSection>
        <TweakSection title="Theme">
          <TweakSelect label="Accent color" value="amber"
            options={[
              { value: 'amber',  label: 'Saw-blade amber' },
              { value: 'forest', label: 'Workshop forest' },
              { value: 'slate',  label: 'Graphite slate' },
              { value: 'rust',   label: 'Iron rust' },
            ]}
            onChange={(v) => {
              const map = { amber: 'oklch(65% 0.14 60)', forest: 'oklch(50% 0.09 150)', slate: 'oklch(45% 0.02 250)', rust: 'oklch(52% 0.15 35)' };
              document.documentElement.style.setProperty('--accent', map[v]);
            }}/>
        </TweakSection>
        <TweakSection title="Quick actions">
          <TweakButton onClick={() => setAdminOpen(true)}>Open admin · pricing</TweakButton>
          <TweakButton onClick={() => {
            setData({
              ...blankData(),
              vendorName: 'Sun Valley Cabinets', vendorContact: 'Mike Alvarez',
              vendorPhone: '(480) 555-0100', vendorEmail: 'mike@sunvalleycabinets.com',
              vendorPO: 'SVC-2026-0418',
              clientName: 'Sarah Coleman', clientPhone: '(480) 555-0142',
              clientEmail: 'sarah.coleman@example.com', preferredContact: 'Text',
              address: '2847 E Desert Broom Way, Phoenix, AZ 85048',
              completionRequested: '2026-05-15', timeframe: '2wk',
              accessNotes: 'Side gate unlocked. Friendly dog. Park in driveway.',
              cabinets: [
                { ...makeCabinet(1), name: 'Sink base', w: '36', wu: 'in', h: '34.5', hu: 'in', d: '24', du: 'in',
                  doors: 2, drawers: 0, shelves: 1, shelfW: '32', shelfD: '22', shelfU: 'in',
                  finishedSide: 'Yes', finishedWhich: 'Both',
                  boxMaterial: 'Birch plywood', boxThickness: '3/4"', cabType: 'Standard wall',
                  notes: 'Water damage on bottom — bottom panel replacement needed.' },
                { ...makeCabinet(2), name: 'Island bank', w: '60', wu: 'in', h: '34.5', hu: 'in', d: '24', du: 'in',
                  doors: 2, drawers: 3, shelves: 1, shelfW: '56', shelfD: '22', shelfU: 'in',
                  finishedSide: 'Yes', finishedWhich: 'Both',
                  boxMaterial: 'Hardrock maple', boxThickness: '3/4"', cabType: 'Island' },
              ],
              toeKick: { height: '4', heightU: 'in', depth: '3', depthU: 'in', setback: '3', setbackU: 'in', thickness: '3/4"', linearFt: '18' },
              specialInstructions: 'Match existing cherry stain. Customer has paint chip available on-site.',
            });
            setStep(1);
          }}>Load sample order</TweakButton>
          <TweakButton onClick={reset}>Clear all data</TweakButton>
        </TweakSection>
      </TweaksPanel>
    </div>
  );
}

function RailEstimate({ data, estimate }) {
  const cabCount = (data.cabinets || []).length;
  const tkFt = data.toeKick?.linearFt || 0;
  const hasOrder = estimate.total > 0;

  return (
    <div className="rail-estimate">
      <div className="label">Live estimate</div>
      <div className="amount">{hasOrder ? fmtMoney(estimate.total) : '—'}</div>
      <div className="range">
        {cabCount} cabinet{cabCount === 1 ? '' : 's'} · {tkFt || 0} ft toe kick
      </div>
      {hasOrder && (
        <>
          <div className="rail-est-rows">
            <div className="rail-est-row"><span>Subtotal</span><span className="mono">{fmtMoney(estimate.subtotal - estimate.tax)}</span></div>
            {estimate.tax > 0 && <div className="rail-est-row"><span>Tax</span><span className="mono">{fmtMoney(estimate.tax)}</span></div>}
            {estimate.rushApplied && <div className="rail-est-row" style={{ color: 'var(--accent-deep)' }}><span>Rush priority</span><span className="mono">applied</span></div>}
            {estimate.minimumApplied && <div className="rail-est-row" style={{ color: 'var(--accent-deep)' }}><span>Minimum</span><span className="mono">applied</span></div>}
          </div>
          <div className="rail-est-foot">Auto-calculated · admin sets the rates</div>
        </>
      )}
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App/>);
