// CalcTool.jsx — full standalone catering cost calculator
// Pricing model calibrated 2026-08-24 against 50 booked FTOTM events (Airtable).
// Backtest: this band contains the actual agreed total for 38 of 50 (76%). The
// previous $20–$30 / $1,500-floor model only contained 19 of 50 (38%).
// Reference stats: all-in per serving median $23.57 (p25 $18.08 / p75 $29.22);
// 1-truck jobs median $2,245; 2-truck median $5,953; 4+ truck median $14,399.
// Servings track guests × trucks almost exactly (median ratio 1.00), which is why
// the ceiling scales per truck rather than per guest.
// Kept in sync with Calculator.jsx (homepage widget).
const CALC_RATES = {
  perGuestLow: 15,
  perGuestHigh: 35,
  truckFloorLow: 1400,
  truckFloorHigh: 3400,
  drinksAdd: 4,
};

// The estimate is the same for every event type — no per-type multiplier. The
// selector is kept only to pass event context into the quote prefill, not to
// change the number. (mult stays at 1.00 across the board.)
const EVENT_TYPES = [
  { label: 'Corporate',        mult: 1.00 },
  { label: 'Wedding',          mult: 1.00 },
  { label: 'Campus or school', mult: 1.00 },
  { label: 'Private party',    mult: 1.00 },
  { label: 'Large event',      mult: 1.00 },
  { label: 'Other',            mult: 1.00 },
];

const round50 = (n) => Math.round(n / 50) * 50;
const fmtMoney = (n) => '$' + Math.round(n).toLocaleString('en-US');

function computeEstimate({ guests, savory, sweet, drinks, mult }) {
  const { perGuestLow, perGuestHigh, truckFloorLow, truckFloorHigh, drinksAdd } = CALC_RATES;
  const trucks = savory + sweet;
  let baseLow  = Math.max(guests * perGuestLow,  trucks * truckFloorLow);
  let baseHigh = Math.max(guests * perGuestHigh, trucks * truckFloorHigh);
  if (drinks) { baseLow += guests * drinksAdd; baseHigh += guests * drinksAdd; }
  return {
    low:  round50(baseLow  * mult),
    high: round50(baseHigh * mult),
    trucks,
  };
}

const recommendTrucks = (guests) => Math.max(1, Math.ceil(guests / 90));

// Animated count-up number ------------------------------------------------
function useCountUp(target, duration = 300) {
  const [val, setVal] = React.useState(target);
  const fromRef = React.useRef(target);
  const rafRef = React.useRef(null);
  React.useEffect(() => {
    const from = fromRef.current;
    const start = performance.now();
    cancelAnimationFrame(rafRef.current);
    const tick = (now) => {
      const t = Math.min(1, (now - start) / duration);
      const eased = 1 - Math.pow(1 - t, 3);
      const cur = from + (target - from) * eased;
      setVal(cur);
      if (t < 1) rafRef.current = requestAnimationFrame(tick);
      else { setVal(target); fromRef.current = target; }
    };
    rafRef.current = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(rafRef.current);
  }, [target, duration]);
  fromRef.current = val;
  return val;
}

// Stepper -----------------------------------------------------------------
const Stepper = ({ value, set, min, max, label, sublabel, icon }) => (
  <div style={{
    border: `1px solid ${T.border}`, borderRadius: 12, padding: '14px 16px',
    background: T.white, display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12,
  }}>
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, minWidth: 0 }}>
      <span style={{ color: T.teal, flex: '0 0 auto' }}>{icon}</span>
      <div style={{ minWidth: 0 }}>
        <div style={{ fontSize: 14, fontWeight: 600, color: T.ink }}>{label}</div>
        {sublabel && <div style={{ fontSize: 12, color: T.inkSoft, marginTop: 1 }}>{sublabel}</div>}
      </div>
    </div>
    <div style={{ display: 'flex', alignItems: 'center', gap: 6, flex: '0 0 auto' }}>
      <button type="button" aria-label={`Decrease ${label}`} onClick={() => set(Math.max(min, value - 1))}
        disabled={value <= min}
        className="step-btn" style={{ opacity: value <= min ? 0.4 : 1 }}>–</button>
      <span className="numeral" style={{ minWidth: 22, textAlign: 'center', fontWeight: 700, fontSize: 17, color: T.ink }}>{value}</span>
      <button type="button" aria-label={`Increase ${label}`} onClick={() => set(Math.min(max, value + 1))}
        disabled={value >= max}
        className="step-btn" style={{ opacity: value >= max ? 0.4 : 1 }}>+</button>
    </div>
  </div>
);

const CalcTool = ({ onQuote }) => {
  const [eventType, setEventType] = React.useState(EVENT_TYPES[0].label);
  const [guests, setGuests]       = React.useState(100);
  const [savory, setSavory]       = React.useState(recommendTrucks(100));
  const [sweet, setSweet]         = React.useState(0);
  const [drinks, setDrinks]       = React.useState(false);
  const [userTouchedSavory, setUserTouchedSavory] = React.useState(false);

  const rec = recommendTrucks(guests);

  // Keep savory suggestion in sync until the user overrides it.
  React.useEffect(() => {
    if (!userTouchedSavory) setSavory(rec);
  }, [rec, userTouchedSavory]);

  const setSavoryManual = (v) => { setUserTouchedSavory(true); setSavory(v); };

  const mult = (EVENT_TYPES.find(e => e.label === eventType) || EVENT_TYPES[0]).mult;
  const { low, high, trucks } = computeEstimate({ guests, savory, sweet, drinks, mult });

  const animLow  = useCountUp(low);
  const animHigh = useCountUp(high);

  const buildPrefill = () => {
    const parts = [`${savory} savory`];
    if (sweet)  parts.push(`${sweet} sweet`);
    parts.push(drinks ? 'drinks on' : 'no drinks');
    const note = `Calculator: ${eventType}, ~${guests} guests, ${parts.join(' + ')}, est. ${fmtMoney(low)}–${fmtMoney(high)} for ~3 hrs.`;
    return { eventType, guests, estimateLow: low, estimateHigh: high, note };
  };

  return (
    <section style={{ background: T.bgAlt, padding: '40px 24px 64px' }}>
      <div style={{ maxWidth: 1080, margin: '0 auto' }}>
        <div className="calc-card" style={{
          background: T.white, borderRadius: 16, border: `1px solid ${T.border}`,
          boxShadow: T.shadowRaised, overflow: 'hidden',
          display: 'grid', gridTemplateColumns: '1fr 0.82fr',
        }}>
          {/* ---------- INPUTS ---------- */}
          <div style={{ padding: 'clamp(24px, 3vw, 40px)' }}>
            <div className="eyebrow" style={{ marginBottom: 8 }}>Build your event</div>
            <h2 style={{ fontSize: 22, margin: '0 0 24px' }}>Tell us the shape of the day</h2>

            {/* Event type */}
            <label style={{ display: 'block', marginBottom: 22 }}>
              <div className="calc-label">Event type</div>
              <div style={{ position: 'relative' }}>
                <select className="calc-select" value={eventType} onChange={e => setEventType(e.target.value)}>
                  {EVENT_TYPES.map(e => <option key={e.label} value={e.label}>{e.label}</option>)}
                </select>
                <span className="calc-select-caret" aria-hidden="true">▾</span>
              </div>
            </label>

            {/* Guests slider */}
            <div style={{ marginBottom: 24 }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 10 }}>
                <span className="calc-label" style={{ marginBottom: 0 }}>Number of guests</span>
                <span className="numeral" style={{ fontWeight: 700, fontSize: 26, color: T.navy, letterSpacing: '-0.02em', lineHeight: 1 }}>
                  {guests.toLocaleString('en-US')}
                </span>
              </div>
              <input type="range" min="75" max="1000" step="5" value={guests}
                onChange={e => setGuests(+e.target.value)} className="calc-range" aria-label="Number of guests" />
              <div style={{ display: 'flex', justifyContent: 'space-between', color: T.inkMute, fontSize: 12, marginTop: 6 }}>
                <span>25</span><span>1,000</span>
              </div>
            </div>

            {/* Smart helper */}
            <div className="calc-helper">
              <IconBolt size={16} style={{ flex: '0 0 auto', marginTop: 1, color: T.teal }} />
              <span>For ~{guests.toLocaleString('en-US')} guests we'd usually suggest <strong>{rec} truck{rec > 1 ? 's' : ''}</strong> to keep lines moving.</span>
            </div>

            {/* Truck steppers */}
            <div style={{ display: 'grid', gap: 12, marginBottom: 14 }}>
              <Stepper value={savory} set={setSavoryManual} min={0} max={6}
                label="Savory trucks" icon={<IconTruck size={20} />}
                sublabel={!userTouchedSavory ? `Suggested: ${rec}` : (savory !== rec ? `We'd suggest ${rec}` : null)} />
              <Stepper value={sweet} set={setSweet} min={0} max={3}
                label="Sweet / dessert trucks" icon={<IconCake size={20} />} />
            </div>

            {/* Drinks toggle */}
            <button type="button" onClick={() => setDrinks(d => !d)} className="calc-toggle-row"
              aria-pressed={drinks}>
              <span style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                <IconGlass size={20} style={{ color: T.teal }} />
                <span>
                  <span style={{ fontSize: 14, fontWeight: 600, color: T.ink, display: 'block' }}>Drinks station</span>
                  <span style={{ fontSize: 12, color: T.inkSoft }}>Specialty coffee, lemonade, or soft bar</span>
                </span>
              </span>
              <span className="calc-switch" data-on={drinks}>
                <span className="calc-switch-knob" />
              </span>
            </button>
          </div>

          {/* ---------- ESTIMATE ---------- */}
          <aside className="calc-estimate">
            <div>
              <div className="micro" style={{ color: T.teal, marginBottom: 12 }}>Estimated range</div>
              <div className="numeral" style={{ fontWeight: 700, color: T.navy, letterSpacing: '-0.03em', lineHeight: 1.04, fontSize: 'clamp(30px, 3.6vw, 44px)' }}>
                {fmtMoney(animLow)} – {fmtMoney(animHigh)}
              </div>
              <div style={{ fontSize: 14, color: T.inkSoft, marginTop: 8, fontWeight: 500 }}>for ~3 hours of service</div>

              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, marginTop: 18 }}>
                <span className="calc-pill">{eventType}</span>
                <span className="calc-pill">{`${guests.toLocaleString('en-US')} guests`}</span>
                <span className="calc-pill">{`${trucks} truck${trucks !== 1 ? 's' : ''}`}</span>
                {drinks && <span className="calc-pill">+ drinks</span>}
              </div>

              <p style={{ fontSize: 13, lineHeight: 1.55, color: T.inkSoft, margin: '20px 0 0' }}>
                Includes vendor cost, FTOTM coordination, and basic permits. This is a ballpark — your real quote depends on menu, location, and travel.
              </p>
            </div>

            <div style={{ marginTop: 24 }}>
              <button type="button" onClick={() => onQuote(buildPrefill())}
                className="btn btn-primary" style={{ width: '100%', justifyContent: 'center' }}>
                Get a real quote →
              </button>
              <a href="tel:+12012082682" className="calc-call">
                <IconPhone size={15} /> Not sure what you need? Call (201) 208-2682
              </a>
            </div>
          </aside>
        </div>
      </div>
    </section>
  );
};

Object.assign(window, { CalcTool });
