/***********/***********************
 * PLANNING PRO PERSONNEL
 * Semaine (time blocking 30 min), Journal, Stats, Paramètres
 * Langue: FR. Fuseau: Africa/Casablanca par défaut de ton compte.
 ***********************/

const CONFIG = {
  sheetNames: {
    week: "Semaine",
    journal: "Journal",
    stats: "Stats",
    settings: "Paramètres"
  },
  startHour: 6,              // débute à 06:00
  endHour: 23,               // termine à 23:00
  slotMinutes: 30,           // pas de 30 minutes
  days: ["Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi","Dimanche"],
  defaultCategories: [
    ["Travail","#1a73e8"],
    ["Sport","#34a853"],
    ["Déjeuner","#fbbc05"],
    ["Sortie","#a142f4"],
    ["Étude / Focus","#00bcd4"],
    ["Repos","#9aa0a6"],
    ["Divers","#ff7043"]
  ]
};

function onOpen() {
  const ui = SpreadsheetApp.getUi();
  ui.createMenu("Planning")
    .addItem("Nouvelle semaine", "resetWeekToNextMonday")
    .addItem("Exporter la semaine vers Journal", "exportWeekToJournal")
    .addItem("Recolorer d'après Paramètres", "applyWeekConditionalFormatting")
    .addToUi();
}

// Lance une fois au début
function setupTemplate() {
  const ss = SpreadsheetApp.getActive();
  // Crée/vides feuilles
  const shSettings = getOrCreateSheet_(CONFIG.sheetNames.settings, ss);
  const shWeek = getOrCreateSheet_(CONFIG.sheetNames.week, ss);
  const shJournal = getOrCreateSheet_(CONFIG.sheetNames.journal, ss);
  const shStats = getOrCreateSheet_(CONFIG.sheetNames.stats, ss);

  setupSettings_(shSettings);
  setupWeek_(shWeek, shSettings);
  setupJournal_(shJournal);
  setupStats_(shStats, shJournal, shSettings);

  // Esthétique minimale
  ss.setSpreadsheetLocale("fr_FR");
  ss.rename("Planning personnel");

  SpreadsheetApp.getUi().alert("Planning prêt. Menu « Planning » ajouté. Remplis la feuille Semaine, puis exporte vers le Journal.");
}

/* ---------------- Paramètres ---------------- */

function setupSettings_(sh) {
  sh.clear();
  sh.setTabColor("#263238");
  sh.getRange("A1").setValue("Catégorie");
  sh.getRange("B1").setValue("Couleur (hex)");
  sh.getRange("D1").setValue("Infos");
  sh.getRange("D2").setValue("Ajoute/édite tes catégories ici. Les couleurs pilotent la mise en forme.");
  sh.getRange("A1:B1").setFontWeight("bold");
  sh.setColumnWidths(1, 2, 160);
  sh.setColumnWidths(4, 1, 380);

  // Valeurs par défaut si vide
  const dataRange = sh.getRange(2,1,CONFIG.defaultCategories.length,2);
  dataRange.setValues(CONFIG.defaultCategories);

  // Nom de plage pour validation
  const lastRow = 1 + CONFIG.defaultCategories.length + 50; // marge
  sh.getRange(2,1,lastRow,1).createNamedRange("CATEGORIES_LIST");
  sh.getRange(2,1,lastRow,2).createNamedRange("CATEGORIES_COLORS");
}

/* ---------------- Semaine (time blocking) ---------------- */

function setupWeek_(sh, shSettings) {
  sh.clear();
  sh.setTabColor("#0b8043");
  const header = ["Heure"].concat(CONFIG.days);
  sh.getRange(1,1,1,header.length).setValues([header]).setFontWeight("bold");
  sh.getRange("A1:H1").setBackground("#E8F0FE");

  // Heures en première colonne
  const times = buildTimeSlots_();
  sh.getRange(2,1,times.length,1).setValues(times.map(t => [t]));
  sh.getRange(2,1,times.length,1).setNumberFormat("HH:mm");

  // Grille
  const numCols = 1 + CONFIG.days.length;
  const numRows = 1 + times.length;
  sh.getRange(1,1,numRows,numCols).setBorder(true,true,true,true,true,true);
  sh.setFrozenRows(1);
  sh.setFrozenColumns(1);
  sh.setColumnWidth(1, 70);
  for (let c=2; c<=numCols; c++) sh.setColumnWidth(c, 150);

  // Validation: liste de catégories
  const valid = SpreadsheetApp.newDataValidation()
    .requireValueInRange(SpreadsheetApp.getActive().getRangeByName("CATEGORIES_LIST"), true)
    .setAllowInvalid(false).build();
  sh.getRange(2,2,times.length,CONFIG.days.length).setDataValidation(valid);

  // Bandeau semaine: lundi → dimanche
  const monday = getNextMonday_(new Date()); // base
  sh.getRange("J1").setValue("Semaine du");
  sh.getRange("K1").setValue(monday);
  sh.getRange("K1").setNumberFormat("dd/mm/yyyy").setFontWeight("bold");
  sh.getRange("J1:K1").setBackground("#F1F3F4");

  // MEP conditionnelle selon couleurs
  applyWeekConditionalFormatting();
}

function resetWeekToNextMonday() {
  const ss = SpreadsheetApp.getActive();
  const sh = ss.getSheetByName(CONFIG.sheetNames.week);
  if (!sh) return;
  // Vide la grille
  const timesLen = buildTimeSlots_().length;
  sh.getRange(2,2,timesLen,CONFIG.days.length).clearContent().clearFormat();
  // Rappel validations
  const valid = SpreadsheetApp.newDataValidation()
    .requireValueInRange(ss.getRangeByName("CATEGORIES_LIST"), true)
    .setAllowInvalid(false).build();
  sh.getRange(2,2,timesLen,CONFIG.days.length).setDataValidation(valid);
  // Remet couleurs
  applyWeekConditionalFormatting();
  // Date lundi prochain
  sh.getRange("K1").setValue(getNextMonday_(new Date())).setNumberFormat("dd/mm/yyyy");
}

/* Mise en forme conditionnelle basée sur Paramètres */
function applyWeekConditionalFormatting() {
  const ss = SpreadsheetApp.getActive();
  const sh = ss.getSheetByName(CONFIG.sheetNames.week);
  const shSettings = ss.getSheetByName(CONFIG.sheetNames.settings);
  if (!sh || !shSettings) return;

  const timesLen = buildTimeSlots_().length;
  const range = sh.getRange(2,2,timesLen,CONFIG.days.length);

  // Efface règles existantes
  sh.clearConditionalFormatRules();

  // Récupère catégories + couleurs
  const catColors = getCategoriesColors_();

  const rules = [];
  catColors.forEach(([cat,color]) => {
    if (!cat || !color) return;
    rules.push(
      SpreadsheetApp.newConditionalFormatRule()
        .whenTextEqualTo(cat)
        .setBackground(color)
        .setFontColor("#ffffff")
        .setRanges([range])
        .build()
    );
  });

  // Règle fallback pour cellules non vides
  rules.push(
    SpreadsheetApp.newConditionalFormatRule()
      .whenTextContains("")
      .setBackground("#e0e0e0")
      .setRanges([range])
      .build()
  );

  sh.setConditionalFormatRules(rules);
}

/* ---------------- Journal ---------------- */

function setupJournal_(sh) {
  sh.clear();
  sh.setTabColor("#7b1fa2");
  const header = ["Date","Début","Fin","Durée (h)","Catégorie","Note"];
  sh.getRange(1,1,1,header.length).setValues([header]).setFontWeight("bold").setBackground("#FCE8FF");
  sh.setFrozenRows(1);
  sh.setColumnWidths(1,6,140);

  // Formats
  sh.getRange("A2:A").setNumberFormat("dd/mm/yyyy");
  sh.getRange("B2:C").setNumberFormat("HH:mm");
  sh.getRange("D2:D").setNumberFormat("0.00");

  // Validation catégorie
  const valid = SpreadsheetApp.newDataValidation()
    .requireValueInRange(SpreadsheetApp.getActive().getRangeByName("CATEGORIES_LIST"), true)
    .setAllowInvalid(false).build();
  sh.getRange("E2:E").setDataValidation(valid);
}

/* Exporte la semaine vers lignes Journal, en fusionnant les créneaux contigus d’une même catégorie */
function exportWeekToJournal() {
  const ss = SpreadsheetApp.getActive();
  const shWeek = ss.getSheetByName(CONFIG.sheetNames.week);
  const shJournal = ss.getSheetByName(CONFIG.sheetNames.journal);
  if (!shWeek || !shJournal) throw new Error("Feuille manquante.");

  const times = buildTimeSlots_(); // array de Date objets heures du jour fictif
  const grid = shWeek.getRange(2,2,times.length,CONFIG.days.length).getValues();
  const monday = shWeek.getRange("K1").getValue(); // base semaine

  const entries = [];
  for (let d=0; d<CONFIG.days.length; d++) {
    let currentCat = null;
    let startIdx = null;

    for (let r=0; r<times.length; r++) {
      const cellVal = (grid[r][d] || "").toString().trim();
      const isChange = cellVal !== currentCat;

      if (isChange) {
        if (currentCat) {
          // fermer période précédente
          entries.push(buildEntry_(monday, d, times, startIdx, r, currentCat));
        }
        currentCat = cellVal || null;
        startIdx = currentCat ? r : null;
      }
    }
    // Fin de journée
    if (currentCat) {
      entries.push(buildEntry_(monday, d, times, startIdx, times.length, currentCat));
    }
  }

  if (entries.length === 0) {
    SpreadsheetApp.getUi().alert("Aucune cellule renseignée dans Semaine.");
    return;
  }

  // Écrit dans Journal
  const startRow = shJournal.getLastRow() + 1;
  shJournal.getRange(startRow,1,entries.length,entries[0].length).setValues(entries);

  SpreadsheetApp.getUi().alert("Export terminé: " + entries.length + " lignes ajoutées au Journal.");
}

function buildEntry_(mondayDate, dayOffset, times, startIdx, endIdx, cat) {
  const date = new Date(mondayDate);
  date.setDate(date.getDate() + dayOffset);

  const start = times[startIdx];
  const end = times[endIdx] || addMinutes_(times[times.length-1], CONFIG.slotMinutes);

  // Convert HH:mm à date du jour
  const dStart = new Date(date); dStart.setHours(start.getHours(), start.getMinutes(), 0, 0);
  const dEnd = new Date(date); dEnd.setHours(end.getHours(), end.getMinutes(), 0, 0);

  const hours = (dEnd - dStart) / 1000 / 3600;

  return [
    new Date(date),
    new Date(dStart),
    new Date(dEnd),
    Number(hours.toFixed(2)),
    cat,
    "" // Note vide
  ];
}

/* ---------------- Stats ---------------- */

function setupStats_(sh, shJournal, shSettings) {
  sh.clear();
  sh.setTabColor("#e37400");
  sh.getRange("A1").setValue("Stats hebdomadaires par catégorie").setFontWeight("bold").setFontSize(12);
  sh.getRange("A1").setBackground("#FFF3E0");

  // Période: semaine de la feuille Semaine si dispo, sinon semaine courante
  sh.getRange("A3").setValue("Lundi de la semaine");
  sh.getRange("B3").setFormula('=IFERROR(\'Semaine\'!K1,TO_DATE(ROUNDDOWN((TODAY()-2)/7)*7+2))'); // lundi européen approx
  sh.getRange("A4").setValue("Dimanche de la semaine");
  sh.getRange("B4").setFormula('=B3+6');

  // Tableau catégories
  sh.getRange("A6").setValue("Catégorie").setFontWeight("bold");
  sh.getRange("B6").setValue("Heures").setFontWeight("bold");
  sh.getRange("A6:B6").setBackground("#FFE0B2");

  // Recopie dynamique des catégories depuis Paramètres
  sh.getRange("A7").setFormula('=FILTER(Paramètres!A2:A,Paramètres!A2:A<>"")');

  // Heures par catégorie (SUMIFS sur Journal entre B3 et B4)
  sh.getRange("B7").setFormula(
    '=ARRAYFORMULA(IF(A7:A="",,ROUND(SUMIFS(Journal!D:D,Journal!E:E,A7:A,Journal!A:A,">="&$B$3,Journal!A:A,"<="&$B$4),2)))'
  );

  // Petit donut
  const lastRow = 6 + 1 + CONFIG.defaultCategories.length + 20;
  const chart = sh.newChart()
    .setChartType(Charts.ChartType.PIE)
    .addRange(sh.getRange(6,1,lastRow,2))
    .setOption("title", "Répartition hebdo (heures)")
    .setPosition(2,4,0,0)
    .build();
  sh.insertChart(chart);
}

/* ---------------- Helpers ---------------- */

function getOrCreateSheet_(name, ss) {
  let sh = ss.getSheetByName(name);
  if (!sh) sh = ss.insertSheet(name);
  return sh;
}

function buildTimeSlots_() {
  const arr = [];
  const base = new Date(2000,0,1,CONFIG.startHour,0,0,0);
  const end = new Date(2000,0,1,CONFIG.endHour,0,0,0);
  let cur = new Date(base);
  while (cur <= end) {
    arr.push(new Date(cur));
    cur = addMinutes_(cur, CONFIG.slotMinutes);
  }
  return arr;
}

function addMinutes_(date, m) {
  const d = new Date(date);
  d.setMinutes(d.getMinutes()+m);
  return d;
}

function getNextMonday_(d) {
  const date = new Date(d);
  const day = date.getDay(); // 0=dim
  const diff = (day === 1) ? 0 : ((8 - day) % 7);
  date.setHours(0,0,0,0);
  date.setDate(date.getDate() + diff);
  return date;
}

function getCategoriesColors_() {
  const ss = SpreadsheetApp.getActive();
  const range = ss.getRangeByName("CATEGORIES_COLORS");
  const values = range.getValues().filter(r => r[0] && r[1]);
  return values; // [[cat, color], ...]
}
************
 * PLANNING PRO PERSONNEL
 * Semaine (time blocking 30 min), Journal, Stats, Paramètres
 * Langue: FR. Fuseau: Africa/Casablanca par défaut de ton compte.
 ***********************/

const CONFIG = {
  sheetNames: {
    week: "Semaine",
    journal: "Journal",
    stats: "Stats",
    settings: "Paramètres"
  },
  startHour: 6,              // débute à 06:00
  endHour: 23,               // termine à 23:00
  slotMinutes: 30,           // pas de 30 minutes
  days: ["Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi","Dimanche"],
  defaultCategories: [
    ["Travail","#1a73e8"],
    ["Sport","#34a853"],
    ["Déjeuner","#fbbc05"],
    ["Sortie","#a142f4"],
    ["Étude / Focus","#00bcd4"],
    ["Repos","#9aa0a6"],
    ["Divers","#ff7043"]
  ]
};

function onOpen() {
  const ui = SpreadsheetApp.getUi();
  ui.createMenu("Planning")
    .addItem("Nouvelle semaine", "resetWeekToNextMonday")
    .addItem("Exporter la semaine vers Journal", "exportWeekToJournal")
    .addItem("Recolorer d'après Paramètres", "applyWeekConditionalFormatting")
    .addToUi();
}

// Lance une fois au début
function setupTemplate() {
  const ss = SpreadsheetApp.getActive();
  // Crée/vides feuilles
  const shSettings = getOrCreateSheet_(CONFIG.sheetNames.settings, ss);
  const shWeek = getOrCreateSheet_(CONFIG.sheetNames.week, ss);
  const shJournal = getOrCreateSheet_(CONFIG.sheetNames.journal, ss);
  const shStats = getOrCreateSheet_(CONFIG.sheetNames.stats, ss);

  setupSettings_(shSettings);
  setupWeek_(shWeek, shSettings);
  setupJournal_(shJournal);
  setupStats_(shStats, shJournal, shSettings);

  // Esthétique minimale
  ss.setSpreadsheetLocale("fr_FR");
  ss.rename("Planning personnel");

  SpreadsheetApp.getUi().alert("Planning prêt. Menu « Planning » ajouté. Remplis la feuille Semaine, puis exporte vers le Journal.");
}

/* ---------------- Paramètres ---------------- */

function setupSettings_(sh) {
  sh.clear();
  sh.setTabColor("#263238");
  sh.getRange("A1").setValue("Catégorie");
  sh.getRange("B1").setValue("Couleur (hex)");
  sh.getRange("D1").setValue("Infos");
  sh.getRange("D2").setValue("Ajoute/édite tes catégories ici. Les couleurs pilotent la mise en forme.");
  sh.getRange("A1:B1").setFontWeight("bold");
  sh.setColumnWidths(1, 2, 160);
  sh.setColumnWidths(4, 1, 380);

  // Valeurs par défaut si vide
  const dataRange = sh.getRange(2,1,CONFIG.defaultCategories.length,2);
  dataRange.setValues(CONFIG.defaultCategories);

  // Nom de plage pour validation
  const lastRow = 1 + CONFIG.defaultCategories.length + 50; // marge
  sh.getRange(2,1,lastRow,1).createNamedRange("CATEGORIES_LIST");
  sh.getRange(2,1,lastRow,2).createNamedRange("CATEGORIES_COLORS");
}

/* ---------------- Semaine (time blocking) ---------------- */

function setupWeek_(sh, shSettings) {
  sh.clear();
  sh.setTabColor("#0b8043");
  const header = ["Heure"].concat(CONFIG.days);
  sh.getRange(1,1,1,header.length).setValues([header]).setFontWeight("bold");
  sh.getRange("A1:H1").setBackground("#E8F0FE");

  // Heures en première colonne
  const times = buildTimeSlots_();
  sh.getRange(2,1,times.length,1).setValues(times.map(t => [t]));
  sh.getRange(2,1,times.length,1).setNumberFormat("HH:mm");

  // Grille
  const numCols = 1 + CONFIG.days.length;
  const numRows = 1 + times.length;
  sh.getRange(1,1,numRows,numCols).setBorder(true,true,true,true,true,true);
  sh.setFrozenRows(1);
  sh.setFrozenColumns(1);
  sh.setColumnWidth(1, 70);
  for (let c=2; c<=numCols; c++) sh.setColumnWidth(c, 150);

  // Validation: liste de catégories
  const valid = SpreadsheetApp.newDataValidation()
    .requireValueInRange(SpreadsheetApp.getActive().getRangeByName("CATEGORIES_LIST"), true)
    .setAllowInvalid(false).build();
  sh.getRange(2,2,times.length,CONFIG.days.length).setDataValidation(valid);

  // Bandeau semaine: lundi → dimanche
  const monday = getNextMonday_(new Date()); // base
  sh.getRange("J1").setValue("Semaine du");
  sh.getRange("K1").setValue(monday);
  sh.getRange("K1").setNumberFormat("dd/mm/yyyy").setFontWeight("bold");
  sh.getRange("J1:K1").setBackground("#F1F3F4");

  // MEP conditionnelle selon couleurs
  applyWeekConditionalFormatting();
}

function resetWeekToNextMonday() {
  const ss = SpreadsheetApp.getActive();
  const sh = ss.getSheetByName(CONFIG.sheetNames.week);
  if (!sh) return;
  // Vide la grille
  const timesLen = buildTimeSlots_().length;
  sh.getRange(2,2,timesLen,CONFIG.days.length).clearContent().clearFormat();
  // Rappel validations
  const valid = SpreadsheetApp.newDataValidation()
    .requireValueInRange(ss.getRangeByName("CATEGORIES_LIST"), true)
    .setAllowInvalid(false).build();
  sh.getRange(2,2,timesLen,CONFIG.days.length).setDataValidation(valid);
  // Remet couleurs
  applyWeekConditionalFormatting();
  // Date lundi prochain
  sh.getRange("K1").setValue(getNextMonday_(new Date())).setNumberFormat("dd/mm/yyyy");
}

/* Mise en forme conditionnelle basée sur Paramètres */
function applyWeekConditionalFormatting() {
  const ss = SpreadsheetApp.getActive();
  const sh = ss.getSheetByName(CONFIG.sheetNames.week);
  const shSettings = ss.getSheetByName(CONFIG.sheetNames.settings);
  if (!sh || !shSettings) return;

  const timesLen = buildTimeSlots_().length;
  const range = sh.getRange(2,2,timesLen,CONFIG.days.length);

  // Efface règles existantes
  sh.clearConditionalFormatRules();

  // Récupère catégories + couleurs
  const catColors = getCategoriesColors_();

  const rules = [];
  catColors.forEach(([cat,color]) => {
    if (!cat || !color) return;
    rules.push(
      SpreadsheetApp.newConditionalFormatRule()
        .whenTextEqualTo(cat)
        .setBackground(color)
        .setFontColor("#ffffff")
        .setRanges([range])
        .build()
    );
  });

  // Règle fallback pour cellules non vides
  rules.push(
    SpreadsheetApp.newConditionalFormatRule()
      .whenTextContains("")
      .setBackground("#e0e0e0")
      .setRanges([range])
      .build()
  );

  sh.setConditionalFormatRules(rules);
}

/* ---------------- Journal ---------------- */

function setupJournal_(sh) {
  sh.clear();
  sh.setTabColor("#7b1fa2");
  const header = ["Date","Début","Fin","Durée (h)","Catégorie","Note"];
  sh.getRange(1,1,1,header.length).setValues([header]).setFontWeight("bold").setBackground("#FCE8FF");
  sh.setFrozenRows(1);
  sh.setColumnWidths(1,6,140);

  // Formats
  sh.getRange("A2:A").setNumberFormat("dd/mm/yyyy");
  sh.getRange("B2:C").setNumberFormat("HH:mm");
  sh.getRange("D2:D").setNumberFormat("0.00");

  // Validation catégorie
  const valid = SpreadsheetApp.newDataValidation()
    .requireValueInRange(SpreadsheetApp.getActive().getRangeByName("CATEGORIES_LIST"), true)
    .setAllowInvalid(false).build();
  sh.getRange("E2:E").setDataValidation(valid);
}

/* Exporte la semaine vers lignes Journal, en fusionnant les créneaux contigus d’une même catégorie */
function exportWeekToJournal() {
  const ss = SpreadsheetApp.getActive();
  const shWeek = ss.getSheetByName(CONFIG.sheetNames.week);
  const shJournal = ss.getSheetByName(CONFIG.sheetNames.journal);
  if (!shWeek || !shJournal) throw new Error("Feuille manquante.");

  const times = buildTimeSlots_(); // array de Date objets heures du jour fictif
  const grid = shWeek.getRange(2,2,times.length,CONFIG.days.length).getValues();
  const monday = shWeek.getRange("K1").getValue(); // base semaine

  const entries = [];
  for (let d=0; d<CONFIG.days.length; d++) {
    let currentCat = null;
    let startIdx = null;

    for (let r=0; r<times.length; r++) {
      const cellVal = (grid[r][d] || "").toString().trim();
      const isChange = cellVal !== currentCat;

      if (isChange) {
        if (currentCat) {
          // fermer période précédente
          entries.push(buildEntry_(monday, d, times, startIdx, r, currentCat));
        }
        currentCat = cellVal || null;
        startIdx = currentCat ? r : null;
      }
    }
    // Fin de journée
    if (currentCat) {
      entries.push(buildEntry_(monday, d, times, startIdx, times.length, currentCat));
    }
  }

  if (entries.length === 0) {
    SpreadsheetApp.getUi().alert("Aucune cellule renseignée dans Semaine.");
    return;
  }

  // Écrit dans Journal
  const startRow = shJournal.getLastRow() + 1;
  shJournal.getRange(startRow,1,entries.length,entries[0].length).setValues(entries);

  SpreadsheetApp.getUi().alert("Export terminé: " + entries.length + " lignes ajoutées au Journal.");
}

function buildEntry_(mondayDate, dayOffset, times, startIdx, endIdx, cat) {
  const date = new Date(mondayDate);
  date.setDate(date.getDate() + dayOffset);

  const start = times[startIdx];
  const end = times[endIdx] || addMinutes_(times[times.length-1], CONFIG.slotMinutes);

  // Convert HH:mm à date du jour
  const dStart = new Date(date); dStart.setHours(start.getHours(), start.getMinutes(), 0, 0);
  const dEnd = new Date(date); dEnd.setHours(end.getHours(), end.getMinutes(), 0, 0);

  const hours = (dEnd - dStart) / 1000 / 3600;

  return [
    new Date(date),
    new Date(dStart),
    new Date(dEnd),
    Number(hours.toFixed(2)),
    cat,
    "" // Note vide
  ];
}

/* ---------------- Stats ---------------- */

function setupStats_(sh, shJournal, shSettings) {
  sh.clear();
  sh.setTabColor("#e37400");
  sh.getRange("A1").setValue("Stats hebdomadaires par catégorie").setFontWeight("bold").setFontSize(12);
  sh.getRange("A1").setBackground("#FFF3E0");

  // Période: semaine de la feuille Semaine si dispo, sinon semaine courante
  sh.getRange("A3").setValue("Lundi de la semaine");
  sh.getRange("B3").setFormula('=IFERROR(\'Semaine\'!K1,TO_DATE(ROUNDDOWN((TODAY()-2)/7)*7+2))'); // lundi européen approx
  sh.getRange("A4").setValue("Dimanche de la semaine");
  sh.getRange("B4").setFormula('=B3+6');

  // Tableau catégories
  sh.getRange("A6").setValue("Catégorie").setFontWeight("bold");
  sh.getRange("B6").setValue("Heures").setFontWeight("bold");
  sh.getRange("A6:B6").setBackground("#FFE0B2");

  // Recopie dynamique des catégories depuis Paramètres
  sh.getRange("A7").setFormula('=FILTER(Paramètres!A2:A,Paramètres!A2:A<>"")');

  // Heures par catégorie (SUMIFS sur Journal entre B3 et B4)
  sh.getRange("B7").setFormula(
    '=ARRAYFORMULA(IF(A7:A="",,ROUND(SUMIFS(Journal!D:D,Journal!E:E,A7:A,Journal!A:A,">="&$B$3,Journal!A:A,"<="&$B$4),2)))'
  );

  // Petit donut
  const lastRow = 6 + 1 + CONFIG.defaultCategories.length + 20;
  const chart = sh.newChart()
    .setChartType(Charts.ChartType.PIE)
    .addRange(sh.getRange(6,1,lastRow,2))
    .setOption("title", "Répartition hebdo (heures)")
    .setPosition(2,4,0,0)
    .build();
  sh.insertChart(chart);
}

/* ---------------- Helpers ---------------- */

function getOrCreateSheet_(name, ss) {
  let sh = ss.getSheetByName(name);
  if (!sh) sh = ss.insertSheet(name);
  return sh;
}

function buildTimeSlots_() {
  const arr = [];
  const base = new Date(2000,0,1,CONFIG.startHour,0,0,0);
  const end = new Date(2000,0,1,CONFIG.endHour,0,0,0);
  let cur = new Date(base);
  while (cur <= end) {
    arr.push(new Date(cur));
    cur = addMinutes_(cur, CONFIG.slotMinutes);
  }
  return arr;
}

function addMinutes_(date, m) {
  const d = new Date(date);
  d.setMinutes(d.getMinutes()+m);
  return d;
}

function getNextMonday_(d) {
  const date = new Date(d);
  const day = date.getDay(); // 0=dim
  const diff = (day === 1) ? 0 : ((8 - day) % 7);
  date.setHours(0,0,0,0);
  date.setDate(date.getDate() + diff);
  return date;
}

function getCategoriesColors_() {
  const ss = SpreadsheetApp.getActive();
  const range = ss.getRangeByName("CATEGORIES_COLORS");
  const values = range.getValues().filter(r => r[0] && r[1]);
  return values; // [[cat, color], ...]
}
Scroll to Top