/* ============================================================
   Modal shell + Request form + Request detail
   ============================================================ */
const { useState, useEffect, useRef } = React;
function Modal({ children, onClose, width = 560 }) {
  const narrow = useIsNarrow(820);
  useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [onClose]);
  return (
    <div onClick={onClose} style={{
      position: "fixed", inset: 0, zIndex: 60, background: "rgba(26,33,56,0.42)",
      backdropFilter: "blur(3px)", display: "grid", placeItems: narrow ? "end center" : "center",
      padding: narrow ? "0" : 24,
    }}>
      <div onClick={(e) => e.stopPropagation()} className="vp-pop" style={{
        width: "100%", maxWidth: narrow ? "100%" : width, maxHeight: narrow ? "94vh" : "92vh", overflowY: "auto",
        background: "var(--surface)",
        borderRadius: narrow ? "var(--r-xl) var(--r-xl) 0 0" : "var(--r-xl)",
        boxShadow: "var(--sh-pop)", border: "1px solid var(--line)",
      }}>{children}</div>
    </div>
  );
}

/* ----- Mini range calendar ----- */
function RangeCalendar({ from, to, onPick, half }) {
  const init = from ? parseISO(from) : parseISO(TODAY);
  const [view, setView] = useState({ y: init.getFullYear(), m: init.getMonth() });
  const firstDow = (new Date(view.y, view.m, 1).getDay() + 6) % 7; // Mon=0
  const daysInMonth = new Date(view.y, view.m + 1, 0).getDate();
  const cells = [];
  for (let i = 0; i < firstDow; i++) cells.push(null);
  for (let d = 1; d <= daysInMonth; d++) cells.push(d);

  const fromD = from ? parseISO(from) : null;
  const toD = to ? parseISO(to) : null;
  const todayD = parseISO(TODAY);

  function cellState(d) {
    const dt = new Date(view.y, view.m, d);
    const iso = toISO(dt);
    const isFrom = from === iso, isTo = to === iso;
    const inRange = fromD && toD && dt > fromD && dt < toD;
    const past = dt < todayD;
    return { dt, iso, isFrom, isTo, inRange, past, weekend: isWeekend(dt), isToday: iso === TODAY };
  }

  return (
    <div>
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 12 }}>
        <button type="button" className="vp-focusable" onClick={() => setView((v) => v.m === 0 ? { y: v.y - 1, m: 11 } : { ...v, m: v.m - 1 })}
          style={navBtn}><Icon name="chevLeft" size={17} /></button>
        <div style={{ fontWeight: 600, fontFamily: "var(--font-display)", fontSize: 16 }}>{MONTHS[view.m]} {view.y}</div>
        <button type="button" className="vp-focusable" onClick={() => setView((v) => v.m === 11 ? { y: v.y + 1, m: 0 } : { ...v, m: v.m + 1 })}
          style={navBtn}><Icon name="chevRight" size={17} /></button>
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(7,1fr)", gap: 3 }}>
        {DOW.map((d) => <div key={d} style={{ textAlign: "center", fontSize: 11, fontWeight: 700, color: "var(--ink-4)", padding: "4px 0" }}>{d[0]}</div>)}
        {cells.map((d, i) => {
          if (d == null) return <div key={i} />;
          const s = cellState(d);
          const selected = s.isFrom || s.isTo;
          return (
            <button key={i} type="button" disabled={s.past}
              onClick={() => onPick(s.iso)}
              className="vp-focusable"
              style={{
                position: "relative", aspectRatio: "1", border: "none", cursor: s.past ? "default" : "pointer",
                borderRadius: s.isFrom ? "8px 4px 4px 8px" : s.isTo ? "4px 8px 8px 4px" : s.inRange ? "3px" : "8px",
                background: selected ? "var(--accent)" : s.inRange ? "var(--accent-soft)" : "transparent",
                color: selected ? "#fff" : s.past ? "var(--ink-4)" : s.weekend ? "var(--ink-4)" : "var(--ink)",
                fontWeight: selected || s.isToday ? 700 : 500, fontSize: 13.5,
                opacity: s.past ? 0.4 : 1, transition: "background 0.12s ease",
                fontFamily: "var(--font-body)",
              }}>
              {d}
              {s.isToday && !selected && <span style={{ position: "absolute", bottom: 4, left: "50%", transform: "translateX(-50%)", width: 4, height: 4, borderRadius: "50%", background: "var(--accent)" }} />}
            </button>
          );
        })}
      </div>
    </div>
  );
}
const navBtn = {
  width: 32, height: 32, display: "grid", placeItems: "center", borderRadius: "var(--r-sm)",
  border: "1px solid var(--line-2)", background: "var(--surface)", cursor: "pointer", color: "var(--ink-2)",
};

/* ----- Request form ----- */
function RequestForm({ user, requests, onSubmit, onClose }) {
  const [type, setType] = useState("vacation");
  const [from, setFrom] = useState("");
  const [to, setTo] = useState("");
  const [replacement, setReplacement] = useState("");
  const [note, setNote] = useState("");
  const [err, setErr] = useState("");
  const narrow = useIsNarrow(820);
  const lt = VP_DATA.leaveTypes[type];

  // half day = single day always
  function pick(iso) {
    if (type === "half") { setFrom(iso); setTo(iso); return; }
    if (!from || (from && to)) { setFrom(iso); setTo(""); }
    else { if (parseISO(iso) < parseISO(from)) { setTo(from); setFrom(iso); } else { setTo(iso); } }
    setErr("");
  }
  useEffect(() => { if (type === "half" && from) setTo(from); }, [type]);

  const colleagues = VP_DATA.people.filter((p) => p.id !== user.id);
  const draft = { type, from, to: to || from, replacement: replacement || null, note };
  const days = (from) ? workingDays({ type, from, to: to || from, person: user.id }) : 0;
  const bal = balanceFor(user.id, requests);
  const overBudget = lt.countsToBalance && days > bal.remaining;

  function submit() {
    if (!from) { setErr("Pick a start date."); return; }
    if (type !== "half" && !to) { setErr("Pick an end date (or click the same day twice)."); return; }
    if (lt.needsReplacement && !replacement) { setErr(`A replacement is required for ${lt.label.toLowerCase()}.`); return; }
    onSubmit({
      id: VP_DATA.rid(), person: user.id, type, from, to: to || from,
      replacement: replacement || null, note: note.trim(), status: "pending", submitted: TODAY,
    });
  }

  return (
    <div>
      <div style={{ padding: "22px 26px", borderBottom: "1px solid var(--line)", display: "flex", justifyContent: "space-between", alignItems: "center" }}>
        <h2 style={{ fontSize: 22 }}>Request time off</h2>
        <button type="button" onClick={onClose} className="vp-focusable" style={{ ...navBtn, border: "none", background: "var(--paper-2)" }}><Icon name="x" size={18} /></button>
      </div>

      <div style={{ padding: "22px 26px", display: "grid", gap: 22 }}>
        {/* Type */}
        <div>
          <div style={fieldLabel}>Type of leave</div>
          <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
            {Object.values(VP_DATA.leaveTypes).map((t) => {
              const on = type === t.id;
              return (
                <button key={t.id} type="button" onClick={() => { setType(t.id); setErr(""); }}
                  className="vp-focusable"
                  style={{
                    display: "inline-flex", alignItems: "center", gap: 7, padding: "9px 13px",
                    borderRadius: "var(--r-sm)", cursor: "pointer", fontWeight: 600, fontSize: 13.5,
                    border: `1px solid ${on ? "transparent" : "var(--line-2)"}`,
                    background: on ? t.soft : "var(--surface)", color: on ? t.color : "var(--ink-2)",
                    boxShadow: on ? `inset 0 0 0 1px ${t.color}` : "none", transition: "all 0.14s ease", whiteSpace: "nowrap",
                  }}>
                  <Icon name={t.icon} size={15} stroke={1.9} /> {t.label}
                </button>
              );
            })}
          </div>
        </div>

        {/* Dates */}
        <div style={{ display: "grid", gridTemplateColumns: narrow ? "1fr" : "1fr 220px", gap: 22, alignItems: "start" }}>
          <div>
            <div style={fieldLabel}>{type === "half" ? "Pick the day" : "Pick your dates"}</div>
            <Card pad="16px" style={{ boxShadow: "none", background: "var(--surface-2)" }}>
              <RangeCalendar from={from} to={to} onPick={pick} half={type === "half"} />
            </Card>
          </div>
          <div style={{ display: "grid", gap: 14 }}>
            <Summary label="Starts" value={from ? fmtDateLong(from) : "—"} />
            <Summary label={type === "half" ? "Half day" : "Ends"} value={type === "half" ? "Afternoon" : (to ? fmtDateLong(to) : "—")} />
            <div style={{
              padding: "13px 15px", borderRadius: "var(--r-md)",
              background: overBudget ? "var(--st-declined-soft)" : "var(--accent-soft)",
              color: overBudget ? "var(--st-declined)" : "var(--accent-ink)",
            }}>
              <div style={{ fontSize: 12, fontWeight: 600, opacity: 0.8 }}>{lt.countsToBalance ? "Counts toward balance" : "Doesn't use vacation days"}</div>
              <div style={{ fontFamily: "var(--font-display)", fontSize: 26, fontWeight: 600, marginTop: 2 }}>
                {days} {days === 1 ? "day" : "days"}
              </div>
              {lt.countsToBalance && <div style={{ fontSize: 12, marginTop: 2 }}>{overBudget ? `Only ${bal.remaining} left` : `${bal.remaining - days} would remain`}</div>}
            </div>
          </div>
        </div>

        {/* Replacement */}
        {(lt.needsReplacement || replacement) && (
          <div>
            <div style={fieldLabel}>
              Replacement during absence {lt.needsReplacement && <span style={{ color: "var(--accent)" }}>· required</span>}
            </div>
            <ColleagueSelect value={replacement} onChange={setReplacement} colleagues={colleagues} />
          </div>
        )}

        {/* Note */}
        <div>
          <div style={fieldLabel}>Note <span style={{ color: "var(--ink-4)", fontWeight: 500 }}>· optional</span></div>
          <textarea value={note} onChange={(e) => setNote(e.target.value)} rows={2}
            placeholder="Anything the reviewer should know?" className="vp-focusable"
            style={{
              width: "100%", padding: "11px 13px", fontSize: 14.5, resize: "vertical",
              border: "1px solid var(--line-2)", borderRadius: "var(--r-sm)", outline: "none",
              color: "var(--ink)", background: "var(--surface)", lineHeight: 1.5,
            }} />
        </div>

        {err && <div className="vp-fade" style={{ display: "flex", gap: 9, alignItems: "center", color: "var(--st-declined)", fontSize: 13.5, fontWeight: 500 }}>
          <Icon name="info" size={17} /> {err}
        </div>}
      </div>

      <div style={{ padding: narrow ? "14px 16px" : "16px 26px", borderTop: "1px solid var(--line)", display: "flex", justifyContent: "space-between", alignItems: "center", gap: 12, position: "sticky", bottom: 0, background: "var(--surface)" }}>
        {!narrow && <span style={{ fontSize: 13, color: "var(--ink-4)" }}>A CEO reviews every request.</span>}
        <div style={{ display: "flex", gap: 10, flex: narrow ? 1 : "none", justifyContent: "flex-end" }}>
          <Button variant="ghost" onClick={onClose}>Cancel</Button>
          <Button icon="check" onClick={submit} disabled={overBudget}>Submit request</Button>
        </div>
      </div>
    </div>
  );
}

function Summary({ label, value }) {
  return (
    <div>
      <div style={{ fontSize: 11.5, fontWeight: 700, letterSpacing: "0.06em", textTransform: "uppercase", color: "var(--ink-4)" }}>{label}</div>
      <div style={{ fontWeight: 600, fontSize: 15.5, color: "var(--ink)", marginTop: 3, fontFamily: "var(--font-display)" }}>{value}</div>
    </div>
  );
}

/* Custom colleague dropdown with avatars */
function ColleagueSelect({ value, onChange, colleagues }) {
  const [open, setOpen] = useState(false);
  const ref = useRef(null);
  useEffect(() => {
    const h = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", h); return () => document.removeEventListener("mousedown", h);
  }, []);
  const sel = value ? VP_DATA.byId[value] : null;
  return (
    <div ref={ref} style={{ position: "relative" }}>
      <button type="button" onClick={() => setOpen((o) => !o)} className="vp-focusable"
        style={{
          width: "100%", display: "flex", alignItems: "center", gap: 11, padding: "10px 13px",
          border: `1px solid ${open ? "var(--accent)" : "var(--line-2)"}`, borderRadius: "var(--r-sm)",
          background: "var(--surface)", cursor: "pointer", textAlign: "left",
          boxShadow: open ? "0 0 0 3px var(--accent-soft)" : "none",
        }}>
        {sel ? <Avatar person={sel} size={30} /> : <div style={{ width: 30, height: 30, borderRadius: "50%", background: "var(--paper-2)", display: "grid", placeItems: "center", color: "var(--ink-4)" }}><Icon name="users" size={16} /></div>}
        <span style={{ flex: 1, fontWeight: sel ? 600 : 500, color: sel ? "var(--ink)" : "var(--ink-4)", fontSize: 14.5 }}>
          {sel ? `${sel.first} ${sel.last}` : "Choose a colleague…"}
        </span>
        <Icon name="chevDown" size={17} style={{ color: "var(--ink-4)", transform: open ? "rotate(180deg)" : "none", transition: "transform 0.16s" }} />
      </button>
      {open && (
        <div className="vp-pop" style={{
          position: "absolute", top: "calc(100% + 6px)", left: 0, right: 0, zIndex: 5,
          background: "var(--surface)", border: "1px solid var(--line)", borderRadius: "var(--r-md)",
          boxShadow: "var(--sh-lg)", padding: 6, maxHeight: 240, overflowY: "auto",
        }}>
          {colleagues.map((p) => (
            <button key={p.id} type="button" onClick={() => { onChange(p.id); setOpen(false); }}
              style={{
                width: "100%", display: "flex", alignItems: "center", gap: 11, padding: "8px 10px",
                border: "none", background: value === p.id ? "var(--accent-soft)" : "transparent",
                borderRadius: "var(--r-sm)", cursor: "pointer", textAlign: "left",
              }}>
              <Avatar person={p} size={30} />
              <div style={{ flex: 1 }}>
                <div style={{ fontWeight: 600, fontSize: 14 }}>{p.first} {p.last}</div>
                <div style={{ fontSize: 12, color: "var(--ink-3)" }}>{p.team}</div>
              </div>
              {value === p.id && <Icon name="check" size={16} style={{ color: "var(--accent)" }} />}
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

const fieldLabel = { fontSize: 13.5, fontWeight: 600, color: "var(--ink-2)", marginBottom: 10 };

Object.assign(window, { Modal, RequestForm, RangeCalendar, ColleagueSelect, Summary });
