<script lang="ts">
  import { onMount } from 'svelte';
  import type { BicorderState, Gradient, AnalysisGradient } from './types';
  import GradientSlider from './components/GradientSlider.svelte';
  import MetadataFields from './components/MetadataFields.svelte';
  import AnalysisDisplay from './components/AnalysisDisplay.svelte';
  import ExportControls from './components/ExportControls.svelte';

  // Load bicorder data from build-time constant
  let data: BicorderState = JSON.parse(JSON.stringify(__BICORDER_DATA__));

  // Initialize timestamp if not set
  if (!data.metadata.timestamp) {
    data.metadata.timestamp = new Date().toISOString();
  }

  // Load saved state from localStorage
  onMount(() => {
    const saved = localStorage.getItem('bicorder-state');
    if (saved) {
      try {
        const savedData = JSON.parse(saved);
        // Preserve the structure but update values
        data.metadata = { ...data.metadata, ...savedData.metadata };

        // Update gradient values
        data.diagnostic.forEach((set, setIdx) => {
          set.gradients.forEach((gradient, gradIdx) => {
            const savedGradient = savedData.diagnostic?.[setIdx]?.gradients?.[gradIdx];
            if (savedGradient) {
              gradient.value = savedGradient.value;
              gradient.notes = savedGradient.notes;
            }
          });
        });

        // Update analysis values
        data.analysis.forEach((item, idx) => {
          const savedItem = savedData.analysis?.[idx];
          if (savedItem) {
            item.notes = savedItem.notes;
          }
        });
      } catch (e) {
        console.error('Failed to load saved state:', e);
      }
    }
  });

  // Save state whenever it changes
  $: {
    if (typeof window !== 'undefined') {
      localStorage.setItem('bicorder-state', JSON.stringify(data));
    }
  }

  // Auto-calculate analysis values
  function calculateHardness(): number | null {
    const values = data.diagnostic
      .flatMap(set => set.gradients)
      .filter(g => !data.metadata.shortform || g.shortform)
      .map(g => g.value)
      .filter((v): v is number => v !== null);

    if (values.length === 0) return null;

    const mean = values.reduce((sum, v) => sum + v, 0) / values.length;
    return Math.round(mean);
  }

  function calculatePolarization(): number | null {
    const values = data.diagnostic
      .flatMap(set => set.gradients)
      .filter(g => !data.metadata.shortform || g.shortform)
      .map(g => g.value)
      .filter((v): v is number => v !== null);

    if (values.length === 0) return null;

    // Calculate how far values are from center (5)
    const deviations = values.map(v => Math.abs(v - 5));
    const avgDeviation = deviations.reduce((sum, d) => sum + d, 0) / deviations.length;

    // Map deviation to polarized (1) vs centrist (9) scale
    // Max deviation is 4 (from 1 or 9), min is 0 (at 5)
    // Higher deviation = more polarized = lower value
    const polarizationScore = 9 - (avgDeviation / 4) * 8;
    return Math.round(polarizationScore);
  }

  // Update automated analysis values reactively
  $: {
    data.analysis.forEach((item, index) => {
      if (item.automated) {
        if (index === 0) {
          data.analysis[0].value = calculateHardness();
        } else if (index === 1) {
          data.analysis[1].value = calculatePolarization();
        }
      }
    });
  }

  function handleMetadataUpdate(event: CustomEvent) {
    data.metadata = { ...data.metadata, ...event.detail };
  }

  function handleReset() {
    if (confirm('Reset all values? This cannot be undone.')) {
      localStorage.removeItem('bicorder-state');
      location.reload();
    }
  }
</script>

<main>
  <div class="header">
    <div class="title">Protocol</div>
    <div class="title">BICORDER</div>
  </div>

  <MetadataFields
    metadata={data.metadata}
    on:update={handleMetadataUpdate}
  />

  {#each data.diagnostic as diagnosticSet, setIndex}
    <section class="diagnostic-set">
      <div class="set-header">{diagnosticSet.set_name.toUpperCase()}</div>
      <div class="set-description">{diagnosticSet.set_description}</div>

      {#each diagnosticSet.gradients as gradient, gradientIndex}
        {#if !data.metadata.shortform || gradient.shortform}
          <GradientSlider
            {gradient}
            on:change={(e) => {
              data.diagnostic[setIndex].gradients[gradientIndex].value = e.detail ?? null;
              data = data;
            }}
            on:notes={(e) => {
              data.diagnostic[setIndex].gradients[gradientIndex].notes = e.detail;
              data = data;
            }}
          />
        {/if}
      {/each}
    </section>
  {/each}

  <section class="analysis-section">
    <div class="set-header">ANALYSIS</div>

    {#each data.analysis as analysisItem, index}
      <AnalysisDisplay
        gradient={analysisItem}
        on:change={(e) => {
          if (!analysisItem.automated) {
            data.analysis[index].value = e.detail ?? null;
            data = data;
          }
        }}
        on:notes={(e) => {
          data.analysis[index].notes = e.detail;
          data = data;
        }}
      />
    {/each}
  </section>

  <ExportControls {data} on:reset={handleReset} />
</main>

<style>
  main {
    max-width: 800px;
    margin: 0 auto;
    padding: 1rem;
  }

  .header {
    text-align: center;
    margin-bottom: 2rem;
    border-bottom: 2px solid var(--border-color);
    padding-bottom: 1rem;
  }

  .title {
    font-size: 1.5rem;
    font-weight: bold;
    letter-spacing: 0.2rem;
  }

  .diagnostic-set, .analysis-section {
    margin: 2rem 0;
    padding: 1rem 0;
    border-top: 2px solid var(--border-color);
  }

  .set-header {
    text-align: center;
    font-size: 1.2rem;
    font-weight: bold;
    letter-spacing: 0.2rem;
    margin-bottom: 0.5rem;
  }

  .set-description {
    text-align: center;
    font-size: 0.9rem;
    margin-bottom: 1.5rem;
    opacity: 0.8;
  }

  @media (max-width: 768px) {
    main {
      padding: 0.5rem;
    }

    .title {
      font-size: 1.2rem;
    }

    .set-header {
      font-size: 1rem;
    }
  }
</style>
