/* House of Swad — Catering page
   Built to the "House of Swad - Catering Menu" design: a browse-only menu with
   a quick estimate that goes out as a WhatsApp enquiry (no cart).
   All content comes from Sanity ("Catering Hero", "Catering Packages",
   "Catering À La Carte", "Catering Plan Your Order", "Catering Terms"), with
   the design's copy below as the fallback if Sanity can't be reached. */

/* ---------- Hero (fetched from Sanity — see applyCateringHero) ---------- */
/* These defaults are shown if Sanity can't be reached. */
let CATERING_HERO = {
  tagline: 'Catering · Pre-orders only',
  title: 'A spread for *every gathering.*',
  description: 'Nepali, Indian and Italian favourites, cooked fresh in our central kitchen and delivered hot to your pujas, parties and office events across the valley.',
  image: 'assets/catering-hero.jpg',
  imageAlt: 'A catering buffet spread',
  badgeTitle: 'Pre-order only',
  badgeText: 'Book ahead, we cook fresh',
  stats: [
    { value: '*15*+ guests', label: 'Minimum for a full catering order' },
    { value: 'Rs *420*', label: 'Packages start per person' },
    { value: '*60*%', label: 'Advance confirms your booking' },
  ],
  cuisines: ['Nepali', 'Indian curries', 'Italian', 'Snacks', 'Desserts'],
};

const CATERING_QUERY_URL = `https://${SANITY_PROJECT_ID}.apicdn.sanity.io/v2024-01-01/data/query/${SANITY_DATASET}?query=` +
  encodeURIComponent(`{
    "hero": *[_type=="cateringHero"][0]{
      tagline, title, description, badgeTitle, badgeText,
      "image": image.asset->url, "imageAlt": image.alt,
      stats[]{ value, label }, cuisines
    },
    "packages": *[_type=="cateringPackages"][0]{
      title, description,
      mainPackage{ name, price, items },
      snacksPackage{ name, price, choiceGroups[]{ diet, chooseCount, options } }
    },
    "menu": *[_type=="cateringMenu"][0]{
      title, description,
      cards[]{
        title, kicker, navLabel, column, style, sideBySide, note, tags,
        "image": image.asset->url, "imageAlt": image.alt,
        groups[]{ label, items[]{ name, detail, price, unit, onRequest } }
      }
    },
    "planner": *[_type=="cateringPlanner"][0]{ title, description, notice, minGuests, advancePercent, smallOrderNote },
    "terms": *[_type=="cateringTerms"][0]{ title, terms }
  }`);

function applyCateringHero(doc) {
  if (!doc || !doc.title) return;
  CATERING_HERO = {
    tagline: doc.tagline || '',
    title: doc.title,
    description: doc.description || '',
    image: doc.image ? `${doc.image}?w=1200&auto=format` : CATERING_HERO.image,
    imageAlt: doc.imageAlt || '',
    badgeTitle: doc.badgeTitle || '',
    badgeText: doc.badgeText || '',
    stats: (doc.stats || []).filter((st) => st && st.value),
    cuisines: (doc.cuisines || []).filter(Boolean),
  };
}

function applyCateringPackages(doc) {
  if (!doc || !doc.title) return;
  PACKAGES_COPY = { title: doc.title, description: doc.description || '' };
  const main = doc.mainPackage;
  if (main && main.name && main.price != null) {
    MAIN_SET = { ...MAIN_SET, name: main.name, price: main.price, items: (main.items || []).filter(Boolean) };
  }
  const snacks = doc.snacksPackage;
  if (snacks && snacks.name && snacks.price != null) {
    SNACKS_SET = {
      ...SNACKS_SET,
      name: snacks.name,
      price: snacks.price,
      groups: (snacks.choiceGroups || []).filter((g) => g && (g.options || []).length).map((g) => ({
        nonveg: g.diet === 'nonveg',
        count: g.chooseCount || 1,
        opts: g.options,
      })),
    };
  }
}

function applyCateringMenu(doc) {
  if (!doc || !doc.title) return;
  const cards = (doc.cards || [])
    .filter((c) => c && c.title)
    .map((c) => ({
      ...c,
      image: c.image ? `${c.image}?w=800&auto=format` : null,
      groups: (c.groups || [])
        .map((g) => ({ label: g.label, items: (g.items || []).filter((it) => it && it.name) }))
        .filter((g) => g.items.length),
    }));
  if (!cards.length) return;
  MENU_COPY = { title: doc.title, description: doc.description || '' };
  MENU_CARDS = cards;
}

function applyCateringPlanner(doc) {
  if (!doc || !doc.title) return;
  PLANNER_COPY = { title: doc.title, description: doc.description || '', notice: doc.notice || '' };
  if (doc.minGuests > 0) SET_MIN_PAX = doc.minGuests;
  if (doc.advancePercent != null) ADVANCE_SHARE = doc.advancePercent / 100;
  if (doc.smallOrderNote !== undefined) SMALL_ORDER_NOTE = doc.smallOrderNote || '';
}

function applyCateringTerms(doc) {
  if (!doc || !doc.title) return;
  TERMS_COPY = { title: doc.title, terms: (doc.terms || []).filter(Boolean) };
}

/* Renders text with *wrapped* words in <em> and newlines as <br>. */
function Marked({ text }) {
  return (text || '').split('\n').map((line, i) => (
    <React.Fragment key={i}>
      {i > 0 && <br />}
      {line.split(/\*([^*]+)\*/).map((part, j) => (j % 2 ? <em key={j}>{part}</em> : part))}
    </React.Fragment>
  ));
}

/* ---------- Set packages (fetched from Sanity — see applyCateringPackages) ---------- */
/* These defaults are shown if Sanity can't be reached. */
let PACKAGES_COPY = {
  title: 'One price, *the whole table.*',
  description: "Two ready-made menus priced per person. Pick your options where you see a slash — we'll plan quantities for your headcount.",
};
let MAIN_SET = {
  id: 'main', name: 'Main Course', price: 620,
  items: [
    'Veg Pulao / Plain Rice / Jeera Rice', 'Plain Daal', 'Saag', 'Mix Veg',
    'Tamatar Achar / Aloo Kakra Achar', 'Chicken Curry / Matar Paneer',
  ],
};
let SNACKS_SET = {
  id: 'snacks', name: 'Snacks', price: 420,
  groups: [
    { nonveg: false, count: 2, opts: ['Mustang Aloo', 'Corn Sadheko', 'Veg Momo', 'Mushroom Choila', 'Pakauda'] },
    { nonveg: true, count: 1, opts: ['Chicken Roast', 'Chicken Momo', 'Chicken Sadheko', 'Timmur Chicken'] },
  ],
};

/* ---------- À la carte (fetched from Sanity — see applyCateringMenu) ---------- */
/* These defaults are shown if Sanity can't be reached. Card order is the
   phone / menu-bar order; `column` places each card on wide screens. */
const one = (items, label) => ({ label, items });
let MENU_COPY = {
  title: 'Build your *own spread.*',
  description: 'Mix curries, biryani, pizza and sweets, or add them to a package. Items without a price are quoted with your order.',
};
let MENU_CARDS = [
  {
    title: 'Curries', kicker: 'Veg', navLabel: 'Curry — Veg', column: 1,
    groups: [one([
      { name: 'Mix Veg Curry' }, { name: 'Veg Manchurian', detail: '(Gravy / Dry)' }, { name: 'Matar Paneer' },
      { name: 'Palak Paneer' }, { name: 'Paneer Butter Masala' }, { name: 'Chana Masala' },
      { name: 'Rajma Masala' }, { name: 'Dal Makhani' },
    ])],
    note: 'Customisation available on request',
  },
  {
    title: 'Curries', kicker: 'Non Veg', navLabel: 'Curry — Non Veg', column: 1,
    groups: [one([
      { name: 'Mutton Curry' }, { name: 'Mutton Rogan Josh' }, { name: 'Chicken Tikka Masala' },
      { name: 'Nepali Chicken Masala' }, { name: 'Chicken Butter Masala' }, { name: 'Fish Curry' },
    ])],
  },
  {
    title: 'Biryani', column: 2, image: 'assets/catering-biryani.jpg', imageAlt: 'Fragrant biryani',
    groups: [one([
      { name: 'Mix Veg Paneer Biryani', price: 350 }, { name: 'Chicken Biryani', price: 380 }, { name: 'Mutton Biryani', price: 600 },
    ])],
    note: 'Served with raita and mula achar',
  },
  {
    title: 'Italian', column: 2,
    groups: [
      one([
        { name: 'Margherita Pizza', price: 600 }, { name: 'Hawaiian Pizza', price: 700 },
        { name: 'Vegetable Pizza', price: 600 }, { name: 'Meat Lovers Pizza', price: 750 },
      ], '12-inch pizza'),
      one([{ name: 'Chicken Alfredo Pasta', price: 400 }, { name: 'Mushroom Alfredo Pasta', price: 380 }], 'Pasta'),
    ],
    note: 'Customisation available on all Italian dishes',
  },
  {
    title: 'Naan & Sides', column: 2,
    groups: [one([{ name: 'Plain Naan' }, { name: 'Butter Naan' }, { name: 'Garlic Naan' }, { name: 'Papad' }, { name: 'Prawns' }])],
  },
  {
    title: 'Frozen Momo', kicker: 'Take-home', column: 3, style: 'soft',
    groups: [one([{ name: 'Veg Momo', price: 150 }, { name: 'Paneer Momo', price: 170 }, { name: 'Non Veg Momo', price: 170 }])],
    tags: ['Min. 4 plates', 'Pre-order only', 'For fresh use only'],
  },
  {
    title: 'Salads', column: 3,
    groups: [one([{ name: 'Green Salad' }, { name: 'Russian Salad' }, { name: 'Chicken Salad' }])],
  },
  {
    title: 'Desserts', column: 3,
    groups: [one([
      { name: 'Gajar Ko Halwa', price: 1600, unit: 'kg' }, { name: 'Gulab Jamun', price: 60 },
      { name: 'Rashbari', price: 60 }, { name: 'Sikarni', price: 50 }, { name: 'Ice Cream', onRequest: true },
    ])],
  },
  {
    title: 'Add-ons', kicker: 'Per plate · priced on request', column: 3, style: 'dark', sideBySide: true,
    groups: [
      one(['Veg Momo', 'Paneer Momo', 'Paneer Pakauda', 'Peanut Sadheko', 'Aloo Sadheko', 'Veg Tempura', 'French Fries / Baked Potatoes', 'Veg Sliders (small burger)'].map((name) => ({ name })), 'Veg'),
      one(['Chicken Roast', 'Chicken Sadheko', 'Chicken Choila', 'Chicken Nuggets', 'Chicken Chilly Boneless', 'Timmur Chicken', 'Fish Fry'].map((name) => ({ name })), 'Non Veg'),
    ],
  },
];

/* ---------- Plan your order copy (fetched from Sanity — see applyCateringPlanner) ---------- */
/* These defaults are shown if Sanity can't be reached. */
let PLANNER_COPY = {
  title: 'Get an estimate *in seconds.*',
  description: "Choose a package and headcount, then send it to us on WhatsApp. Add à la carte dishes in the same chat — we'll confirm the final total, date and delivery time.",
  notice: 'Estimates cover food only. Delivery charges vary by location; buffet service and crockery are available at extra cost.',
};

/* ---------- Calculator settings (fetched from Sanity — see applyCateringPlanner) ---------- */
/* These defaults are used if Sanity can't be reached. */
let SET_MIN_PAX = 15;
let ADVANCE_SHARE = 0.6;
let SMALL_ORDER_NOTE = "Under 15 guests, food is delivered in buckets at NPR 150 per bucket — we'll add this to your quote.";

/* ---------- Terms (fetched from Sanity — see applyCateringTerms) ---------- */
let TERMS_COPY = {
  title: 'Terms & *conditions.*',
  terms: [
    'All orders are accepted on a pre-order basis, with a minimum of 15 guests.',
    'A 60% advance confirms your booking; the balance is due upon delivery.',
    'For orders below 15 guests, food is delivered in buckets at NPR 150 per bucket.',
    'Delivery charges apply and vary by location.',
    'Buffet service, crockery and additional arrangements are available at an extra charge.',
    'Please do not reheat food directly in the hotcase; any damage will be charged at its full replacement cost.',
  ],
};
const rs = (v) => `Rs ${Number(v).toLocaleString('en-IN')}`;

function Eyebrow({ children }) {
  return <div className="cr-eyebrow"><span />{children}</div>;
}

/* ---------- Hero ---------- */
function CateringHero() {
  const h = CATERING_HERO;
  return (
    <section className="cr-hero">
      <div className="cr-wrap cr-hero-grid">
        <div>
          {h.tagline && <div className="cr-pill reveal"><span />{h.tagline}</div>}
          <h1 className="reveal" data-stagger="1"><Marked text={h.title} /></h1>
          <p className="cr-lede reveal" data-stagger="2">{h.description}</p>
          <div className="cr-ctas reveal" data-stagger="3">
            <a href="#packages" className="cr-btn cr-btn-primary">See packages</a>
            <a href="#menu" className="cr-btn cr-btn-line">Browse full menu</a>
          </div>
          {h.stats.length > 0 && (
            <div className="cr-stats reveal" data-stagger="3">
              {h.stats.map((st, i) => (
                <div key={i}><div className="v"><Marked text={st.value} /></div><div className="l">{st.label}</div></div>
              ))}
            </div>
          )}
        </div>
        <div className="cr-hero-photo reveal" data-stagger="2">
          <div className="frame"><img src={h.image} alt={h.imageAlt} /></div>
          {h.badgeTitle && (
            <div className="badge">
              <span className="ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="4" width="18" height="18" rx="2" /><path d="M16 2v4M8 2v4M3 10h18" /></svg></span>
              <span><strong>{h.badgeTitle}</strong>{h.badgeText}</span>
            </div>
          )}
        </div>
      </div>
    </section>
  );
}

function CuisineRibbon() {
  if (!CATERING_HERO.cuisines.length) return null;
  return (
    <div className="cr-ribbon">
      <div className="cr-wrap">
        {CATERING_HERO.cuisines.map((c, i) => (
          <React.Fragment key={c}>{i > 0 && <span className="dot" />}<span>{c}</span></React.Fragment>
        ))}
      </div>
    </div>
  );
}

/* ---------- Set packages ---------- */
function SlashText({ text }) {
  const parts = text.split('/').map((p) => p.trim());
  return parts.map((p, i) => <React.Fragment key={i}>{i > 0 && <span className="sl"> / </span>}{p}</React.Fragment>);
}
function PackagesSection({ onPick }) {
  const pick = (id) => () => onPick(id);
  return (
    <section id="packages" className="cr-section cr-white">
      <div className="cr-wrap">
        <Eyebrow>Set Packages</Eyebrow>
        <div className="cr-head">
          <h2><Marked text={PACKAGES_COPY.title} /></h2>
          <p>{PACKAGES_COPY.description}</p>
        </div>
        <div className="cr-pkgs">
          <article className="cr-pkg main">
            <div className="top">
              <div><div className="k">Package 01</div><h3>{MAIN_SET.name}</h3></div>
              <div className="price"><div className="n">{rs(MAIN_SET.price)}</div><div className="u">per person</div></div>
            </div>
            <ol>
              {MAIN_SET.items.map((it, i) => <li key={it}><span className="num">{i + 1}</span><span><SlashText text={it} /></span></li>)}
            </ol>
            <a href="#plan" className="cr-btn cr-pkg-cta" onClick={pick(MAIN_SET.id)}>Plan with this package →</a>
          </article>
          <article className="cr-pkg snacks">
            <div className="top">
              <div><div className="k">Package 02</div><h3>{SNACKS_SET.name}</h3></div>
              <div className="price"><div className="n">{rs(SNACKS_SET.price)}</div><div className="u">per person</div></div>
            </div>
            <div className="cols">
              {SNACKS_SET.groups.map((g, i) => (
                <div key={i}>
                  <div className={`tag${g.nonveg ? ' dark' : ''}`}>{g.nonveg ? 'Non-veg' : 'Veg'} · choose any {g.count}</div>
                  <ul>{g.opts.map((o) => <li key={o}>{o}</li>)}</ul>
                </div>
              ))}
            </div>
            <a href="#plan" className="cr-btn cr-pkg-cta" onClick={pick(SNACKS_SET.id)}>Plan with this package →</a>
          </article>
        </div>
      </div>
    </section>
  );
}

/* ---------- À la carte ---------- */
const slug = (text) => text.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
/* Gives each card a unique anchor id from its menu-bar label (or title). */
function withAnchors(cards) {
  const seen = {};
  return cards.map((c) => {
    const base = slug(c.navLabel || c.title) || 'card';
    seen[base] = (seen[base] || 0) + 1;
    return { ...c, anchor: seen[base] > 1 ? `${base}-${seen[base]}` : base };
  });
}
function MenuRow({ name, detail, price, unit, onRequest }) {
  const hasPrice = price != null;
  return (
    <li className="cr-row">
      <span className="nm">{name}{detail && <span className="dt"> {detail}</span>}</span>
      {(hasPrice || onRequest) && <span className="lead" />}
      {hasPrice && <span className="pr">{rs(price)}{unit && <span className="u"> / {unit.replace(/^per /, '')}</span>}</span>}
      {!hasPrice && onRequest && <span className="pr req">on request</span>}
    </li>
  );
}
function MenuCard({ card }) {
  const { anchor, kicker, title, groups, sideBySide, note, tags, style, image, imageAlt } = card;
  const tone = style && style !== 'plain' ? ` ${style}` : '';
  return (
    <div id={anchor} className={`cr-card${tone}`}>
      {image && <div className="ph"><img src={image} alt={imageAlt || ''} loading="lazy" /></div>}
      <div className="bd">
        {kicker && <div className="kick">{kicker}</div>}
        <h3>{title}</h3>
        {sideBySide ? (
          <div className="addon-cols">
            {groups.map((g, i) => (
              <div key={i}>
                {g.label && <div className="kick sub">{g.label}</div>}
                <ul>{g.items.map((it, j) => <li key={j}>{it.name}{it.detail ? ` ${it.detail}` : ''}</li>)}</ul>
              </div>
            ))}
          </div>
        ) : groups.map((g, i) => (
          <div key={i}>
            {g.label && <div className="kick sub">{g.label}</div>}
            <ul className="cr-list">{g.items.map((it, j) => <MenuRow key={j} {...it} />)}</ul>
          </div>
        ))}
        {note && <p className="nt">{note}</p>}
        {tags && tags.length > 0 && <div className="tags">{tags.map((t) => <span key={t}>{t}</span>)}</div>}
      </div>
    </div>
  );
}
function MenuSectionCatering() {
  const cards = withAnchors(MENU_CARDS);
  // Wide screens: fixed columns (as in the design), cards top to bottom in list order.
  const columns = [1, 2, 3].map((n) => cards.filter((c) => (c.column || 1) === n));
  return (
    <section id="menu" className="cr-section cr-menu">
      <div className="cr-wrap">
        <Eyebrow>À la carte</Eyebrow>
        <div className="cr-head">
          <h2><Marked text={MENU_COPY.title} /></h2>
          <p>{MENU_COPY.description}</p>
        </div>
      </div>
      <nav className="cr-chipnav" aria-label="Menu sections">
        <div className="cr-wrap">{cards.map((c) => <a key={c.anchor} href={`#${c.anchor}`}>{c.navLabel || c.title}</a>)}</div>
      </nav>
      <div className="cr-wrap cr-masonry">
        {columns.map((col, i) => (
          <div className="cr-col" key={i}>
            {col.map((c) => <MenuCard key={c.anchor} card={c} />)}
          </div>
        ))}
      </div>
    </section>
  );
}

/* ---------- Plan your order (quick estimate → WhatsApp) ---------- */
function Planner({ pkgId, setPkgId }) {
  const pkgs = [MAIN_SET, SNACKS_SET];
  const [guests, setGuests] = React.useState(25);
  const [date, setDate] = React.useState('');
  const pkg = pkgs.find((p) => p.id === pkgId);
  const n = Math.max(1, guests || 1);
  const sub = pkg.price * n;
  const adv = Math.round(sub * ADVANCE_SHARE);
  const msg = `Hi House of Swad, I'd like a catering quote.\nPackage: ${pkg.name} package (${rs(pkg.price)}/person)\nGuests: ${n}` + (date ? `\nDate: ${date}` : '') + `\nEstimate: ${rs(sub)}`;
  return (
    <section id="plan" className="cr-section">
      <div className="cr-wrap cr-plan">
        <div>
          <Eyebrow>Plan Your Order</Eyebrow>
          <h2 className="cr-h2"><Marked text={PLANNER_COPY.title} /></h2>
          <p className="cr-p">{PLANNER_COPY.description}</p>
          {PLANNER_COPY.notice && <div className="cr-callout"><span className="bang">!</span><span>{PLANNER_COPY.notice}</span></div>}
        </div>
        <div className="cr-plan-card">
          <div className="lbl">Package</div>
          <div className="seg" role="group" aria-label="Package">
            {pkgs.map((p) => (
              <button key={p.id} type="button" aria-pressed={p.id === pkgId} onClick={() => setPkgId(p.id)}>{p.name} · {rs(p.price)}</button>
            ))}
          </div>
          <div className="fields">
            <label>
              <span className="lbl">Guests</span>
              <span className="stepper">
                <button type="button" aria-label="Fewer guests" onClick={() => setGuests((g) => Math.max(1, g - 5))}>−</button>
                <input type="number" min="1" value={n} onChange={(e) => setGuests(parseInt(e.target.value, 10) || 1)} />
                <button type="button" aria-label="More guests" onClick={() => setGuests((g) => g + 5)}>+</button>
              </span>
            </label>
            <label>
              <span className="lbl">Event date</span>
              <input type="date" className="date" value={date} onChange={(e) => setDate(e.target.value)} />
            </label>
          </div>
          <div className="sum">
            <div><span>{n} guests × {rs(pkg.price)}</span><strong>{rs(sub)}</strong></div>
            <div><span>{Math.round(ADVANCE_SHARE * 100)}% advance to confirm</span><strong>{rs(adv)}</strong></div>
            <div className="bal"><span>Balance on delivery</span><strong>{rs(sub - adv)}</strong></div>
          </div>
          {n < SET_MIN_PAX && SMALL_ORDER_NOTE && <p className="warn">{SMALL_ORDER_NOTE}</p>}
          <a href={waLink(msg)} target="_blank" rel="noopener" className="cr-btn cr-btn-primary wide"><WAIcon /> Send enquiry on WhatsApp</a>
          <a href={`tel:${TEL}`} className="cr-call">or call {PHONE_LABEL}</a>
        </div>
      </div>
    </section>
  );
}

/* ---------- Terms ---------- */
function CateringTerms() {
  if (!TERMS_COPY.terms.length) return null;
  return (
    <section id="terms" className="cr-section cr-white">
      <div className="cr-wrap">
        <Eyebrow>Good to Know</Eyebrow>
        <h2 className="cr-h2 sm"><Marked text={TERMS_COPY.title} /></h2>
        <ol className="cr-terms">
          {TERMS_COPY.terms.map((t, i) => <li key={i}><span className="num">{String(i + 1).padStart(2, '0')}</span><span>{t}</span></li>)}
        </ol>
      </div>
    </section>
  );
}

/* ---------- App ---------- */
function CateringApp() {
  useReveal();
  const [pkgId, setPkgId] = React.useState(MAIN_SET.id);
  React.useEffect(() => {
    // Content mounts only after the Sanity fetch, so the browser's own
    // load-time anchor scroll has nothing to land on — redo it once here.
    const key = window.location.hash.replace('#', '');
    if (key) document.getElementById(key)?.scrollIntoView({ block: 'start' });
  }, []);
  return (
    <div style={{ minHeight: '100vh', background: 'var(--hos-warm-cream)' }}>
      <Header activeKey="catering" />
      <main className="cr-page">
        <CateringHero />
        <CuisineRibbon />
        <PackagesSection onPick={setPkgId} />
        <MenuSectionCatering />
        <Planner pkgId={pkgId} setPkgId={setPkgId} />
        <CateringTerms />
      </main>
      <Footer />
    </div>
  );
}

window.mountSwadCatering = function mountSwadCatering(rootEl) {
  fetch(CATERING_QUERY_URL).then((r) => r.json()).then(({ result }) => {
    applyCateringHero(result && result.hero);
    applyCateringPackages(result && result.packages);
    applyCateringMenu(result && result.menu);
    applyCateringPlanner(result && result.planner);
    applyCateringTerms(result && result.terms);
  }).catch(() => {}).then(() => {
    ReactDOM.createRoot(rootEl).render(<CateringApp />);
  });
};
