/* 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, compact }) {
  const CL = window.CL, CLA = window.CLA;
  const weeks = useMemoC(() => buildMonthWeeks(year, month), [year, month]);
  const todayISO = (window.CLA && window.CLA.todayISO) ? window.CLA.todayISO() : CL.iso(new Date());
  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">
      {!compact && (
      <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>

      {!compact && (
      <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>
  );
}

/* ---------- Vista agrupada por equipos (modo "Todos los equipos") ---------- */
function TeamGroupedCalendar({ teams, events, year, month, onPrev, onNext, canPrev, canNext, expandedTeams, onToggleTeam, onSelectTeam, onPickResource, setTip, onExpandAll, onCollapseAll }) {
  const CL = window.CL, CLA = window.CLA;
  return (
    <div>
      <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>
        <div style={{ fontSize: 12, color: "var(--muted)", fontWeight: 600 }}>Vista por equipos · {teams.length} jefes de proyecto</div>
        <button className="btn" onClick={onExpandAll} style={{ marginLeft: 10 }}>{Icon.grid({ width: 14, height: 14 })} Expandir todos</button>
        <button className="btn" onClick={onCollapseAll}>{Icon.x({ width: 14, height: 14 })} Colapsar</button>
      </div>
      <div className="teams-stack">
        {teams.map((tm) => {
          const open = expandedTeams.has(tm.id);
          const resIds = tm.resources.map((r) => r.id);
          // ocupación promedio mensual del equipo
          let pct = 0, count = 0;
          tm.resources.forEach((r) => { const o = CLA.monthOccupation(events, r.id, year, month); if (o.disponibles > 0) { pct += o.pct; count++; } });
          const avgPct = count ? Math.round(pct / count) : 0;
          // contadores rápidos del mes
          const monthEvs = events.filter((e) => resIds.includes(e.resourceId)).filter((e) => {
            const s = CL.parseISO(e.start), en = CL.parseISO(e.end);
            const m0 = new Date(year, month, 1), m1 = new Date(year, month + 1, 0);
            return !(en < m0 || s > m1);
          });
          const asignaciones = monthEvs.filter((e) => e.type === "asignacion").length;
          const enRiesgo = monthEvs.filter((e) => e.type === "asignacion" && (e.estado === "en_riesgo" || e.estado === "retrasada")).length;
          return (
            <div className={"team-section" + (open ? " open" : "")} key={tm.id}>
              <button className="team-section-head" onClick={() => onToggleTeam(tm.id)}>
                <span className="ts-chev">{Icon.chevR({ width: 15, height: 15 })}</span>
                <span className="team-dot" style={{ background: avatarColor(tm.id) }}></span>
                <span className="ts-name">{tm.pm}<span className="ts-team"> · Equipo {tm.team}</span></span>
                <span className="ts-meta">{tm.resources.length} recurso{tm.resources.length === 1 ? "" : "s"}</span>
                <span className="ts-meta">{asignaciones} asign.{enRiesgo > 0 ? <span style={{ color: "var(--rojo)", marginLeft: 6 }}>· {enRiesgo} ⚠</span> : ""}</span>
                <span className="ts-occ" style={{ background: occColor(avgPct), color: occText(avgPct) }}>{avgPct}%</span>
                <button className="navbtn ts-jump" onClick={(e) => { e.stopPropagation(); onSelectTeam(tm.id); }} title="Ver solo este equipo">{Icon.chart({ width: 13, height: 13 })}</button>
              </button>
              {open && (
                <div className="team-section-body">
                  <Calendar
                    scope={{ type: "team", id: tm.id }}
                    resource={null}
                    resourceIds={resIds}
                    events={events}
                    year={year}
                    month={month}
                    onPrev={onPrev} onNext={onNext}
                    canPrev={canPrev} canNext={canNext}
                    onAddOpen={() => {}}
                    onEditOpen={() => {}}
                    setTip={setTip}
                    compact={true}
                  />
                  <div className="team-section-resources">
                    {tm.resources.map((r) => (
                      <button key={r.id} className="ts-resource" onClick={() => onPickResource(r.id)} title={`Ver calendario de ${r.name}`}>
                        <span className="avatar" style={{ width: 22, height: 22, borderRadius: 6, background: avatarColor(r.id), fontSize: 9.5 }}>{r.initials}</span>
                        <span style={{ flex: 1, textAlign: "left" }}>{r.name}</span>
                        <span className="ts-resource-role">{r.roleShort}</span>
                      </button>
                    ))}
                  </div>
                </div>
              )}
            </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, TeamGroupedCalendar, estadoLabel, estadoClass, buildMonthWeeks, colorFor });
