/**
* 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
function renderStepsVisualization() {
  fetch('../static/js/final_combined_with_all_data.json') // Chemin à adapter si nécessaire
      .then((response) => response.json())
      .then((data) => {
          const parseDate = d3.timeParse("%Y-%m-%d");
          const formatYear = d3.timeFormat("%Y");
          const formatMonth = d3.timeFormat("%Y-%m");
          const members = ["Corentin", "Maya", "Anis", "Amira"];

          data.forEach(d => d.date = parseDate(d.date));

          const margin = { top: 50, right: 230, bottom: 150, left: 70 };
          const width = 800 - margin.left - margin.right;
          const height = 500 - margin.top - margin.bottom;

          const svg = d3.select("#visualization")
              .append("svg")
              .attr("width", width + margin.left + margin.right)
              .attr("height", height + margin.top + margin.bottom)
              .append("g")
              .attr("transform", `translate(${margin.left},${margin.top})`);

          const years = [2021, 2022, 2023, 2024];
          const sliderContainer = d3.select("#slider-container");

          const rangeSlider = sliderContainer.append("input")
              .attr("type", "range")
              .attr("min", 0)
              .attr("max", years.length - 1)
              .attr("value", years.indexOf(2024))
              .style("width", "60%");

          const yearDisplay = sliderContainer.append("span")
              .text(years[years.indexOf(2024)]);

          updateVisualization(2024);

          function updateVisualization(selectedYear) {
              const filteredData = data.filter(d => formatYear(d.date) === selectedYear.toString());

              if (filteredData.length === 0) {
                  console.log(`Aucune donnée pour l'année ${selectedYear}`);
                  return;
              }

              const groupedData = d3.groups(filteredData, d => formatMonth(d.date));

              const aggregatedData = groupedData.map(([month, records]) => {
                  const aggregated = { month };
                  members.forEach(member => {
                      aggregated[`Steps_${member}`] = d3.mean(records, d => d[`Steps_${member}`] || 0);
                  });
                  return aggregated;
              });

              svg.selectAll("*").remove();

              const xScale = d3.scaleBand()
                  .domain(aggregatedData.map(d => d.month))
                  .range([0, width])
                  .padding(0.2);

              const yScale = d3.scaleLinear()
                  .domain([0, d3.max(aggregatedData, d => Math.max(...members.map(member => d[`Steps_${member}`])))]).nice()
                  .range([height, 0]);

              const colorMap = {
                  "Maya": "#0f7e06",
                  "Corentin": "#1d38e3",
                  "Anis": "#d6bff4",
                  "Amira": "#7e09bd"
              };

              svg.append("g")
                  .attr("transform", `translate(0, ${height})`)
                  .call(d3.axisBottom(xScale))
                  .selectAll("text")
                  .attr("transform", "rotate(-45)")
                  .style("text-anchor", "end");

              svg.append("g").call(d3.axisLeft(yScale));

              svg.append("text")
                  .attr("x", width / 2)
                  .attr("y", height + 70)
                  .attr("text-anchor", "middle")
                  .style("font-size", "14px")
                  .text("Mois");

              svg.append("text")
                  .attr("transform", "rotate(-90)")
                  .attr("x", -height / 2)
                  .attr("y", -50)
                  .attr("text-anchor", "middle")
                  .style("font-size", "14px")
                  .text("Nombre de pas");

              members.forEach((member) => {
                  const lineData = aggregatedData.map(d => {
                      let steps = d[`Steps_${member}`] === -1.0 ? 0 : d[`Steps_${member}`];
                      return { month: d.month, steps };
                  });

                  const line = d3.line()
                      .x(d => xScale(d.month) + xScale.bandwidth() / 2)
                      .y(d => yScale(d.steps))
                      .defined(d => d.steps !== 0);

                  svg.append("path")
                      .data([lineData])
                      .attr("class", `line-${member}`)
                      .attr("d", line)
                      .attr("fill", "none")
                      .attr("stroke", colorMap[member])
                      .attr("stroke-width", 2);
              });
          }

          rangeSlider.on("input", function () {
              const selectedYear = years[this.value];
              yearDisplay.text(selectedYear);
              updateVisualization(selectedYear);
          });
      });
}






// VISU 2
function renderDistanceVisualization() {
  fetch('../static/js/final_combined_with_all_data.json') // Chemin à adapter si nécessaire
      .then((response) => response.json())
      .then((data) => {
          const parseDate = d3.timeParse("%Y-%m-%d");
          const formatYear = d3.timeFormat("%Y");
          const formatMonth = d3.timeFormat("%Y-%m");
          const members = ["Corentin", "Maya", "Anis", "Amira"];

          data.forEach(d => d.date = parseDate(d.date));

          const margin = { top: 50, right: 230, bottom: 150, left: 70 };
          const width = 800 - margin.left - margin.right;
          const height = 500 - margin.top - margin.bottom;

          const svg = d3.select("#distance-visualization")
              .append("svg")
              .attr("width", width + margin.left + margin.right)
              .attr("height", height + margin.top + margin.bottom)
              .append("g")
              .attr("transform", `translate(${margin.left},${margin.top})`);

          const years = [2023, 2024];
          const sliderContainer = d3.select("#distance-slider-container");

          const rangeSlider = sliderContainer.append("input")
              .attr("type", "range")
              .attr("min", 0)
              .attr("max", years.length - 1)
              .attr("value", years.indexOf(2024))
              .style("width", "60%");

          const yearDisplay = sliderContainer.append("span")
              .text(years[years.indexOf(2024)]);

          const tooltip = d3.select("body").append("div")
              .attr("class", "tooltip")
              .style("opacity", 0);

          function updateVisualization(selectedYear) {
              const filteredData = data.filter(d => formatYear(d.date) === selectedYear.toString());
              const groupedData = d3.groups(filteredData, d => formatMonth(d.date));

              const colorMap = {
                  "Maya": "#0f7e06",
                  "Corentin": "#1d38e3",
                  "Anis": "#d6bff4",
                  "Amira": "#7e09bd"
              };

              const aggregatedData = groupedData.map(([month, records]) => {
                  const aggregated = { month };
                  members.forEach(member => {
                      aggregated[`Distance_${member}`] = d3.mean(records, d => {
                          const distance = d[`Distance_${member}`];
                          return (distance !== -1) ? distance : undefined;
                      }) || 0;

                      aggregated[`Calories_${member}`] = d3.mean(records, d => {
                          const calories = d[`Calories_${member}`];
                          return (calories !== -1) ? calories : undefined;
                      }) || 0;
                  });
                  return aggregated;
              });

              svg.selectAll("*").remove();

              const bubbleSizeScale = d3.scaleLinear()
                  .domain([0, d3.max(aggregatedData, d => Math.max(...members.map(member => d[`Distance_${member}`])) )])
                  .range([2, 20]);

              const xScale = d3.scaleLinear()
                  .domain([0, d3.max(aggregatedData, d => Math.max(...members.map(member => d[`Distance_${member}`])) )])
                  .range([0, width]);

              const yScale = d3.scaleLinear()
                  .domain([0, d3.max(aggregatedData, d => Math.max(...members.map(member => d[`Calories_${member}`])) )])
                  .range([height, 0]);

              svg.append("text")
                  .attr("x", width / 2)
                  .attr("y", margin.top - 60)
                  .attr("text-anchor", "middle")
                  .style("font-size", "16px")
                  .style("font-weight", "bold")
                  .text("Comparaison des calories brûlées vs distance parcourue");

              svg.append("g")
                  .attr("transform", `translate(0, ${height})`)
                  .call(d3.axisBottom(xScale));

              svg.append("text")
                  .attr("x", width / 2)
                  .attr("y", height + 70)
                  .attr("text-anchor", "middle")
                  .style("font-size", "14px")
                  .text("Distance (KM)");

              svg.append("g").call(d3.axisLeft(yScale));

              svg.append("text")
                  .attr("transform", "rotate(-90)")
                  .attr("x", -height / 2)
                  .attr("y", -50)
                  .attr("text-anchor", "middle")
                  .style("font-size", "14px")
                  .text("Calories brûlées");

              members.forEach((member) => {
                  svg.selectAll(`.bubble-${member}`)
                      .data(aggregatedData)
                      .enter()
                      .append("circle")
                      .attr("cx", d => xScale(d[`Distance_${member}`]))
                      .attr("cy", d => yScale(d[`Calories_${member}`]))
                      .attr("r", d => bubbleSizeScale(d[`Distance_${member}`]))
                      .attr("fill", d => {
                          return (d[`Distance_${member}`] === 0 || d[`Calories_${member}`] === 0) ? "gray" : colorMap[member];
                      })
                      .style("opacity", 0.7)
                      .on("mouseover", function(event, d) {
                          tooltip.transition().duration(200).style("opacity", .9);
                          tooltip.html(`Mois : ${d.month}<br>Distance : ${d[`Distance_${member}`]} km<br>Calories : ${d[`Calories_${member}`]} cal`)
                              .style("left", (event.pageX + 5) + "px")
                              .style("top", (event.pageY - 28) + "px");
                      })
                      .on("mouseout", function() {
                          tooltip.transition().duration(500).style("opacity", 0);
                      });
              });
          }

          updateVisualization(years[1]);

          rangeSlider.on("input", function() {
              const selectedYear = years[this.value];
              yearDisplay.text(selectedYear);
              updateVisualization(selectedYear);
          });
      });
}

//VISU 3
function renderCaloriesVisualization() {
  fetch('../static/js/final_combined_with_all_data.json')
    .then((response) => response.json())
    .then((data) => {
      const parseDate = d3.timeParse("%Y-%m-%d");
      const formatYear = d3.timeFormat("%Y");
      const formatMonth = d3.timeFormat("%Y-%m");
      const members = ["Corentin", "Maya", "Anis", "Amira"];

      data.forEach(d => d.date = parseDate(d.date));

      const margin = { top: 50, right: 230, bottom: 150, left: 70 };
      const width = 800 - margin.left - margin.right;
      const height = 500 - margin.top - margin.bottom;

      const svg = d3.select("#calories-visualization")
        .append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", `translate(${margin.left},${margin.top})`);

      const years = [2022, 2023, 2024];
      const sliderContainer = d3.select("#calories-slider-container");

      const rangeSlider = sliderContainer.append("input")
        .attr("type", "range")
        .attr("min", 0)
        .attr("max", years.length - 1)
        .attr("value", years.indexOf(2024))
        .style("width", "60%");

      const yearDisplay = sliderContainer.append("span")
        .text(years[years.indexOf(2024)]);

      updateVisualization(2024);

      function updateVisualization(selectedYear) {
        const filteredData = data.filter(d => formatYear(d.date) === selectedYear.toString());

        if (filteredData.length === 0) {
          console.log(`Aucune donnée pour l'année ${selectedYear}`);
          return;
        }

        const groupedData = d3.groups(filteredData, d => formatMonth(d.date));

        const aggregatedData = groupedData.map(([month, records]) => {
          const aggregated = { month };
          members.forEach(member => {
            aggregated[`Calories_${member}`] = d3.mean(records, d => d[`Calories_${member}`] || 0);
          });
          return aggregated;
        });

        svg.selectAll("*").remove();

        svg.append("text")
          .attr("x", width / 2)
          .attr("y", margin.top - 60)
          .attr("text-anchor", "middle")
          .style("font-size", "16px")
          .style("font-weight", "bold")
          .text("Analyse des calories brûlées par mois");

        const xScale = d3.scaleBand()
          .domain(aggregatedData.map(d => d.month))
          .range([0, width])
          .padding(0.2);

        const yScale = d3.scaleLinear()
          .domain([0, d3.max(aggregatedData, d => Math.max(...members.map(member => d[`Calories_${member}`])))]).nice()
          .range([height, 0]);

        const colorScale = d3.scaleOrdinal()
          .domain(members)
          .range(["#1d38e3", "#0f7e06", "#d6bff4", "#7e09bd"]);

        svg.append("g")
          .attr("transform", `translate(0, ${height})`)
          .call(d3.axisBottom(xScale))
          .selectAll("text")
          .attr("transform", "rotate(-45)")
          .style("text-anchor", "end");

        svg.append("text")
          .attr("x", width / 2)
          .attr("y", height + 70)
          .attr("text-anchor", "middle")
          .style("font-size", "14px")
          .text("Mois");

        svg.append("g").call(d3.axisLeft(yScale));

        svg.append("text")
          .attr("transform", "rotate(-90)")
          .attr("x", -height / 2)
          .attr("y", -50)
          .attr("text-anchor", "middle")
          .style("font-size", "14px")
          .text("Calories brûlées");

        members.forEach(member => {
          const areaData = aggregatedData.map(d => ({
            month: d.month,
            calories: d[`Calories_${member}`] || 0
          }));

          const area = d3.area()
            .x(d => xScale(d.month) + xScale.bandwidth() / 2)
            .y0(yScale(0))
            .y1(d => yScale(d.calories));

          svg.append("path")
            .data([areaData])
            .attr("fill", colorScale(member))
            .attr("opacity", 0.8)
            .attr("d", area);
        });
      }

      rangeSlider.on("input", function () {
        const selectedYear = years[this.value];
        yearDisplay.text(selectedYear);
        updateVisualization(selectedYear);
      });
    });
}
document.addEventListener("DOMContentLoaded", function () {
  renderStepsVisualization();
  renderDistanceVisualization();
  renderCaloriesVisualization();
});