/* global React */
const { useState, useEffect, useRef } = React;

// ============================================================
//  Booking modal — slides in from the right.
//  Lightweight Zod-style validation (no external lib).
// ============================================================

function validate(values) {
  const errs = {};
  if (!values.name || values.name.trim().length < 2) errs.name = "Please enter your full name.";
  if (!values.email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(values.email)) errs.email = "Enter a valid work email.";
  if (!values.company || values.company.trim().length < 2) errs.company = "Company name is required.";
  if (!values.service) errs.service = "Pick the service you're interested in.";
  if (!values.slot) errs.slot = "Pick a time slot.";
  if (values.message && values.message.length > 1000) errs.message = "Keep it under 1000 characters.";
  return errs;
}

const BOOKING_SERVICES = [
  "IT consulting & digital transformation",
  "Agile project management",
  "Application development",
  "Cloud & infrastructure services",
  "Cybersecurity",
  "24/7 managed IT services",
];

function generateSlots() {
  const out = [];
  const now = new Date();
  for (let d = 1; d <= 5; d++) {
    const day = new Date(now);
    day.setDate(now.getDate() + d);
    if (day.getDay() === 0 || day.getDay() === 6) { d++; continue; }
    const dayLabel = day.toLocaleDateString(undefined, { weekday: "short", month: "short", day: "numeric" });
    ["10:00", "11:30", "14:00", "15:30", "17:00"].forEach((t, i) => {
      out.push({ id: `${dayLabel}-${t}`, day: dayLabel, time: t, disabled: (d === 1 && i < 2) });
    });
    if (out.length >= 25) break;
  }
  return out;
}

function BookingModal({ isOpen, onClose }) {
  const [values, setValues] = useState({ name: "", email: "", company: "", service: "", slot: "", message: "" });
  const [errors, setErrors] = useState({});
  const [touched, setTouched] = useState({});
  const [state, setState] = useState("idle"); // idle | submitting | success
  const slots = useState(() => generateSlots())[0];
  const panelRef = useRef(null);

  useEffect(() => {
    if (isOpen) {
      document.body.classList.add("no-scroll");
      // focus first field after enter animation
      setTimeout(() => panelRef.current?.querySelector("input,select,textarea")?.focus(), 400);
    } else {
      document.body.classList.remove("no-scroll");
    }
    const onKey = (e) => { if (e.key === "Escape" && isOpen) onClose(); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [isOpen, onClose]);

  const setField = (k, v) => {
    setValues((s) => ({ ...s, [k]: v }));
    if (touched[k]) setErrors(validate({ ...values, [k]: v }));
  };

  const submit = (e) => {
    e.preventDefault();
    const eobj = validate(values);
    setErrors(eobj);
    setTouched({ name: 1, email: 1, company: 1, service: 1, slot: 1, message: 1 });
    if (Object.keys(eobj).length > 0) return;
    setState("submitting");
    setTimeout(() => setState("success"), 1100);
  };

  const reset = () => {
    setValues({ name: "", email: "", company: "", service: "", slot: "", message: "" });
    setErrors({}); setTouched({}); setState("idle");
  };

  return (
    <div
      style={{
        position: "fixed", inset: 0, zIndex: 200,
        pointerEvents: isOpen ? "auto" : "none",
      }}
      aria-hidden={!isOpen}
    >
      {/* scrim */}
      <div
        onClick={onClose}
        style={{
          position: "absolute", inset: 0,
          background: "rgba(20,20,19,0.45)",
          opacity: isOpen ? 1 : 0,
          transition: "opacity 400ms ease",
        }}
      />
      {/* panel */}
      <div
        ref={panelRef}
        role="dialog" aria-label="Book a call"
        style={{
          position: "absolute", top: 0, right: 0, height: "100%",
          width: "min(560px, 100%)", background: "var(--color-canvas)",
          transform: isOpen ? "translateX(0)" : "translateX(105%)",
          transition: "transform 600ms cubic-bezier(0.7, 0, 0.2, 1)",
          boxShadow: "-20px 0 60px rgba(20,20,19,0.18)",
          display: "flex", flexDirection: "column",
        }}
      >
        {/* header */}
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "20px 28px", borderBottom: "1px solid var(--color-hairline)" }}>
          <div style={{ display: "inline-flex", alignItems: "center", gap: 10 }}>
            <SpikeMark size={18} />
            <span style={{ fontFamily: "var(--font-display)", fontSize: 22 }}>Book a call</span>
          </div>
          <button onClick={onClose} aria-label="Close"
            style={{ width: 40, height: 40, border: "1px solid var(--color-hairline)", borderRadius: 9999, background: "transparent", cursor: "pointer", display: "inline-flex", alignItems: "center", justifyContent: "center" }}>
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5"><path d="M5 5l14 14M5 19L19 5"/></svg>
          </button>
        </div>

        {/* body */}
        <div style={{ padding: "28px", overflowY: "auto", flex: 1 }}>
          {state === "success" ? (
            <SuccessPanel values={values} onClose={onClose} onAnother={reset} />
          ) : (
            <form onSubmit={submit} noValidate>
              <p style={{ color: "var(--color-body)", marginBottom: 24 }}>
                A 30-minute call with one of our principals. We'll confirm by email within an hour.
              </p>

              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }} className="bk-grid">
                <Field label="Full name" name="name" value={values.name} error={touched.name && errors.name} onChange={(v) => setField("name", v)} onBlur={() => setTouched({ ...touched, name: 1 })} />
                <Field label="Work email" name="email" value={values.email} type="email" error={touched.email && errors.email} onChange={(v) => setField("email", v)} onBlur={() => setTouched({ ...touched, email: 1 })} />
                <Field label="Company" name="company" value={values.company} error={touched.company && errors.company} onChange={(v) => setField("company", v)} onBlur={() => setTouched({ ...touched, company: 1 })} wide />
                <div className="field" style={{ gridColumn: "1 / -1" }}>
                  <label>Service interested in</label>
                  <select value={values.service} onChange={(e) => setField("service", e.target.value)} onBlur={() => setTouched({ ...touched, service: 1 })}>
                    <option value="">Select a service…</option>
                    {BOOKING_SERVICES.map((s) => <option key={s} value={s}>{s}</option>)}
                  </select>
                  <span className="err">{touched.service && errors.service}</span>
                </div>
              </div>

              <div className="field" style={{ marginTop: 4 }}>
                <label>Pick a time slot · 30 min</label>
                <div className="slots">
                  {slots.slice(0, 12).map((s) => (
                    <button
                      type="button" key={s.id}
                      disabled={s.disabled}
                      onClick={() => setField("slot", s.id)}
                      onBlur={() => setTouched({ ...touched, slot: 1 })}
                      className={["slot", values.slot === s.id ? "selected" : "", s.disabled ? "disabled" : ""].join(" ")}
                    >
                      <div style={{ fontWeight: 500 }}>{s.day}</div>
                      <div style={{ opacity: 0.75, fontSize: 12 }}>{s.time}</div>
                    </button>
                  ))}
                </div>
                <span className="err">{touched.slot && errors.slot}</span>
              </div>

              <div className="field" style={{ marginTop: 16 }}>
                <label>Anything we should know?</label>
                <textarea
                  value={values.message}
                  onChange={(e) => setField("message", e.target.value)}
                  onBlur={() => setTouched({ ...touched, message: 1 })}
                  placeholder="A few lines about your project, timeline or pain point."
                />
                <span className="err">{touched.message && errors.message}</span>
              </div>

              <button
                type="submit" disabled={state === "submitting"}
                className="btn-coral"
                style={{ width: "100%", marginTop: 20, height: 56, justifyContent: "center", borderRadius: 12 }}
              >
                {state === "submitting" ? (
                  <span style={{ display: "inline-flex", alignItems: "center", gap: 10 }}>
                    <span style={{ width: 14, height: 14, border: "2px solid currentColor", borderTopColor: "transparent", borderRadius: 9999, animation: "spin 700ms linear infinite" }} /> Sending…
                  </span>
                ) : (
                  <>Confirm booking <Arrow/></>
                )}
              </button>
              <p style={{ marginTop: 12, fontSize: 12, color: "var(--color-muted)", textAlign: "center" }}>
                By submitting, you agree to our privacy notice. We never share your data.
              </p>
            </form>
          )}
        </div>
      </div>
      <style>{`
        @keyframes spin { to { transform: rotate(360deg); } }
        @media (max-width: 540px) {
          .bk-grid { grid-template-columns: 1fr !important; }
        }
      `}</style>
    </div>
  );
}

function Field({ label, name, value, type = "text", error, onChange, onBlur, wide }) {
  return (
    <div className="field" style={wide ? { gridColumn: "1 / -1" } : null}>
      <label htmlFor={name}>{label}</label>
      <input id={name} name={name} type={type} value={value} onChange={(e) => onChange(e.target.value)} onBlur={onBlur} autoComplete={type === "email" ? "email" : "off"} />
      <span className="err">{error}</span>
    </div>
  );
}

function SuccessPanel({ values, onClose, onAnother }) {
  return (
    <div style={{ paddingTop: 24, animation: "fadeUp 700ms ease" }}>
      <style>{`@keyframes fadeUp { from { opacity:0; transform: translateY(12px); } to { opacity:1; transform:none; } }`}</style>
      <div style={{ width: 64, height: 64, borderRadius: 9999, background: "var(--color-primary)", color: "var(--color-on-primary)", display: "inline-flex", alignItems: "center", justifyContent: "center" }}>
        <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12l4 4 10-10"/></svg>
      </div>
      <h3 style={{ fontFamily: "var(--font-display)", fontSize: 40, marginTop: 24, letterSpacing: "-0.5px" }}>You're booked.</h3>
      <p style={{ marginTop: 12, color: "var(--color-body)", maxWidth: 420 }}>
        Thanks, {values.name.split(" ")[0]}. A calendar invite for <strong>{values.slot.replace(/-/, " · ")}</strong> is on its way to {values.email}.
      </p>
      <div style={{ marginTop: 28, padding: 20, background: "var(--color-surface-card)", borderRadius: 12 }}>
        <div className="eyebrow"><span className="dot"/> What happens next</div>
        <ul style={{ margin: "12px 0 0", paddingLeft: 18, color: "var(--color-body)" }}>
          <li>Brief intake email arrives within an hour.</li>
          <li>One of our principals will join the call.</li>
          <li>You'll leave with a written next-step recommendation.</li>
        </ul>
      </div>
      <div style={{ display: "flex", gap: 10, marginTop: 24 }}>
        <button className="btn-coral" onClick={onClose}>Close</button>
        <button className="btn-ghost" onClick={onAnother}>Book another</button>
      </div>
    </div>
  );
}

Object.assign(window, { BookingModal });
