/* Simple forms: Rate Extension & General Request */
const { useState } = React;

// ---- Update Existing Rate Form ----
function RateExtensionForm({ onBack }) {
  const T = window.EMMA_TOKENS;
  const MOCK_HOTELS = window.EMMA_DATA.MOCK_HOTELS;
  const MEAL_PLANS = window.EMMA_DATA.MEAL_PLANS;
  const dowOpts = [{ code: "MO", label: "Mon" }, { code: "TU", label: "Tue" }, { code: "WE", label: "Wed" }, { code: "TH", label: "Thu" }, { code: "FR", label: "Fri" }, { code: "SA", label: "Sat" }, { code: "SU", label: "Sun" }];

  const [form, setForm] = useState({
    requesterName: "", requesterEmail: "",
    customerName: "", customerIds: [{ type: "", id: "" }], hotels: [],
    channels: [], lanyonManaged: "",
    currentRateRef: "", currentRateDates: "",
    reason: "",
    priceCodeType: "Dynamic Rate",
    rooms: [""], meals: [],
    hotelConfigs: {},
    hotelMatrices: {},
    seasons: [{ id: "S1", start: null, end: null, basedOnRate: "", discountPercent: "", dowFilter: ["MO", "TU", "WE", "TH", "FR", "SA", "SU"] }],
    activeSeasonId: "S1",
    matrix: {}, seasonMatrices: {},
    attachments: [], notes: "",
    acknowledged: false,
  });
  const [submitState, setSubmitState] = useState({ status: "idle", error: null, ticketId: null });
  const [submitted, setSubmitted] = useState(false);
  const upd = (patch) => setForm(f => ({ ...f, ...patch }));
  const updSeason = (id, patch) => upd({ seasons: form.seasons.map(s => s.id === id ? { ...s, ...patch } : s) });
  const addSeason = () => { const id = `S${String(form.seasons.length + 1)}`; upd({ seasons: [...form.seasons, { id, start: null, end: null, basedOnRate: "", discountPercent: "", dowFilter: ["MO", "TU", "WE", "TH", "FR", "SA", "SU"] }] }); };
  const removeSeason = (id) => { if (form.seasons.length > 1) upd({ seasons: form.seasons.filter(s => s.id !== id), activeSeasonId: form.seasons[0].id }); };
  const activeSeasonId = form.activeSeasonId || form.seasons[0]?.id || "S1";
  const activeSeason = form.seasons.find(s => s.id === activeSeasonId) || form.seasons[0];

  const buildHtml = (submissionId) => {
    const d = (v) => v || "—";
    const fmtDate = (v) => v ? window.fmt(v) : "—";
    const row = (label, value) => `<tr><th style="text-align:left;padding:6px 10px;color:#6B6B63;font-weight:500;width:180px;border-bottom:1px solid #E5E0D6">${label}</th><td style="padding:6px 10px;color:#1B1D1A;border-bottom:1px solid #E5E0D6">${d(value)}</td></tr>`;
    const hotelNames = form.hotels.map(id => { const h = MOCK_HOTELS.find(m => m.id === id); return h ? h.name : id; });
    const roomNames = form.rooms.filter(r => r.trim());
    const mealLabels = form.meals.map(c => { const m = MEAL_PLANS.find(x => x.code === c); return m ? m.label : c; });
    const dowLabels = { MO: "Mon", TU: "Tue", WE: "Wed", TH: "Thu", FR: "Fri", SA: "Sat", SU: "Sun" };

    let seasonsHtml = "";
    if (form.seasons.length) {
      seasonsHtml = `<table style="width:100%;border-collapse:collapse;border:1px solid #E5E0D6;margin-top:8px">
        <thead><tr>
          <th style="padding:8px 10px;text-align:left;font-size:11px;font-weight:600;color:#6B6B63;border-bottom:2px solid #E5E0D6;background:#F4F1EB">Dates</th>
          <th style="padding:8px 10px;text-align:left;font-size:11px;font-weight:600;color:#6B6B63;border-bottom:2px solid #E5E0D6;background:#F4F1EB">Based on</th>
          <th style="padding:8px 10px;text-align:right;font-size:11px;font-weight:600;color:#6B6B63;border-bottom:2px solid #E5E0D6;background:#F4F1EB">Discount</th>
          <th style="padding:8px 10px;text-align:left;font-size:11px;font-weight:600;color:#6B6B63;border-bottom:2px solid #E5E0D6;background:#F4F1EB">Days</th>
        </tr></thead><tbody>`;
      form.seasons.forEach(s => {
        const days = (s.dowFilter || []).map(d => dowLabels[d] || d).join(", ") || "All";
        seasonsHtml += `<tr>
          <td style="padding:6px 10px;font-size:13px;border-bottom:1px solid #E5E0D6">${fmtDate(s.start)} → ${fmtDate(s.end)}</td>
          <td style="padding:6px 10px;font-size:13px;border-bottom:1px solid #E5E0D6">${d(s.basedOnRate)}</td>
          <td style="padding:6px 10px;font-size:13px;text-align:right;font-family:monospace;border-bottom:1px solid #E5E0D6">${d(s.discountPercent)}%</td>
          <td style="padding:6px 10px;font-size:11px;border-bottom:1px solid #E5E0D6">${days}</td>
        </tr>`;
      });
      seasonsHtml += `</tbody></table>`;
    }

    return `<div style="font-family:Inter,sans-serif;color:#1B1D1A;max-width:680px;margin:0 auto">
      <div style="background:#5B6E4E;color:#fff;padding:20px 24px;border-radius:8px 8px 0 0">
        <h1 style="margin:0;font-size:20px;font-weight:600">Update Existing Rate</h1>
        <p style="margin:6px 0 0;font-size:13px;opacity:0.85">Reference: <strong>${submissionId}</strong> · Submitted ${new Date().toLocaleString("en-GB", { dateStyle: "medium", timeStyle: "short" })}</p>
      </div>
      <div style="padding:24px;background:#fff;border:1px solid #E5E0D6;border-top:none;border-radius:0 0 8px 8px">
        <div style="margin-bottom:20px"><div style="font-size:14px;font-weight:700;color:#5B6E4E;text-transform:uppercase;border-bottom:2px solid #5B6E4E;padding-bottom:6px;margin-bottom:12px">Requester</div>
          <table style="width:100%;border-collapse:collapse;font-size:13px">${row("Name", form.requesterName)}${row("Email", form.requesterEmail)}</table></div>
        <div style="margin-bottom:20px"><div style="font-size:14px;font-weight:700;color:#5B6E4E;text-transform:uppercase;border-bottom:2px solid #5B6E4E;padding-bottom:6px;margin-bottom:12px">Current Rate</div>
          <table style="width:100%;border-collapse:collapse;font-size:13px">${row("Customer", form.customerName)}${(form.customerIds || []).filter(c => c.id).length ? row("Customer ID(s)", (form.customerIds || []).filter(c => c.id).map(c => `${c.type || "ID"}: ${c.id}`).join(", ")) : ""}${row("Hotels", hotelNames.join(", ") || "—")}${row("Channels", (form.channels || []).map(c => ({ DIRECT: "Hotel Direct", WEB: "Hotel Website", GDS: "GDS" }[c] || c)).join(", ") || "—")}${(form.channels || []).includes("GDS") ? row("Lanyon managed RFP", form.lanyonManaged || "Not answered") : ""}${row("Rate reference", form.currentRateRef)}${row("Reason for update", form.reason)}</table></div>
        <div style="margin-bottom:20px"><div style="font-size:14px;font-weight:700;color:#5B6E4E;text-transform:uppercase;border-bottom:2px solid #5B6E4E;padding-bottom:6px;margin-bottom:12px">Updated Pricing</div>
          <table style="width:100%;border-collapse:collapse;font-size:13px">${row("Pricing type", form.priceCodeType || "—")}${row("Room types", roomNames.join(", ") || "—")}${row("Meal plans", mealLabels.join(", ") || "—")}</table>
          ${seasonsHtml}</div>
        <div><div style="font-size:14px;font-weight:700;color:#5B6E4E;text-transform:uppercase;border-bottom:2px solid #5B6E4E;padding-bottom:6px;margin-bottom:12px">Attachments & Notes</div>
          <table style="width:100%;border-collapse:collapse;font-size:13px">${row("Attachments", form.attachments.length ? form.attachments.map(a => a.name).join(", ") : "None")}${row("Notes", form.notes || "None")}</table></div>
      </div></div>`;
  };

  const submit = async () => {
    const submissionId = `UPD-${new Date().toISOString().slice(0,10).replace(/-/g,"")}-${Math.random().toString(36).slice(2,7).toUpperCase()}`;
    setSubmitState({ status: "submitting", error: null, ticketId: null });
    const hotelNames = form.hotels.map(id => { const h = MOCK_HOTELS.find(m => m.id === id); return h ? h.name : id; });
    const payload = {
      submissionId,
      submittedAt: new Date().toISOString(),
      requesterName: form.requesterName,
      requesterEmail: form.requesterEmail,
      subject: `Update Existing Rate: ${form.customerName || "Customer"} — ${hotelNames[0] || "Hotel"}${hotelNames.length > 1 ? ` +${hotelNames.length - 1}` : ""} [${submissionId}]`,
      ticketType: "Update Existing Rate",
      htmlBody: buildHtml(submissionId),
    };
    const filePromises = (form.attachments || []).filter(a => a._file).map(a =>
      new Promise(resolve => { const r = new FileReader(); r.onload = () => resolve({ name: a.name, type: a.type, data: r.result.split(",")[1] }); r.onerror = () => resolve(null); r.readAsDataURL(a._file); })
    );
    const files = (await Promise.all(filePromises)).filter(Boolean);
    try {
      const endpoint = window.SUBMIT_ENDPOINT;
      if (endpoint) {
        const res = await fetch(endpoint, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload) });
        const result = await res.json().catch(() => ({}));
        if (!res.ok) throw new Error(result.error || `Server error ${res.status}`);
        if (files.length && result.freshdeskTicketId) {
          for (const file of files) {
            try { await fetch(endpoint, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ action: "attach", freshdeskTicketId: result.freshdeskTicketId, file }) }); } catch (e) { console.warn(`Failed to attach ${file.name}:`, e.message); }
          }
        }
        setSubmitState({ status: "ok", error: null, ticketId: result.ticketId || submissionId });
      } else {
        await new Promise(r => setTimeout(r, 900));
        setSubmitState({ status: "ok", error: null, ticketId: submissionId });
      }
      setSubmitted(true);
    } catch (e) { setSubmitState({ status: "error", error: e.message, ticketId: null }); }
  };

  if (submitted) return (
    <SuccessScreen ticketId={submitState.ticketId} label="Update Existing Rate" email={form.requesterEmail} onReset={() => { setForm({ requesterName: "", requesterEmail: "", customerName: "", customerIds: [{ type: "", id: "" }], hotels: [], channels: [], lanyonManaged: "", currentRateRef: "", currentRateDates: "", reason: "", priceCodeType: "Dynamic Rate", rooms: [""], meals: [], hotelConfigs: {}, hotelMatrices: {}, seasons: [{ id: "S1", start: null, end: null, basedOnRate: "", discountPercent: "", dowFilter: ["MO", "TU", "WE", "TH", "FR", "SA", "SU"] }], activeSeasonId: "S1", matrix: {}, seasonMatrices: {}, attachments: [], notes: "", acknowledged: false }); setSubmitted(false); }} onBack={onBack} />
  );

  return (
    <FormShell title="Update Existing Rate" subtitle="Modify pricing, dates, or terms on a rate already loaded in the system" onBack={onBack}>
      <window.SectionHeader title="Requester" />
      <window.Grid>
        <window.Field label="Your name" required span={6}><window.TextField value={form.requesterName} onChange={v => upd({ requesterName: v })} placeholder="Full name" /></window.Field>
        <window.Field label="Email" required span={6}><window.TextField value={form.requesterEmail} onChange={v => upd({ requesterEmail: v })} placeholder="name@axiomhospitality.com" type="email" /></window.Field>
      </window.Grid>

      <window.SectionHeader title="Current rate" subtitle="Identify the rate to update" />
      <window.Grid>
        <window.Field label="Customer / company name" required span={6}><window.TextField value={form.customerName} onChange={v => upd({ customerName: v })} placeholder="e.g. Bluepeak Consulting" /></window.Field>
        <window.Field label="Customer ID(s)" span={6} hint="Add one or more IDs">
          <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
            {(form.customerIds && form.customerIds.length ? form.customerIds : [{ type: "", id: "" }]).map((cid, i) => (
              <div key={i} style={{ display: "flex", gap: 8, alignItems: "center" }}>
                <div style={{ minWidth: 130 }}>
                  <window.Select value={cid.type} onChange={v => { const next = [...(form.customerIds || [{ type: "", id: "" }])]; next[i] = { ...next[i], type: v }; upd({ customerIds: next }); }} options={["PCR", "IATA", "Emma Client ID"]} placeholder="ID type…" />
                </div>
                <div style={{ flex: 1 }}>
                  <window.TextField value={cid.id} onChange={v => { const next = [...(form.customerIds || [{ type: "", id: "" }])]; next[i] = { ...next[i], id: v }; upd({ customerIds: next }); }} placeholder={cid.type ? `Enter ${cid.type}` : "Select type first"} mono />
                </div>
                {(form.customerIds || []).length > 1 && (
                  <button type="button" onClick={() => upd({ customerIds: (form.customerIds || []).filter((_, idx) => idx !== i) })} style={{ background: "transparent", border: `1px solid ${T.border}`, color: T.muted, padding: "4px 8px", borderRadius: 4, fontSize: 12, cursor: "pointer" }}>×</button>
                )}
              </div>
            ))}
            <button type="button" onClick={() => upd({ customerIds: [...(form.customerIds || [{ type: "", id: "" }]), { type: "", id: "" }] })} style={{ alignSelf: "flex-start", background: "transparent", border: `1px dashed ${T.border}`, color: T.accent, padding: "5px 12px", borderRadius: 4, fontSize: 11.5, cursor: "pointer", fontWeight: 600 }}>+ Add another ID</button>
          </div>
        </window.Field>
        <window.Field label="Current rate reference" span={6} hint="Rate code, contract code, or description"><window.TextField value={form.currentRateRef} onChange={v => upd({ currentRateRef: v })} placeholder="e.g. BLPK-26-NEG or 'Bluepeak Corporate 2026'" /></window.Field>
        <window.Field label="Hotels" required span={12}>
          <window.ChipMultiSelect options={MOCK_HOTELS.map(h => ({ code: h.id, label: h.name }))} value={form.hotels} onChange={v => upd({ hotels: v })} />
        </window.Field>
        <window.Field label="Channels" required span={12} hint="Where this rate will be distributed">
          <window.ChipMultiSelect
            options={[{ code: "DIRECT", label: "Hotel Direct" }, { code: "WEB", label: "Hotel Website" }, { code: "GDS", label: "GDS" }]}
            value={form.channels || []}
            onChange={(v) => upd({ channels: v })}
          />
          {(form.channels || []).includes("GDS") && (
            <div style={{ display: "flex", flexDirection: "column", gap: 10, marginTop: 10 }}>
              <div style={{ padding: "10px 14px", background: "#FBF1D9", border: "1px solid #E2C77E", borderRadius: 6, fontSize: 12.5, color: "#7A5A0B", lineHeight: 1.55 }}>
                <strong>GDS selected:</strong> GDS loading can take up to <strong>5 working days</strong>. Please ensure GDS loading instructions are uploaded in the <strong>Files</strong> section before submitting.
              </div>
              <window.Field label="Is the RFP for this account managed in Lanyon?" required>
                <div style={{ display: "flex", gap: 10 }}>
                  {["Yes", "No"].map(opt => (
                    <label key={opt} onClick={() => upd({ lanyonManaged: opt })} style={{
                      flex: 1, padding: 12, borderRadius: 6, cursor: "pointer", textAlign: "center",
                      border: `1.5px solid ${form.lanyonManaged === opt ? T.accent : T.border}`,
                      background: form.lanyonManaged === opt ? T.accentSoft : T.surface,
                      fontSize: 13, fontWeight: form.lanyonManaged === opt ? 600 : 500, color: T.ink,
                    }}>{opt}</label>
                  ))}
                </div>
              </window.Field>
            </div>
          )}
        </window.Field>
        <window.Field label="Reason for update" required span={12}><window.TextArea value={form.reason} onChange={v => upd({ reason: v })} rows={2} placeholder="e.g. Annual renewal at +3%, mid-year amendment, extend validity 6 months" /></window.Field>
      </window.Grid>

      <window.SectionHeader title="Updated pricing" subtitle="Select pricing type and define room types, meal plans, and seasons" />
      <div style={{ padding: "10px 14px", background: "#FBF1D9", border: "1px solid #E2C77E", borderRadius: 6, fontSize: 12.5, color: "#7A5A0B", lineHeight: 1.55, marginBottom: 4 }}>
        <strong>Please note:</strong> Rates entered here will override current pricing seasons. Please only use applicable date ranges.
      </div>

      {!form.hotels.length && (
        <div style={{ padding: "20px 24px", background: "#FBF1D9", border: "1px solid #E2C77E", borderRadius: 8, textAlign: "center" }}>
          <div style={{ fontSize: 14, fontWeight: 600, color: "#7A5A0B", marginBottom: 6 }}>No hotels selected</div>
          <div style={{ fontSize: 13, color: "#7A5A0B", lineHeight: 1.5 }}>Please select at least one hotel above before setting up pricing.</div>
        </div>
      )}

      {form.hotels.length > 0 && (<>

      {/* Dynamic / Static selector */}
      <window.Field label="Pricing type" required>
        <div style={{ display: "flex", gap: 14, marginTop: 4 }}>
          {["Dynamic Rate", "Static Rate"].map(t => (
            <label key={t} style={{
              flex: 1, padding: 14, borderRadius: 8, cursor: "pointer",
              border: `1.5px solid ${form.priceCodeType === t ? T.accent : T.border}`,
              background: form.priceCodeType === t ? T.accentSoft : T.surface,
            }} onClick={() => upd({ priceCodeType: t })}>
              <div style={{ display: "flex", alignItems: "flex-start", gap: 10 }}>
                <div style={{ marginTop: 1 }}><window.Radio checked={form.priceCodeType === t} label="" /></div>
                <div>
                  <div style={{ fontSize: 13.5, fontWeight: 600, color: T.ink }}>{t}</div>
                  <div style={{ fontSize: 12, color: T.muted, marginTop: 3, lineHeight: 1.45 }}>
                    {t === "Dynamic Rate" ? "Percentage discount off a base rate. Same discount applies to all room types." : "Static prices per room × meal × occupancy."}
                  </div>
                </div>
              </div>
            </label>
          ))}
        </div>
      </window.Field>

      {/* Per-hotel config */}
      {(() => {
        const isMultiHotel = form.hotels.length > 1;
        const hc = form.hotelConfigs || {};
        const getHC = (hid) => hc[hid] || { rooms: [""], meals: [] };
        const setHC = (hid, patch) => upd({ hotelConfigs: { ...hc, [hid]: { ...getHC(hid), ...patch } } });
        const copyToAll = (srcId) => {
          const src = getHC(srcId);
          const next = { ...hc };
          form.hotels.forEach(h => { next[h] = { ...src }; });
          upd({ hotelConfigs: next });
        };
        const hMatrices = form.hotelMatrices || {};

        const renderRoomsMeals = (rooms, meals, setRooms, setMeals) => (
          <>
            <window.Field label="Room types" required hint="Add up to 8 room types">
              <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                {(rooms.length ? rooms : [""]).map((rt, i) => (
                  <div key={i} style={{ display: "flex", alignItems: "center", gap: 8 }}>
                    <span style={{ fontFamily: T.mono, fontSize: 11, fontWeight: 700, color: T.faint, minWidth: 20 }}>{i + 1}</span>
                    <div style={{ flex: 1 }}>
                      <window.TextField value={rt} onChange={v => { const next = [...rooms]; next[i] = v; setRooms(next); }} placeholder={`Room type ${i + 1} — e.g. Standard Double, Superior King`} />
                    </div>
                    {rooms.length > 1 && (
                      <button type="button" onClick={() => setRooms(rooms.filter((_, idx) => idx !== i))} style={{ background: "transparent", border: `1px solid ${T.border}`, color: T.muted, padding: "4px 8px", borderRadius: 4, fontSize: 12, cursor: "pointer" }}>×</button>
                    )}
                  </div>
                ))}
                {rooms.length < 8 && (
                  <button type="button" onClick={() => setRooms([...rooms, ""])} style={{ alignSelf: "flex-start", background: "transparent", border: `1px dashed ${T.border}`, color: T.accent, padding: "6px 14px", borderRadius: 4, fontSize: 12, cursor: "pointer", fontWeight: 600 }}>+ Add room type</button>
                )}
              </div>
            </window.Field>
            <window.Field label="Meal plans" required>
              <window.ChipMultiSelect options={MEAL_PLANS} value={meals} onChange={setMeals} />
            </window.Field>
          </>
        );

        return (
          <>
            {/* Single hotel */}
            {!isMultiHotel && renderRoomsMeals(
              form.rooms, form.meals,
              (r) => upd({ rooms: r }),
              (m) => upd({ meals: m })
            )}

            {/* Multi-hotel: stacked */}
            {isMultiHotel && (
              <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
                {form.hotels.map((hid, hi) => {
                  const hotel = MOCK_HOTELS.find(h => h.id === hid);
                  const cfg = getHC(hid);
                  return (
                    <div key={hid} style={{ border: `1px solid ${T.border}`, borderRadius: 8 }}>
                      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "10px 14px", background: "#E4EFEC", borderBottom: `1px solid ${T.border}`, borderRadius: "8px 8px 0 0" }}>
                        <div style={{ display: "flex", alignItems: "baseline", gap: 8 }}>
                          <span style={{ fontFamily: T.mono, fontSize: 11, color: T.faint }}>{hid}</span>
                          <span style={{ fontSize: 14, fontWeight: 600, color: T.ink }}>{hotel?.name || hid}</span>
                        </div>
                        {hi === 0 && form.hotels.length > 1 && (
                          <button type="button" onClick={() => copyToAll(hid)} style={{ background: "transparent", border: `1px solid ${T.border}`, color: T.accentInk, padding: "3px 10px", borderRadius: 4, fontSize: 11, cursor: "pointer", fontWeight: 600 }}>Copy to all hotels</button>
                        )}
                      </div>
                      <div style={{ padding: 16, display: "flex", flexDirection: "column", gap: 14 }}>
                        {renderRoomsMeals(
                          cfg.rooms, cfg.meals,
                          (r) => setHC(hid, { rooms: r }),
                          (m) => setHC(hid, { meals: m })
                        )}

                        {/* Static Rate: per-hotel pricing grids */}
                        {form.priceCodeType === "Static Rate" && form.seasons.map((s, si) => {
                          const sMatrix = (hMatrices[hid] || {})[s.id] || {};
                          const setSMatrix = (m) => upd({ hotelMatrices: { ...hMatrices, [hid]: { ...(hMatrices[hid] || {}), [s.id]: m } } });
                          return (
                            <div key={s.id} style={{ border: `1px solid ${T.border}`, borderRadius: 6 }}>
                              <div style={{ padding: "8px 12px", background: T.surface2, borderBottom: `1px solid ${T.border}`, fontSize: 12, fontWeight: 600, color: T.accentInk }}>
                                Season {si + 1} {s.start && s.end ? `· ${window.fmt(s.start)} → ${window.fmt(s.end)}` : ""}
                              </div>
                              <div style={{ padding: 2 }}>
                                <window.PricingMatrix
                                  priceCodeType={form.priceCodeType}
                                  rooms={cfg.rooms.filter(r => r.trim())}
                                  meals={cfg.meals}
                                  matrix={sMatrix}
                                  onChange={setSMatrix}
                                  currency="GBP"
                                />
                              </div>
                            </div>
                          );
                        })}
                      </div>
                    </div>
                  );
                })}
              </div>
            )}
          </>
        );
      })()}

      {/* Dynamic Rate: season cards with discount % and day-of-week */}
      {form.priceCodeType === "Dynamic Rate" && (
        <>
          <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginTop: 8 }}>
            <window.Label hint="Each season can have its own discount and day-of-week rules. Use the same date range with different days for midweek/weekend splits.">Pricing seasons</window.Label>
          </div>
          {(() => {
            const overlaps = [];
            for (let i = 0; i < form.seasons.length; i++) {
              for (let j = i + 1; j < form.seasons.length; j++) {
                const a = form.seasons[i], b = form.seasons[j];
                if (a.start && a.end && b.start && b.end && a.start <= b.end && b.start <= a.end) {
                  const aDow = a.dowFilter || [], bDow = b.dowFilter || [];
                  if (aDow.some(d => bDow.includes(d))) overlaps.push(`${a.id} & ${b.id}`);
                }
              }
            }
            return overlaps.length ? (
              <div style={{ padding: "10px 14px", background: "#FBE5E0", border: "1px solid #E5BAAF", borderRadius: 6, fontSize: 12.5, color: "#7A2415", lineHeight: 1.55 }}>
                <strong>Overlap detected:</strong> {overlaps.join(", ")} have overlapping dates and days of week.
              </div>
            ) : null;
          })()}
          <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
            {form.seasons.map((s, i) => (
              <div key={s.id} style={{ background: T.surface, border: `1px solid ${T.border}`, borderRadius: 8, padding: 16 }}>
                <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 12 }}>
                  <span style={{ fontFamily: T.mono, fontSize: 11, fontWeight: 700, color: T.accent, background: T.accentSoft, padding: "2px 8px", borderRadius: 4 }}>Season {i + 1}</span>
                  {form.seasons.length > 1 && (
                    <button type="button" onClick={() => removeSeason(s.id)} style={{ background: "transparent", border: `1px solid ${T.border}`, color: T.muted, padding: "3px 8px", borderRadius: 4, fontSize: 11, cursor: "pointer" }}>Remove</button>
                  )}
                </div>
                <window.Grid gap={12}>
                  <window.Field label="Season dates" required span={6}>
                    <window.DateRangeField start={s.start} end={s.end} onChange={(st, en) => updSeason(s.id, { start: st, end: en })} />
                  </window.Field>
                  <window.Field label="Based on rate" span={6}><window.TextField value={s.basedOnRate || ""} onChange={v => updSeason(s.id, { basedOnRate: v })} placeholder="e.g. BAR, Best Flexible Rate" /></window.Field>
                  <window.Field label="Percentage discount" required span={6}><window.TextField value={s.discountPercent || ""} onChange={v => updSeason(s.id, { discountPercent: v })} placeholder="e.g. -10" suffix="%" mono /></window.Field>
                  <window.Field label="Days of week" span={12}>
                    <window.ChipMultiSelect options={dowOpts} value={s.dowFilter || ["MO", "TU", "WE", "TH", "FR", "SA", "SU"]} onChange={v => updSeason(s.id, { dowFilter: v })} />
                  </window.Field>
                </window.Grid>
              </div>
            ))}
          </div>
          <button type="button" onClick={addSeason} style={{ background: "transparent", border: `1px dashed ${T.border}`, color: T.accent, padding: "10px 18px", borderRadius: 6, fontSize: 13, cursor: "pointer", fontWeight: 600, marginTop: 8, width: "100%" }}>+ Add season</button>
        </>
      )}

      {/* Static Rate: stacked seasons with pricing matrices (single hotel only) */}
      {form.priceCodeType === "Static Rate" && form.hotels.length === 1 && (
        <>
          <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginTop: 8 }}>
            <window.Label hint="Each season holds its own fixed amounts">Pricing seasons</window.Label>
          </div>
          {(() => {
            const overlaps = [];
            for (let i = 0; i < form.seasons.length; i++) {
              for (let j = i + 1; j < form.seasons.length; j++) {
                const a = form.seasons[i], b = form.seasons[j];
                if (a.start && a.end && b.start && b.end && a.start <= b.end && b.start <= a.end) overlaps.push(`${a.id} & ${b.id}`);
              }
            }
            return overlaps.length ? (
              <div style={{ padding: "10px 14px", background: "#FBE5E0", border: "1px solid #E5BAAF", borderRadius: 6, fontSize: 12.5, color: "#7A2415", lineHeight: 1.55 }}>
                <strong>Date overlap detected:</strong> {overlaps.join(", ")} have overlapping date ranges.
              </div>
            ) : null;
          })()}
          <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
            {form.seasons.map((s, i) => {
              const sMatrix = form.seasonMatrices?.[s.id] || (i === 0 ? form.matrix : {}) || {};
              const setSMatrix = (m) => upd({ seasonMatrices: { ...(form.seasonMatrices || {}), [s.id]: m }, ...(i === 0 ? { matrix: m } : {}) });
              return (
                <div key={s.id} style={{ border: `1px solid ${T.border}`, borderRadius: 8 }}>
                  <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "10px 14px", background: T.accentSoft, borderBottom: `1px solid ${T.border}` }}>
                    <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                      <span style={{ fontFamily: T.mono, fontSize: 11, fontWeight: 700, color: T.accent }}>Season {i + 1}</span>
                      <div style={{ minWidth: 240 }}>
                        <window.DateRangeField start={s.start} end={s.end} onChange={(st, en) => updSeason(s.id, { start: st, end: en })} />
                      </div>
                      {s.start && s.end && (
                        <span style={{ fontSize: 12, color: T.accentInk, fontWeight: 500 }}>{window.fmt(s.start)} → {window.fmt(s.end)}</span>
                      )}
                    </div>
                    {form.seasons.length > 1 && (
                      <button type="button" onClick={() => removeSeason(s.id)} style={{ background: "transparent", border: `1px solid ${T.border}`, color: T.muted, padding: "3px 8px", borderRadius: 4, fontSize: 11, cursor: "pointer" }}>Remove</button>
                    )}
                  </div>
                  <div style={{ padding: 2 }}>
                    <window.PricingMatrix
                      priceCodeType={form.priceCodeType}
                      rooms={form.rooms.filter(r => r.trim())}
                      meals={form.meals}
                      matrix={sMatrix}
                      onChange={setSMatrix}
                      currency="GBP"
                    />
                  </div>
                </div>
              );
            })}
          </div>
          <button type="button" onClick={addSeason} style={{ background: "transparent", border: `1px dashed ${T.border}`, color: T.accent, padding: "10px 18px", borderRadius: 6, fontSize: 13, cursor: "pointer", fontWeight: 600, marginTop: 8, width: "100%" }}>+ Add season</button>
        </>
      )}

      {/* Multi-hotel Static Rate: season date management (grids are in hotel sections) */}
      {form.priceCodeType === "Static Rate" && form.hotels.length > 1 && (
        <>
          <window.Label hint="Season dates are shared across hotels — pricing per hotel is set above">Pricing seasons</window.Label>
          <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
            {form.seasons.map((s, i) => (
              <div key={s.id} style={{ display: "flex", alignItems: "center", gap: 10, padding: "10px 14px", background: T.surface, border: `1px solid ${T.border}`, borderRadius: 6 }}>
                <span style={{ fontFamily: T.mono, fontSize: 11, fontWeight: 700, color: T.accent }}>Season {i + 1}</span>
                <div style={{ minWidth: 240 }}>
                  <window.DateRangeField start={s.start} end={s.end} onChange={(st, en) => updSeason(s.id, { start: st, end: en })} />
                </div>
                {form.seasons.length > 1 && (
                  <button type="button" onClick={() => removeSeason(s.id)} style={{ background: "transparent", border: `1px solid ${T.border}`, color: T.muted, padding: "3px 8px", borderRadius: 4, fontSize: 11, cursor: "pointer", marginLeft: "auto" }}>Remove</button>
                )}
              </div>
            ))}
          </div>
          <button type="button" onClick={addSeason} style={{ background: "transparent", border: `1px dashed ${T.border}`, color: T.accent, padding: "10px 18px", borderRadius: 6, fontSize: 13, cursor: "pointer", fontWeight: 600, marginTop: 8, width: "100%" }}>+ Add season</button>
        </>
      )}

      </>)}

      <window.SectionHeader title="Files & notes" />
      <window.Field label="Attachments"><window.Attachments files={form.attachments} onChange={a => upd({ attachments: a })} /></window.Field>
      <window.Field label="Notes for the load team"><window.TextArea value={form.notes} onChange={v => upd({ notes: v })} rows={2} placeholder="Anything else…" /></window.Field>

      <div style={{ marginTop: 20 }}>
        <window.Checkbox checked={form.acknowledged} onChange={v => upd({ acknowledged: v })} label={<span style={{ fontWeight: 600 }}>I confirm the details above are correct</span>} />
      </div>
      <div style={{ display: "flex", justifyContent: "flex-end", marginTop: 16 }}>
        <window.Button variant="primary" disabled={!form.acknowledged || !form.requesterName || !form.requesterEmail || !form.customerName || !form.reason || submitState.status === "submitting"} onClick={submit}>
          {submitState.status === "submitting" ? "Submitting…" : "Submit update request"}
        </window.Button>
      </div>
      {submitState.status === "error" && <div style={{ marginTop: 10, padding: "10px 14px", background: "#FBE5E0", border: "1px solid #E5BAAF", borderRadius: 6, fontSize: 12.5, color: "#7A2415" }}>Failed: {submitState.error}</div>}
    </FormShell>
  );
}

// ---- General Request Form ----
function GeneralRequestForm({ onBack }) {
  const T = window.EMMA_TOKENS;
  const MOCK_HOTELS = window.EMMA_DATA.MOCK_HOTELS;
  const [form, setForm] = useState({
    requesterName: "", requesterEmail: "",
    hotels: [],
    subject: "", message: "",
    attachments: [], acknowledged: false,
  });
  const [submitState, setSubmitState] = useState({ status: "idle", error: null, ticketId: null });
  const [submitted, setSubmitted] = useState(false);
  const upd = (patch) => setForm(f => ({ ...f, ...patch }));

  const buildHtml = (submissionId) => {
    const d = (v) => v || "—";
    const row = (label, value) => `<tr><th style="text-align:left;padding:6px 10px;color:#6B6B63;font-weight:500;width:180px;border-bottom:1px solid #E5E0D6">${label}</th><td style="padding:6px 10px;color:#1B1D1A;border-bottom:1px solid #E5E0D6">${d(value)}</td></tr>`;
    const hotelNames = form.hotels.map(id => { const h = MOCK_HOTELS.find(m => m.id === id); return h ? h.name : id; });
    return `<div style="font-family:Inter,sans-serif;color:#1B1D1A;max-width:680px;margin:0 auto">
      <div style="background:#6B5B3E;color:#fff;padding:20px 24px;border-radius:8px 8px 0 0">
        <h1 style="margin:0;font-size:20px;font-weight:600">General Request</h1>
        <p style="margin:6px 0 0;font-size:13px;opacity:0.85">Reference: <strong>${submissionId}</strong> · Submitted ${new Date().toLocaleString("en-GB", { dateStyle: "medium", timeStyle: "short" })}</p>
      </div>
      <div style="padding:24px;background:#fff;border:1px solid #E5E0D6;border-top:none;border-radius:0 0 8px 8px">
        <div style="margin-bottom:20px"><div style="font-size:14px;font-weight:700;color:#6B5B3E;text-transform:uppercase;border-bottom:2px solid #6B5B3E;padding-bottom:6px;margin-bottom:12px">Requester</div>
          <table style="width:100%;border-collapse:collapse;font-size:13px">${row("Name", form.requesterName)}${row("Email", form.requesterEmail)}${row("Hotels", hotelNames.join(", ") || "—")}</table></div>
        <div style="margin-bottom:20px"><div style="font-size:14px;font-weight:700;color:#0E5E55;text-transform:uppercase;border-bottom:2px solid #0E5E55;padding-bottom:6px;margin-bottom:12px">Request</div>
          <table style="width:100%;border-collapse:collapse;font-size:13px">${row("Subject", form.subject)}</table>
          <div style="margin-top:12px;padding:14px;background:#F4F1EB;border-radius:6px;font-size:13px;line-height:1.6;white-space:pre-wrap">${d(form.message)}</div></div>
        <div><div style="font-size:14px;font-weight:700;color:#0E5E55;text-transform:uppercase;border-bottom:2px solid #0E5E55;padding-bottom:6px;margin-bottom:12px">Attachments</div>
          <table style="width:100%;border-collapse:collapse;font-size:13px">${row("Files", form.attachments.length ? form.attachments.map(a => a.name).join(", ") : "None")}</table></div>
      </div></div>`;
  };

  const submit = async () => {
    const submissionId = `GEN-${new Date().toISOString().slice(0,10).replace(/-/g,"")}-${Math.random().toString(36).slice(2,7).toUpperCase()}`;
    setSubmitState({ status: "submitting", error: null, ticketId: null });
    const payload = {
      submissionId,
      submittedAt: new Date().toISOString(),
      requesterName: form.requesterName,
      requesterEmail: form.requesterEmail,
      subject: `General Request: ${form.subject || "No subject"} [${submissionId}]`,
      ticketType: "General Request",
      htmlBody: buildHtml(submissionId),
    };
    const filePromises = (form.attachments || []).filter(a => a._file).map(a =>
      new Promise(resolve => { const r = new FileReader(); r.onload = () => resolve({ name: a.name, type: a.type, data: r.result.split(",")[1] }); r.onerror = () => resolve(null); r.readAsDataURL(a._file); })
    );
    const files = (await Promise.all(filePromises)).filter(Boolean);
    try {
      const endpoint = window.SUBMIT_ENDPOINT;
      if (endpoint) {
        const res = await fetch(endpoint, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload) });
        const result = await res.json().catch(() => ({}));
        if (!res.ok) throw new Error(result.error || `Server error ${res.status}`);
        if (files.length && result.freshdeskTicketId) {
          for (const file of files) {
            try { await fetch(endpoint, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ action: "attach", freshdeskTicketId: result.freshdeskTicketId, file }) }); } catch (e) { console.warn(`Failed to attach ${file.name}:`, e.message); }
          }
        }
        setSubmitState({ status: "ok", error: null, ticketId: result.ticketId || submissionId });
      } else {
        await new Promise(r => setTimeout(r, 900));
        setSubmitState({ status: "ok", error: null, ticketId: submissionId });
      }
      setSubmitted(true);
    } catch (e) { setSubmitState({ status: "error", error: e.message, ticketId: null }); }
  };

  if (submitted) return (
    <SuccessScreen ticketId={submitState.ticketId} label="General Request" email={form.requesterEmail} onReset={() => { setForm({ requesterName: "", requesterEmail: "", hotels: [], subject: "", message: "", attachments: [], acknowledged: false }); setSubmitted(false); }} onBack={onBack} />
  );

  return (
    <FormShell title="General Request" subtitle="Ask a question, report an issue, or request something not covered by other forms" onBack={onBack}>
      <window.SectionHeader title="Requester" />
      <window.Grid>
        <window.Field label="Your name" required span={6}><window.TextField value={form.requesterName} onChange={v => upd({ requesterName: v })} placeholder="Full name" /></window.Field>
        <window.Field label="Email" required span={6}><window.TextField value={form.requesterEmail} onChange={v => upd({ requesterEmail: v })} placeholder="name@axiomhospitality.com" type="email" /></window.Field>
      </window.Grid>

      <window.SectionHeader title="Your request" />
      <window.Field label="Hotels" required hint="Which hotels does this relate to">
        <window.ChipMultiSelect options={MOCK_HOTELS.map(h => ({ code: h.id, label: h.name }))} value={form.hotels} onChange={v => upd({ hotels: v })} />
      </window.Field>
      <window.Field label="Subject" required><window.TextField value={form.subject} onChange={v => upd({ subject: v })} placeholder="Brief summary of your request" /></window.Field>
      <window.Field label="Message" required hint="Provide as much detail as possible"><window.TextArea value={form.message} onChange={v => upd({ message: v })} rows={6} placeholder="Describe what you need, including any relevant rate codes, hotel names, dates, or customer details…" /></window.Field>

      <window.SectionHeader title="Attachments" />
      <window.Field label="Files" hint="Optional — attach any relevant documents"><window.Attachments files={form.attachments} onChange={a => upd({ attachments: a })} /></window.Field>

      <div style={{ marginTop: 20 }}>
        <window.Checkbox checked={form.acknowledged} onChange={v => upd({ acknowledged: v })} label={<span style={{ fontWeight: 600 }}>I confirm the details above are correct</span>} />
      </div>
      <div style={{ display: "flex", justifyContent: "flex-end", marginTop: 16 }}>
        <window.Button variant="primary" disabled={!form.acknowledged || !form.requesterName || !form.requesterEmail || !form.subject || !form.message || submitState.status === "submitting"} onClick={submit}>
          {submitState.status === "submitting" ? "Submitting…" : "Submit request"}
        </window.Button>
      </div>
      {submitState.status === "error" && <div style={{ marginTop: 10, padding: "10px 14px", background: "#FBE5E0", border: "1px solid #E5BAAF", borderRadius: 6, fontSize: 12.5, color: "#7A2415" }}>Failed: {submitState.error}</div>}
    </FormShell>
  );
}

// ---- Shared components ----
function FormShell({ title, subtitle, onBack, children }) {
  const T = window.EMMA_TOKENS;
  return (
    <div style={{ width: "100%", maxWidth: 760, margin: "0 auto" }}>
      <button type="button" onClick={onBack} style={{ background: "transparent", border: "none", color: T.accent, fontSize: 13, fontWeight: 600, cursor: "pointer", padding: "0 0 16px", display: "flex", alignItems: "center", gap: 6 }}>
        ← Back to request types
      </button>
      <div style={{ background: T.surface, border: `1px solid ${T.border}`, borderRadius: 10, padding: "28px 32px", boxShadow: "0 2px 12px rgba(0,0,0,0.04)" }}>
        <h2 style={{ margin: "0 0 4px", fontSize: 26, fontWeight: 500, color: T.ink, fontFamily: "'Cormorant Garamond', Georgia, serif" }}>{title}</h2>
        {subtitle && <p style={{ margin: "0 0 24px", fontSize: 13, color: T.muted }}>{subtitle}</p>}
        <div style={{ display: "flex", flexDirection: "column", gap: 20 }}>{children}</div>
      </div>
    </div>
  );
}

function SuccessScreen({ ticketId, label, email, onReset, onBack }) {
  const T = window.EMMA_TOKENS;
  return (
    <div style={{ width: "100%", maxWidth: 500, margin: "0 auto", textAlign: "center", padding: "60px 20px" }}>
      <div style={{ width: 56, height: 56, borderRadius: "50%", background: T.okSoft, display: "inline-flex", alignItems: "center", justifyContent: "center", marginBottom: 18 }}>
        <svg width="22" height="22" viewBox="0 0 22 22"><path d="M5 11l4 4 8-9" stroke={T.ok} fill="none" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" /></svg>
      </div>
      <h2 style={{ margin: 0, fontSize: 28, fontWeight: 500, fontFamily: "'Cormorant Garamond', Georgia, serif" }}>{label} submitted</h2>
      <p style={{ color: T.muted, fontSize: 14, marginTop: 8 }}>Reference <span style={{ fontFamily: T.mono, color: T.ink, fontWeight: 600 }}>{ticketId}</span></p>
      <p style={{ color: T.muted, fontSize: 13, marginTop: 10, lineHeight: 1.6 }}>
        Standard processing time is 5 business days. A confirmation has been sent to <strong>{email}</strong>.
      </p>
      <div style={{ display: "flex", gap: 10, justifyContent: "center", marginTop: 22 }}>
        <window.Button variant="secondary" onClick={onReset}>Submit another</window.Button>
        <window.Button variant="primary" onClick={onBack}>Back to home</window.Button>
      </div>
    </div>
  );
}

// Export
window.RateExtensionForm = RateExtensionForm;
window.GeneralRequestForm = GeneralRequestForm;
