// Modals: AddPerformance, EditPerformance, StageEditor, LineupMatrix
// Each follows the same Crewli light-mode chrome.

const M = (function () {
  const ESC_KEY = 27;

  function Backdrop({ children, onClose }) {
    React.useEffect(() => {
      const h = (e) => { if (e.keyCode === ESC_KEY) onClose(); };
      window.addEventListener("keydown", h);
      return () => window.removeEventListener("keydown", h);
    }, []);
    return (
      <div className="cw-backdrop" onMouseDown={(e) => { if (e.target === e.currentTarget) onClose(); }}>
        {children}
      </div>
    );
  }

  function Field({ label, hint, error, children }) {
    return (
      <label className={"cw-field" + (error ? " cw-field-error" : "")}>
        <span className="cw-field-lbl">{label}</span>
        {children}
        {error
          ? <span className="cw-field-err" role="alert">
              <svg width="12" height="12" viewBox="0 0 12 12" aria-hidden="true">
                <circle cx="6" cy="6" r="5.4" fill="#d63d4b"/>
                <rect x="5.4" y="3" width="1.2" height="3.6" fill="white"/>
                <rect x="5.4" y="7.4" width="1.2" height="1.2" fill="white"/>
              </svg>
              {error}
            </span>
          : hint && <span className="cw-field-hint">{hint}</span>}
      </label>
    );
  }

  // ─── Add / Edit Performance ─────────────────────────────────────────
  // "Add" creates a brand-new act (artist + performance) on the fly.
  // Fields: Naam Act, Genre, Status. Stage/tijd komen mee als de popup
  // geopend is via een lege cel in de timetable — starttijd is dan
  // alleen-lezen, eindtijd = start + 1u.
  function PerformanceModal({ mode, perf, day, stages, artists, onSave, onClose, onDelete }) {
    const D = window.CrewliData;
    const H = window.CrewliHelpers;
    const fromTimetable = mode === "add" && perf?.stage_id != null && perf?.start != null;
    const start = fromTimetable ? perf.start : null;
    const end = fromTimetable ? perf.start + 60 : null;

    // Edit mode preloads the existing artist; add mode is a blank act form.
    const existingArtist = mode === "edit" ? artists.find(a => a.id === perf?.artist_id) : null;
    const [name, setName]   = React.useState(existingArtist?.name || "");
    const [genre, setGenre] = React.useState(existingArtist?.genre || D.GENRES[0]);
    const [status, setStatus] = React.useState(perf?.status || (fromTimetable ? "concept" : "requested"));
    // Duur (alleen relevant bij + Performance vanuit header — wachtrij heeft geen tijd)
    const [duration, setDuration] = React.useState(60);

    const stage = fromTimetable ? stages.find(s => s.id === perf.stage_id) : null;
    const startStr = start != null ? H.fmtTime(start, D.TIME.startHour) : null;
    const endStr   = end   != null ? H.fmtTime(end,   D.TIME.startHour) : null;

    const [touched, setTouched] = React.useState(false);
    const trimmed = name.trim();
    const nameError = trimmed.length === 0 ? "Naam Act is verplicht"
                    : trimmed.length > 60 ? "Maximaal 60 tekens"
                    : null;
    const canSave = !nameError;

    function save() {
      setTouched(true);
      if (!canSave) return;

      if (mode === "edit") {
        // Edit only updates status here (rename/genre niet binnen scope).
        onSave({ artistUpdate: null, perf: { ...perf, status } });
        return;
      }

      // ── Add: create artist + performance ──
      // Initials: keep only Latin letters/digits to avoid weird glyphs in the avatar.
      const safeChars = trimmed.replace(/[^A-Za-z0-9 ]/g, "").trim();
      const parts = safeChars.split(/\s+/).filter(Boolean);
      let initials = parts.length >= 2
        ? (parts[0][0] + parts[1][0])
        : (parts[0] ? parts[0].slice(0, 2) : "");
      initials = initials.toUpperCase() || "??";
      const newArtist = {
        id: "a_" + Math.random().toString(36).slice(2, 8),
        name: name.trim(),
        initials,
        genre,
        draw: 0,
        advance: { tour: false, hosp: false, travel: false, flight: false, rider: false },
      };
      const basePerf = {
        id: "p_" + Math.random().toString(36).slice(2, 8),
        artist_id: newArtist.id,
        day_id: day.id,
        status,
      };
      if (fromTimetable) {
        const lanePart = Number.isInteger(perf.lane) ? { lane: perf.lane } : {};
        onSave({ newArtist, perf: { ...basePerf, stage_id: perf.stage_id, start, end, ...lanePart } });
      } else {
        // Geen timetable-context → wachtrij. Bewaar duur zodat block bij drop de juiste breedte krijgt.
        onSave({ newArtist, perf: { ...basePerf, stage_id: null, dur: duration } });
      }
    }

    return (
      <Backdrop onClose={onClose}>
        <div className="cw-modal" style={{ width: 480 }} onMouseDown={(e) => e.stopPropagation()}>
          <div className="cw-modal-hd">
            <div className="cw-modal-title">
              {mode === "add" ? "Performance toevoegen" : "Performance bewerken"}
              <span className="cw-modal-sub">{day.label} · {D.EVENT.name}</span>
            </div>
            <button className="cw-icon-btn" onClick={onClose} aria-label="Sluiten">×</button>
          </div>
          <div className="cw-modal-body">
            <Field label="Naam Act" error={touched && nameError ? nameError : null}>
              <input className={"cw-input" + (touched && nameError ? " cw-input-error" : "")}
                     type="text" autoFocus
                     placeholder="bijv. Mau P"
                     value={name}
                     onChange={(e) => setName(e.target.value)}
                     onBlur={() => setTouched(true)}
                     disabled={mode === "edit"}
                     maxLength={80}
                     aria-invalid={touched && !!nameError}
                     aria-describedby={touched && nameError ? "cw-name-err" : undefined} />
            </Field>

            <div className="cw-row-2">
              <Field label="Genre">
                <select className="cw-input" value={genre}
                        onChange={(e) => setGenre(e.target.value)}
                        disabled={mode === "edit"}>
                  {D.GENRES.map(g => <option key={g} value={g}>{g}</option>)}
                </select>
              </Field>
              <Field label="Status">
                <select className="cw-input" value={status}
                        onChange={(e) => setStatus(e.target.value)}>
                  {Object.keys(H.STATUS).map(k =>
                    <option key={k} value={k}>{H.STATUS[k].label}</option>)}
                </select>
              </Field>
            </div>

            {fromTimetable && stage && (
              <div className="cw-mctx">
                <div className="cw-mctx-stage">
                  <span className="cw-mctx-stage-bar" style={{ background: stage.color }}></span>
                  <div className="cw-mctx-stage-body">
                    <span className="cw-mctx-eyebrow">Stage</span>
                    <span className="cw-mctx-stage-name">{stage.name}</span>
                  </div>
                  <span className="cw-mctx-readonly" title="Sleep het block in de timetable om te wijzigen">vast</span>
                </div>
                <div className="cw-mctx-time">
                  <div className="cw-mctx-time-col">
                    <span className="cw-mctx-eyebrow">Starttijd</span>
                    <span className="cw-mctx-time-val">{startStr}</span>
                  </div>
                  <span className="cw-mctx-arrow" aria-hidden="true">→</span>
                  <div className="cw-mctx-time-col">
                    <span className="cw-mctx-eyebrow">Eindtijd</span>
                    <span className="cw-mctx-time-val cw-mctx-time-soft">{endStr}</span>
                  </div>
                  <div className="cw-mctx-time-spacer"></div>
                  <span className="cw-mctx-dur">60 min</span>
                </div>
              </div>
            )}

            {!fromTimetable && mode === "add" && (
              <>
                <Field label="Duur optreden" hint="Wordt gebruikt zodra je het block uit de wachtrij naar de timetable sleept">
                  <select className="cw-input" value={duration}
                          onChange={(e) => setDuration(+e.target.value)}>
                    <option value={30}>30 min</option>
                    <option value={45}>45 min</option>
                    <option value={60}>60 min (1 uur)</option>
                    <option value={75}>75 min</option>
                    <option value={90}>90 min (1u30)</option>
                    <option value={120}>120 min (2 uur)</option>
                    <option value={150}>150 min (2u30)</option>
                    <option value={180}>180 min (3 uur)</option>
                  </select>
                </Field>
                <div className="cw-modal-hint">
                  Geen tijdslot gekozen — landt in de <b>wachtrij</b>.
                </div>
              </>
            )}
          </div>
          <div className="cw-modal-ft">
            {mode === "edit" && (
              <button className="cw-btn cw-btn-danger" onClick={() => onDelete(perf.id)}>Verwijderen</button>
            )}
            <div style={{ flex: 1 }}></div>
            <button className="cw-btn" onClick={onClose}>Annuleren</button>
            <button className="cw-btn cw-btn-primary" onClick={save} disabled={!canSave}>
              {mode === "add" ? "Toevoegen" : "Opslaan"}
            </button>
          </div>
        </div>
      </Backdrop>
    );
  }

  // ─── Stage editor ────────────────────────────────────────────────────
  function StageEditor({ stage, days, stageDays, onSave, onClose, onDelete, mode, defaultDayIds }) {
    const isCreate = mode === "create";
    const [name, setName] = React.useState(stage.name);
    const [color, setColor] = React.useState(stage.color);
    const [capacity, setCapacity] = React.useState(stage.capacity);
    const [activeDays, setActiveDays] = React.useState(
      isCreate
        ? (defaultDayIds || [])
        : days.filter(d => stageDays.some(sd => sd.stage_id === stage.id && sd.day_id === d.id)).map(d => d.id)
    );

    const SWATCHES = ["#e85d75", "#7a8af0", "#f0a04b", "#5fc9a8", "#c89af0", "#e8d05f", "#3cc2a8", "#5a8fcf", "#cf5a8f", "#8fcf5a"];

    function toggleDay(id) {
      setActiveDays(activeDays.includes(id)
        ? activeDays.filter(x => x !== id)
        : [...activeDays, id]);
    }
    function save() {
      onSave({ ...stage, name, color, capacity: +capacity }, activeDays);
    }

    return (
      <Backdrop onClose={onClose}>
        <div className="cw-modal" style={{ width: 480 }} onMouseDown={(e) => e.stopPropagation()}>
          <div className="cw-modal-hd">
            <div className="cw-modal-title">
              {isCreate ? "Stage aanmaken" : "Stage bewerken"}
              <span className="cw-modal-sub">{isCreate ? "Nieuwe stage" : stage.name}</span>
            </div>
            <button className="cw-icon-btn" onClick={onClose} aria-label="Sluiten">×</button>
          </div>
          <div className="cw-modal-body">
            <Field label="Naam">
              <input className="cw-input" value={name} onChange={(e) => setName(e.target.value)} />
            </Field>
            <Field label="Capaciteit" hint="Voor capacity-warnings op artiesten met grote draw">
              <input className="cw-input" type="number" value={capacity} onChange={(e) => setCapacity(e.target.value)} />
            </Field>
            <Field label="Kleur">
              <div className="cw-swatch-row">
                {SWATCHES.map(c => (
                  <button key={c}
                          className={"cw-swatch" + (c === color ? " is-active" : "")}
                          style={{ background: c }}
                          onClick={() => setColor(c)} />
                ))}
              </div>
            </Field>
            <Field label="Actief op dagen" hint="Deze stage verschijnt alleen in de timetable van geselecteerde dagen">
              <div className="cw-day-chips">
                {days.map(d => (
                  <button key={d.id}
                          className={"cw-chip" + (activeDays.includes(d.id) ? " is-active" : "")}
                          onClick={() => toggleDay(d.id)}>
                    {d.label}
                  </button>
                ))}
              </div>
            </Field>
          </div>
          <div className="cw-modal-ft">
            {!isCreate && (
              <button className="cw-btn cw-btn-danger" onClick={() => onDelete(stage.id)}>Verwijder stage</button>
            )}
            <div style={{ flex: 1 }}></div>
            <button className="cw-btn" onClick={onClose}>Annuleren</button>
            <button className="cw-btn cw-btn-primary" onClick={save}>{isCreate ? "Aanmaken" : "Opslaan"}</button>
          </div>
        </div>
      </Backdrop>
    );
  }

  // ─── Lineup matrix: stages × days bulk editor ────────────────────────
  function LineupMatrix({ stages, days, stageDays, onSave, onClose }) {
    // Build state: { stageId: Set<dayId> }
    const [matrix, setMatrix] = React.useState(() => {
      const m = {};
      stages.forEach(s => {
        m[s.id] = new Set(stageDays.filter(sd => sd.stage_id === s.id).map(sd => sd.day_id));
      });
      return m;
    });

    function toggle(sid, did) {
      setMatrix(prev => {
        const next = { ...prev };
        const s = new Set(next[sid]);
        s.has(did) ? s.delete(did) : s.add(did);
        next[sid] = s;
        return next;
      });
    }

    function save() {
      const out = [];
      for (const sid in matrix) {
        for (const did of matrix[sid]) out.push({ stage_id: sid, day_id: did });
      }
      onSave(out);
    }

    return (
      <Backdrop onClose={onClose}>
        <div className="cw-modal" style={{ width: 640 }} onMouseDown={(e) => e.stopPropagation()}>
          <div className="cw-modal-hd">
            <div className="cw-modal-title">
              Lineup per dag
              <span className="cw-modal-sub">Welke stages draaien op welke dag</span>
            </div>
            <button className="cw-icon-btn" onClick={onClose} aria-label="Sluiten">×</button>
          </div>
          <div className="cw-modal-body">
            <table className="cw-matrix">
              <thead>
                <tr>
                  <th>Stage</th>
                  {days.map(d => <th key={d.id}>{d.label}</th>)}
                </tr>
              </thead>
              <tbody>
                {stages.map(s => (
                  <tr key={s.id}>
                    <td>
                      <span className="cw-stage-dot" style={{ background: s.color }}></span>
                      {s.name}
                    </td>
                    {days.map(d => (
                      <td key={d.id} className="cw-matrix-cell">
                        <button
                          className={"cw-check" + (matrix[s.id].has(d.id) ? " is-checked" : "")}
                          onClick={() => toggle(s.id, d.id)}
                          aria-label={`Toggle ${s.name} on ${d.label}`}>
                          {matrix[s.id].has(d.id) && (
                            <svg width="12" height="12" viewBox="0 0 12 12">
                              <path d="M2 6 L5 9 L10 3" fill="none" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
                            </svg>
                          )}
                        </button>
                      </td>
                    ))}
                  </tr>
                ))}
              </tbody>
            </table>
            <p className="cw-hint">
              Tip: stages die op meerdere dagen draaien (zoals Silent Disco of Schirmbar)
              kun je hier in één keer instellen.
            </p>
          </div>
          <div className="cw-modal-ft">
            <div style={{ flex: 1 }}></div>
            <button className="cw-btn" onClick={onClose}>Annuleren</button>
            <button className="cw-btn cw-btn-primary" onClick={save}>Opslaan</button>
          </div>
        </div>
      </Backdrop>
    );
  }

  return { PerformanceModal, StageEditor, LineupMatrix };
})();

Object.assign(window, { CrewliModals: M });
