/* Modales CRUD: Jefe de Proyecto, Recurso, Solicitudes */
const { useState: useS } = React;

/* ---------- Jefe de Proyecto / Equipo ---------- */
function PMModal({ initial, onSave, onDelete, onClose }) {
  const CL = window.CL;
  const isEdit = !!(initial && initial.id);
  const [pm, setPm] = useS(initial?.pm || "");
  const [team, setTeam] = useS(initial?.team || "");
  const [template, setTemplate] = useS(!isEdit);
  const valid = pm.trim() && team.trim();
  const resCount = isEdit ? (CL.TEAMS.find((t) => t.id === initial.id)?.resources.length || 0) : 0;
  function submit() { if (valid) onSave({ id: initial?.id, pm: pm.trim(), team: team.trim(), template: !isEdit && template }); }
  const onKey = (e) => { if (e.key === "Enter") submit(); };

  return (
    <div className="overlay" onMouseDown={(e) => { if (e.target.classList.contains("overlay")) onClose(); }}>
      <div className="modal">
        <div className="modal-head">
          <h2>{isEdit ? "Editar Jefe de Proyecto" : "Nuevo Jefe de Proyecto"}</h2>
          <button className="navbtn" onClick={onClose} style={{ border: "none" }}>{Icon.x({ width: 18, height: 18 })}</button>
        </div>
        <div className="modal-body">
          <div className="field">
            <label>Nombre del Jefe de Proyecto</label>
            <input value={pm} autoFocus onChange={(e) => setPm(e.target.value)} onKeyDown={onKey} placeholder="Ej. Carlos Mendoza" />
          </div>
          <div className="field">
            <label>Nombre del equipo</label>
            <input value={team} onChange={(e) => setTeam(e.target.value)} onKeyDown={onKey} placeholder="Ej. Aurora" />
          </div>
          {!isEdit && (
            <label className="check-row">
              <input type="checkbox" checked={template} onChange={(e) => setTemplate(e.target.checked)} />
              <span>Crear con plantilla estándar <b>(3 desarrolladores, 1 QA, 1 analista prod.)</b></span>
            </label>
          )}
        </div>
        <div className="modal-foot">
          <div>{isEdit && <button className="btn" onClick={() => onDelete(initial.id)} style={{ color: "var(--rojo-700)", borderColor: "#F3D0D4" }}>{Icon.trash({ width: 15, height: 15 })} Eliminar equipo</button>}</div>
          <div style={{ display: "flex", gap: 10 }}>
            <button className="btn" onClick={onClose}>Cancelar</button>
            <button className="btn btn-primary" onClick={submit} disabled={!valid}>{isEdit ? "Guardar" : "Crear equipo"}</button>
          </div>
        </div>
      </div>
    </div>
  );
}

/* ---------- Recurso (Dev / QA / Prod) ---------- */
function ResourceModal({ initial, teamName, onSave, onDelete, onClose }) {
  const CL = window.CL;
  const isEdit = !!(initial && initial.id);
  const [name, setName] = useS(initial?.name || "");
  const [role, setRole] = useS(initial?.role || "Desarrollador");
  const valid = name.trim();
  function submit() { if (valid) onSave({ id: initial?.id, name: name.trim(), role }); }

  return (
    <div className="overlay" onMouseDown={(e) => { if (e.target.classList.contains("overlay")) onClose(); }}>
      <div className="modal">
        <div className="modal-head">
          <div>
            <h2>{isEdit ? "Editar recurso" : "Nuevo recurso"}</h2>
            <div style={{ fontSize: 12, color: "var(--muted)", marginTop: 2 }}>Equipo {teamName}</div>
          </div>
          <button className="navbtn" onClick={onClose} style={{ border: "none" }}>{Icon.x({ width: 18, height: 18 })}</button>
        </div>
        <div className="modal-body">
          <div className="field">
            <label>Nombre completo</label>
            <input value={name} autoFocus onChange={(e) => setName(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") submit(); }} placeholder="Ej. Mateo Quispe" />
          </div>
          <div className="field">
            <label>Rol</label>
            <div className="type-pick" style={{ gridTemplateColumns: "1fr 1fr 1fr" }}>
              {CL.ROLES.map((r) => (
                <button key={r.role} className={"type-opt" + (role === r.role ? " sel" : "")} onClick={() => setRole(r.role)} style={{ justifyContent: "center" }}>
                  {r.roleShort === "Dev" ? "Desarrollador" : r.role}
                </button>
              ))}
            </div>
          </div>
        </div>
        <div className="modal-foot">
          <div>{isEdit && <button className="btn" onClick={() => onDelete(initial.id)} style={{ color: "var(--rojo-700)", borderColor: "#F3D0D4" }}>{Icon.trash({ width: 15, height: 15 })} Eliminar</button>}</div>
          <div style={{ display: "flex", gap: 10 }}>
            <button className="btn" onClick={onClose}>Cancelar</button>
            <button className="btn btn-primary" onClick={submit} disabled={!valid}>{isEdit ? "Guardar" : "Agregar recurso"}</button>
          </div>
        </div>
      </div>
    </div>
  );
}

/* ---------- Solicitudes (códigos) ---------- */
function ProjectsModal({ events, onCommit, onClose }) {
  const CL = window.CL;
  const [draft, setDraft] = useS(() => CL.PROJECTS.map((p) => ({ _key: p.id, id: p.id, numero: p.numero || 0, name: p.name, color: p.color, division: p.division || "", departamento: p.departamento || "" })));
  const marcasOf = (pid) => (events || []).filter((e) => e.type === "asignacion" && e.projectId === pid).length;

  function set(i, patch) { setDraft((d) => d.map((row, j) => (j === i ? Object.assign({}, row, patch) : row))); }
  function addRow() {
    const used = new Set(draft.map((d) => d.color));
    const color = CL.PROJECT_COLORS.find((c) => !used.has(c)) || CL.PROJECT_COLORS[draft.length % CL.PROJECT_COLORS.length];
    const maxN = draft.reduce((m, r) => Math.max(m, Number(r.numero) || 0), 0);
    setDraft((d) => d.concat([{ _key: CL.uid("new"), id: "", numero: maxN + 1, name: "", color, division: "", departamento: "" }]));
  }
  function removeRow(i) { setDraft((d) => d.filter((_, j) => j !== i)); }

  // validación
  const ids = draft.map((d) => d.id.trim());
  const dupe = ids.some((id, i) => id && ids.indexOf(id) !== i);
  const empty = draft.some((d) => !d.id.trim() || !d.name.trim());
  const valid = !dupe && !empty;

  // impacto: marcas que se eliminarán al borrar solicitudes
  const origIds = CL.PROJECTS.map((p) => p.id);
  const keptKeys = new Set(draft.map((d) => d._key));
  const removedNow = origIds.filter((id) => !keptKeys.has(id));
  const marcasARemover = removedNow.reduce((s, id) => s + marcasOf(id), 0);

  function commit() {
    if (!valid) return;
    const newProjects = draft.map((d) => ({ id: d.id.trim(), numero: Number(d.numero) || 0, name: d.name.trim(), color: d.color, division: (d.division || "").trim(), departamento: (d.departamento || "").trim() }));
    const originals = CL.PROJECTS.map((p) => p.id);
    const remap = {};
    draft.forEach((d) => { if (d._key && originals.includes(d._key) && d._key !== d.id.trim()) remap[d._key] = d.id.trim(); });
    const kept = new Set(draft.filter((d) => originals.includes(d._key)).map((d) => d._key));
    const removed = originals.filter((id) => !kept.has(id));
    onCommit({ newProjects, remap, removed });
  }

  return (
    <div className="overlay" onMouseDown={(e) => { if (e.target.classList.contains("overlay")) onClose(); }}>
      <div className="modal" style={{ maxWidth: 820 }}>
        <div className="modal-head">
          <div>
            <h2>Gestionar códigos de solicitud</h2>
            <div style={{ fontSize: 12, color: "var(--muted)", marginTop: 2 }}>Catálogo de solicitudes / proyectos. Cada marca de tipo "asignación" se enlaza a uno.</div>
          </div>
          <button className="navbtn" onClick={onClose} style={{ border: "none" }}>{Icon.x({ width: 18, height: 18 })}</button>
        </div>
        <div className="modal-body" style={{ gap: 14, maxHeight: "62vh", overflowY: "auto" }}>
          {draft.map((row, i) => (
            <div className="proj-card" key={row._key}>
              <div className="proj-row2">
                <label className="pf"><span className="pl">Código</span><input value={row.id} onChange={(e) => set(i, { id: e.target.value.toUpperCase() })} placeholder="SOL-0000" /></label>
                <label className="pf pf-num"><span className="pl">N°</span><input type="number" value={row.numero} onChange={(e) => set(i, { numero: e.target.value })} placeholder="0" /></label>
                <label className="pf pf-name"><span className="pl">Nombre de la solicitud</span><input value={row.name} onChange={(e) => set(i, { name: e.target.value })} placeholder="Nombre" /></label>
                <button className="navbtn del-sm" onClick={() => removeRow(i)} title="Eliminar solicitud">{Icon.trash({ width: 15, height: 15 })}</button>
              </div>
              <div className="proj-row2">
                <label className="pf"><span className="pl">División</span><input value={row.division || ""} onChange={(e) => set(i, { division: e.target.value })} placeholder="Ej. Tecnología" /></label>
                <label className="pf"><span className="pl">Departamento</span><input value={row.departamento || ""} onChange={(e) => set(i, { departamento: e.target.value })} placeholder="Ej. Canales Digitales" /></label>
                <div className="pf">
                  <span className="pl">Color</span>
                  <div className="swatches">
                    {CL.PROJECT_COLORS.map((c) => (
                      <button key={c} className={"swatch" + (row.color === c ? " sel" : "")} style={{ background: c }} onClick={() => set(i, { color: c })}></button>
                    ))}
                  </div>
                </div>
              </div>
              {origIds.includes(row._key) && marcasOf(row._key) > 0 && <div className="proj-marcas">{marcasOf(row._key)} marca{marcasOf(row._key) === 1 ? "" : "s"} en el calendario</div>}
            </div>
          ))}
          <button className="btn add-proj" onClick={addRow}>{Icon.plus({ width: 15, height: 15 })} Agregar solicitud</button>
          {dupe && <div className="warn-text">{Icon.alert({ width: 14, height: 14 })} Hay códigos duplicados.</div>}
          {empty && !dupe && <div className="warn-text" style={{ color: "var(--muted)" }}>{Icon.alert({ width: 14, height: 14 })} Completa código y nombre en cada fila.</div>}
          {marcasARemover > 0 && <div className="warn-text">{Icon.alert({ width: 14, height: 14 })} Al guardar se eliminarán {marcasARemover} marca{marcasARemover === 1 ? "" : "s"} del calendario de las solicitudes borradas.</div>}
        </div>
        <div className="modal-foot" style={{ justifyContent: "flex-end" }}>
          <button className="btn" onClick={onClose}>Cancelar</button>
          <button className="btn btn-primary" onClick={commit} disabled={!valid}>Guardar cambios</button>
        </div>
      </div>
    </div>
  );
}

/* ---------- Confirmación destructiva genérica ---------- */
function ConfirmModal({ title, message, note, confirmLabel, cancelLabel, danger, onConfirm, onClose }) {
  function onKey(e) { if (e.key === "Escape") onClose(); if (e.key === "Enter") onConfirm(); }
  return (
    <div className="overlay" onMouseDown={(e) => { if (e.target.classList.contains("overlay")) onClose(); }} onKeyDown={onKey} tabIndex={-1}>
      <div className="modal" style={{ maxWidth: 460 }}>
        <div className="modal-head">
          <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
            <span style={{ display: "inline-flex", alignItems: "center", justifyContent: "center", width: 36, height: 36, borderRadius: 10, background: danger ? "#FDE7E9" : "var(--accent-soft)", color: danger ? "var(--rojo)" : "var(--accent)" }}>
              {Icon.alert({ width: 20, height: 20 })}
            </span>
            <h2 style={{ margin: 0 }}>{title}</h2>
          </div>
          <button className="navbtn" onClick={onClose} style={{ border: "none" }}>{Icon.x({ width: 18, height: 18 })}</button>
        </div>
        <div className="modal-body">
          <div style={{ fontSize: 13.5, color: "var(--tinta)", lineHeight: 1.5 }}>{message}</div>
          {note && <div style={{ fontSize: 12, color: "var(--muted)", background: "var(--bg)", border: "1px solid var(--line)", borderRadius: 10, padding: "10px 12px", lineHeight: 1.5 }}>{note}</div>}
        </div>
        <div className="modal-foot" style={{ justifyContent: "flex-end" }}>
          <button className="btn" onClick={onClose}>{cancelLabel || "Cancelar"}</button>
          <button className="btn" onClick={onConfirm} style={danger ? { background: "var(--rojo)", color: "#fff", borderColor: "var(--rojo)" } : undefined}>
            {confirmLabel || "Confirmar"}
          </button>
        </div>
      </div>
    </div>
  );
}

/* ---------- Vista consolidada de marcas (Solicitudes) ---------- */
function SolicitudesView({ events, onEditEvent, onAskDeleteEvent, onAskDeleteAll, onManageCatalog, onClose }) {
  const CL = window.CL;
  const [q, setQ] = useS("");
  const norm = (s) => String(s == null ? "" : s).toLowerCase().normalize("NFD").replace(/[̀-ͯ]/g, "");
  const term = norm(q);
  const rows = events.slice().sort((a, b) => (a.start < b.start ? 1 : -1)).map((ev) => {
    const res = CL.RESOURCE_MAP.get(ev.resourceId);
    const team = res ? CL.TEAMS.find((t) => t.id === res.pmId) : null;
    const proj = ev.projectId ? CL.PROJECT_MAP.get(ev.projectId) : null;
    return { ev, res, team, proj };
  }).filter(({ ev, res, team, proj }) => {
    if (!term) return true;
    return [ev.projectId, ev.title, CL.EVENT_TYPES[ev.type]?.label, team?.pm, res?.name, res?.role, ev.estado, ev.start, ev.end, proj?.division, proj?.departamento, proj?.numero].some((v) => norm(v).includes(term));
  });

  return (
    <div className="overlay" onMouseDown={(e) => { if (e.target.classList.contains("overlay")) onClose(); }}>
      <div className="modal sol-modal">
        <div className="modal-head">
          <div>
            <h2>Solicitudes — vista consolidada</h2>
            <div style={{ fontSize: 12, color: "var(--muted)", marginTop: 2 }}>
              {events.length} marca{events.length === 1 ? "" : "s"} registrada{events.length === 1 ? "" : "s"} en total{term ? ` · ${rows.length} filtrada${rows.length === 1 ? "" : "s"}` : ""}
            </div>
          </div>
          <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
            <input className="sol-search" value={q} onChange={(e) => setQ(e.target.value)} placeholder="Buscar por código, recurso, equipo…" />
            <button className="btn" onClick={onManageCatalog} title="Editar códigos, números, división, departamento y color de las solicitudes">{Icon.doc({ width: 15, height: 15 })} Gestionar códigos</button>
            <button className="btn" onClick={onAskDeleteAll} disabled={events.length === 0} style={{ color: "var(--rojo-700)", borderColor: "#F3D0D4" }}>{Icon.trash({ width: 15, height: 15 })} Eliminar todas</button>
            <button className="navbtn" onClick={onClose} style={{ border: "none" }}>{Icon.x({ width: 18, height: 18 })}</button>
          </div>
        </div>
        <div className="modal-body" style={{ padding: 0 }}>
          {rows.length === 0 ? (
            <div className="sol-empty">
              {events.length === 0
                ? "No hay marcas registradas todavía. Selecciona un recurso en el calendario y usa \"Agregar marca\"."
                : "No hay marcas que coincidan con la búsqueda."}
            </div>
          ) : (
            <div className="sol-table-wrap">
              <table className="sol-table">
                <thead>
                  <tr>
                    <th>Código</th>
                    <th>N°</th>
                    <th>Nombre</th>
                    <th>Tipo de marca</th>
                    <th>Jefe de Proyecto</th>
                    <th>Recurso</th>
                    <th>Rol</th>
                    <th>Estado</th>
                    <th>Inicio</th>
                    <th>Fin</th>
                    <th>División</th>
                    <th>Departamento</th>
                    <th>Color</th>
                    <th></th>
                  </tr>
                </thead>
                <tbody>
                  {rows.map(({ ev, res, team, proj }) => {
                    const tType = CL.EVENT_TYPES[ev.type];
                    const color = proj?.color || tType?.color || "#999";
                    return (
                      <tr key={ev.id}>
                        <td className="mono">{ev.projectId || "—"}</td>
                        <td className="tnum">{proj?.numero || (ev.projectId ? "—" : "")}</td>
                        <td>{ev.title || (proj ? proj.name : "—")}</td>
                        <td><span className="sol-tag" style={{ background: (tType?.color || "var(--accent)") + "22", color: tType?.color || "var(--accent)" }}>{tType?.label || ev.type}</span></td>
                        <td>{team?.pm || "—"}</td>
                        <td>{res?.name || "—"}</td>
                        <td>{res?.role || "—"}</td>
                        <td>{ev.estado ? <span className={"chip " + estadoClass(ev.estado)}>{estadoLabel(ev.estado)}</span> : "—"}</td>
                        <td className="tnum mono">{ev.start}</td>
                        <td className="tnum mono">{ev.end}</td>
                        <td>{proj?.division || "—"}</td>
                        <td>{proj?.departamento || "—"}</td>
                        <td><span className="sol-sw" style={{ background: color }} title={color}></span></td>
                        <td style={{ whiteSpace: "nowrap" }}>
                          <button className="navbtn sol-act" title="Editar marca" onClick={() => onEditEvent(ev)}>{Icon.pencil({ width: 14, height: 14 })}</button>
                          <button className="navbtn sol-act sol-act-del" title="Eliminar marca" onClick={() => onAskDeleteEvent(ev)}>{Icon.trash({ width: 14, height: 14 })}</button>
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { PMModal, ResourceModal, ProjectsModal, ConfirmModal, SolicitudesView });
