/**
* Template Name: Bootslander
* Template URL: https://bootstrapmade.com/bootslander-free-bootstrap-landing-page-template/
* Updated: Mar 17 2024 with Bootstrap v5.3.3
* Author: BootstrapMade.com
* License: https://bootstrapmade.com/license/
*/

(function() {
  "use strict";

  /**
   * Easy selector helper function
   */
  const select = (el, all = false) => {
    el = el.trim()
    if (all) {
      return [...document.querySelectorAll(el)]
    } else {
      return document.querySelector(el)
    }
  }

  /**
   * Easy event listener function
   */
  const on = (type, el, listener, all = false) => {
    let selectEl = select(el, all)
    if (selectEl) {
      if (all) {
        selectEl.forEach(e => e.addEventListener(type, listener))
      } else {
        selectEl.addEventListener(type, listener)
      }
    }
  }

  /**
   * Easy on scroll event listener 
   */
  const onscroll = (el, listener) => {
    el.addEventListener('scroll', listener)
  }

  /**
   * Navbar links active state on scroll
   */
  let navbarlinks = select('#navbar .scrollto', true)
  const navbarlinksActive = () => {
    let position = window.scrollY + 200
    navbarlinks.forEach(navbarlink => {
      if (!navbarlink.hash) return
      let section = select(navbarlink.hash)
      if (!section) return
      if (position >= section.offsetTop && position <= (section.offsetTop + section.offsetHeight)) {
        navbarlink.classList.add('active')
      } else {
        navbarlink.classList.remove('active')
      }
    })
  }
  window.addEventListener('load', navbarlinksActive)
  onscroll(document, navbarlinksActive)

  /**
   * Scrolls to an element with header offset
   */
  const scrollto = (el) => {
    let header = select('#header')
    let offset = header.offsetHeight

    if (!header.classList.contains('header-scrolled')) {
      offset -= 20
    }

    let elementPos = select(el).offsetTop
    window.scrollTo({
      top: elementPos - offset,
      behavior: 'smooth'
    })
  }

  /**
   * Toggle .header-scrolled class to #header when page is scrolled
   */
  let selectHeader = select('#header')
  if (selectHeader) {
    const headerScrolled = () => {
      if (window.scrollY > 100) {
        selectHeader.classList.add('header-scrolled')
      } else {
        selectHeader.classList.remove('header-scrolled')
      }
    }
    window.addEventListener('load', headerScrolled)
    onscroll(document, headerScrolled)
  }

  /**
   * Back to top button
   */
  let backtotop = select('.back-to-top')
  if (backtotop) {
    const toggleBacktotop = () => {
      if (window.scrollY > 100) {
        backtotop.classList.add('active')
      } else {
        backtotop.classList.remove('active')
      }
    }
    window.addEventListener('load', toggleBacktotop)
    onscroll(document, toggleBacktotop)
  }

  /**
   * Mobile nav toggle
   */
  on('click', '.mobile-nav-toggle', function(e) {
    select('#navbar').classList.toggle('navbar-mobile')
    this.classList.toggle('bi-list')
    this.classList.toggle('bi-x')
  })

  /**
   * Mobile nav dropdowns activate
   */
  on('click', '.navbar .dropdown > a', function(e) {
    if (select('#navbar').classList.contains('navbar-mobile')) {
      e.preventDefault()
      this.nextElementSibling.classList.toggle('dropdown-active')
    }
  }, true)

  /**
   * Scrool with ofset on links with a class name .scrollto
   */
  on('click', '.scrollto', function(e) {
    if (select(this.hash)) {
      e.preventDefault()

      let navbar = select('#navbar')
      if (navbar.classList.contains('navbar-mobile')) {
        navbar.classList.remove('navbar-mobile')
        let navbarToggle = select('.mobile-nav-toggle')
        navbarToggle.classList.toggle('bi-list')
        navbarToggle.classList.toggle('bi-x')
      }
      scrollto(this.hash)
    }
  }, true)

  /**
   * Scroll with ofset on page load with hash links in the url
   */
  window.addEventListener('load', () => {
    if (window.location.hash) {
      if (select(window.location.hash)) {
        scrollto(window.location.hash)
      }
    }
  });

  /**
   * Preloader
   */
  let preloader = select('#preloader');
  if (preloader) {
    window.addEventListener('load', () => {
      preloader.remove()
    });
  }

  /**
   * Initiate glightbox
   */
  const glightbox = GLightbox({
    selector: '.glightbox'
  });

  /**
   * Initiate gallery lightbox 
   */
  const galleryLightbox = GLightbox({
    selector: '.gallery-lightbox'
  });

  /**
   * Testimonials slider
   */
  new Swiper('.testimonials-slider', {
    speed: 600,
    loop: true,
    autoplay: {
      delay: 5000,
      disableOnInteraction: false
    },
    slidesPerView: 'auto',
    pagination: {
      el: '.swiper-pagination',
      type: 'bullets',
      clickable: true
    }
  });

  /**
   * Animation on scroll
   */
  window.addEventListener('load', () => {
    AOS.init({
      duration: 1000,
      easing: 'ease-in-out',
      once: true,
      mirror: false
    })
  });

  /**
   * Initiate Pure Counter 
   */
  new PureCounter();

})();

// VISU 1
document.addEventListener("DOMContentLoaded", function () {
  function sleepAnalysis() {
      d3.json("../static/js/sleep_combined_clean.json").then(function (data) {
          // Pré-traitement des données
          data.forEach((d) => {
              d.date = d3.timeParse("%Y-%m-%d")(d.date);
              d.month = d3.timeMonth(d.date);
          });

          // Initialisation des constantes
          const svgWidth = 800;
          const svgHeight = 400;
          const margin = { top: 20, right: 60, bottom: 60, left: 60 };
          const colorScale = d3.scaleOrdinal(["#ff6347", "#4682b4", "#32cd32", "#ff1493"]);

          // Fonction pour afficher le graphique principal (par mois)
          function renderMonthlyChart(year, members) {
              const monthsForYear = d3.timeMonths(new Date(`${year}-01-01`), new Date(`${year}-12-31`));
              const groupedData = d3.group(data, (d) => d.month);

              const nestedData = monthsForYear.map((month) => {
                  const valuesForMonth = groupedData.get(month) || [];
                  const avgMonthSleep = members.map((member) => {
                      const memberData = valuesForMonth.filter((d) => d[member] !== null);
                      return {
                          member,
                          value: memberData.length > 0 ? d3.mean(memberData, (v) => v[member]) : null,
                      };
                  });

                  return { month, values: avgMonthSleep };
              });

              const svg = d3.select("#chart").attr("width", svgWidth).attr("height", svgHeight);
              svg.selectAll("*").remove();

              const x = d3.scaleBand()
                  .domain(monthsForYear)
                  .range([margin.left, svgWidth - margin.right])
                  .padding(0.05);

              const y = d3.scaleLinear()
                  .domain([0, d3.max(nestedData, (d) => d3.max(d.values, (v) => v.value))])
                  .nice()
                  .range([svgHeight - margin.bottom, margin.top]);

              svg.append("g")
                  .attr("transform", `translate(0,${svgHeight - margin.bottom})`)
                  .call(d3.axisBottom(x).tickFormat(d3.timeFormat("%B")));

              svg.append("g")
                  .attr("transform", `translate(${margin.left},0)`)
                  .call(d3.axisLeft(y));

              svg.append("g")
                  .selectAll("g")
                  .data(nestedData)
                  .enter()
                  .append("g")
                  .attr("transform", (d) => `translate(${x(d.month)},0)`)
                  .selectAll("rect")
                  .data((d) => d.values.filter((v) => v.value !== null))
                  .enter()
                  .append("rect")
                  .attr("x", (d, i) => i * (x.bandwidth() / members.length))
                  .attr("y", (d) => y(d.value))
                  .attr("width", x.bandwidth() / members.length - 1)
                  .attr("height", (d) => svgHeight - margin.bottom - y(d.value))
                  .attr("fill", (d) => colorScale(d.member))
                  .on("click", (event, d) => {
                      renderDailyChart(year, d.member, d.month, colorScale(d.member));
                  });
          }

          // Fonction pour afficher le graphique journalier (par jour)
          function renderDailyChart(year, member, month, color) {
              const monthData = data.filter(
                  (d) =>
                      d.month.getMonth() === month.getMonth() &&
                      d.date.getFullYear() === year &&
                      d[member] !== null
              );

              const daysInMonth = Array.from({ length: 31 }, (_, i) => i + 1);
              const dailyData = daysInMonth.map((day) => {
                  const dayData = monthData.find((d) => d.date.getDate() === day);
                  return { day, sleepHours: dayData ? dayData[member] : null };
              });

              const svg = d3.select("#dailyChart").attr("width", svgWidth).attr("height", svgHeight);
              svg.selectAll("*").remove();

              const x = d3.scaleBand()
                  .domain(dailyData.map((d) => d.day))
                  .range([margin.left, svgWidth - margin.right])
                  .padding(0.1);

              const y = d3.scaleLinear()
                  .domain([0, d3.max(dailyData, (d) => d.sleepHours)])
                  .nice()
                  .range([svgHeight - margin.bottom, margin.top]);

              svg.append("g")
                  .attr("transform", `translate(0,${svgHeight - margin.bottom})`)
                  .call(d3.axisBottom(x));

              svg.append("g")
                  .attr("transform", `translate(${margin.left},0)`)
                  .call(d3.axisLeft(y));

              svg.append("g")
                  .selectAll("rect")
                  .data(dailyData)
                  .enter()
                  .append("rect")
                  .attr("x", (d) => x(d.day))
                  .attr("y", (d) => (d.sleepHours ? y(d.sleepHours) : svgHeight - margin.bottom))
                  .attr("width", x.bandwidth())
                  .attr("height", (d) => (d.sleepHours ? svgHeight - margin.bottom - y(d.sleepHours) : 0))
                  .attr("fill", color);
          }

          // Gestion des interactions
          function initializeInteractions() {
              const yearSelect = document.getElementById("yearSelect");
              const memberSelect = document.getElementById("memberSelect");
              const backButton = document.getElementById("backButton");

              yearSelect.addEventListener("change", () => {
                  const year = +yearSelect.value;
                  const members = Array.from(memberSelect.querySelectorAll("input:checked")).map((c) => c.value);
                  renderMonthlyChart(year, members);
              });

              memberSelect.querySelectorAll("input").forEach((input) => {
                  input.addEventListener("change", () => {
                      const year = +yearSelect.value;
                      const members = Array.from(memberSelect.querySelectorAll("input:checked")).map((c) => c.value);
                      renderMonthlyChart(year, members);
                  });
              });

              backButton.addEventListener("click", () => {
                  document.getElementById("dailyChart").style.display = "none";
                  document.getElementById("chart").style.display = "block";
                  backButton.style.display = "none";
              });
          }

          // Initialisation complète
          renderMonthlyChart(2024, ["Anis", "Maya", "Corentin", "Amira"]);
          initializeInteractions();
      });
  }

  // Appel de la fonction principale
  sleepAnalysis();
});