<template>
    <section id="beeswarm">
      <div id="text1" class="text-container">
        <p>
          Everyone needs access to clean water. Water insecurity is influenced by a number of social vulnerability indicators. This includes 
          <span 
            :class="['highlight', 'Demographiccharacteristics', { checked: isChecked.Demographiccharacteristics }]" 
            @click="toggleCategory('Demographiccharacteristics')"
          >
            demographic characteristics
          </span>,
          <span 
            :class="['highlight', 'Health', { checked: isChecked.Health }]" 
            @click="toggleCategory('Health')"
          >
            health
          </span>, 
          <span 
            :class="['highlight', 'Livingconditions', { checked: isChecked.Livingconditions }]" 
            @click="toggleCategory('Livingconditions')"
          >
            living conditions
          </span>, 
          <span 
            :class="['highlight', 'Socioeconomicstatus', { checked: isChecked.Socioeconomicstatus }]" 
            @click="toggleCategory('Socioeconomicstatus')"
          >
            socioeconomic status
          </span>,
          <span 
            :class="['highlight', 'Riskperception', { checked: isChecked.Riskperception }]" 
            @click="toggleCategory('Riskperception')"
          >
            risk perception
          </span>,
          <span 
            :class="['highlight', 'Landtenure', { checked: isChecked.Landtenure }]" 
            @click="toggleCategory('Landtenure')"
          >
            land tenure
          </span>, and 
          <span 
            :class="['highlight', 'Exposure', { checked: isChecked.Exposure }]" 
            @click="toggleCategory('Exposure')"
          >
            exposure to stressors
          </span> (like drought or pollution).
        </p>
      </div>
      <div id="beeswarm-chart-container">
        <div id="tooltip" style="position: absolute; opacity: 0; background: #f9f9f9; padding: 5px; border: 1px solid #ccc; border-radius: 5px;"></div>
      </div>
    </section>
  </template>
  
  <script setup>
  import { onMounted, ref, watch } from "vue";
  import * as d3 from 'd3';
  
  // Global variables 
  const publicPath = import.meta.env.BASE_URL;
  const dataSet1 = ref([]); 
  const dataSet2 = ref([]); 
  const selectedDataSet = ref('dataSet1');
  const data = ref([]);
  let simulation;
  
  // Set up SVG
  let svg;
  const height = 800;
  const width = 800;
  const margin = { top: 50, right: 20, bottom: 50, left: 50 };
  
  const isChecked = ref({
    Demographiccharacteristics: true,
    Health: true,
    Livingconditions: true,
    Socioeconomicstatus: true,
    Riskperception: true,
    Landtenure: true,
    Exposure: true
  });
  
  // Set colors for bubble charts
  const dimensionColors = {
    Demographiccharacteristics: "#092836",
    Landtenure: "#1b695e",
    Livingconditions: "#7a5195",
    Socioeconomicstatus: "#2a468f",
    Health: "#ef5675",
    Riskperception: "#ff764a",
    Exposure: "#ffa600"
  };
  
  // Load data and then make chart
  onMounted(async () => {
    try {
      await loadDatasets();
      data.value = selectedDataSet.value === 'dataSet1' ? dataSet1.value : dataSet2.value;
      if (data.value.length > 0) {
        createBeeswarmChart();
      } else {
        console.error('Error loading data');
      }
    } catch (error) {
      console.error('Error during component mounting', error);
    }
  });
  
  async function loadDatasets() {
    try {
      dataSet1.value = await loadData('determinant_uncertainty.csv');
      dataSet2.value = await loadData('indicator_uncertainty.csv');
      console.log('data in')
    } catch (error) {
      console.error('Error loading datasets', error);
    }
  }
  
  async function loadData(fileName) {
    try {
      const data = await d3.csv(publicPath + fileName, d => { 
        d.level_agreement = +(+d.level_agreement).toFixed(2); 
        d.evidence_val = +d.evidence_val; 
        d.sig_value = +d.sig_value; 
        return d;
      });
      return data;
    } catch (error) {
      console.error(`Error loading data from ${fileName}`, error);
      return [];
    }
  }
  // make beeswarm of determinants
  function createBeeswarmChart() {
    svg = d3
      .select('#beeswarm-chart-container')
      .append('svg')
      .attr('class', 'beeswarmSvg')
      .attr('width', width)
      .attr('height', height);
  
    const yScale = d3.scaleLinear()
      .domain([40, d3.max(data.value, d => d.level_agreement)])
      .range([height-margin.bottom, margin.top]);
    
    // Set radius based on evidence value
    const radiusScale = d3.scaleLinear()
      .domain([d3.min(data.value, d => d.evidence_val), d3.max(data.value, d => d.evidence_val)])
      .range([10, 70]);
  
    const yAxis = svg.append('g')
      .attr("transform", "translate(100, 0)")
      .call(d3.axisLeft(yScale).ticks(5))
      .attr("stroke-width", 2)
      .attr("font-size", 20);
  
    // Add label to y axis
    svg.append('text')
    .attr("class", "yLabel")
    .attr("text-anchor", "left")
    .attr("font-weight", 700)
    .attr("transform", `translate(${margin.left}, ${margin.top/2})`)
    .text("Level of Agreement");

    svg.append('text')
      .attr("class", "yLabel")
      .attr("text-anchor", "left")
      .attr("font-weight", 700)
      .attr("transform", `translate(${margin.left}, ${height - (margin.bottom/2)})`)
      .text("Inconclusive");

  
    // Set forces
    const forceY = d3.forceY(d => yScale(d.level_agreement)).strength(0.5);
    const forceX = d3.forceX(margin.left + (width / 2)).strength(0.5);
    const forceCollide = d3.forceCollide(d => radiusScale(d.evidence_val) + 5).iterations(20);
    const forceManyBody = d3.forceManyBody().strength(-5);
  
    const bubbles = svg
      .selectAll('.bubble')
      .data(data.value)
      .enter()
      .append('circle')
      .attr('class', 'bubble')
      .attr('r', d => radiusScale(d.evidence_val))
      .style('fill', d => dimensionColors[d.dimension.replace(' ', '')])
      .on('mouseover', function (event, d) {
      const [x, y] = d3.pointer(event);
      d3.select('#tooltip')
        .style('opacity', 1)
        .html(`<strong>${d.determinant}</strong><br>appeared in ${d.evidence_val} studies`)
        .style('left', (x + 10) + 'px')
        .style('top', (y - 28) + 'px');

        d3.select(this)
        .attr('stroke', d => dimensionColors[d.dimension.replace(' ', '')])
        .attr('stroke-width', 15);
    })
      .on('mouseout', function () {
        d3.select('#tooltip').style('opacity', 0);
        d3.select(this)
          .attr('stroke', null)
          .attr('stroke-width', null);
      });
  
    // Run simulation
    simulation = d3.forceSimulation()
      .force('x', forceX)
      .force('y', forceY)
      .force('collide', forceCollide)
      .force('charge', forceManyBody)
      .nodes(data.value)
      .on('tick', ticked)
      .alpha(0.75)
      .alphaDecay(0.03);
  
      function ticked() {
        bubbles
          .attr("cx", d => Math.max(margin.left +radiusScale(d.evidence_val), Math.min(width - margin.right - radiusScale(d.evidence_val), d.x)))
          .attr("cy", d => Math.max(radiusScale(d.evidence_val), Math.min(height - radiusScale(d.evidence_val), d.y)))
          .each(d => { d.y = Math.max(radiusScale(d.evidence_val), Math.min(height - radiusScale(d.evidence_val), yScale(d.level_agreement))); });
      }
  }
  
  function toggleCategory(category) {
    //console.log(`Toggle category called for: ${category}`);
    isChecked.value[category] = !isChecked.value[category];
    console.log(`Category toggled: ${category}, new value: ${isChecked.value[category]}`);
    updateChart();
  }
  
  function updateChart() {
    console.log('Update chart called');
    const yScale = d3.scaleLinear()
      .domain([40, d3.max(data.value, d => d.level_agreement)])
      .range([height-margin.bottom, margin.top]);
  
    // Set radius based on evidence value
    const radiusScale = d3.scaleLinear()
      .domain([d3.min(data.value, d => d.evidence_val), d3.max(data.value, d => d.evidence_val)])
      .range([10, 90]);
  
    // Filter data based on active categories
    const activeCategories = Object.keys(isChecked.value).filter(category => isChecked.value[category]);
    const dataPoints = data.value.filter(d => activeCategories.includes(d.dimension.replace(' ', '')));
    console.log('Active categories:', activeCategories);
    console.log('Filtered data points:', dataPoints);
  
    // Update existing bubbles and add new bubbles
    const bubbles = svg.selectAll(".bubble")
      .data(dataPoints, d => d.id);
  
    // Remove old bubbles
    bubbles.exit().remove();
  
    // Update existing bubbles
    bubbles
      .attr('r', d => radiusScale(d.evidence_val))
      .style('fill', d => dimensionColors[d.dimension.replace(' ', '')]);
  
    // Add new bubbles
    bubbles.enter()
      .append('circle')
      .attr('class', 'bubble')
      .attr('r', d => radiusScale(d.evidence_val))
      .style('fill', d => dimensionColors[d.dimension.replace(' ', '')])
      .merge(bubbles)  // Merge to apply forces to new and existing bubbles
      .attr('cx', d => d.x)  // Use existing x position
      .attr('cy', d => d.y);
  
    // Restart simulation with new data
    simulation.nodes(dataPoints)
      .force('x', forceX)
      .force('y', forceY)
      .force('collide', forceCollide)
      .force('charge', forceManyBody)
      .alpha(0.2)
      .restart();
  }
  </script>
  
  <style scoped lang="scss">
  $switchWidth: 12rem;
  $Demographiccharacteristics: #092836;
  $Landtenure: #1b695e;
  $Livingconditions: #7a5195;
  $Socioeconomicstatus: #2a468f;
  $Health: #ef5675;
  $Riskperception: #ff764a;
  $Exposure: #ffa600;
  
  #beeswarm-chart-container {
      text-align: center;
      position: relative;
  }
  
  #beeswarm-chart-container svg {
      max-width: 100%;
      max-height: 100%;
      height: auto; /* Maintain aspect ratio */
      display: inline-block;
  }
  
  .bubble {
      stroke: black;
      stroke-width: 2px; 
      fill-opacity: 0.8; 
  }
  
  .chart-text {
      user-select: none;
  }
  .yLabel {
      font-weight: bold;
  }
  
  .highlight {
      color: white;
      padding: 0.25px 5px;
      border-radius: 10px;
      white-space: nowrap;
      font-weight: bold;
      cursor: pointer; /* Add cursor pointer for better UX */
      transition: all 0.1s; /* Smooth transition for background color and border */
  }
  
  .highlight:not(.checked) {
      background-color: white;
      border: 2px solid;
  }
  .highlight.Demographiccharacteristics {
      background-color: $Demographiccharacteristics;
  }
  .highlight.Demographiccharacteristics:not(.checked) {
      color: $Demographiccharacteristics;
      border-color: $Demographiccharacteristics;
  }
  .highlight.Landtenure {
      background-color: $Landtenure;
  }
  .highlight.Landtenure:not(.checked) {
      color: $Landtenure;
      border-color: $Landtenure;
  }
  .highlight.Livingconditions {
      background-color: $Livingconditions;
  }
  .highlight.Livingconditions:not(.checked) {
      color: $Livingconditions;
      border-color: $Livingconditions;
  }
  .highlight.Socioeconomicstatus {
      background-color: $Socioeconomicstatus;
  }
  .highlight.Socioeconomicstatus:not(.checked) {
      color: $Socioeconomicstatus;
      border-color: $Socioeconomicstatus;
  }
  .highlight.Health {
      background-color: $Health;
  }
  .highlight.Health:not(.checked) {
      color: $Health;
      border-color: $Health;
  }
  .highlight.Riskperception {
      background-color: $Riskperception;
  }
  .highlight.Riskperception:not(.checked) {
      color: $Riskperception;
      border-color: $Riskperception;
  }
  .highlight.Exposure {
      background-color: $Exposure;
  }
  .highlight.Exposure:not(.checked) {
      color: $Exposure;
      border-color: $Exposure;
  }
  #tooltip {
  position: absolute;
  opacity: 0;
  background: #f9f9f9;
  padding: 5px;
  border: 15px solid black;
  border-radius: 15px;
  pointer-events: none; /* Prevent tooltip from blocking mouse events */
}

  </style>