/**
 * family-calendar.js (FIXED: Selection, View Buttons, Colors)
 */

document.addEventListener("DOMContentLoaded", () => {
  const CONGE_TYPES = ["OFF_CAROLE", "EXTRA_OFF_CAROLE"];
  const GUARDE_TYPES = ["CENTRE", "AVIS"];
  const PEP_TYPES = ["PEP_SICK"];
  const MODIFIABLE_TYPES = [...CONGE_TYPES, ...GUARDE_TYPES, ...PEP_TYPES];

  class FamilyCalendar {
    constructor() {
      this.planningBody = document.getElementById("planningBody");
      this.selectionMenu = document.getElementById("selectionMenu");
      // Menu dans le body pour position absolue correcte
      if (
        this.selectionMenu &&
        this.selectionMenu.parentElement !== document.body
      ) {
        document.body.appendChild(this.selectionMenu);
      }
      this.schoolHolidaysTableBody = document.querySelector(
        "#schoolHolidaysTable tbody",
      );
      this.monthCalendar = document.getElementById("fc-month-calendar");
      this.monthSelectionMenu = document.getElementById(
        "fc-month-selectionMenu",
      );
      if (
        this.monthSelectionMenu &&
        this.monthSelectionMenu.parentElement !== document.body
      ) {
        document.body.appendChild(this.monthSelectionMenu);
      }

      // Etat
      this.currentMonth = new Date();
      this.currentMonth.setDate(1);
      this.viewMode = "1month";
      this.currentSchoolYearStart = null;

      this.isSelecting = false;
      this.selectedCells = [];
      this.monthSelectedCells = [];
      this.isMonthSelecting = false;
      this._currentBulkInfo = null;

      // Données
      this.dbEvents = [];
      this.fixedEvents = [];
      this.events = [];
      this.leaves = [];
      this.weeks = [];
      this.monthlyLeaveBalances = {
        2: { CP: {}, JRA: {}, JA: {} },
        3: { CP: {}, JRA: {}, JA: {} },
      };

      if (!this.planningBody) return;
      this.init();
    }

    async init() {
      this.setupEventListeners();
      const now = new Date();
      this.currentSchoolYearStart =
        now.getMonth() >= 8 ? now.getFullYear() : now.getFullYear() - 1;
      await this.refreshAllData();
      this.updateSchoolYearLabel();
    }

    async refreshAllData() {
      try {
        const weeksData = await this.fetchApi(
          `/modules/family-calendar/includes/api/get-calendar-weeks-scolaire.php?school_year_start=${this.currentSchoolYearStart}`,
        );
        this.weeks = this.processWeeks(weeksData.weeks || []);

        const eventsData = await this.fetchApi(
          "/modules/family-calendar/includes/api/get-events.php",
        );
        this.dbEvents = (eventsData.events || []).map((e) => ({
          ...e,
          duration: parseFloat(e.duration),
        }));

        this.fixedEvents = await this.fetchPublicAndSchoolHolidays();

        const leavesData = await this.fetchApi(
          "/modules/family-calendar/includes/api/get-leaves.php",
        );
        this.leaves = leavesData.leaves || [];

        const balancesData = await this.fetchApi(
          "/modules/family-calendar/includes/api/get-leave-balances.php",
        );
        this.leaveBalances = balancesData.balances || [];

        this.events = [...this.dbEvents, ...this.fixedEvents];
        this.publicHolidayDates = new Set(
          this.fixedEvents
            .filter((e) => e.type === "PUBLIC_HOLIDAY")
            .map((e) => e.date),
        );

        this.reprocessAndRender();
      } catch (e) {
        console.error("Erreur chargement", e);
      }
    }

    // Appel API pour les vacances scolaires (Zone C) avec dédoublonnage
    async fetchPublicAndSchoolHolidays() {
      // 1. Jours fériés 2025-2026 (Statique)
      const publicHolidays = [
        "2025-11-01",
        "2025-11-11",
        "2025-12-25",
        "2026-01-01",
        "2026-04-06",
        "2026-05-01",
        "2026-05-08",
        "2026-05-14",
        "2026-05-25",
        "2026-07-14",
        "2026-08-15",
      ].map((date, idx) => ({
        id: `ph-${idx}`,
        date,
        type: "PUBLIC_HOLIDAY",
        duration: 1,
      }));

      // 2. Vacances Scolaires (API Gouv)
      const schoolHolidayEvents = [];
      try {
        const url =
          "https://data.education.gouv.fr/api/explore/v2.1/catalog/datasets/fr-en-calendrier-scolaire/records?where=annee_scolaire='2025-2026' AND zones LIKE '%Zone C%'&limit=100";
        const res = await fetch(url);
        const data = await res.json();
        const rawRecords = data.results || [];

        // --- DÉDOUBLONNAGE ---
        // On utilise une Map pour ne garder qu'une entrée unique par (Description + Date Début)
        const uniqueHolidaysMap = new Map();

        rawRecords.forEach((r) => {
          // Clé unique : "Vacances de Noël|2025-12-20"
          const key = `${r.description}|${r.start_date}`;
          if (!uniqueHolidaysMap.has(key)) {
            uniqueHolidaysMap.set(key, r);
          }
        });

        // Convertir la Map en tableau
        const uniqueRecords = Array.from(uniqueHolidaysMap.values());

        // Remplir le tableau HTML du haut (avec la liste propre)
        this.renderSchoolHolidaysTable(uniqueRecords);

        // Générer les événements jour par jour (uniquement sur la liste propre)
        uniqueRecords.forEach((r, idx) => {
          let curr = new Date(r.start_date);
          const end = new Date(r.end_date);
          // Boucle jour par jour
          while (curr < end) {
            const iso = curr.toISOString().split("T")[0];
            schoolHolidayEvents.push({
              id: `sh-${iso}-${idx}`,
              date: iso,
              type: "VACANCES_SCOLAIRES",
              duration: 1,
            });
            curr.setDate(curr.getDate() + 1);
          }
        });
      } catch (e) {
        console.warn(
          "Impossible de charger les vacances scolaires depuis l'API Gouv.",
          e,
        );
      }

      return [...publicHolidays, ...schoolHolidayEvents];
    }

    processWeeks(rawWeeks) {
      return rawWeeks.map((w) => ({
        id: `${w.week_iso_year}-W${w.week_iso_number}`,
        monthKey: `${w.year}-${String(w.month).padStart(2, "0")}`,
        monthName: w.month_name,
        weekLabel: w.week_label,
        dayDates: {
          mon: new Date(w.mon_date + "T00:00:00"),
          tue: new Date(w.tue_date + "T00:00:00"),
          wed: new Date(w.wed_date + "T00:00:00"),
          thu: new Date(w.thu_date + "T00:00:00"),
          fri: new Date(w.fri_date + "T00:00:00"),
        },
        dayFlags: {
          mon: { events: [] },
          tue: { events: [] },
          wed: { events: [] },
          thu: { events: [] },
          fri: { events: [] },
        },
        totals: {
          offCarole: 0,
          extraOffCarole: 0,
          centre: 0,
          avis: 0,
          pepSick: 0,
          presencePep: 0,
          alexCP: 0,
          alexJRA: 0,
          alexJA: 0,
          laiaCP: 0,
          laiaJRA: 0,
          laiaJA: 0,
        },
      }));
    }

    reprocessAndRender() {
      this.reprocessEvents();
      this.calculateMonthlyBalances();
      this.updateGlobalSummary();
      this.renderTable();
      this.renderMonthCalendar();
    }

    reprocessEvents() {
      this.weeks.forEach((w) => {
        Object.keys(w.totals).forEach((k) => (w.totals[k] = 0));
        Object.values(w.dayFlags).forEach((f) => (f.events = []));

        this.events.forEach((e) => {
          const d = new Date(e.date + "T00:00:00");
          if (d >= w.dayDates.mon && d <= w.dayDates.fri) {
            const dayKey = Object.keys(w.dayDates).find(
              (k) => w.dayDates[k].getTime() === d.getTime(),
            );
            if (dayKey) w.dayFlags[dayKey].events.push(e);
            const dur = parseFloat(e.duration) || 1;
            const typeMap = {
              OFF_CAROLE: "offCarole",
              EXTRA_OFF_CAROLE: "extraOffCarole",
              CENTRE: "centre",
              AVIS: "avis",
              PEP_SICK: "pepSick",
            };
            if (typeMap[e.type]) w.totals[typeMap[e.type]] += dur;
          }
        });

        this.leaves.forEach((l) => {
          const d = new Date(l.leave_date + "T00:00:00");
          if (d >= w.dayDates.mon && d <= w.dayDates.fri) {
            const dur = parseFloat(l.duration) || 1;
            const prefix =
              l.person_id === 2 ? "alex" : l.person_id === 3 ? "laia" : null;
            if (prefix) w.totals[`${prefix}${l.leave_type}`] += dur;
          }
        });

        let workingDays = 0;
        Object.values(w.dayDates).forEach((d) => {
          if (!this.publicHolidayDates.has(d.toISOString().split("T")[0]))
            workingDays++;
        });
        w.totals.presencePep = Math.max(
          0,
          workingDays -
            (w.totals.offCarole + w.totals.extraOffCarole + w.totals.pepSick),
        );
      });
    }

    calculateMonthlyBalances() {
      const balances = {
        2: { CP: {}, JRA: {}, JA: {} },
        3: { CP: {}, JRA: {}, JA: {} },
      };
      const ymSet = new Set();
      this.weeks.forEach((w) => ymSet.add(w.monthKey));
      const ymList = Array.from(ymSet).sort();

      const usageByMonth = {};
      this.leaves.forEach((l) => {
        const pid = l.person_id;
        const type = l.leave_type;
        const ym = l.leave_date.substring(0, 7);
        if (!usageByMonth[pid]) usageByMonth[pid] = {};
        if (!usageByMonth[pid][type]) usageByMonth[pid][type] = {};
        usageByMonth[pid][type][ym] =
          (usageByMonth[pid][type][ym] || 0) + parseFloat(l.duration);
      });

      [2, 3].forEach((pid) => {
        ["CP", "JRA", "JA"].forEach((type) => {
          ymList.forEach((ym) => {
            const [currYear, currMonth] = ym.split("-").map(Number);
            let refYear = currYear;
            if (type === "CP")
              refYear = currMonth >= 6 ? currYear : currYear - 1;

            const initialObj = this.leaveBalances.find(
              (b) =>
                b.person_id == pid &&
                b.leave_type == type &&
                b.balance_year == refYear,
            );
            const initial = initialObj
              ? parseFloat(initialObj.initial_balance)
              : type === "CP"
                ? 25
                : type === "JRA"
                  ? 10
                  : 0;

            let usedBefore = 0;
            let periodStartMonth = type === "CP" ? "06" : "01";
            const periodStart = `${refYear}-${periodStartMonth}`;

            Object.keys(usageByMonth[pid]?.[type] || {}).forEach((usedYm) => {
              if (usedYm >= periodStart && usedYm < ym) {
                usedBefore += usageByMonth[pid][type][usedYm];
              }
            });

            const available = Math.max(0, initial - usedBefore);
            const usedInMonth = usageByMonth[pid]?.[type]?.[ym] || 0;
            balances[pid][type][ym] = {
              availableAtMonthStart: available,
              usedInMonth: usedInMonth,
            };
          });
        });
      });
      this.monthlyLeaveBalances = balances;
    }

    renderTable() {
      this.planningBody.innerHTML = "";
      const monthSpans = this.weeks.reduce((acc, w) => {
        acc[w.monthKey] = (acc[w.monthKey] || 0) + 1;
        return acc;
      }, {});
      const processedMonths = {};
      const processedLeavesCols = {};
      const fmt = (n) =>
        n > 0 ? (Number.isInteger(n) ? n : n.toFixed(1)) : "";

      this.weeks.forEach((w, idx) => {
        const tr = document.createElement("tr");
        if (idx === 0 || this.weeks[idx - 1].monthKey !== w.monthKey)
          tr.classList.add("fc-month-first-week-row");
        if (
          idx === this.weeks.length - 1 ||
          this.weeks[idx + 1].monthKey !== w.monthKey
        )
          tr.classList.add("fc-month-last-week-row");

        if (!processedMonths[w.monthKey]) {
          processedMonths[w.monthKey] = true;
          const td = document.createElement("td");
          td.className = "col-month";
          td.textContent = w.monthName;
          td.rowSpan = monthSpans[w.monthKey];
          tr.appendChild(td);
        }

        const tdW = document.createElement("td");
        tdW.className = "col-month";
        tdW.textContent = w.weekLabel;
        tr.appendChild(tdW);

        ["mon", "tue", "wed", "thu", "fri"].forEach((d) => {
          const td = document.createElement("td");
          const dateObj = w.dayDates[d];
          const iso = dateObj.toISOString().split("T")[0];
          td.dataset.date = iso;
          td.textContent = String(dateObj.getDate()).padStart(2, "0");
          td.className = "col-day";

          const dayEvents = w.dayFlags[d].events;
          dayEvents.forEach((evt) => {
            if (evt.type === "OFF_CAROLE")
              td.classList.add("fc-day--off-carole");
            if (evt.type === "EXTRA_OFF_CAROLE")
              td.classList.add("fc-day--extra-off-carole");
            if (evt.type === "PUBLIC_HOLIDAY")
              td.classList.add("fc-day--public-holiday");
            if (evt.type === "VACANCES_SCOLAIRES")
              td.classList.add("fc-day--school-holiday");
            if (evt.type === "CENTRE") td.classList.add("fc-day--centre");
            if (evt.type === "AVIS") td.classList.add("fc-day--avis");
            if (evt.type === "PEP_SICK")
              td.innerHTML += `<span class="fc-pep-sick-emoji">🤒</span>`;
          });

          const dayLeaves = this.leaves.filter((l) => l.leave_date === iso);
          if (dayLeaves.length) {
            let html = `<div style="position:absolute; bottom:0; left:0; width:100%; font-size:9px; line-height:1; display:flex; justify-content:center; gap:2px; pointer-events:none;">`;
            // --- CORRECTION COULEURS ---
            if (dayLeaves.some((l) => l.person_id === 2))
              html += `<span style="color:#0f766e; font-weight:800;">A</span>`; // Teal
            if (dayLeaves.some((l) => l.person_id === 3))
              html += `<span style="color:#b45309; font-weight:800;">L</span>`; // Amber
            html += `</div>`;
            td.innerHTML += html;
          }
          tr.appendChild(td);
        });

        [
          "offCarole",
          "extraOffCarole",
          "centre",
          "avis",
          "pepSick",
          "presencePep",
        ].forEach((k) => {
          const td = document.createElement("td");
          td.className = "col-total";
          td.textContent = fmt(w.totals[k]);
          tr.appendChild(td);
        });

        if (!processedLeavesCols[w.monthKey]) {
          processedLeavesCols[w.monthKey] = true;
          const span = monthSpans[w.monthKey];
          const ym = w.monthKey;
          const renderPersonCols = (pid, prefix) => {
            ["CP", "JRA", "JA"].forEach((type) => {
              const info = this.monthlyLeaveBalances[pid][type][ym];
              const tdAv = document.createElement("td");
              tdAv.className = `${prefix}-sub ${prefix}-av`;
              tdAv.rowSpan = span;
              tdAv.textContent = info ? fmt(info.availableAtMonthStart) : "-";
              tr.appendChild(tdAv);
              const tdUse = document.createElement("td");
              tdUse.className = `${prefix}-sub ${prefix}-use`;
              tdUse.rowSpan = span;
              tdUse.textContent = info ? fmt(info.usedInMonth) : "";
              tr.appendChild(tdUse);
            });
          };
          renderPersonCols(2, "col-alex");
          renderPersonCols(3, "col-laia");
        }
        this.planningBody.appendChild(tr);
      });
    }

    renderMonthCalendar() {
      if (!this.monthCalendar) return;
      this.monthCalendar.innerHTML = ""; // CLEAN UP

      const y = this.currentMonth.getFullYear();
      const m = this.currentMonth.getMonth();

      const titleEl = document.querySelector("#fc-current-month-year");
      if (titleEl) {
        if (this.viewMode === "year") {
          titleEl.textContent = `Année scolaire ${this.currentSchoolYearStart} – ${this.currentSchoolYearStart + 1}`;
        } else if (this.viewMode === "2months") {
          const nextM = new Date(y, m + 1, 1);
          const m1 = new Intl.DateTimeFormat("fr-FR", { month: "long" }).format(
            this.currentMonth,
          );
          const m2 = new Intl.DateTimeFormat("fr-FR", {
            month: "long",
            year: "numeric",
          }).format(nextM);
          titleEl.textContent = `${m1} - ${m2}`;
        } else {
          titleEl.textContent = new Intl.DateTimeFormat("fr-FR", {
            month: "long",
            year: "numeric",
          }).format(this.currentMonth);
        }
      }

      if (this.viewMode === "year") {
        this.renderYearView();
        return;
      }
      if (this.viewMode === "2months") {
        this.renderTwoMonthsView();
        return;
      }

      this.monthCalendar.innerHTML = this.generateMonthHTML(y, m);
    }

    renderTwoMonthsView() {
      const y = this.currentMonth.getFullYear();
      const m = this.currentMonth.getMonth();
      const nextDate = new Date(y, m + 1, 1);
      let html = `<div class="fc-two-months-container">`;
      html += `<div class="fc-month-container"><div class="fc-month-title">${new Intl.DateTimeFormat("fr-FR", { month: "long" }).format(this.currentMonth)}</div>${this.generateMonthHTML(y, m)}</div>`;
      html += `<div class="fc-month-container"><div class="fc-month-title">${new Intl.DateTimeFormat("fr-FR", { month: "long" }).format(nextDate)}</div>${this.generateMonthHTML(nextDate.getFullYear(), nextDate.getMonth())}</div>`;
      html += `</div>`;
      this.monthCalendar.innerHTML = html;
    }

    renderYearView() {
      const startYear = this.currentSchoolYearStart;
      let html = '<div class="fc-year-container">';
      // Sept-Dec
      for (let i = 8; i < 12; i++)
        html += `<div class="fc-year-month"><div class="fc-year-month-title">${new Intl.DateTimeFormat("fr-FR", { month: "long" }).format(new Date(startYear, i))}</div>${this.generateMonthHTML(startYear, i)}</div>`;
      // Jan-Aug
      for (let i = 0; i < 8; i++)
        html += `<div class="fc-year-month"><div class="fc-year-month-title">${new Intl.DateTimeFormat("fr-FR", { month: "long" }).format(new Date(startYear + 1, i))}</div>${this.generateMonthHTML(startYear + 1, i)}</div>`;
      html += "</div>";
      this.monthCalendar.innerHTML = html;
    }

    generateMonthHTML(year, month) {
      let html = `<table class="fc-month-table"><thead><tr>`;
      ["L", "M", "M", "J", "V"].forEach((d) => (html += `<th>${d}</th>`));
      html += `</tr></thead><tbody>`;

      const firstDay = new Date(year, month, 1);
      const startDay = (firstDay.getDay() + 6) % 7;
      const daysInMonth = new Date(year, month + 1, 0).getDate();
      let dayCounter = 1;

      for (let row = 0; row < 6; row++) {
        html += `<tr>`;
        for (let col = 0; col < 5; col++) {
          if (
            (row === 0 && col < startDay && startDay < 5) ||
            dayCounter > daysInMonth
          ) {
            html += `<td class="fc-day--other-month"></td>`;
          } else if (row === 0 && startDay >= 5) {
            html += `<td class="fc-day--other-month"></td>`;
          } else {
            const iso = `${year}-${String(month + 1).padStart(2, "0")}-${String(dayCounter).padStart(2, "0")}`;
            let cls = "fc-month-day";
            const dayEvts = this.events.filter((e) => e.date === iso);
            if (dayEvts.some((e) => e.type === "VACANCES_SCOLAIRES"))
              cls += " fc-day--school-holiday";
            if (dayEvts.some((e) => e.type === "PUBLIC_HOLIDAY"))
              cls += " fc-day--public-holiday";
            if (dayEvts.some((e) => e.type === "OFF_CAROLE"))
              cls += " fc-day--off-carole";
            if (dayEvts.some((e) => e.type === "EXTRA_OFF_CAROLE"))
              cls += " fc-day--extra-off-carole";
            if (dayEvts.some((e) => ["CENTRE", "AVIS"].includes(e.type))) {
              cls += " fc-day--has-guard";
              if (dayEvts.some((e) => e.type === "CENTRE"))
                cls += " fc-day--centre";
              if (dayEvts.some((e) => e.type === "AVIS"))
                cls += " fc-day--avis";
            }

            let content = `<div style="position:relative; height:100%;">${dayCounter}`;
            if (dayEvts.some((e) => e.type === "PEP_SICK"))
              content += `<span style="position:absolute; bottom:2px; right:2px;">🤒</span>`;
            const dayLeaves = this.leaves.filter((l) => l.leave_date === iso);
            if (dayLeaves.length) {
              content += `<div style="position:absolute; bottom:2px; left:2px; font-size:10px; font-weight:bold;">`;
              if (dayLeaves.some((l) => l.person_id === 2))
                content += `<span style="color:#0f766e">A</span> `;
              if (dayLeaves.some((l) => l.person_id === 3))
                content += `<span style="color:#b45309">L</span>`;
              content += `</div>`;
            }
            content += `</div>`;
            html += `<td class="${cls}" data-date="${iso}">${content}</td>`;
            dayCounter++;
          }
        }
        html += `</tr>`;
        if (dayCounter > daysInMonth) break;
      }
      html += `</tbody></table>`;
      return html;
    }

    renderSchoolHolidaysTable(records) {
      if (!this.schoolHolidaysTableBody) return;
      records.sort((a, b) => new Date(a.start_date) - new Date(b.start_date));
      this.schoolHolidaysTableBody.innerHTML = records
        .map(
          (r) => `
         <tr>
           <td>${r.description}</td>
           <td>${new Date(r.start_date).toLocaleDateString("fr-FR")}</td>
           <td>${new Date(r.end_date).toLocaleDateString("fr-FR")}</td>
           <td>${r.zones}</td>
         </tr>
       `,
        )
        .join("");
    }

    updateGlobalSummary() {
      const div = document.getElementById("globalSummary");
      if (!div) return;
      const stats = { off: 0, extra: 0, sick: 0, pep: 0, totalWorking: 0 };
      this.weeks.forEach((w) => {
        stats.off += w.totals.offCarole;
        stats.extra += w.totals.extraOffCarole;
        stats.sick += w.totals.pepSick;
        stats.pep += w.totals.presencePep;
        Object.values(w.dayDates).forEach((d) => {
          if (!this.publicHolidayDates.has(d.toISOString().split("T")[0]))
            stats.totalWorking++;
        });
      });
      div.innerHTML = `
         <p><strong>Off Carole :</strong> ${stats.off} jours</p>
         <p><strong>Extra Off Carole :</strong> ${stats.extra} jours</p>
         <p><strong>Pep malade :</strong> ${stats.sick} jours</p>
         <p><strong>Présence Pep :</strong> ${stats.pep} jours</p>
         <p style="font-size:0.8em; color:#666; margin-top:4px;">(Sur jours ouvrés totaux : ${stats.totalWorking})</p>
       `;
    }

    updateSchoolYearLabel() {
      const lbl = document.getElementById("fc-current-school-year-label");
      if (lbl)
        lbl.textContent = `${this.currentSchoolYearStart} – ${this.currentSchoolYearStart + 1}`;
    }

    // ================== INTERACTIONS ==================

    setupEventListeners() {
      // Planning Hebdo
      this.planningBody.addEventListener("mousedown", (e) =>
        this.handleMouseDown(e),
      );
      document.addEventListener("mousemove", (e) => this.handleMouseMove(e));
      document.addEventListener("mouseup", (e) => this.handleMouseUp(e));

      // Calendrier Mensuel (Clic simple pour ouvrir le menu)
      if (this.monthCalendar) {
        this.monthCalendar.addEventListener("click", (e) => {
          const td = e.target.closest("td[data-date]");
          if (td) {
            this.monthSelectedCells = [td]; // Simuler sélection unique
            this.showMenu(e.pageX, e.pageY, [td.dataset.date], true);
          }
        });
      }

      // Menus Contextuels
      document.addEventListener("click", (e) => this.closeMenusIfOutside(e));
      const handleMenu = (e) => {
        const btn = e.target.closest("button");
        if (btn) this.handleMenuAction(btn.dataset);
      };
      if (this.selectionMenu)
        this.selectionMenu.addEventListener("click", handleMenu);
      if (this.monthSelectionMenu)
        this.monthSelectionMenu.addEventListener("click", handleMenu);

      // Boutons Navigation Mensuelle
      document
        .getElementById("fc-prev-month")
        ?.addEventListener("click", () => {
          this.currentMonth.setMonth(this.currentMonth.getMonth() - 1);
          this.renderMonthCalendar();
        });
      document
        .getElementById("fc-next-month")
        ?.addEventListener("click", () => {
          this.currentMonth.setMonth(this.currentMonth.getMonth() + 1);
          this.renderMonthCalendar();
        });

      // Boutons Navigation Année Scolaire
      document
        .getElementById("fc-prev-school-year")
        ?.addEventListener("click", () => this.changeSchoolYear(-1));
      document
        .getElementById("fc-next-school-year")
        ?.addEventListener("click", () => this.changeSchoolYear(1));

      // Boutons de Vue (1 mois / 2 mois / Année)
      document.querySelectorAll(".fc-view-button").forEach((btn) => {
        btn.addEventListener("click", (e) => {
          document
            .querySelectorAll(".fc-view-button")
            .forEach((b) => b.classList.remove("fc-view-button--active"));
          e.target.classList.add("fc-view-button--active");
          this.viewMode = e.target.dataset.view;
          this.renderMonthCalendar();
        });
      });
    }

    handleMouseDown(e) {
      const td = e.target.closest("#planningTable td[data-date]");
      if (!td) return;
      e.preventDefault();
      this.clearSelection();
      this.isSelecting = true;
      this.selectCell(td);
    }

    handleMouseMove(e) {
      if (!this.isSelecting) return;
      const td = e.target.closest("#planningTable td[data-date]");
      if (td && !this.selectedCells.includes(td)) this.selectCell(td);
    }

    handleMouseUp(e) {
      if (!this.isSelecting) return;

      // FIX CRITIQUE : Si on relâche la souris sur une case qu'on n'a pas eu le temps de "survoler" (mouvement rapide)
      // on l'ajoute maintenant pour être sûr qu'elle est dans la sélection.
      const td = e.target.closest("#planningTable td[data-date]");
      if (td && !this.selectedCells.includes(td)) {
        this.selectCell(td);
      }

      this.isSelecting = false;
      if (!this.selectedCells.length) return;

      const dates = this.selectedCells.map((c) => c.dataset.date);
      this.showMenu(e.pageX, e.pageY, dates, false);
    }

    selectCell(cell) {
      cell.classList.add("fc-day--selected");
      this.selectedCells.push(cell);
    }

    clearSelection() {
      this.selectedCells.forEach((c) => c.classList.remove("fc-day--selected"));
      this.selectedCells = [];
      this.selectionMenu.style.display = "none";
      if (this.monthSelectionMenu)
        this.monthSelectionMenu.style.display = "none";
    }

    closeMenusIfOutside(e) {
      if (
        !this.selectionMenu.contains(e.target) &&
        !this.monthSelectionMenu?.contains(e.target) &&
        !this.menuJustOpened
      ) {
        this.clearSelection();
      }
    }

    showMenu(x, y, dates, isMonthView) {
      const menu = isMonthView ? this.monthSelectionMenu : this.selectionMenu;
      if (!menu) return;

      this._currentBulkInfo = { dates };
      const dateLabel =
        dates.length > 1
          ? `${dates.length} jours`
          : new Date(dates[0]).toLocaleDateString("fr-FR");

      let html = `<div class="fc-menu-section"><strong>${dateLabel}</strong></div>`;

      // Carole
      html += `<div class="fc-menu-section"><strong>Congés Carole</strong><div class="fc-menu-grid">`;
      html += `<button class="fc-menu-btn" data-action="add" data-type="OFF_CAROLE" data-person="Carole">Off Carole</button>`;
      html += `<button class="fc-menu-btn" data-action="add" data-type="EXTRA_OFF_CAROLE" data-person="Carole">Extra Off</button>`;
      html += `</div><button class="fc-menu-danger" data-action="clear-type" data-cat="CONGE">Effacer congés Carole</button></div>`;

      // Garde
      html += `<div class="fc-menu-section"><strong>Garde</strong><div class="fc-menu-grid">`;
      html += `<button class="fc-menu-btn" data-action="add" data-type="CENTRE">Centre</button>`;
      html += `<button class="fc-menu-btn" data-action="add" data-type="AVIS">Avis</button>`;
      html += `</div><button class="fc-menu-danger" data-action="clear-type" data-cat="GARDE">Effacer Garde</button></div>`;

      // Pep
      html += `<div class="fc-menu-section"><strong>Pep</strong>`;
      html += `<button class="fc-menu-btn" data-action="add" data-type="PEP_SICK" style="width:100%">Pep Malade</button>`;
      html += `<button class="fc-menu-danger" data-action="clear-type" data-cat="PEP">Effacer Pep</button></div>`;

      // Alex/Laia
      html += `<div class="fc-menu-section"><strong>Congés Alex / Laia</strong><div class="fc-menu-leaves-table"><table><thead><tr><th>Alex</th><th>Laia</th></tr></thead><tbody>`;
      ["CP", "JRA", "JA"].forEach((t) => {
        html += `<tr><td><button class="fc-menu-btn" data-action="add-leave" data-pid="2" data-type="${t}">${t}</button></td>`;
        html += `<td><button class="fc-menu-btn" data-action="add-leave" data-pid="3" data-type="${t}">${t}</button></td></tr>`;
      });
      html += `</tbody></table></div>`;
      html += `<button class="fc-menu-danger" data-action="clear-leaves">Effacer Alex/Laia</button></div>`;

      menu.innerHTML = html;

      const menuWidth = 240;
      let left = x + 10;
      if (left + menuWidth > window.innerWidth) left = x - menuWidth - 10;

      menu.style.left = `${left}px`;
      menu.style.top = `${y + 10}px`;
      menu.style.display = "block";

      this.menuJustOpened = true;
      setTimeout(() => (this.menuJustOpened = false), 100);
    }

    async handleMenuAction(dataset) {
      this.selectionMenu.style.display = "none";
      if (this.monthSelectionMenu)
        this.monthSelectionMenu.style.display = "none";

      const { action, type, pid, cat } = dataset;
      const dates = this._currentBulkInfo.dates;

      try {
        if (action === "add") {
          let typesToClear = [];
          if (["OFF_CAROLE", "EXTRA_OFF_CAROLE"].includes(type))
            typesToClear = CONGE_TYPES;
          if (["CENTRE", "AVIS"].includes(type)) typesToClear = GUARDE_TYPES;
          if (type === "PEP_SICK") typesToClear = PEP_TYPES;

          if (typesToClear.length) {
            await this.postApi(
              "/modules/family-calendar/includes/api/manage-event.php",
              {
                action: "bulk_delete_day_types",
                dates,
                types: typesToClear,
              },
            );
          }
          const payload = dates.map((d) => ({
            date: d,
            type: type,
            duration: 1,
            person: "Carole",
          }));
          await this.postApi(
            "/modules/family-calendar/includes/api/save-events.php",
            payload,
          );
        } else if (action === "clear-type") {
          let typesToClear = [];
          if (cat === "CONGE") typesToClear = CONGE_TYPES;
          if (cat === "GARDE") typesToClear = GUARDE_TYPES;
          if (cat === "PEP") typesToClear = PEP_TYPES;

          await this.postApi(
            "/modules/family-calendar/includes/api/manage-event.php",
            {
              action: "bulk_delete_day_types",
              dates,
              types: typesToClear,
            },
          );
        } else if (action === "add-leave") {
          await this.postApi(
            "/modules/family-calendar/includes/api/manage-leaf.php",
            {
              action: "bulk_delete_day_person",
              dates,
              person_id: pid,
            },
          );
          const payload = dates.map((d) => ({
            date: d,
            person_id: pid,
            leave_type: type,
            duration: 1,
          }));
          await this.postApi(
            "/modules/family-calendar/includes/api/save-leaves.php",
            payload,
          );
        } else if (action === "clear-leaves") {
          await this.postApi(
            "/modules/family-calendar/includes/api/manage-leaf.php",
            { action: "bulk_delete_day_person", dates, person_id: 2 },
          );
          await this.postApi(
            "/modules/family-calendar/includes/api/manage-leaf.php",
            { action: "bulk_delete_day_person", dates, person_id: 3 },
          );
        }

        await this.refreshAllData();
      } catch (e) {
        alert("Erreur action: " + e.message);
      }
    }

    async fetchApi(url) {
      return fetch(url).then((r) => r.json());
    }

    async postApi(url, data) {
      const res = await fetch(url, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(data),
      });
      if (!res.ok) throw new Error(await res.text());
      return res.json();
    }

    async changeSchoolYear(delta) {
      this.currentSchoolYearStart += delta;
      this.updateSchoolYearLabel();
      await this.refreshAllData();
    }
  }

  new FamilyCalendar();
});
