{% extends "base.html" %}
{% block title %}Configuration initiale — GMAO{% endblock %}

{% block content %}
<div class="container-fluid py-4">
  <div class="card shadow mx-auto" style="max-width: 1200px">
    <div class="card-header bg-primary text-white">
      <h4 class="mb-0"><i class="bi bi-gear-fill"></i> Configuration initiale GMAO</h4>
      <div class="small mt-1 opacity-75">Version <code class="text-white">v{{ gmao_version }}</code> · Commit déployé : <code class="text-white">{{ build_commit }}</code></div>
    </div>
    <div class="card-body">
      <div class="row g-3 mb-4" aria-label="Niveaux de configuration"><div class="col-md-4"><div class="border rounded p-3 h-100"><h5>ESSENTIEL</h5><p class="small mb-0">Administrateur, établissement, bâtiments, zones, locaux, techniciens et horaires. À ce niveau, votre GMAO peut maintenant être utilisée.</p></div></div><div class="col-md-4"><div class="border rounded p-3 h-100"><h5>MAINTENANCE / PATRIMOINE</h5><p class="small mb-0">Profils de locaux, équipements, lots, préventif, entreprises et planning des salles.</p></div></div><div class="col-md-4"><div class="border rounded p-3 h-100"><h5>AVANCÉ / FACULTATIF</h5><p class="small mb-0">Logements, compteurs, cartographie technique et intégrations. Ces fonctions ne bloquent jamais l’installation.</p></div></div></div>
      <div class="d-flex flex-wrap justify-content-between gap-2 mb-4" id="stepIndicators">
        {% set labels = ['Admin', 'Collège', 'Bâtiments', 'Zones', 'Salles', 'Lots', 'Calendrier', 'ENT', 'Pronote', 'Fin'] %}
        {% for label in labels %}
        <div class="text-center flex-fill small" id="step{{ loop.index }}-indicator">
          <i class="bi bi-{{ loop.index }}-circle fs-4"></i><div>{{ label }}</div>
        </div>
        {% endfor %}
      </div>

      <div id="step1" class="step-panel">
        <h5>Compte administrateur</h5>
        <div class="mb-3"><label class="form-label" for="adminUsername">Nom d’utilisateur</label>
          <input class="form-control" id="adminUsername" minlength="3" value="{{ progress.data.admin_username }}" required>
        </div>
        <div class="mb-3"><label class="form-label" for="adminPassword">Mot de passe</label>
          <input type="password" class="form-control" id="adminPassword" minlength="12" autocomplete="new-password" required>
          <div class="form-text">12 caractères minimum.</div>
        </div>
      </div>

      <div id="step2" class="step-panel d-none">
        <h5>Établissement</h5>
        <div class="mb-2"><label class="form-label" for="collegeName">Nom</label><input class="form-control" id="collegeName" value="{{ progress.data.college.name }}"></div>
        <div class="mb-2"><label class="form-label" for="collegeAddress">Adresse</label><input class="form-control" id="collegeAddress" value="{{ progress.data.college.address }}"></div>
        <div class="row"><div class="col-md-4 mb-2"><label class="form-label" for="collegeZip">Code postal</label><input class="form-control" id="collegeZip" value="{{ progress.data.college.zip }}"></div>
        <div class="col-md-8 mb-2"><label class="form-label" for="collegeCity">Ville</label><input class="form-control" id="collegeCity" value="{{ progress.data.college.city }}"></div></div>
      </div>

      <div id="step3" class="step-panel d-none">
        <h5>Bâtiments</h5>
        <p class="text-muted">Les bâtiments existants sont chargés et mis à jour. Retirer une ligne de l’écran ne supprime jamais le bâtiment ni ses locaux.</p>
        <div id="buildingsList"></div>
        <button class="btn btn-outline-primary btn-sm" type="button" onclick="addBuilding()"><i class="bi bi-plus-circle"></i> Ajouter</button>
      </div>

      <div id="step4" class="step-panel d-none">
        <h5>Zones</h5>
        <p class="text-muted">Chaque zone appartient à un bâtiment. Les zones déjà importées sont conservées.</p>
        <div id="zonesList"></div>
        <button class="btn btn-outline-primary btn-sm" type="button" onclick="addZone()"><i class="bi bi-plus-circle"></i> Ajouter</button>
      </div>

      <div id="step5" class="step-panel d-none">
        <h5>Salles et locaux</h5>
        <p class="text-muted">Une salle peut être affectée à une zone, avec son étage et son code. Les salles existantes ne sont jamais supprimées par le wizard.</p>
        <div class="table-responsive"><table class="table table-sm align-middle"><thead><tr><th>Nom</th><th>Code</th><th>Bâtiment</th><th>Zone</th><th>Étage</th><th></th></tr></thead><tbody id="roomsList"></tbody></table></div>
        <button class="btn btn-outline-primary btn-sm" type="button" onclick="addRoom()"><i class="bi bi-plus-circle"></i> Ajouter</button>
      </div>

      <div id="step6" class="step-panel d-none">
        <h5>Catalogue des lots et catégories</h5>
        <div class="alert alert-info">Le catalogue issu du dump SQL est intégré à l’application. Cette étape crée les entrées manquantes et corrige leurs associations sans supprimer les données existantes.</div>
        <div class="row mb-3"><div class="col"><strong>{{ lots_data|length }}</strong> catégories</div><div class="col"><strong>{{ lots_data.values()|map('length')|sum }}</strong> lots</div></div>
        <div class="accordion" id="catalogAccordion">
          {% for category, lots in lots_data.items() %}
          <div class="accordion-item"><h2 class="accordion-header"><button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#catalog{{ loop.index }}">{{ category }} <span class="badge bg-secondary ms-2">{{ lots|length }}</span></button></h2>
          <div id="catalog{{ loop.index }}" class="accordion-collapse collapse" data-bs-parent="#catalogAccordion"><div class="accordion-body"><ul class="mb-0">{% for lot in lots %}<li>{{ lot }}{% if task_counts.get(lot) %}<span class="badge bg-info text-dark ms-2">{{ task_counts.get(lot) }} tâche(s) préventive(s)</span>{% endif %}</li>{% endfor %}</ul></div></div></div>
          {% endfor %}
        </div>
      </div>

      <div id="step7" class="step-panel d-none">
        <h5>Calendrier</h5>
        <div class="alert alert-info">
          Les vacances scolaires sont considérées comme non travaillées. Ajoutez uniquement les journées où vous êtes présent ; chaque journée peut avoir des horaires différents.
        </div>
        <div class="row"><div class="col-md-6"><label class="form-label" for="academiqueZone">Zone académique</label><select class="form-select" id="academiqueZone"><option value="A">Zone A</option><option value="B">Zone B</option><option value="C">Zone C</option></select></div>
        <div class="col-md-6"><label class="form-label" for="anneeScolaire">Année de début</label><input type="number" class="form-control" id="anneeScolaire" min="2024" value="{{ progress.data.vacances_annee or 2026 }}"></div></div>
        <div class="form-check mt-3"><input class="form-check-input" type="checkbox" id="importAutoVacances" checked><label class="form-check-label" for="importAutoVacances">Importer les dates officielles dès que l’importeur académique sera disponible</label></div>
        <div class="form-check"><input class="form-check-input" type="checkbox" id="importAutoFeries" checked><label class="form-check-label" for="importAutoFeries">Importer les jours fériés lorsqu’un importeur sera configuré</label></div>
        <hr>
        <div class="d-flex justify-content-between align-items-center mb-2"><h6 class="mb-0">Périodes de vacances et présences exceptionnelles</h6><button type="button" class="btn btn-outline-primary btn-sm" onclick="addVacationPeriod()"><i class="bi bi-plus-circle"></i> Ajouter une période</button></div>
        <div id="vacationPeriodsList"></div>
      </div>

      <div id="step8" class="step-panel d-none"><h5>ENT</h5><div class="alert alert-secondary">Configuration facultative. Elle sera réalisée depuis la page dédiée après l’installation ; tant qu’elle est absente, son watchdog reste arrêté.</div></div>
      <div id="step9" class="step-panel d-none"><h5>Pronote</h5><div class="alert alert-secondary">Configuration facultative. Elle sera réalisée depuis la page dédiée après l’installation ; tant qu’elle est absente, son watchdog reste arrêté.</div></div>
      <div id="step10" class="step-panel d-none"><h5>Terminer</h5><div class="alert alert-success">Vérifiez les étapes précédentes, puis finalisez l’installation.</div></div>

      <div class="d-flex justify-content-between mt-4">
        <button id="prevBtn" class="btn btn-secondary" type="button" onclick="previousStep()"><i class="bi bi-arrow-left"></i> Précédent</button>
        <button id="nextBtn" class="btn btn-primary" type="button" onclick="nextStep()">Suivant <i class="bi bi-arrow-right"></i></button>
        <button id="finishBtn" class="btn btn-success d-none" type="button" onclick="finishSetup()"><i class="bi bi-check-lg"></i> Terminer</button>
      </div>
    </div>
  </div>
</div>

<script>
const totalSteps = 10;
let displayStep = Math.min(Math.max(Number({{ progress.step|default(0) }}) + 1, 1), totalSteps);
const setupData = {{ progress.data|tojson }};
let buildings = setupData.buildings || [];
let zones = setupData.zones || [];
let rooms = setupData.rooms || [];
let vacationPeriods = setupData.vacation_periods || [];

function field(value, placeholder, type = 'text') {
  const input = document.createElement('input');
  input.className = 'form-control form-control-sm'; input.type = type;
  input.value = value ?? ''; input.placeholder = placeholder; return input;
}
function selectField(options, value, emptyLabel = null) {
  const select = document.createElement('select'); select.className = 'form-select form-select-sm';
  if (emptyLabel !== null) select.add(new Option(emptyLabel, ''));
  options.forEach(item => select.add(new Option(item.label, String(item.value))));
  select.value = value == null ? '' : String(value); return select;
}
function removeButton(callback) {
  const button = document.createElement('button'); button.type = 'button'; button.className = 'btn btn-outline-secondary btn-sm';
  button.title = 'Retirer de cette saisie sans supprimer en base'; button.innerHTML = '<i class="bi bi-x-lg"></i>'; button.onclick = callback; return button;
}

function renderBuildings() {
  const root = document.getElementById('buildingsList'); root.replaceChildren();
  buildings.forEach((item, index) => {
    const row = document.createElement('div'); row.className = 'row g-2 mb-2';
    const nameCol = document.createElement('div'); nameCol.className = 'col-md-5'; const name = field(item.name, 'Nom du bâtiment'); name.oninput = () => item.name = name.value; nameCol.append(name);
    const descCol = document.createElement('div'); descCol.className = 'col-md-6'; const desc = field(item.description, 'Description'); desc.oninput = () => item.description = desc.value; descCol.append(desc);
    const action = document.createElement('div'); action.className = 'col-md-1'; action.append(removeButton(() => { buildings.splice(index, 1); renderBuildings(); }));
    row.append(nameCol, descCol, action); root.append(row);
  });
}
function addBuilding() { buildings.push({name: '', description: ''}); renderBuildings(); }

function buildingOptions() { return buildings.filter(b => b.id && b.name).map(b => ({value: b.id, label: b.name})); }
function renderZones() {
  const root = document.getElementById('zonesList'); root.replaceChildren();
  zones.forEach((item, index) => {
    const row = document.createElement('div'); row.className = 'row g-2 mb-2';
    const nameCol = document.createElement('div'); nameCol.className = 'col-md-6'; const name = field(item.name, 'Nom de la zone'); name.oninput = () => item.name = name.value; nameCol.append(name);
    const buildingCol = document.createElement('div'); buildingCol.className = 'col-md-5'; const building = selectField(buildingOptions(), item.building_id, 'Choisir un bâtiment'); building.onchange = () => item.building_id = Number(building.value); buildingCol.append(building);
    const action = document.createElement('div'); action.className = 'col-md-1'; action.append(removeButton(() => { zones.splice(index, 1); renderZones(); }));
    row.append(nameCol, buildingCol, action); root.append(row);
  });
}
function addZone() { zones.push({name: '', building_id: buildings[0]?.id || null}); renderZones(); }

function zoneOptions(buildingId) { return zones.filter(z => Number(z.building_id) === Number(buildingId) && z.id).map(z => ({value: z.id, label: z.name})); }
function renderRooms() {
  const root = document.getElementById('roomsList'); root.replaceChildren();
  rooms.forEach((item, index) => {
    const row = document.createElement('tr');
    const nameCell = document.createElement('td'); const name = field(item.name, 'Nom'); name.oninput = () => item.name = name.value; nameCell.append(name);
    const codeCell = document.createElement('td'); const code = field(item.code, 'Code'); code.oninput = () => item.code = code.value; codeCell.append(code);
    const buildingCell = document.createElement('td'); const building = selectField(buildingOptions(), item.building_id); building.onchange = () => { item.building_id = Number(building.value); item.zone_id = null; renderRooms(); }; buildingCell.append(building);
    const zoneCell = document.createElement('td'); const zone = selectField(zoneOptions(item.building_id), item.zone_id, 'Sans zone'); zone.onchange = () => item.zone_id = zone.value ? Number(zone.value) : null; zoneCell.append(zone);
    const floorCell = document.createElement('td'); const floor = field(item.floor ?? 0, '0', 'number'); floor.style.width = '75px'; floor.oninput = () => item.floor = Number(floor.value); floorCell.append(floor);
    const action = document.createElement('td'); action.append(removeButton(() => { rooms.splice(index, 1); renderRooms(); }));
    row.append(nameCell, codeCell, buildingCell, zoneCell, floorCell, action); root.append(row);
  });
}
function addRoom() { rooms.push({name: '', code: '', building_id: buildings[0]?.id || null, zone_id: null, floor: 0}); renderRooms(); }

function renderVacationPeriods() {
  const root = document.getElementById('vacationPeriodsList'); root.replaceChildren();
  vacationPeriods.forEach((period, periodIndex) => {
    period.work_days = period.work_days || [];
    const card = document.createElement('div'); card.className = 'card mb-3';
    const body = document.createElement('div'); body.className = 'card-body';
    const periodRow = document.createElement('div'); periodRow.className = 'row g-2 align-items-end mb-3';
    const nameCol = document.createElement('div'); nameCol.className = 'col-md-5'; nameCol.append(labelFor('Nom de la période'));
    const name = field(period.name, 'Ex. Vacances de la Toussaint'); name.oninput = () => period.name = name.value; nameCol.append(name);
    const startCol = document.createElement('div'); startCol.className = 'col-md-3'; startCol.append(labelFor('Début'));
    const start = field(period.start_date, '', 'date'); start.oninput = () => period.start_date = start.value; startCol.append(start);
    const endCol = document.createElement('div'); endCol.className = 'col-md-3'; endCol.append(labelFor('Fin'));
    const end = field(period.end_date, '', 'date'); end.oninput = () => period.end_date = end.value; endCol.append(end);
    const removeCol = document.createElement('div'); removeCol.className = 'col-md-1'; removeCol.append(removeButton(() => { vacationPeriods.splice(periodIndex, 1); renderVacationPeriods(); }));
    periodRow.append(nameCol, startCol, endCol, removeCol); body.append(periodRow);

    const heading = document.createElement('div'); heading.className = 'd-flex justify-content-between align-items-center mb-2';
    const text = document.createElement('strong'); text.textContent = 'Journées travaillées pendant cette période';
    const add = document.createElement('button'); add.type = 'button'; add.className = 'btn btn-outline-success btn-sm'; add.innerHTML = '<i class="bi bi-calendar-plus"></i> Ajouter une journée';
    add.onclick = () => { period.work_days.push({work_date: '', start_time: '08:00', end_time: '16:00', lunch_start: '12:00', lunch_end: '12:45', notes: ''}); renderVacationPeriods(); };
    heading.append(text, add); body.append(heading);

    const responsive = document.createElement('div'); responsive.className = 'table-responsive';
    const table = document.createElement('table'); table.className = 'table table-sm align-middle';
    table.innerHTML = '<thead><tr><th>Date</th><th>Début</th><th>Fin</th><th>Pause début</th><th>Pause fin</th><th>Note</th><th></th></tr></thead>';
    const tbody = document.createElement('tbody');
    period.work_days.forEach((day, dayIndex) => {
      const row = document.createElement('tr');
      const values = [
        ['work_date', 'date'], ['start_time', 'time'], ['end_time', 'time'],
        ['lunch_start', 'time'], ['lunch_end', 'time'], ['notes', 'text'],
      ];
      values.forEach(([key, type]) => {
        const cell = document.createElement('td'); const input = field(day[key], '', type);
        if (key === 'notes') input.placeholder = 'Ex. remise en route';
        input.oninput = () => day[key] = input.value; cell.append(input); row.append(cell);
      });
      const action = document.createElement('td'); action.append(removeButton(() => { period.work_days.splice(dayIndex, 1); renderVacationPeriods(); })); row.append(action); tbody.append(row);
    });
    if (!period.work_days.length) {
      const row = document.createElement('tr'); const cell = document.createElement('td'); cell.colSpan = 7; cell.className = 'text-muted text-center'; cell.textContent = 'Aucune présence : toute la période sera non travaillée.'; row.append(cell); tbody.append(row);
    }
    table.append(tbody); responsive.append(table); body.append(responsive); card.append(body); root.append(card);
  });
  if (!vacationPeriods.length) {
    const empty = document.createElement('p'); empty.className = 'text-muted'; empty.textContent = 'Ajoutez les périodes manuellement en attendant l’import des dates officielles.'; root.append(empty);
  }
}
function labelFor(text) { const label = document.createElement('label'); label.className = 'form-label small mb-1'; label.textContent = text; return label; }
function addVacationPeriod() { vacationPeriods.push({name: '', start_date: '', end_date: '', work_days: []}); renderVacationPeriods(); }

function showStep(step) {
  displayStep = step;
  document.querySelectorAll('.step-panel').forEach((panel, index) => panel.classList.toggle('d-none', index + 1 !== step));
  for (let i = 1; i <= totalSteps; i++) {
    const icon = document.querySelector(`#step${i}-indicator i`);
    icon.className = i < step ? 'bi bi-check-circle-fill fs-4 text-success' : `bi bi-${i}-circle fs-4 ${i === step ? 'text-primary' : 'text-secondary'}`;
  }
  document.getElementById('prevBtn').classList.toggle('invisible', step === 1);
  document.getElementById('nextBtn').classList.toggle('d-none', step === totalSteps);
  document.getElementById('finishBtn').classList.toggle('d-none', step !== totalSteps);
  if (step === 3) renderBuildings(); if (step === 4) renderZones(); if (step === 5) renderRooms(); if (step === 7) renderVacationPeriods();
}

async function saveStep(step, data) {
  const response = await fetch(`/setup-wizard/api/step/${step}`, {method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(data)});
  const result = await response.json();
  if (!response.ok || !result.success) throw new Error(result.error || 'Erreur de sauvegarde');
  return result;
}
async function nextStep() {
  try {
    let result;
    if (displayStep === 1) {
      const username = document.getElementById('adminUsername').value.trim(), password = document.getElementById('adminPassword').value;
      if (username.length < 3 || password.length < 12) throw new Error('Le nom doit faire 3 caractères et le mot de passe 12 caractères minimum.');
      result = await saveStep(1, {username, password});
    } else if (displayStep === 2) {
      const data = {name: document.getElementById('collegeName').value.trim(), address: document.getElementById('collegeAddress').value.trim(), zip: document.getElementById('collegeZip').value.trim(), city: document.getElementById('collegeCity').value.trim()};
      if (!data.name || !data.address || !/^\d{5}$/.test(data.zip) || !data.city) throw new Error('Complétez les informations du collège (code postal à 5 chiffres).');
      result = await saveStep(2, data);
    } else if (displayStep === 3) {
      const valid = buildings.filter(b => b.name?.trim()); if (!valid.length) throw new Error('Ajoutez au moins un bâtiment.');
      result = await saveStep(3, {buildings: valid}); buildings = result.buildings;
    } else if (displayStep === 4) {
      result = await saveStep(4, {zones: zones.filter(z => z.name?.trim())}); zones = result.zones;
    } else if (displayStep === 5) {
      result = await saveStep(5, {rooms: rooms.filter(r => r.name?.trim())}); rooms = result.rooms;
    } else if (displayStep === 6) {
      result = await saveStep(6, {});
    } else if (displayStep === 7) {
      result = await saveStep(7, {zone: document.getElementById('academiqueZone').value, annee: Number(document.getElementById('anneeScolaire').value), import_vacances: document.getElementById('importAutoVacances').checked, import_feries: document.getElementById('importAutoFeries').checked, vacation_periods: vacationPeriods});
    } else {
      result = await saveStep(displayStep, {skipped: displayStep === 8 || displayStep === 9});
    }
    showStep(Math.min(displayStep + 1, totalSteps));
  } catch (error) { alert(error.message); }
}
function previousStep() { if (displayStep > 1) showStep(displayStep - 1); }
async function finishSetup() {
  try {
    await saveStep(10, {});
    const response = await fetch('/setup-wizard/api/complete', {method: 'POST', headers: {'Content-Type': 'application/json'}, body: '{}'});
    const result = await response.json(); if (!response.ok || !result.success) throw new Error(result.error || 'Finalisation impossible');
    window.location.assign('/auth/login');
  } catch (error) { alert(error.message); }
}

renderBuildings(); renderZones(); renderRooms(); renderVacationPeriods(); showStep(displayStep);
</script>
{% endblock %}
