/* Vista Calendario mensual */
const { useState: useStateC, useMemo: useMemoC, useRef: useRefC } = React;

const DAY_MS = 86400000;
function daysBetween(a, b) { return Math.round((b.getTime() - a.getTime()) / DAY_MS); }

function buildMonthWeeks(year, month) {
  const CL = window.CL;
  const first = new Date(year, month, 1);
  const offset = (first.getDay() + 6) % 7; // lunes = 0
  const gridStart = CL.addDays(first, -offset);
  const last = new Date(year, month + 1, 0);
  const days = [];
  let d = gridStart;
  while (true) {
    days.push({
      date: new Date(d), day: d.getDate(),
      inMonth: d.getMonth() === month,
      weekend: CL.isWeekend(d), holiday: CL.isHoliday(d),
      holidayName: CL.holidayName(d),
      iso: CL.iso(d),
    });
    d = CL.addDays(d, 1);
    if (d.getTime() > last.getTime() && days.length % 7 === 0) break;
    if (days.length > 50) break;
  }
  const weeks = [];
  for (let i = 0; i < days.length; i += 7) weeks.push(days.slice(i, i + 7));
  return weeks;
}

function colorFor(ev) {
  const CL = window.CL;
  if (ev.type === "asignacion") return (CL.PROJECT_MAP.get(ev.projectId) || {}).color || "#7C3AED";
  return CL.EVENT_TYPES[ev.type].color;
}

function layoutWeek(events, week) {
  const CL = window.CL;
  const ws = week[0].date, we = week[6].date;
  const segs = [];
  for (const ev of events) {
    const es = CL.parseISO(ev.start), ee = CL.parseISO(ev.end);
    if (ee.getTime() < ws.getTime() || es.getTime() > we.getTime()) continue;
    const startCol = Math.max(0, Math.min(6, daysBetween(ws, es < ws ? ws : es)));
    const endCol = Math.max(0, Math.min(6, daysBetween(ws, ee > we ? we : ee)));
    segs.push({ ev, startCol, endCol, contL: es.getTime() < ws.getTime(), contR: ee.getTime() > we.getTime(), color: colorFor(ev) });
  }
  // ordenar: asignaciones primero, luego por inicio y longitud
  segs.sort((a, b) => {
    const pa = a.ev.type === "asignacion" ? 0 : 1, pb = b.ev.type === "asignacion" ? 0 : 1;
    if (pa !== pb) return pa - pb;
    if (a.startCol !== b.startCol) return a.startCol - b.startCol;
    return (b.endCol - b.startCol) - (a.endCol - a.startCol);
  });
  const lanes = [];
  segs.forEach((s) => {
    let placed = false;
    for (let li = 0; li < lanes.length; li++) {
      if (lanes[li] < s.startCol) { s.lane = li; lanes[li] = s.endCol; placed = true; break; }
    }
    if (!placed) { s.lane = lanes.length; lanes.push(s.endCol); }
  });
  return { segs, laneCount: lanes.length };
}

function Calendar({ scope, resource, resourceIds, events, year, month, setMonth, onPrev, onNext, canPrev, canNext, onAddOpen, onEditOpen, setTip }) {
  const CL = window.CL, CLA = window.CLA;
  const weeks = useMemoC(() => buildMonthWeeks(year, month), [year, month]);
  const todayISO = "2026-06-05";
  const isTeamMode = scope.type !== "resource";

  const resEvents = useMemoC(() => resource ? events.filter((e) => e.resourceId === resource.id) : [], [events, resource]);

  function showTip(e, html) {
    setTip({ x: e.clientX + 12, y: e.clientY + 14, html });
  }

  return (
    <div className="cal-wrap">
      <div className="cal-head">
        <div className="cal-month">{CL.MONTHS[month]} {year}</div>
        <div className="cal-nav">
          <button className="navbtn" onClick={onPrev} disabled={!canPrev}>{Icon.chevL({})}</button>
          <button className="navbtn" onClick={onNext} disabled={!canNext}>{Icon.chevR({})}</button>
        </div>
        <div className="spacer" style={{ flex: 1 }}></div>
        {!isTeamMode && (
          <button className="btn btn-primary" onClick={onAddOpen}>{Icon.plus({})} Agregar marca</button>
        )}
        {isTeamMode && <div style={{ fontSize: 12, color: "var(--muted)", fontWeight: 600 }}>Carga del equipo · {resourceIds.length} recursos</div>}
      </div>

      {/* encabezado días */}
      <div className="cal-grid">
        {CL.DOW.map((d, i) => <div key={d} className={"dow" + (i >= 5 ? " we" : "")}>{d}</div>)}
      </div>

      <div>
        {weeks.map((week, wi) => {
          const { segs, laneCount } = isTeamMode ? { segs: [], laneCount: 0 } : layoutWeek(resEvents, week);
          const rows = isTeamMode ? "" : "34px " + Array(Math.max(laneCount, 3)).fill("22px").join(" ");
          return (
            <div key={wi} className="week-grid" style={{ display: "grid", gridTemplateColumns: "repeat(7,1fr)", gridTemplateRows: isTeamMode ? undefined : rows, position: "relative", rowGap: 0 }}>
              {/* fondos */}
              {week.map((dy, i) => {
                let cls = "cell";
                if (!dy.inMonth) cls += " outside";
                else if (dy.holiday) cls += " holiday";
                else if (dy.weekend) cls += " weekend";
                if (dy.iso === todayISO) cls += " today";
                return (
                  <div key={"bg" + i} className={cls}
                    style={{ gridColumn: i + 1, gridRow: isTeamMode ? undefined : "1 / -1", minHeight: isTeamMode ? 116 : undefined }}>
                    <div className="daynum">{dy.day}</div>
                    {dy.holiday && <div className="holiday-tag">{dy.holidayName}</div>}
                    {/* Team mode aggregate */}
                    {isTeamMode && dy.inMonth && !dy.weekend && !dy.holiday && (() => {
                      let busy = 0, off = 0, over = 0;
                      resourceIds.forEach((rid) => {
                        const { load, off: o } = CLA.dayLoad(events, rid, dy.date);
                        if (o) off++; else if (load > 0) { busy++; if (load > 1) over++; }
                      });
                      const total = resourceIds.length;
                      const free = total - busy - off;
                      return (
                        <div style={{ marginTop: "auto" }}
                          onMouseEnter={(e) => showTip(e, `<b>${busy}/${total} asignados</b><div class='tip-row'><span>En descanso</span><b>${off}</b></div><div class='tip-row'><span>Sobrecargados</span><b>${over}</b></div><div class='tip-row'><span>Libres</span><b>${free}</b></div>`)}
                          onMouseMove={(e) => showTip(e, `<b>${busy}/${total} asignados</b><div class='tip-row'><span>En descanso</span><b>${off}</b></div><div class='tip-row'><span>Sobrecargados</span><b>${over}</b></div><div class='tip-row'><span>Libres</span><b>${free}</b></div>`)}
                          onMouseLeave={() => setTip(null)}>
                          <div style={{ display: "flex", height: 8, borderRadius: 20, overflow: "hidden", background: "#EDEAF4" }}>
                            {busy > 0 && <div style={{ width: (busy / total * 100) + "%", background: over > 0 ? "linear-gradient(90deg,var(--accent),var(--rojo))" : "var(--accent-2)" }}></div>}
                            {off > 0 && <div style={{ width: (off / total * 100) + "%", background: "var(--ev-vac)" }}></div>}
                          </div>
                          <div style={{ fontSize: 10, fontWeight: 700, color: "var(--muted)", marginTop: 4, fontVariantNumeric: "tabular-nums" }}>
                            {busy}<span style={{ color: "var(--muted-2)", fontWeight: 600 }}>/{total}</span>
                            {over > 0 && <span style={{ color: "var(--rojo)", marginLeft: 5 }}>⚠ {over}</span>}
                          </div>
                        </div>
                      );
                    })()}
                  </div>
                );
              })}
              {/* barras de eventos (modo recurso) */}
              {!isTeamMode && segs.map((s, si) => {
                const ev = s.ev;
                const wd = CL.workingDaysBetween(ev.start, ev.end);
                const tipHtml = `<b>${ev.title}</b><div class='tip-row'><span>${ev.type === "asignacion" ? ev.projectId : CL.EVENT_TYPES[ev.type].label}</span><b>${wd} días lab.</b></div><div class='tip-row'><span>${ev.start}</span><span>→ ${ev.end}</span></div>` + (ev.estado ? `<div class='tip-row'><span>Estado</span><b>${estadoLabel(ev.estado)}</b></div>` : "");
                return (
                  <div key={"ev" + si}
                    className={"ev-bar" + (s.contL ? " cont-l" : "") + (s.contR ? " cont-r" : "")}
                    style={{ gridColumn: `${s.startCol + 1} / ${s.endCol + 2}`, gridRow: s.lane + 2, background: s.color, margin: "0 2px 2px" }}
                    onClick={() => onEditOpen(ev)}
                    onMouseEnter={(e) => showTip(e, tipHtml)} onMouseMove={(e) => showTip(e, tipHtml)} onMouseLeave={() => setTip(null)}>
                    {!s.contL && <span className="ev-ic">{evIcon(ev.type, {})}</span>}
                    {!s.contL ? (ev.type === "asignacion" ? ev.projectId + " · " + ev.title : ev.title) : "↤"}
                  </div>
                );
              })}
            </div>
          );
        })}
      </div>

      {/* Leyenda */}
      <div className="legend">
        {CL.PROJECTS.map((p) => (
          <div key={p.id} className="legend-item"><span className="legend-sw" style={{ background: p.color }}></span>{p.id}</div>
        ))}
        <div className="legend-item"><span className="legend-sw" style={{ background: "var(--ev-vac)" }}></span>Vacaciones</div>
        <div className="legend-item"><span className="legend-sw" style={{ background: "var(--ev-lic)" }}></span>Licencia</div>
        <div className="legend-item"><span className="legend-sw" style={{ background: "var(--ev-cap)" }}></span>Capacitación</div>
        <div className="legend-item"><span className="legend-sw holiday"></span>Feriado</div>
        <div className="legend-item"><span className="legend-sw weekend"></span>No laborable</div>
      </div>
    </div>
  );
}

function estadoLabel(e) {
  return { completada: "Completada", en_curso: "En curso", en_riesgo: "En riesgo", retrasada: "Retrasada" }[e] || e;
}
function estadoClass(e) {
  return { completada: "ok", en_curso: "warn", en_riesgo: "warn", retrasada: "bad" }[e] || "warn";
}

Object.assign(window, { Calendar, estadoLabel, estadoClass, buildMonthWeeks, colorFor });
