/* Variation 1 — Multi-step wizard. Best for guided sales-rep flow. */
const { useState, useMemo } = React;
const T = window.EMMA_TOKENS;
const { MOCK_HOTELS, ROOM_TYPES, MEAL_PLANS, CURRENCIES, RATE_TYPES, PRICE_CODE_TYPES, CANCELLATION_POLICIES, HOTEL_PROFILE } = window.EMMA_DATA;
const suggestCodes = window.suggestCodes;

// Intersection of room/cancel availability across selected hotels.
// If no hotels selected yet, fall back to the full superset.
function availableForHotels(hotelIds, kind) {
  if (!hotelIds || !hotelIds.length) return kind === "rooms" ? ROOM_TYPES.map(r => r.code) : CANCELLATION_POLICIES.map(c => c.code);
  const sets = hotelIds.map(id => new Set(HOTEL_PROFILE[id]?.[kind] || []));
  const first = sets[0];
  return [...first].filter(code => sets.every(s => s.has(code)));
}

// Small "Recommended" chip shown beside auto-suggestable fields.
function SuggestionChip({ value, onUse, label = "Recommended" }) {
  if (!value) return null;
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 6, fontSize: 12 }}>
      <span style={{ color: T.muted, fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: 0.4 }}>{label}</span>
      <span style={{ fontFamily: T.mono, background: T.accentSoft, color: T.accentInk, padding: "3px 8px", borderRadius: 4, border: `1px solid #BFD8D2` }}>{value}</span>
      <button type="button" onClick={onUse} style={{ background: "transparent", border: `1px solid ${T.border}`, color: T.accentInk, padding: "3px 8px", borderRadius: 4, fontSize: 11.5, cursor: "pointer", fontWeight: 600 }}>Use</button>
    </div>
  );
}

// Tabs across selected hotels. Returns null when only 1 (or 0) hotel.
function HotelTabs({ hotels, activeId, onChange, label = "Per hotel", trailing }) {
  if (!hotels || hotels.length < 2) return null;
  const items = hotels.map(id => MOCK_HOTELS.find(h => h.id === id)).filter(Boolean);
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "8px 10px", border: `1px solid ${T.border}`, borderRadius: 6, background: T.surface2, flexWrap: "wrap" }}>
      <span style={{ fontSize: 10.5, fontWeight: 700, color: T.muted, textTransform: "uppercase", letterSpacing: 0.5, marginRight: 4 }}>{label}</span>
      <div style={{ display: "flex", gap: 6, flexWrap: "wrap", flex: 1 }}>
        {items.map(h => {
          const a = h.id === activeId;
          return (
            <button key={h.id} type="button" onClick={() => onChange(h.id)} style={{
              padding: "6px 10px", borderRadius: 4,
              border: `1.5px solid ${a ? T.accent : T.border}`,
              background: a ? T.accentSoft : T.surface,
              color: a ? T.accentInk : T.ink,
              fontSize: 12.5, fontWeight: a ? 600 : 500, cursor: "pointer",
              display: "inline-flex", alignItems: "center", gap: 6,
            }}>
              <span style={{ fontFamily: T.mono, fontSize: 10.5, color: a ? T.accent : T.faint }}>{h.id.slice(-3)}</span>
              {h.name}
            </button>
          );
        })}
      </div>
      {trailing}
    </div>
  );
}

const STEPS = [
  { id: "requester", label: "Requester", desc: "Who is filing this request" },
  { id: "customer", label: "Identify Client", desc: "Client & hotel selection" },
  { id: "price", label: "Price Code", desc: "Room × meal × occupancy" },
  { id: "rate", label: "Rate", desc: "Windows, inclusions, segment" },
  { id: "contract", label: "Contract", desc: "Validity, cancellation, stay rules" },
  { id: "files", label: "Files", desc: "Attachments & notes" },
  { id: "review", label: "Review", desc: "Confirm & submit" },
];

function WizardVariation(props) {
  const [form, setForm] = useState(window.emptyForm());
  const [step, setStep] = useState(0);
  const [submitted, setSubmitted] = useState(false);
  const [submitState, setSubmitState] = useState({ status: "idle", error: null, ticketId: null });
  const upd = (patch) => setForm(f => ({ ...f, ...patch }));

  // ---- Build a clean HTML summary for Freshdesk ticket body & confirmation email ----
  const buildHtmlSummary = (submissionId) => {
    const d = (v) => v || "—";
    const fmtDate = (v) => v ? window.fmt(v) : "—";
    const hotelNames = form.hotels.map(id => { const h = MOCK_HOTELS.find(m => m.id === id); return h ? `${h.name} (${id})` : id; });
    const roomLabels = form.rooms.map(c => { const r = window.EMMA_DATA.ROOM_TYPES.find(x => x.code === c); return r ? r.label : c; });
    const mealLabels = form.meals.map(c => { const m = window.EMMA_DATA.MEAL_PLANS.find(x => x.code === c); return m ? m.label : c; });
    const cancelLabels = (form.cancellationPolicies || []).map(c => { const p = window.EMMA_DATA.CANCELLATION_POLICIES.find(x => x.code === c); return p ? p.label : c; });

    const sectionStyle = `style="margin-bottom:24px"`;
    const headingStyle = `style="font-size:14px;font-weight:700;color:#0E5E55;text-transform:uppercase;letter-spacing:0.5px;border-bottom:2px solid #0E5E55;padding-bottom:6px;margin-bottom:12px"`;
    const tableStyle = `style="width:100%;border-collapse:collapse;font-size:13px"`;
    const thStyle = `style="text-align:left;padding:6px 10px;color:#6B6B63;font-weight:500;width:180px;vertical-align:top;border-bottom:1px solid #E5E0D6"`;
    const tdStyle = `style="padding:6px 10px;color:#1B1D1A;border-bottom:1px solid #E5E0D6"`;

    const row = (label, value) => `<tr><th ${thStyle}>${label}</th><td ${tdStyle}>${d(value)}</td></tr>`;

    // Build seasons summary
    let seasonRows = "";
    (form.seasons || []).forEach(s => {
      seasonRows += `<tr><td ${tdStyle} colspan="2" style="padding:6px 10px;color:#1B1D1A;border-bottom:1px solid #E5E0D6;background:#F4F1EB"><strong>${d(s.name)}</strong>: ${d(s.basePrice)} base &nbsp;·&nbsp; ${fmtDate(s.start)} → ${fmtDate(s.end)}</td></tr>`;
    });

    // Build full pricing matrix tables per season (and per hotel when multi-hotel)
    const occCols = [
      { key: "1", label: "1 Adult" },
      { key: "2", label: "2 Adults" },
      { key: "X", label: "Extra Adult" },
      { key: "C", label: "Child" },
    ];
    const matrixThStyle = `style="padding:8px 10px;text-align:right;font-size:11px;font-weight:600;color:#6B6B63;border-bottom:2px solid #E5E0D6;background:#F4F1EB"`;
    const matrixThLeftStyle = `style="padding:8px 10px;text-align:left;font-size:11px;font-weight:600;color:#6B6B63;border-bottom:2px solid #E5E0D6;background:#F4F1EB"`;
    const matrixTdStyle = `style="padding:6px 10px;text-align:right;font-size:13px;font-family:'JetBrains Mono',monospace;color:#1B1D1A;border-bottom:1px solid #E5E0D6"`;
    const matrixTdLeftStyle = `style="padding:6px 10px;text-align:left;font-size:12px;color:#1B1D1A;border-bottom:1px solid #E5E0D6"`;
    const isBase = form.priceCodeType === "Dynamic Rate";
    const cur = form.contractCurrency || "EUR";
    const isMultiHotel = form.hotels.length > 1;
    const hotelMatrices = form.hotelMatrices || {};
    const seasonMatrices = form.seasonMatrices || {};

    // Helper: get the right matrix for a given hotel + season
    const getMatrix = (hotelId, seasonId) => {
      if (isMultiHotel && hotelId) {
        // Multi-hotel: try per-hotel first, fall back to shared seasonMatrices
        const perHotel = (hotelMatrices[hotelId] || {})[seasonId];
        if (perHotel && Object.keys(perHotel).length) return perHotel;
      }
      // Single hotel or fallback: use seasonMatrices, then form.matrix
      return seasonMatrices[seasonId] || form.matrix || {};
    };

    // Helper: render one pricing table
    const renderMatrixTable = (matrix) => {
      return `<table style="width:100%;border-collapse:collapse;border:1px solid #E5E0D6">
        <thead>
          <tr>
            <th ${matrixThLeftStyle}>Room</th>
            <th ${matrixThLeftStyle}>Meal</th>
            ${occCols.map(c => `<th ${matrixThStyle}>${c.label}</th>`).join("")}
          </tr>
        </thead>
        <tbody>
          ${form.rooms.map(rt => form.meals.map(mp => {
            const roomLabel = window.EMMA_DATA.ROOM_TYPES.find(x => x.code === rt)?.label || rt;
            const mealLabel = window.EMMA_DATA.MEAL_PLANS.find(x => x.code === mp)?.label || mp;
            return `<tr>
              <td ${matrixTdLeftStyle}><strong>${roomLabel}</strong></td>
              <td ${matrixTdLeftStyle}>${mealLabel}</td>
              ${occCols.map(c => {
                const val = matrix[`${rt}|${mp}|${c.key}`] || "";
                return `<td ${matrixTdStyle}>${val ? (isBase && val !== "0.00" ? (parseFloat(val) >= 0 ? "+" : "") + val : val) : "—"}</td>`;
              }).join("")}
            </tr>`;
          }).join("")).join("")}
        </tbody>
      </table>`;
    };

    let pricingTablesHtml = "";
    if (isBase) {
      // Base Price Code: show simple season discount table
      if ((form.seasons || []).length) {
        const dowLabels = { MO: "Mon", TU: "Tue", WE: "Wed", TH: "Thu", FR: "Fri", SA: "Sat", SU: "Sun" };
        pricingTablesHtml += `<table style="width:100%;border-collapse:collapse;border:1px solid #E5E0D6;margin-top:12px">
          <thead><tr>
            <th ${matrixThLeftStyle}>Season</th>
            <th ${matrixThLeftStyle}>Dates</th>
            <th ${matrixThLeftStyle}>Based on</th>
            <th ${matrixThStyle}>Discount</th>
            <th ${matrixThLeftStyle}>Days</th>
          </tr></thead><tbody>`;
        (form.seasons || []).forEach(s => {
          const days = (s.dowFilter || []).map(d => dowLabels[d] || d).join(", ") || "All";
          pricingTablesHtml += `<tr>
            <td ${matrixTdLeftStyle}><strong>${d(s.name)}</strong></td>
            <td ${matrixTdLeftStyle}>${fmtDate(s.start)} → ${fmtDate(s.end)}</td>
            <td ${matrixTdLeftStyle}>${d(s.basedOnRate)}</td>
            <td ${matrixTdStyle}>${d(s.discountPercent)}%</td>
            <td ${matrixTdLeftStyle} style="padding:6px 10px;text-align:left;font-size:11px;color:#1B1D1A;border-bottom:1px solid #E5E0D6">${days}</td>
          </tr>`;
        });
        pricingTablesHtml += `</tbody></table>`;
      }
    } else if (form.rooms.length && form.meals.length) {
      if (isMultiHotel) {
        // Multi-hotel: one section per hotel, each with all seasons
        form.hotels.forEach(hid => {
          const hName = MOCK_HOTELS.find(m => m.id === hid)?.name || hid;
          pricingTablesHtml += `
          <div style="margin-top:18px;margin-bottom:10px">
            <div style="font-size:13px;font-weight:700;color:#0E5E55;padding:8px 12px;background:#E4EFEC;border-radius:4px;border:1px solid #BFD8D2">
              ${hName} <span style="font-weight:400;font-family:'JetBrains Mono',monospace;font-size:11px;color:#6B6B63;margin-left:6px">${hid}</span>
            </div>
          </div>`;
          (form.seasons || []).forEach(s => {
            const matrix = getMatrix(hid, s.id);
            pricingTablesHtml += `
            <div style="margin-top:8px;margin-bottom:14px;margin-left:12px">
              <div style="font-size:11px;font-weight:600;color:#073A34;margin-bottom:5px;text-transform:uppercase;letter-spacing:0.3px">${d(s.name)} <span style="font-weight:400;color:#6B6B63;text-transform:none">&nbsp;·&nbsp; ${d(s.basePrice)} ${cur} base &nbsp;·&nbsp; ${fmtDate(s.start)} → ${fmtDate(s.end)}</span></div>
              ${renderMatrixTable(matrix)}
            </div>`;
          });
        });
      } else {
        // Single hotel: one table per season
        (form.seasons || []).forEach(s => {
          const matrix = getMatrix(null, s.id);
          pricingTablesHtml += `
          <div style="margin-top:14px;margin-bottom:18px">
            <div style="font-size:12px;font-weight:700;color:#073A34;margin-bottom:6px;text-transform:uppercase;letter-spacing:0.3px">${d(s.name)} <span style="font-weight:400;color:#6B6B63;text-transform:none">&nbsp;·&nbsp; ${d(s.basePrice)} ${cur} base &nbsp;·&nbsp; ${fmtDate(s.start)} → ${fmtDate(s.end)}</span></div>
            ${renderMatrixTable(matrix)}
          </div>`;
        });
      }
    }

    // Build per-hotel cancellation summary
    let hotelCancelRows = "";
    if (form.hotels.length > 1 && form.hotelCancellation) {
      form.hotels.forEach(hid => {
        const policies = (form.hotelCancellation[hid] || []).map(c => { const p = window.EMMA_DATA.CANCELLATION_POLICIES.find(x => x.code === c); return p ? p.label : c; });
        const hName = MOCK_HOTELS.find(m => m.id === hid)?.name || hid;
        if (policies.length) hotelCancelRows += row(hName, policies.join(", "));
      });
    }

    return `
<div style="font-family:Inter,Segoe UI,Helvetica,Arial,sans-serif;color:#1B1D1A;max-width:680px;margin:0 auto">
  <div style="background:#0E5E55;color:#fff;padding:20px 24px;border-radius:8px 8px 0 0">
    <h1 style="margin:0;font-size:20px;font-weight:600">Rate Load Request</h1>
    <p style="margin:6px 0 0;font-size:13px;opacity:0.85">Reference: <strong>${submissionId}</strong> &nbsp;·&nbsp; Submitted ${new Date().toLocaleString("en-GB", { dateStyle: "medium", timeStyle: "short" })}</p>
  </div>
  <div style="padding:24px;background:#FFFFFF;border:1px solid #E5E0D6;border-top:none;border-radius:0 0 8px 8px">

    <div ${sectionStyle}>
      <div ${headingStyle}>Requester</div>
      <table ${tableStyle}>
        ${row("Name", form.requesterName)}
        ${row("Email", form.requesterEmail)}
      </table>
    </div>

    <div ${sectionStyle}>
      <div ${headingStyle}>Customer</div>
      <table ${tableStyle}>
        ${row("Status", form.customerIsNew ? "New customer" : "Existing customer")}
        ${row("Customer ID(s)", (form.customerIds || []).filter(c => c.id).map(c => `${c.type || "ID"}: ${c.id}`).join("<br>") || "—")}
        ${row("Name", form.customerName)}
        ${row("Address", form.customerAddress)}
        ${row("Email", form.customerEmail)}
        ${row("Phone", form.customerPhone)}
        ${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") : ""}
      </table>
    </div>

    <div ${sectionStyle}>
      <div ${headingStyle}>Contract</div>
      <table ${tableStyle}>
        ${row("Rate type", form.rateType + (form.rateType === "Corporate Negotiated" && form.lraType ? ` · ${form.lraType}` : ""))}
        ${row("Validity", `${fmtDate(form.contractStart)} → ${fmtDate(form.contractEnd)}`)}
        ${row("Currency", form.contractCurrency)}
        ${row("Tax handling", form.contractTax)}
        ${row("Hotels", hotelNames.length ? hotelNames.join("<br>") : "—")}
      </table>
    </div>

    <div ${sectionStyle}>
      <div ${headingStyle}>Price Code</div>
      <table ${tableStyle}>
        ${row("Type", form.priceCodeType)}
        ${row("Name", form.priceCodeName)}
        ${row("Per person", form.perPerson ? "Yes" : "No")}
        ${row("Meal plan allocation", form.mealPlanAllocation ? "Yes" : "No")}
        ${row("Room types", roomLabels.join(", ") || "—")}
        ${row("Meal plans", mealLabels.join(", ") || "—")}
      </table>
      ${pricingTablesHtml || `<p style="font-size:13px;color:#6B6B63;margin-top:10px">No pricing data entered.</p>`}
    </div>

    <div ${sectionStyle}>
      <div ${headingStyle}>Rate</div>
      <table ${tableStyle}>
        ${row("Rate description", form.rateDescription)}
        ${row("Inclusions", form.rateInclusions)}
        ${row("Market segment", form.marketSegment)}
        ${row("Cancellation", cancelLabels.length ? cancelLabels.join(", ") : (form.cancellationPolicy || (form.refundable ? "Refundable" : "Non-refundable")))}
        ${hotelCancelRows ? `<tr><th ${thStyle} colspan="2" style="text-align:left;padding:6px 10px;color:#6B6B63;font-weight:500;width:180px;vertical-align:top;border-bottom:1px solid #E5E0D6;background:#F4F1EB"><em>Per-hotel cancellation</em></th></tr>${hotelCancelRows}` : ""}
      </table>
    </div>

    <div ${sectionStyle}>
      <div ${headingStyle}>Windows</div>
      <table ${tableStyle}>
        ${row("Booking window", `${fmtDate(form.bookingStart)} → ${fmtDate(form.bookingEnd)}`)}
        ${row("Travel window", `${fmtDate(form.travelStart)} → ${fmtDate(form.travelEnd)}`)}
      </table>
    </div>

    <div ${sectionStyle}>
      <div ${headingStyle}>Stay Rules</div>
      <table ${tableStyle}>
        ${row("Length of stay", `${form.minLOS || "—"} – ${form.maxLOS || "∞"} nights`)}
        ${row("Blackout dates", form.blackoutDates || "None")}
        ${row("Days allowed", form.dowAllowed ? form.dowAllowed.join(", ") : "All")}
        ${row("Advance purchase", form.advancePurchase ? `${form.advanceDays || "?"} days` : "Not required")}
        ${row("Commissionable", form.commissionable ? `Yes · ${form.commissionPercent || "—"}%` : "No")}
        ${row("Closed to arrival on blackouts", form.closedToArrival ? "Yes" : "No")}
      </table>
    </div>

    <div ${sectionStyle}>
      <div ${headingStyle}>Attachments &amp; Notes</div>
      <table ${tableStyle}>
        ${row("Attachments", (form.attachments || []).length ? form.attachments.map(a => `${a.name} (${(a.size / 1024).toFixed(0)} KB)`).join("<br>") : "None")}
        ${row("Notes", form.notes || "None")}
      </table>
    </div>

    <div style="margin-top:20px;padding:14px;background:#E4EFEC;border-radius:6px;font-size:12px;color:#073A34">
      <strong>What happens next?</strong> The load team will process this request within ${form.ratePriority === "Urgent (24h)" ? "24" : form.ratePriority === "Expedited (48h)" ? "48" : "72"} hours. You'll receive a confirmation when the rate is live.
    </div>
  </div>
</div>`.trim();
  };

  const buildPayload = (submissionId) => ({
    submissionId,
    submittedAt: new Date().toISOString(),
    // Top-level fields for easy Zapier mapping (email step + ticket subject)
    requesterName: form.requesterName,
    requesterEmail: form.requesterEmail,
    subject: `New Rate Request: ${form.customerName || "Customer"} — ${(() => { const hn = form.hotels.map(id => { const h = MOCK_HOTELS.find(m => m.id === id); return h ? h.name : id; }); return hn.length ? hn[0] : "Hotel"; })()}${form.hotels.length > 1 ? ` +${form.hotels.length - 1} more` : ""} [${submissionId}]`,
    ticketType: "New Rate Request",
    priority: form.ratePriority,
    // Formatted HTML for Freshdesk ticket description AND confirmation email body
    htmlBody: buildHtmlSummary(submissionId),
    // Structured data (unchanged — available for automation / field mapping)
    requester: { name: form.requesterName, email: form.requesterEmail, priority: form.ratePriority },
    customer: { isNew: form.customerIsNew, ids: (form.customerIds || []).filter(c => c.id), name: form.customerName, address: form.customerAddress, email: form.customerEmail, phone: form.customerPhone, channels: form.channels, lanyonManaged: form.lanyonManaged },
    reasonForRequest: form.notes,
    contract: {
      existingContractId: form.existingContract?.id || null,
      name: form.contractName, code: form.contractCode,
      validity: { start: window.iso(form.contractStart), end: window.iso(form.contractEnd) },
      currency: form.contractCurrency, taxHandling: form.contractTax, rateType: form.rateType, lraType: form.lraType || null,
      hotels: form.hotels,
      hotelConfigs: form.hotelConfigs || {},
      cancellationPolicies: form.cancellationPolicies || [],
      cancellationPerHotel: form.hotels.length > 1 ? form.hotelCancellation : null,
    },
    priceCode: {
      type: form.priceCodeType,
      perPerson: form.perPerson, mealPlanAllocation: form.mealPlanAllocation,
      rooms: form.rooms, meals: form.meals,
      seasons: (form.seasons || []).map(s => ({ ...s, start: window.iso(s.start), end: window.iso(s.end), matrix: (form.seasonMatrices || {})[s.id] || {} })),
      perHotelMatrices: form.hotels.length > 1 ? form.hotelMatrices : null,
    },
    rate: { description: form.rateDescription, inclusions: form.rateInclusions, marketSegment: form.marketSegment, refundable: form.refundable, priority: form.ratePriority, allocation: form.allocation },
    stayRules: { minLOS: form.minLOS, maxLOS: form.maxLOS, blackoutDates: form.blackoutDates, dowAllowed: form.dowAllowed, advancePurchase: form.advancePurchase, advanceDays: form.advanceDays, commissionable: form.commissionable, commissionPercent: form.commissionPercent, closedToArrival: form.closedToArrival, cancellationPolicy: form.cancellationPolicy },
    window: { booking: { start: window.iso(form.bookingStart), end: window.iso(form.bookingEnd) }, travel: { start: window.iso(form.travelStart), end: window.iso(form.travelEnd) } },
    attachments: (form.attachments || []).map(a => ({ name: a.name, size: a.size, type: a.type })),
    notes: form.notes,
  });

  const submit = async () => {
    const submissionId = `RLR-${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 = buildPayload(submissionId);

    // Collect files for separate upload
    const filePromises = (form.attachments || []).filter(a => a._file).map(a => {
      return new Promise((resolve) => {
        const reader = new FileReader();
        reader.onload = () => resolve({ name: a.name, type: a.type, data: reader.result.split(",")[1] });
        reader.onerror = () => resolve(null);
        reader.readAsDataURL(a._file);
      });
    });
    const files = (await Promise.all(filePromises)).filter(Boolean);

    // Don't include files in the main payload
    delete payload.fileUploads;

    const endpoint = window.SUBMIT_ENDPOINT;
    try {
      if (endpoint && (endpoint.startsWith("http") || endpoint === "/api/submit")) {
        // Step 1: Create ticket (no files)
        const res = await fetch(endpoint || "/api/submit", {
          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}`);

        // Step 2: Attach files one by one
        if (files.length && result.freshdeskTicketId) {
          console.log(`[RLR] Attaching ${files.length} file(s) to ticket ${result.freshdeskTicketId}`);
          for (const file of files) {
            try {
              const attachRes = await fetch(endpoint || "/api/submit", {
                method: "POST",
                headers: { "Content-Type": "application/json" },
                body: JSON.stringify({ action: "attach", freshdeskTicketId: result.freshdeskTicketId, file }),
              });
              const attachResult = await attachRes.json().catch(() => ({}));
              console.log(`[RLR] Attach ${file.name}:`, attachRes.ok ? "OK" : attachResult.error);
            } catch (e) { console.warn(`[RLR] Failed to attach ${file.name}:`, e.message); }
          }
        } else if (files.length) {
          console.warn("[RLR] No freshdeskTicketId returned — skipping file attachments");
        }

        setSubmitState({ status: "ok", error: null, ticketId: result.ticketId || submissionId });
      } else {
        await new Promise(r => setTimeout(r, 900));
        setSubmitState({ status: "ok", error: null, ticketId: submissionId });
      }
      console.log("[RLR submitted]", payload);
      setSubmitted(true);
    } catch (e) {
      setSubmitState({ status: "error", error: e.message, ticketId: null });
    }
  };

  const completion = useMemo(() => {
    const checks = {
      requester: !!(form.requesterName && form.requesterEmail),
      customer: !!(form.customerName && form.customerAddress && form.hotels.length && form.notes && (form.channels || []).length),
      contract: !!(form.rateType && form.contractStart && form.contractEnd && (form.rateType !== "Corporate Negotiated" || form.lraType)),
      price: (() => {
        const rooms = form.rooms.filter(r => r.trim());
        if (!rooms.length || !form.meals.length) return false;
        if (form.priceCodeType === "Static Rate") {
          // Check all room × meal have 1AD and 2AD filled
          const matrices = form.hotels.length > 1
            ? Object.values(form.hotelConfigs || {}).flatMap(cfg => {
                const r = (cfg.rooms || []).filter(x => x.trim());
                const m = cfg.meals || [];
                return Object.values(form.hotelMatrices || {}).flatMap(hm => Object.values(hm || {}).map(sm => ({ rooms: r, meals: m, matrix: sm })));
              })
            : (form.seasons || []).map(s => ({ rooms, meals: form.meals, matrix: (form.seasonMatrices || {})[s.id] || form.matrix || {} }));
          return matrices.every(({ rooms: rs, meals: ms, matrix: mx }) =>
            rs.every(rt => ms.every(mp => mx[`${rt}|${mp}|1`] && mx[`${rt}|${mp}|2`]))
          );
        }
        return true;
      })(),
      rate: !!(form.rateDescription && form.marketSegment && form.bookingStart && form.bookingEnd && form.travelStart && form.travelEnd),
      files: true,
      review: form.acknowledged,
    };
    return checks;
  }, [form]);

  const next = () => setStep(s => Math.min(STEPS.length - 1, s + 1));
  const prev = () => setStep(s => Math.max(0, s - 1));
  const cur = STEPS[step];

  if (submitted) return <SubmittedScreen form={form} ticketId={submitState.ticketId} onReset={() => { setForm(window.emptyForm()); setStep(0); setSubmitted(false); setSubmitState({ status: "idle", error: null, ticketId: null }); }} />;

  return (
    <div style={{ width: 1100, height: 760, background: T.bg, fontFamily: T.sans, color: T.ink, display: "flex", flexDirection: "column", overflow: "hidden" }}>
      {/* Top bar */}
      <header style={{
        display: "flex", alignItems: "center", justifyContent: "space-between",
        padding: "14px 24px", borderBottom: `1px solid ${T.border}`, background: T.surface,
      }}>
        <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
          <Logo />
          <div style={{ width: 1, height: 22, background: T.border }} />
          <div>
          <div style={{ fontSize: 17, fontWeight: 500, color: T.ink, fontFamily: "'Cormorant Garamond', 'EB Garamond', Georgia, serif", letterSpacing: 0.2 }}>Rate Load Request</div>
            <div style={{ fontSize: 11.5, color: T.muted, fontFamily: T.mono }}>Rate load workflow</div>
          </div>
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
          <window.Pill tone="neutral" size="sm">Draft auto-saved · 12:04</window.Pill>
          <window.Button variant="ghost" size="sm" onClick={() => setForm(window.sampleFill())}>Fill sample</window.Button>
          <window.Button variant="secondary" size="sm">Save draft</window.Button>
        </div>
      </header>

      {/* Body */}
      <div style={{ flex: 1, display: "grid", gridTemplateColumns: "260px 1fr", overflow: "hidden" }}>
        {/* Stepper */}
        <aside style={{ borderRight: `1px solid ${T.border}`, background: T.surface, padding: "20px 0", overflowY: "auto" }}>
          {props.onBack && (
            <button type="button" onClick={props.onBack} style={{ display: "flex", alignItems: "center", gap: 6, padding: "8px 22px 14px", background: "transparent", border: "none", color: T.accent, fontSize: 12.5, fontWeight: 600, cursor: "pointer", width: "100%", borderBottom: `1px solid ${T.border}`, marginBottom: 10 }}>
              ← Back to home
            </button>
          )}
          <div style={{ padding: "0 22px 14px", fontSize: 10.5, fontWeight: 700, color: T.faint, letterSpacing: 1, textTransform: "uppercase" }}>
            Steps · {step + 1} of {STEPS.length}
          </div>
          {STEPS.map((s, i) => {
            const active = i === step;
            const done = completion[s.id];
            const passed = i < step;
            return (
              <button key={s.id} onClick={() => setStep(i)}
                style={{
                  display: "flex", alignItems: "flex-start", gap: 12,
                  width: "100%", padding: "10px 22px", border: "none",
                  background: active ? T.accentSoft : "transparent",
                  borderLeft: `3px solid ${active ? T.accent : "transparent"}`,
                  cursor: "pointer", textAlign: "left",
                }}>
                <div style={{
                  width: 24, height: 24, borderRadius: "50%", flexShrink: 0,
                  display: "flex", alignItems: "center", justifyContent: "center",
                  fontSize: 11, fontWeight: 700, fontFamily: T.mono,
                  background: done ? T.ok : (active ? T.accent : T.surface2),
                  color: done || active ? "#fff" : T.muted,
                  border: `1px solid ${done ? T.ok : (active ? T.accent : T.border)}`,
                }}>
                  {done ? <svg width="11" height="11" viewBox="0 0 11 11"><path d="M2 5.5l2.2 2L9 3" stroke="white" fill="none" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" /></svg> : i + 1}
                </div>
                <div style={{ minWidth: 0, flex: 1 }}>
                  <div style={{ fontSize: 13.5, fontWeight: 600, color: active ? T.accentInk : T.ink }}>{s.label}</div>
                  <div style={{ fontSize: 11.5, color: T.muted, marginTop: 2 }}>{s.desc}</div>
                </div>
              </button>
            );
          })}
          <div style={{ padding: "20px 22px 0", borderTop: `1px solid ${T.border}`, marginTop: 16 }}>
            <div style={{ fontSize: 10.5, fontWeight: 700, color: T.faint, letterSpacing: 1, textTransform: "uppercase", marginBottom: 8 }}>Rate flow</div>
            <FlowDiagram />
          </div>
        </aside>

        {/* Step content */}
        <main style={{ overflowY: "auto", padding: "28px 36px 80px" }}>
          <div style={{ maxWidth: 720 }}>
            <div style={{ display: "flex", alignItems: "baseline", gap: 12, marginBottom: 22 }}>
              <div style={{ fontSize: 11.5, fontFamily: T.mono, color: T.faint, fontWeight: 700, letterSpacing: 1 }}>STEP {step + 1} / {STEPS.length}</div>
              <h2 style={{ margin: 0, fontSize: 32, fontWeight: 500, color: T.ink, letterSpacing: -0.5, fontFamily: "'Cormorant Garamond', 'EB Garamond', Georgia, serif" }}>{cur.label}</h2>
            </div>

            {cur.id === "requester" && <StepRequester form={form} upd={upd} />}
            {cur.id === "customer" && <StepCustomer form={form} upd={upd} />}
            {cur.id === "contract" && <StepContract form={form} upd={upd} />}
            {cur.id === "price" && <StepPrice form={form} upd={upd} />}
            {cur.id === "rate" && <StepRate form={form} upd={upd} />}
            {cur.id === "files" && <StepStay form={form} upd={upd} />}
            {cur.id === "review" && <StepReview form={form} upd={upd} />}
          </div>
        </main>
      </div>

      {/* Footer nav */}
      <footer style={{
        display: "flex", justifyContent: "space-between", alignItems: "center",
        padding: "14px 36px", borderTop: `1px solid ${T.border}`, background: T.surface,
      }}>
        <window.Button variant="ghost" onClick={() => { if (step === 0 && props.onBack) { props.onBack(); } else { prev(); } }}>← Back</window.Button>
        <div style={{ fontSize: 12, color: T.muted }}>
          {Object.values(completion).filter(Boolean).length} of {STEPS.length} sections complete
        </div>
        {step < STEPS.length - 1 ? (
          <window.Button variant="primary" onClick={next}>Continue →</window.Button>
        ) : (
          <window.Button variant="primary" disabled={!form.acknowledged || submitState.status === "submitting"} onClick={submit}>
            {submitState.status === "submitting" ? "Submitting…" : "Submit request"}
          </window.Button>
        )}
      </footer>
      {submitState.status === "error" && (
        <div style={{ position: "absolute", bottom: 70, right: 24, background: T.dangerSoft, border: `1px solid #E5BAAF`, color: "#7A2415", padding: "10px 14px", borderRadius: 6, fontSize: 12.5, maxWidth: 320 }}>
          Submission failed: {submitState.error}. Check SUBMIT_ENDPOINT.
        </div>
      )}
    </div>
  );
}

function Logo() {
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
      <div style={{
        fontFamily: "'Cormorant Garamond', 'EB Garamond', Georgia, serif",
        fontSize: 22, fontWeight: 500, color: T.ink,
        letterSpacing: 4, lineHeight: 1,
      }}>AXIOM</div>
      <div style={{
        width: 1, height: 18, background: T.borderStrong || T.border,
      }} />
      <div style={{
        fontSize: 9.5, fontWeight: 600, color: T.muted,
        letterSpacing: 2.5, textTransform: "uppercase",
      }}>Hospitality</div>
    </div>
  );
}

function FlowDiagram() {
  const Node = ({ label, code }) => (
    <div style={{ background: T.surface2, border: `1px solid ${T.border}`, borderRadius: 5, padding: "7px 9px" }}>
      <div style={{ fontSize: 10, color: T.muted, fontFamily: T.mono }}>{code}</div>
      <div style={{ fontSize: 12, fontWeight: 600, color: T.ink, marginTop: 1 }}>{label}</div>
    </div>
  );
  const Arrow = () => <div style={{ height: 12, marginLeft: 12, borderLeft: `1.5px dashed ${T.borderStrong}` }} />;
  return (
    <div>
      <Node label="Price Code" code="01 · matrix" />
      <Arrow />
      <Node label="Rate" code="02 · uses code" />
      <Arrow />
      <Node label="Contract" code="03 · header" />
      <div style={{ fontSize: 11, color: T.muted, marginTop: 10, lineHeight: 1.4 }}>
        Price code drives room × meal × occupancy. Rate inherits the contract code.
      </div>
    </div>
  );
}

// ---- Step components -----------------------------------------------------
function StepRequester({ form, upd }) {
  return (
    <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>
      <div style={{ gridColumn: "span 12", marginTop: 4, padding: "12px 14px", background: T.surface2, border: `1px solid ${T.border}`, borderRadius: 6, fontSize: 12.5, color: T.ink, lineHeight: 1.55 }}>
        <div style={{ fontWeight: 600, marginBottom: 4, color: T.ink }}>Standard processing time is 5 business days. Please note the following may extend turnaround:</div>
        <ul style={{ margin: 0, paddingLeft: 18, color: T.muted }}>
          <li><strong>New accounts</strong> take longer — a database request for a new profile must be raised first (this will be handled by the support team).</li>
          <li><strong>GDS requests</strong> require an additional load step and can take up to 5 additional days.</li>
          <li><strong>Peak RFP season</strong> can extend the turnaround time.</li>
          <li><strong>Lanyon RFPs</strong> do not require a submission as they should automatically be created upon acceptance.</li>
        </ul>
      </div>
    </window.Grid>
  );
}

function StepCustomer({ form, upd }) {
  const isNew = form.customerIsNew;
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
      <window.Field label="Customer status" required>
        <div style={{ display: "flex", gap: 10 }}>
          {[{ k: false, label: "Existing customer", desc: "Enter customer details" }, { k: true, label: "New customer", desc: "Enter customer details manually" }].map(opt => {
            const a = isNew === opt.k;
            return (
              <label key={String(opt.k)} onClick={() => upd({ customerIsNew: opt.k, customer: opt.k ? null : form.customer })} style={{
                flex: 1, padding: 14, borderRadius: 8, cursor: "pointer",
                border: `1.5px solid ${a ? T.accent : T.border}`,
                background: a ? T.accentSoft : T.surface,
              }}>
                <div style={{ display: "flex", alignItems: "flex-start", gap: 10 }}>
                  <div style={{ marginTop: 1 }}><window.Radio checked={a} label="" /></div>
                  <div>
                    <div style={{ fontSize: 13.5, fontWeight: 600, color: T.ink }}>{opt.label}</div>
                    <div style={{ fontSize: 12, color: T.muted, marginTop: 3 }}>{opt.desc}</div>
                  </div>
                </div>
              </label>
            );
          })}
        </div>
      </window.Field>

      <window.Grid>
        <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="Customer name" required span={6}>
          <window.TextField value={form.customerName} onChange={(v) => upd({ customerName: v })} placeholder="Company / agency legal name" />
        </window.Field>
        <window.Field label="Customer address" required span={12}>
          <window.TextArea value={form.customerAddress} onChange={(v) => upd({ customerAddress: v })} rows={2} placeholder="Street, City, Postal code, Country" />
        </window.Field>
        <window.Field label="Customer email" span={6}>
          <window.TextField value={form.customerEmail} onChange={(v) => upd({ customerEmail: v })} placeholder="e.g. procurement@company.com" />
        </window.Field>
        <window.Field label="Customer phone" span={6}>
          <window.TextField value={form.customerPhone} onChange={(v) => upd({ customerPhone: v })} placeholder="e.g. +44 20 7123 4567" />
        </window.Field>
        {isNew && (
          <div style={{ gridColumn: "span 12", padding: "10px 12px", background: T.warnSoft || "#FBF1D9", border: `1px solid ${T.warn || "#E2C77E"}`, borderRadius: 6, fontSize: 12, color: T.muted, lineHeight: 1.5 }}>
            New customer profiles must be created in the database before the rate can be loaded — this adds turnaround time.
          </div>
        )}
        <window.Field label="Hotels in scope" required span={12} hint={`${form.hotels.length} selected. ${form.hotels.length > 1 ? "You'll set per-hotel details on later steps." : "Pick all hotels this rate should load at."}`}>
          <window.ChipMultiSelect
            options={MOCK_HOTELS.map(h => ({ code: h.id, label: h.name }))}
            value={form.hotels}
            onChange={(v) => upd({ hotels: v, activeHotelTab: v.includes(form.activeHotelTab) ? form.activeHotelTab : v[0] || null })}
          />
        </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.Grid>

      <window.Field label="Reason for request" required hint="Why this rate is being loaded">
        <window.TextArea
          value={form.notes}
          onChange={(v) => upd({ notes: v })}
          placeholder="e.g. Annual renewal, new RFP win, mid-year amendment, group block release…"
          rows={3}
        />
      </window.Field>
    </div>
  );
}

function Stat({ label, value }) {
  return (
    <div>
      <div style={{ fontSize: 10.5, color: T.faint, fontWeight: 600, textTransform: "uppercase", letterSpacing: 0.4 }}>{label}</div>
      <div style={{ fontSize: 14, color: T.ink, fontWeight: 500, marginTop: 3 }}>{value}</div>
    </div>
  );
}

function StepContract({ form, upd }) {
  const isMultiHotel = form.hotels.length > 1;
  const allowedCancel = availableForHotels(form.hotels, "cancel");
  const cancelOpts = CANCELLATION_POLICIES.filter(p => allowedCancel.includes(p.code)).map(p => ({ code: p.code, label: p.label }));
  const selectedCancel = (form.cancellationPolicies || []).filter(c => allowedCancel.includes(c));
  const hotelCancellation = form.hotelCancellation || {};
  const setHotelCancel = (hid, codes) => upd({ hotelCancellation: { ...hotelCancellation, [hid]: codes } });

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 24 }}>
      {/* ---- Contract details ---- */}
      <window.Grid>
        <window.Field label="Rate type" required span={form.rateType === "Corporate Negotiated" ? 8 : 12}>
          <window.Select value={form.rateType} onChange={(v) => upd({ rateType: v, lraType: v === "Corporate Negotiated" ? "" : "" })} options={RATE_TYPES} />
        </window.Field>
        {form.rateType === "Corporate Negotiated" && (
          <window.Field label="LRA / Non-LRA" required span={4} hint="Per nomenclature: CL / CS / CD">
            <window.Select value={form.lraType} onChange={(v) => upd({ lraType: v })} options={["", "LRA", "Non-LRA Static", "Non-LRA Dynamic"]} placeholder="Select…" />
          </window.Field>
        )}
        <window.Field label="Validity" required span={12} hint="Effective dates">
          <window.DateRangeField start={form.contractStart} end={form.contractEnd} onChange={(s, e) => upd({ contractStart: s, contractEnd: e })} />
        </window.Field>
        <window.Field label="Currency" required span={6}>
          <window.Select value={form.contractCurrency} onChange={(v) => upd({ contractCurrency: v })} options={CURRENCIES} />
        </window.Field>
        <window.Field label="Tax handling" required span={6}>
          <window.Select value={form.contractTax} onChange={(v) => upd({ contractTax: v })} options={["Inclusive", "Exclusive"]} />
        </window.Field>
      </window.Grid>

      {/* ---- Cancellation ---- */}
      <div style={{ borderTop: `1px solid ${T.border}`, paddingTop: 20 }}>
        <window.SectionHeader title="Cancellation" subtitle="Cancellation terms for this contract" />
        <div style={{ marginTop: 12 }}>
          <window.Field label="Cancellation policy" required hint="Describe the cancellation terms">
            <window.TextArea
              value={form.cancellationPolicy || ""}
              onChange={(v) => upd({ cancellationPolicy: v })}
              rows={3}
              placeholder="e.g. Free cancellation up to 48 hours before arrival. After that, first night charge applies. No-show: full stay charged."
            />
          </window.Field>
        </div>
      </div>

      {/* ---- Stay rules ---- */}
      <div style={{ borderTop: `1px solid ${T.border}`, paddingTop: 20 }}>
        <window.SectionHeader title="Stay rules" subtitle="Restrictions enforced at booking time" />
        <div style={{ marginTop: 12 }}>
          <window.Grid>
            <window.Field label="Min length of stay" required span={6} hint="Required nights">
              <window.TextField value={form.minLOS} onChange={(v) => upd({ minLOS: v })} suffix="nights" placeholder="1" />
            </window.Field>
            <window.Field label="Max length of stay" span={6} hint="Optional cap">
              <window.TextField value={form.maxLOS} onChange={(v) => upd({ maxLOS: v })} suffix="nights" placeholder="No max" />
            </window.Field>
            <window.Field label="Blackout dates" span={12} hint="Dates where rate is not bookable">
              <window.TextField value={form.blackoutDates} onChange={(v) => upd({ blackoutDates: v })} placeholder="e.g. 24 Dec 2026 – 02 Jan 2027; 14 Feb 2026" />
            </window.Field>
            <window.Field label="Day-of-week restrictions" span={12} hint="Days where rate is bookable (default: all)">
              <window.ChipMultiSelect
                options={[{ 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" }]}
                value={form.dowAllowed || ["MO", "TU", "WE", "TH", "FR", "SA", "SU"]}
                onChange={(v) => upd({ dowAllowed: v })}
              />
            </window.Field>
            <div style={{ gridColumn: "span 12", display: "flex", flexDirection: "column", gap: 8, marginTop: 4 }}>
              <window.Checkbox checked={form.advancePurchase} onChange={(v) => upd({ advancePurchase: v })} label="Advance purchase required" hint="Specify lead time below if checked" />
              {form.advancePurchase && (
                <div style={{ marginLeft: 28, maxWidth: 240 }}>
                  <window.TextField value={form.advanceDays} onChange={(v) => upd({ advanceDays: v })} suffix="days before arrival" placeholder="14" />
                </div>
              )}
              <window.Checkbox checked={form.commissionable} onChange={(v) => upd({ commissionable: v })} label="Commissionable" hint="Travel agencies receive commission on bookings" />
              {form.commissionable && (
                <div style={{ marginLeft: 28, maxWidth: 240 }}>
                  <window.TextField value={form.commissionPercent || ""} onChange={(v) => upd({ commissionPercent: v })} suffix="%" placeholder="10" />
                </div>
              )}
            </div>
          </window.Grid>
        </div>
      </div>
    </div>
  );
}

function StepPrice({ form, upd }) {
  const isBase = form.priceCodeType === "Dynamic Rate";
  const seasons = form.seasons || [{ id: "S1", name: "", basePrice: "", start: null, end: null, basedOnRate: "", discountPercent: "", dowFilter: ["MO", "TU", "WE", "TH", "FR", "SA", "SU"] }];
  const activeSeasonId = form.activeSeasonId || seasons[0].id;
  const activeSeason = seasons.find(s => s.id === activeSeasonId) || seasons[0];
  const isMultiHotel = form.hotels.length > 1;
  const activeHotelId = form.activeHotelTab && form.hotels.includes(form.activeHotelTab) ? form.activeHotelTab : form.hotels[0];

  const updSeason = (id, patch) => {
    const next = seasons.map(s => s.id === id ? { ...s, ...patch } : s);
    upd({ seasons: next });
  };
  const addSeason = () => {
    const nextNum = seasons.length + 1;
    const id = `S${nextNum}`;
    upd({ seasons: [...seasons, { id, name: "", basePrice: "", start: null, end: null, basedOnRate: "", discountPercent: "", dowFilter: ["MO", "TU", "WE", "TH", "FR", "SA", "SU"] }], activeSeasonId: id });
  };
  const removeSeason = (id) => {
    if (seasons.length <= 1) return;
    const next = seasons.filter(s => s.id !== id);
    upd({ seasons: next, activeSeasonId: next[0].id });
  };

  // Matrix for Fixed Price Code only
  const matrixKey = activeSeasonId;
  const hotelMatrices = form.hotelMatrices || {};
  const seasonMatrices = form.seasonMatrices || {};
  const currentMatrix = isMultiHotel
    ? ((hotelMatrices[activeHotelId] || {})[matrixKey] || {})
    : (seasonMatrices[matrixKey] || form.matrix || {});
  const setMatrix = (m) => {
    if (isMultiHotel) {
      upd({ hotelMatrices: { ...hotelMatrices, [activeHotelId]: { ...(hotelMatrices[activeHotelId] || {}), [matrixKey]: m } } });
    } else {
      upd({ seasonMatrices: { ...seasonMatrices, [matrixKey]: m }, matrix: m });
    }
  };
  const copyMatrixToAllHotels = () => {
    const next = { ...hotelMatrices };
    form.hotels.forEach(hid => {
      next[hid] = { ...(next[hid] || {}), [matrixKey]: { ...currentMatrix } };
    });
    upd({ hotelMatrices: next });
  };

  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" }];

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
      {!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 go back to <strong>Identify Client</strong> and select at least one hotel before setting up pricing.</div>
        </div>
      )}
      {form.hotels.length > 0 && (<>
      <window.Field label="Price code type" required>
        <div style={{ display: "flex", gap: 14, marginTop: 4 }}>
          {PRICE_CODE_TYPES.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. Add seasons with day-of-week rules."
                      : "Static prices per room × meal × occupancy."}
                  </div>
                </div>
              </div>
            </label>
          ))}
        </div>
      </window.Field>

      {/* Per-hotel config helper */}
      {(() => {
        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 });
        };

        // For single hotel, use top-level form.rooms/meals
        const hotelList = isMultiHotel ? form.hotels : [null];

        const renderRoomsMeals = (rooms, meals, setRooms, setMeals, hotelId) => (
          <>
            <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: room types and meals at top level */}
            {!isMultiHotel && renderRoomsMeals(
              form.rooms, form.meals,
              (r) => upd({ rooms: r }),
              (m) => upd({ meals: m }),
              null
            )}

            {/* Multi-hotel: stacked hotel sections */}
            {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 }),
                          hid
                        )}

                        {/* Static Rate: per-hotel pricing grids */}
                        {!isBase && seasons.map((s, si) => {
                          const sMatrix = (hotelMatrices[hid] || {})[s.id] || {};
                          const setSMatrix = (m) => upd({ hotelMatrices: { ...hotelMatrices, [hid]: { ...(hotelMatrices[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={form.contractCurrency}
                                />
                              </div>
                            </div>
                          );
                        })}
                      </div>
                    </div>
                  );
                })}
              </div>
            )}
          </>
        );
      })()}

      {/* ---- Base Price Code: simple season cards with discount % and day-of-week ---- */}
      {isBase && (
        <div>
          <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>

          {/* Overlap warning for Dynamic */}
          {(() => {
            const overlaps = [];
            for (let i = 0; i < seasons.length; i++) {
              for (let j = i + 1; j < seasons.length; j++) {
                const a = seasons[i], b = 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, marginBottom: 8 }}>
                <strong>Overlap detected:</strong> {overlaps.join(", ")} have overlapping dates and days of week. Adjust date ranges or day-of-week selections to avoid conflicts.
              </div>
            ) : null;
          })()}
          <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
            {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 }}>
                  <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                    <span style={{ fontFamily: T.mono, fontSize: 11, fontWeight: 700, color: T.accent, background: T.accentSoft, padding: "2px 8px", borderRadius: 4 }}>Season {i + 1}</span>
                    <span style={{ fontSize: 13, fontWeight: 600, color: T.ink }}>{s.start && s.end ? `${window.fmt(s.start)} → ${window.fmt(s.end)}` : `Season ${i + 1}`}</span>
                  </div>
                  {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} hint="The rate this discount is derived from">
                    <window.TextField value={s.basedOnRate || ""} onChange={(v) => updSeason(s.id, { basedOnRate: v })} placeholder="e.g. BAR, Best Flexible Rate, Rack Rate" />
                  </window.Field>
                  <window.Field label="Percentage discount" required span={6} hint="Applied to all room types">
                    <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} hint="Which days this season/discount applies to">
                    <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={{ alignSelf: "flex-start", 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>
        </div>
      )}

      {/* ---- Static Rate: stacked seasons with pricing matrices (single hotel only) ---- */}
      {!isBase && !isMultiHotel && (
        <>
          <window.Label hint={`${seasons.length} season${seasons.length === 1 ? "" : "s"} · each season holds its own fixed amounts`}>Pricing seasons</window.Label>

          {/* Overlap warning */}
          {(() => {
            const overlaps = [];
            for (let i = 0; i < seasons.length; i++) {
              for (let j = i + 1; j < seasons.length; j++) {
                const a = seasons[i], b = seasons[j];
                if (a.start && a.end && b.start && b.end && a.start <= b.end && b.start <= a.end) {
                  overlaps.push(`Season ${i+1} & Season ${j+1}`);
                }
              }
            }
            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 dates. Please adjust date ranges to avoid conflicts.
              </div>
            ) : null;
          })()}

          <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
            {seasons.map((s, i) => {
              const sMatrix = seasonMatrices[s.id] || (i === 0 ? form.matrix : {}) || {};
              const setSMatrix = (m) => upd({ seasonMatrices: { ...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>
                    {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} meals={form.meals}
                      matrix={sMatrix}
                      onChange={setSMatrix}
                      currency={form.contractCurrency}
                    />
                  </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 management only (grids are in hotel sections above) */}
      {!isBase && isMultiHotel && (
        <>
          <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 }}>
            {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>
                {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>
        </>
      )}
      </>)}
    </div>
  );
}

function StepRate({ form, upd }) {
  const MARKET_SEGMENTS = window.EMMA_DATA.MARKET_SEGMENTS;
  return (
    <window.Grid>
      {/* Booking & stay windows at top */}
      <div style={{ gridColumn: "span 12" }}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 10 }}>
          <window.Label hint="When the rate can be booked and when guests can stay">Booking & stay windows</window.Label>
          {(() => {
            const seasons = form.seasons || [];
            const valids = seasons.filter(s => s.start && s.end);
            const stayStart = valids.length ? valids.reduce((a, s) => !a || s.start < a ? s.start : a, null) : null;
            const stayEnd = valids.length ? valids.reduce((a, s) => !a || s.end > a ? s.end : a, null) : null;
            const bookStart = form.contractStart;
            const bookEnd = form.contractEnd;
            return (
              <window.Button variant="secondary" size="sm" onClick={() => {
                upd({
                  bookingStart: bookStart, bookingEnd: bookEnd,
                  travelStart: stayStart, travelEnd: stayEnd,
                });
              }}>Copy from price code</window.Button>
            );
          })()}
        </div>
        <window.Grid>
          <window.Field label="Booking window" required span={6} hint="When bookings can be made">
            <window.DateRangeField start={form.bookingStart} end={form.bookingEnd} onChange={(s, e) => upd({ bookingStart: s, bookingEnd: e })} />
          </window.Field>
          <window.Field label="Stay window" required span={6} hint="Travel / stay dates">
            <window.DateRangeField start={form.travelStart} end={form.travelEnd} onChange={(s, e) => upd({ travelStart: s, travelEnd: e })} />
          </window.Field>
        </window.Grid>
      </div>

      {/* Rate description / inclusions */}
      <div style={{ gridColumn: "span 12", marginTop: 8, paddingTop: 14, borderTop: `1px solid ${T.border}` }}>
        <window.Label hint="Visible to bookers — describe what this rate offers">Rate details</window.Label>
      </div>
      <window.Field label="Rate name / description" required span={12}>
        <window.TextArea value={form.rateDescription} onChange={(v) => upd({ rateDescription: v })} rows={2} placeholder="e.g. Bluepeak Corporate 2026 — negotiated rate for all London properties" />
      </window.Field>
      <window.Field label="Inclusions" span={12} hint="What's included with this rate">
        <window.TextField value={form.rateInclusions} onChange={(v) => upd({ rateInclusions: v })} placeholder="e.g. WiFi, breakfast, late checkout, airport transfer" />
      </window.Field>

      {/* Market segment */}
      <window.Field label="Market segment" required span={6}>
        <window.Select value={form.marketSegment} onChange={(v) => upd({ marketSegment: v })} options={MARKET_SEGMENTS} placeholder="Select segment…" />
      </window.Field>
    </window.Grid>
  );
}

function StepStayRules({ form, upd }) {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
      <div style={{ padding: "12px 14px", background: T.surface2, border: `1px solid ${T.border}`, borderRadius: 6, fontSize: 12.5, color: T.muted }}>
        Stay restrictions apply to the rate. They are enforced at booking time in the system.
      </div>
      <window.Grid>
        <window.Field label="Min length of stay" required span={6} hint="Required nights">
          <window.TextField value={form.minLOS} onChange={(v) => upd({ minLOS: v })} suffix="nights" placeholder="1" />
        </window.Field>
        <window.Field label="Max length of stay" span={6} hint="Optional cap">
          <window.TextField value={form.maxLOS} onChange={(v) => upd({ maxLOS: v })} suffix="nights" placeholder="No max" />
        </window.Field>
        <window.Field label="Blackout dates" span={12} hint="Dates where rate is not bookable">
          <window.TextField value={form.blackoutDates} onChange={(v) => upd({ blackoutDates: v })} placeholder="e.g. 24 Dec 2026 – 02 Jan 2027; 14 Feb 2026" />
        </window.Field>
        <window.Field label="Day-of-week restrictions" span={12} hint="Days where rate is bookable (default: all)">
          <window.ChipMultiSelect
            options={[{ 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" }]}
            value={form.dowAllowed || ["MO", "TU", "WE", "TH", "FR", "SA", "SU"]}
            onChange={(v) => upd({ dowAllowed: v })}
          />
        </window.Field>
        <div style={{ gridColumn: "span 12", display: "flex", flexDirection: "column", gap: 8, marginTop: 4 }}>
          <window.Checkbox checked={form.advancePurchase} onChange={(v) => upd({ advancePurchase: v })} label="Advance purchase required" hint="Specify lead time below if checked" />
          {form.advancePurchase && (
            <div style={{ marginLeft: 28, maxWidth: 240 }}>
              <window.TextField value={form.advanceDays} onChange={(v) => upd({ advanceDays: v })} suffix="days before arrival" placeholder="14" />
            </div>
          )}
          <window.Checkbox checked={form.commissionable} onChange={(v) => upd({ commissionable: v })} label="Commissionable" hint="Travel agencies receive commission on bookings" />
          <window.Checkbox checked={form.closedToArrival} onChange={(v) => upd({ closedToArrival: v })} label="Closed to arrival on blackout dates" />
        </div>
      </window.Grid>
    </div>
  );
}

function StepStay({ form, upd }) {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
      <window.Field label="Attachments" hint="Rate sheet, signed contract">
        <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={3} placeholder="Anything special about this load…" />
      </window.Field>
    </div>
  );
}

function StepReview({ form, upd }) {
  const Section = ({ title, children, step }) => (
    <div style={{ background: T.surface, border: `1px solid ${T.border}`, borderRadius: 8, marginBottom: 14, overflow: "hidden" }}>
      <div style={{ padding: "10px 14px", background: T.surface2, borderBottom: `1px solid ${T.border}`, display: "flex", justifyContent: "space-between", alignItems: "center" }}>
        <div style={{ fontSize: 12, fontWeight: 700, color: T.ink2, textTransform: "uppercase", letterSpacing: 0.4 }}>{title}</div>
        <span style={{ fontSize: 11.5, color: T.accent, fontWeight: 600, cursor: "pointer" }}>Edit step {step + 1}</span>
      </div>
      <div style={{ padding: 14 }}>{children}</div>
    </div>
  );
  const Row = ({ label, value, mono }) => (
    <div style={{ display: "flex", justifyContent: "space-between", padding: "5px 0", borderBottom: `1px dashed ${T.border}`, fontSize: 13 }}>
      <span style={{ color: T.muted }}>{label}</span>
      <span style={{ color: T.ink, fontFamily: mono ? T.mono : T.sans, fontWeight: mono ? 500 : 400 }}>{value || "—"}</span>
    </div>
  );
  return (
    <div>
      <Section title="Requester" step={0}>
        <Row label="Name" value={form.requesterName} />
        <Row label="Email" value={form.requesterEmail} mono />
      </Section>
      <Section title="Customer" step={1}>
        <Row label="Account" value={form.customer ? `${form.customer.name}` : form.customerName} />
        <Row label="ID(s)" value={(form.customerIds || []).filter(c => c.id).map(c => `${c.type}: ${c.id}`).join(", ") || "—"} mono />
        <Row label="Email" value={form.customerEmail} mono />
        <Row label="Phone" value={form.customerPhone} />
        <Row label="Hotels" value={form.hotels.length ? `${form.hotels.length} selected · ${form.hotels.map(h => MOCK_HOTELS.find(m => m.id === h)?.id.slice(-3)).filter(Boolean).join(", ")}` : null} />
        <Row label="Channels" value={(form.channels || []).map(c => ({ DIRECT: "Hotel Direct", WEB: "Hotel Website", GDS: "GDS" }[c] || c)).join(", ") || "—"} />
        {(form.channels || []).includes("GDS") && <Row label="Lanyon managed RFP" value={form.lanyonManaged || "Not answered"} />}
      </Section>
      <Section title="Price code" step={2}>
        <Row label="Type" value={form.priceCodeType} />
        <Row label="Rooms × Meals" value={`${form.rooms.length} × ${form.meals.length}`} />
        {form.hotels.length > 1 ? (
          <Row label="Per-hotel pricing" value={`${Object.keys(form.hotelMatrices || {}).filter(k => form.hotels.includes(k)).length} of ${form.hotels.length} hotels customised`} />
        ) : (
          <Row label="Cells filled" value={`${Object.values(form.matrix).filter(v => v && v !== "0,00" && v !== "0.00").length} of ${form.rooms.length * form.meals.length * 4}`} />
        )}
      </Section>
      <Section title="Rate" step={3}>
        <Row label="Description" value={form.rateDescription} />
        <Row label="Inclusions" value={form.rateInclusions} />
        <Row label="Market segment" value={form.marketSegment} />
        <Row label="Booking" value={form.bookingStart ? `${window.fmt(form.bookingStart)} → ${window.fmt(form.bookingEnd)}` : null} />
        <Row label="Stay" value={form.travelStart ? `${window.fmt(form.travelStart)} → ${window.fmt(form.travelEnd)}` : null} />
      </Section>
      <Section title="Contract" step={4}>
        <Row label="Rate type" value={form.rateType + (form.rateType === "Corporate Negotiated" && form.lraType ? ` · ${form.lraType}` : "")} />
        <Row label="Validity" value={form.contractStart && form.contractEnd ? `${window.fmt(form.contractStart)} → ${window.fmt(form.contractEnd)}` : null} />
        <Row label="Currency · tax" value={`${form.contractCurrency} · ${form.contractTax}`} />
          <Row label="Cancellation" value={form.cancellationPolicy || "Not set"} />
        <Row label="Length of stay" value={`${form.minLOS || "—"} – ${form.maxLOS || "∞"} nights`} />
        <Row label="Blackout dates" value={form.blackoutDates} />
      </Section>
      <Section title="Files" step={5}>
        <Row label="Attachments" value={`${form.attachments.length} file(s)`} />
      </Section>
      <div style={{ background: T.warnSoft, border: `1px solid #EDD2A9`, borderRadius: 8, padding: 14, marginTop: 18 }}>
        <window.Checkbox
          checked={form.acknowledged}
          onChange={(v) => upd({ acknowledged: v })}
          label={<span style={{ fontWeight: 600 }}>I confirm the details are correct and match naming conventions</span>}
          hint="Tax and currency must be identical across contract, price code and rate. Submitter is responsible for accuracy."
        />
      </div>
    </div>
  );
}

function SubmittedScreen({ form, ticketId, onReset }) {
  return (
    <div style={{ width: 1100, height: 760, background: T.bg, fontFamily: T.sans, color: T.ink, display: "flex", alignItems: "center", justifyContent: "center" }}>
      <div style={{ maxWidth: 480, textAlign: "center" }}>
        <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: 30, fontWeight: 500, letterSpacing: -0.4, fontFamily: "'Cormorant Garamond', 'EB Garamond', Georgia, serif" }}>Ticket created</h2>
        <p style={{ color: T.muted, fontSize: 14, marginTop: 8 }}>
          Reference <span style={{ fontFamily: T.mono, color: T.ink, fontWeight: 600 }}>{ticketId}</span> · {form.contractCode || "—"} · {form.customer?.name || "Customer"}
        </p>
        <p style={{ color: T.muted, fontSize: 13, marginTop: 14, lineHeight: 1.6 }}>
          The load team has been notified. They'll load this rate within {form.ratePriority === "Urgent (24h)" ? "24" : form.ratePriority === "Expedited (48h)" ? "48" : "72"} hours.
          A confirmation email with the full summary has been sent to <strong>{form.requesterEmail}</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={() => window.open("https://connectconsultingsolutions.freshdesk.com/support/tickets", "_blank")}>View tickets</window.Button>
        </div>
      </div>
    </div>
  );
}

window.WizardVariation = WizardVariation;
