"""
Parse USDA NASS CSVs and generate Iowa Corn Dashboard HTML.
"""
import csv
import json
import re
from collections import defaultdict

CORN_CSV = r"C:\Users\wsu\Downloads\88D08B80-1879-34AE-A13B-7D5D70C76F9E.csv"
SOIL_CSV = r"C:\Users\wsu\Downloads\nass_soil_iowa.csv"
OUT_HTML = r"C:\Users\wsu\Downloads\viz\iowa_corn_dashboard.html"

YEARS = [2021, 2022, 2023, 2024, 2025]

# ── Parse corn CSV ──────────────────────────────────────────────
condition_data = defaultdict(lambda: defaultdict(dict))  # {year: {week: {rating: val}}}
progress_data = defaultdict(lambda: defaultdict(dict))   # {year: {week: {stage: val}}}

with open(CORN_CSV, encoding='utf-8') as f:
    reader = csv.DictReader(f)
    for row in reader:
        if row['Program'] != 'SURVEY':
            continue
        year = int(row['Year'])
        if year not in YEARS:
            continue
        period = row['Period']
        if not period.startswith('WEEK'):
            continue
        week = int(period.replace('WEEK #', ''))
        item = row['Data Item']
        val_str = row['Value'].replace(',', '').strip()
        if val_str in ('', '(D)', '(Z)', '(H)', '(L)', '(S)'):
            continue
        try:
            val = float(val_str)
        except ValueError:
            continue

        # Condition data - exclude PREVIOUS YEAR and 5 YEAR AVG
        if 'CONDITION, MEASURED IN PCT' in item:
            for rating in ['EXCELLENT', 'GOOD', 'FAIR', 'POOR', 'VERY POOR']:
                if item.endswith(f'PCT {rating}'):
                    condition_data[year][week][rating] = val
                    break

        # Progress data - exclude PREVIOUS YEAR and 5 YEAR AVG
        if 'PROGRESS, MEASURED IN PCT' in item:
            for stage in ['PLANTED', 'EMERGED', 'SILKING', 'DOUGH', 'DENTED', 'MATURE', 'HARVESTED']:
                if item.endswith(f'PCT {stage}'):
                    progress_data[year][week][stage] = val
                    break

# ── Parse soil CSV ──────────────────────────────────────────────
topsoil_data = defaultdict(lambda: defaultdict(dict))    # {year: {week: {metric: val}}}
subsoil_data = defaultdict(lambda: defaultdict(dict))

with open(SOIL_CSV, encoding='utf-8') as f:
    reader = csv.DictReader(f)
    for row in reader:
        if row['Program'] != 'SURVEY':
            continue
        year = int(row['Year'])
        if year not in YEARS:
            continue
        period = row['Period']
        if not period.startswith('WEEK'):
            continue
        week = int(period.replace('WEEK #', ''))
        item = row['Data Item']
        val_str = row['Value'].replace(',', '').strip()
        if val_str in ('', '(D)', '(Z)', '(H)', '(L)', '(S)'):
            continue

        # Skip PREVIOUS YEAR and 5 YEAR AVG
        if 'PREVIOUS YEAR' in item or '5 YEAR AVG' in item:
            continue

        try:
            val = float(val_str)
        except ValueError:
            continue

        for level in ['ADEQUATE', 'SURPLUS', 'SHORT', 'VERY SHORT']:
            if item.endswith(f'PCT {level}'):
                if 'TOPSOIL' in item:
                    topsoil_data[year][week][level] = val
                elif 'SUBSOIL' in item:
                    subsoil_data[year][week][level] = val
                break

# ── Build JSON for JS ───────────────────────────────────────────

def build_condition_json():
    """Good + Excellent combined % by week for each year."""
    result = {}
    for year in YEARS:
        weeks_sorted = sorted(condition_data[year].keys())
        weeks = []
        values = []
        for w in weeks_sorted:
            d = condition_data[year][w]
            good = d.get('GOOD', 0)
            exc = d.get('EXCELLENT', 0)
            weeks.append(w)
            values.append(good + exc)
        result[str(year)] = {'weeks': weeks, 'values': values}
    return result

def build_progress_json():
    """Progress stages by week for each year."""
    stages = ['PLANTED', 'EMERGED', 'SILKING', 'DOUGH', 'DENTED', 'MATURE', 'HARVESTED']
    result = {}
    for year in YEARS:
        weeks_sorted = sorted(progress_data[year].keys())
        year_data = {'weeks': weeks_sorted, 'stages': {}}
        for stage in stages:
            vals = []
            for w in weeks_sorted:
                vals.append(progress_data[year][w].get(stage, None))
            # Only include stage if it has any non-None data
            if any(v is not None for v in vals):
                year_data['stages'][stage] = vals
        result[str(year)] = year_data
    return result

def build_soil_json(data):
    """Adequate and Surplus % by week for each year."""
    result = {}
    for year in YEARS:
        weeks_sorted = sorted(data[year].keys())
        adequate = []
        surplus = []
        short_vals = []
        vshort = []
        for w in weeks_sorted:
            d = data[year][w]
            adequate.append(d.get('ADEQUATE', None))
            surplus.append(d.get('SURPLUS', None))
            short_vals.append(d.get('SHORT', None))
            vshort.append(d.get('VERY SHORT', None))
        result[str(year)] = {
            'weeks': weeks_sorted,
            'adequate': adequate,
            'surplus': surplus,
            'short': short_vals,
            'very_short': vshort,
        }
    return result

# Compute summary stats
def compute_peak_ge():
    """Peak Good+Excellent for each year and in which week."""
    peaks = {}
    for year in YEARS:
        max_val = 0
        max_week = 0
        for w, d in condition_data[year].items():
            ge = d.get('GOOD', 0) + d.get('EXCELLENT', 0)
            if ge > max_val:
                max_val = ge
                max_week = w
        peaks[str(year)] = {'peak': max_val, 'week': max_week}
    return peaks

condition_json = json.dumps(build_condition_json())
progress_json = json.dumps(build_progress_json())
topsoil_json = json.dumps(build_soil_json(topsoil_data))
subsoil_json = json.dumps(build_soil_json(subsoil_data))
peak_ge_json = json.dumps(compute_peak_ge())

# Quick check
print("Condition years:", list(condition_data.keys()))
for y in YEARS:
    cw = sorted(condition_data[y].keys())
    pw = sorted(progress_data[y].keys())
    tw = sorted(topsoil_data[y].keys())
    sw = sorted(subsoil_data[y].keys())
    print(f"  {y}: condition weeks={len(cw)}, progress weeks={len(pw)}, topsoil weeks={len(tw)}, subsoil weeks={len(sw)}")

# ── Generate HTML ───────────────────────────────────────────────

html = f"""<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Iowa Corn Crop Progress & Condition 2021-2025</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.7/dist/chart.umd.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
<style>
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap');

  * {{ margin: 0; padding: 0; box-sizing: border-box; }}

  body {{
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    background: #0a0a1a;
    color: #e0e0f0;
    min-height: 100vh;
    padding: 24px;
  }}

  .dashboard {{
    max-width: 1440px;
    margin: 0 auto;
  }}

  /* Header */
  .header {{
    text-align: center;
    padding: 40px 20px 20px;
    position: relative;
  }}

  .header::before {{
    content: '';
    position: absolute;
    top: 0; left: 50%;
    transform: translateX(-50%);
    width: 120px; height: 4px;
    background: linear-gradient(90deg, #ef476f, #ffd166, #06d6a0, #118ab2, #073b4c);
    border-radius: 2px;
  }}

  .header h1 {{
    font-size: 2.2rem;
    font-weight: 800;
    background: linear-gradient(135deg, #e0e0f0 0%, #a0a0c0 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    margin-bottom: 8px;
    letter-spacing: -0.5px;
  }}

  .header .subtitle {{
    font-size: 0.9rem;
    color: #8888aa;
    font-weight: 400;
  }}

  .header .corn-icon {{
    font-size: 1.6rem;
    margin-right: 8px;
  }}

  /* Summary cards */
  .summary-row {{
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 16px;
    margin: 24px 0 32px;
  }}

  .summary-card {{
    background: linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%);
    backdrop-filter: blur(20px);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 16px;
    padding: 20px;
    text-align: center;
    transition: transform 0.2s, box-shadow 0.2s;
    position: relative;
    overflow: hidden;
  }}

  .summary-card:hover {{
    transform: translateY(-2px);
    box-shadow: 0 8px 32px rgba(0,0,0,0.3);
  }}

  .summary-card .year-label {{
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 1.5px;
    margin-bottom: 8px;
    opacity: 0.8;
  }}

  .summary-card .peak-value {{
    font-size: 2.4rem;
    font-weight: 800;
    line-height: 1;
    margin-bottom: 4px;
  }}

  .summary-card .peak-label {{
    font-size: 0.7rem;
    color: #8888aa;
    font-weight: 500;
  }}

  .summary-card .glow {{
    position: absolute;
    top: -50%; left: -50%;
    width: 200%; height: 200%;
    border-radius: 50%;
    opacity: 0.06;
    pointer-events: none;
  }}

  /* Chart grid */
  .chart-grid {{
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 24px;
    margin-bottom: 32px;
  }}

  .chart-card {{
    background: linear-gradient(135deg, rgba(255,255,255,0.04) 0%, rgba(255,255,255,0.01) 100%);
    backdrop-filter: blur(20px);
    border: 1px solid rgba(255,255,255,0.07);
    border-radius: 20px;
    padding: 24px;
    position: relative;
    overflow: hidden;
  }}

  .chart-card::before {{
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 3px;
    border-radius: 20px 20px 0 0;
  }}

  .chart-card:nth-child(1)::before {{ background: linear-gradient(90deg, #06d6a0, #118ab2); }}
  .chart-card:nth-child(2)::before {{ background: linear-gradient(90deg, #ffd166, #ef476f); }}
  .chart-card:nth-child(3)::before {{ background: linear-gradient(90deg, #118ab2, #073b4c); }}
  .chart-card:nth-child(4)::before {{ background: linear-gradient(90deg, #ef476f, #ffd166); }}

  .chart-card h2 {{
    font-size: 1.05rem;
    font-weight: 700;
    margin-bottom: 4px;
    color: #d0d0e8;
    letter-spacing: -0.3px;
  }}

  .chart-card .chart-desc {{
    font-size: 0.75rem;
    color: #666688;
    margin-bottom: 16px;
    font-weight: 400;
  }}

  .chart-wrapper {{
    position: relative;
    height: 320px;
  }}

  /* Year selector for progress chart */
  .year-selector {{
    display: flex;
    gap: 6px;
    margin-bottom: 12px;
    flex-wrap: wrap;
  }}

  .year-btn {{
    padding: 5px 14px;
    border-radius: 8px;
    border: 1px solid rgba(255,255,255,0.12);
    background: rgba(255,255,255,0.04);
    color: #aaa;
    font-size: 0.75rem;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.2s;
    font-family: 'Inter', sans-serif;
  }}

  .year-btn:hover {{ background: rgba(255,255,255,0.08); }}
  .year-btn.active {{
    color: #fff;
    border-color: currentColor;
  }}

  /* Download button */
  .download-btn {{
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 12px 28px;
    background: linear-gradient(135deg, rgba(6,214,160,0.15), rgba(17,138,178,0.15));
    border: 1px solid rgba(6,214,160,0.3);
    border-radius: 12px;
    color: #06d6a0;
    font-family: 'Inter', sans-serif;
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.2s;
    margin-top: 16px;
  }}

  .download-btn:hover {{
    background: linear-gradient(135deg, rgba(6,214,160,0.25), rgba(17,138,178,0.25));
    transform: translateY(-1px);
    box-shadow: 0 4px 20px rgba(6,214,160,0.2);
  }}

  .footer {{
    text-align: center;
    padding: 24px 0 16px;
    color: #444466;
    font-size: 0.75rem;
  }}

  /* Legend row */
  .legend-row {{
    display: flex;
    justify-content: center;
    gap: 24px;
    margin: 8px 0 20px;
    flex-wrap: wrap;
  }}

  .legend-item {{
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.78rem;
    font-weight: 500;
    color: #999;
  }}

  .legend-dot {{
    width: 10px;
    height: 10px;
    border-radius: 50%;
    display: inline-block;
  }}

  @media (max-width: 900px) {{
    .chart-grid {{ grid-template-columns: 1fr; }}
    .summary-row {{ grid-template-columns: repeat(3, 1fr); }}
    .header h1 {{ font-size: 1.6rem; }}
  }}

  @media (max-width: 560px) {{
    .summary-row {{ grid-template-columns: repeat(2, 1fr); }}
    body {{ padding: 12px; }}
  }}
</style>
</head>
<body>
<div class="dashboard" id="dashboard">

  <div class="header">
    <h1><span class="corn-icon">&#127805;</span>Iowa Corn Crop Progress & Condition 2021-2025</h1>
    <p class="subtitle">Source: USDA NASS Quick Stats &bull; State Level Data &bull; Weekly Survey Reports</p>
  </div>

  <!-- Year legend -->
  <div class="legend-row">
    <span class="legend-item"><span class="legend-dot" style="background:#ef476f"></span>2021</span>
    <span class="legend-item"><span class="legend-dot" style="background:#ffd166"></span>2022</span>
    <span class="legend-item"><span class="legend-dot" style="background:#06d6a0"></span>2023</span>
    <span class="legend-item"><span class="legend-dot" style="background:#118ab2"></span>2024</span>
    <span class="legend-item"><span class="legend-dot" style="background:#073b4c"></span>2025</span>
  </div>

  <!-- Summary Cards -->
  <div class="summary-row" id="summaryRow"></div>

  <!-- Charts -->
  <div class="chart-grid">

    <!-- 1. Condition -->
    <div class="chart-card">
      <h2>Corn Condition: Good + Excellent %</h2>
      <p class="chart-desc">Weekly combined Good &amp; Excellent rating by year</p>
      <div class="chart-wrapper"><canvas id="conditionChart"></canvas></div>
    </div>

    <!-- 2. Progress -->
    <div class="chart-card">
      <h2>Corn Progress by Growth Stage</h2>
      <p class="chart-desc">Cumulative % of crop reaching each stage &mdash; select year</p>
      <div class="year-selector" id="progressYearBtns"></div>
      <div class="chart-wrapper"><canvas id="progressChart"></canvas></div>
    </div>

    <!-- 3. Topsoil Moisture -->
    <div class="chart-card">
      <h2>Topsoil Moisture: Adequate %</h2>
      <p class="chart-desc">Weekly adequate moisture level by year</p>
      <div class="chart-wrapper"><canvas id="topsoilChart"></canvas></div>
    </div>

    <!-- 4. Subsoil Moisture -->
    <div class="chart-card">
      <h2>Subsoil Moisture: Adequate %</h2>
      <p class="chart-desc">Weekly adequate moisture level by year</p>
      <div class="chart-wrapper"><canvas id="subsoilChart"></canvas></div>
    </div>

  </div>

  <div style="text-align:center">
    <button class="download-btn" onclick="downloadPNG()">
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
      Download PNG
    </button>
  </div>

  <div class="footer">
    Generated from USDA NASS Quick Stats data &bull; Iowa State Level &bull; Crop Years 2021&ndash;2025
  </div>

</div>

<script>
// ── Data ──────────────────────────────────────────────────────
const conditionData = {condition_json};
const progressData = {progress_json};
const topsoilData = {topsoil_json};
const subsoilData = {subsoil_json};
const peakGE = {peak_ge_json};

const YEAR_COLORS = {{
  '2021': '#ef476f',
  '2022': '#ffd166',
  '2023': '#06d6a0',
  '2024': '#118ab2',
  '2025': '#073b4c'
}};

const YEAR_COLORS_LIGHT = {{
  '2021': 'rgba(239,71,111,0.12)',
  '2022': 'rgba(255,209,102,0.12)',
  '2023': 'rgba(6,214,160,0.12)',
  '2024': 'rgba(17,138,178,0.12)',
  '2025': 'rgba(7,59,76,0.25)'
}};

const YEARS = ['2021','2022','2023','2024','2025'];

const STAGE_COLORS = {{
  'PLANTED':   '#06d6a0',
  'EMERGED':   '#118ab2',
  'SILKING':   '#ffd166',
  'DOUGH':     '#ef476f',
  'DENTED':    '#e07020',
  'MATURE':    '#9b59b6',
  'HARVESTED': '#073b4c'
}};

// ── Chart.js defaults ─────────────────────────────────────────
Chart.defaults.color = '#8888aa';
Chart.defaults.borderColor = 'rgba(255,255,255,0.06)';
Chart.defaults.font.family = "'Inter', sans-serif";
Chart.defaults.font.size = 11;

const gridOpts = {{
  color: 'rgba(255,255,255,0.05)',
  drawBorder: false
}};

// ── Summary cards ─────────────────────────────────────────────
const summaryRow = document.getElementById('summaryRow');
YEARS.forEach(yr => {{
  const p = peakGE[yr];
  const card = document.createElement('div');
  card.className = 'summary-card';
  const c = YEAR_COLORS[yr];
  card.innerHTML = `
    <div class="glow" style="background:radial-gradient(circle, ${{c}}, transparent)"></div>
    <div class="year-label" style="color:${{c}}">${{yr}}</div>
    <div class="peak-value" style="color:${{c}}">${{p.peak}}%</div>
    <div class="peak-label">Peak G+E &bull; Week ${{p.week}}</div>
  `;
  summaryRow.appendChild(card);
}});

// ── 1. Condition Chart ────────────────────────────────────────
(() => {{
  const ctx = document.getElementById('conditionChart').getContext('2d');
  const datasets = YEARS.map(yr => {{
    const d = conditionData[yr];
    if (!d || !d.weeks.length) return null;
    return {{
      label: yr,
      data: d.weeks.map((w, i) => ({{ x: w, y: d.values[i] }})),
      borderColor: YEAR_COLORS[yr],
      backgroundColor: YEAR_COLORS_LIGHT[yr],
      borderWidth: yr === '2025' ? 3 : 2,
      pointRadius: yr === '2025' ? 4 : 2,
      pointHoverRadius: 6,
      tension: 0.35,
      fill: false
    }};
  }}).filter(Boolean);

  new Chart(ctx, {{
    type: 'line',
    data: {{ datasets }},
    options: {{
      responsive: true,
      maintainAspectRatio: false,
      interaction: {{ mode: 'index', intersect: false }},
      scales: {{
        x: {{
          type: 'linear',
          title: {{ display: true, text: 'Week Number', font: {{ weight: 600 }} }},
          grid: gridOpts,
          ticks: {{ stepSize: 2 }}
        }},
        y: {{
          title: {{ display: true, text: 'Good + Excellent %', font: {{ weight: 600 }} }},
          grid: gridOpts,
          min: 0,
          max: 100
        }}
      }},
      plugins: {{
        legend: {{ display: false }},
        tooltip: {{
          backgroundColor: 'rgba(10,10,30,0.92)',
          borderColor: 'rgba(255,255,255,0.1)',
          borderWidth: 1,
          padding: 12,
          titleFont: {{ weight: 700 }},
          callbacks: {{
            title: (items) => 'Week ' + items[0].parsed.x,
            label: (ctx) => ctx.dataset.label + ': ' + ctx.parsed.y + '%'
          }}
        }}
      }}
    }}
  }});
}})();

// ── 2. Progress Chart ─────────────────────────────────────────
let progressChart = null;
let currentProgressYear = '2025';

function buildProgressChart(yr) {{
  const ctx = document.getElementById('progressChart').getContext('2d');
  const d = progressData[yr];
  if (!d) return;

  const datasets = Object.entries(d.stages).map(([stage, vals]) => ({{
    label: stage.charAt(0) + stage.slice(1).toLowerCase(),
    data: d.weeks.map((w, i) => ({{ x: w, y: vals[i] }})),
    borderColor: STAGE_COLORS[stage] || '#888',
    backgroundColor: (STAGE_COLORS[stage] || '#888') + '18',
    borderWidth: 2,
    pointRadius: 2,
    pointHoverRadius: 5,
    tension: 0.3,
    fill: true
  }}));

  if (progressChart) progressChart.destroy();

  progressChart = new Chart(ctx, {{
    type: 'line',
    data: {{ datasets }},
    options: {{
      responsive: true,
      maintainAspectRatio: false,
      interaction: {{ mode: 'index', intersect: false }},
      scales: {{
        x: {{
          type: 'linear',
          title: {{ display: true, text: 'Week Number', font: {{ weight: 600 }} }},
          grid: gridOpts,
          ticks: {{ stepSize: 4 }}
        }},
        y: {{
          title: {{ display: true, text: '% Complete', font: {{ weight: 600 }} }},
          grid: gridOpts,
          min: 0,
          max: 100
        }}
      }},
      plugins: {{
        legend: {{
          position: 'bottom',
          labels: {{ usePointStyle: true, pointStyle: 'circle', padding: 14, font: {{ size: 10 }} }}
        }},
        tooltip: {{
          backgroundColor: 'rgba(10,10,30,0.92)',
          borderColor: 'rgba(255,255,255,0.1)',
          borderWidth: 1,
          padding: 12,
          titleFont: {{ weight: 700 }},
          callbacks: {{
            title: (items) => yr + ' \u2014 Week ' + items[0].parsed.x,
            label: (ctx) => ctx.dataset.label + ': ' + (ctx.parsed.y != null ? ctx.parsed.y + '%' : 'N/A')
          }}
        }}
      }}
    }}
  }});
}}

// Year buttons
const btnContainer = document.getElementById('progressYearBtns');
YEARS.forEach(yr => {{
  const btn = document.createElement('button');
  btn.className = 'year-btn' + (yr === currentProgressYear ? ' active' : '');
  btn.textContent = yr;
  btn.style.color = yr === currentProgressYear ? YEAR_COLORS[yr] : '';
  btn.style.borderColor = yr === currentProgressYear ? YEAR_COLORS[yr] : '';
  btn.onclick = () => {{
    currentProgressYear = yr;
    document.querySelectorAll('.year-btn').forEach(b => {{
      b.classList.remove('active');
      b.style.color = '';
      b.style.borderColor = '';
    }});
    btn.classList.add('active');
    btn.style.color = YEAR_COLORS[yr];
    btn.style.borderColor = YEAR_COLORS[yr];
    buildProgressChart(yr);
  }};
  btnContainer.appendChild(btn);
}});

buildProgressChart(currentProgressYear);

// ── 3 & 4. Soil Moisture Charts ───────────────────────────────
function buildSoilChart(canvasId, data, label) {{
  const ctx = document.getElementById(canvasId).getContext('2d');
  const datasets = YEARS.map(yr => {{
    const d = data[yr];
    if (!d || !d.weeks.length) return null;
    return {{
      label: yr,
      data: d.weeks.map((w, i) => ({{ x: w, y: d.adequate[i] }})),
      borderColor: YEAR_COLORS[yr],
      backgroundColor: YEAR_COLORS_LIGHT[yr],
      borderWidth: yr === '2025' ? 3 : 2,
      pointRadius: yr === '2025' ? 3 : 1.5,
      pointHoverRadius: 5,
      tension: 0.35,
      fill: false
    }};
  }}).filter(Boolean);

  new Chart(ctx, {{
    type: 'line',
    data: {{ datasets }},
    options: {{
      responsive: true,
      maintainAspectRatio: false,
      interaction: {{ mode: 'index', intersect: false }},
      scales: {{
        x: {{
          type: 'linear',
          title: {{ display: true, text: 'Week Number', font: {{ weight: 600 }} }},
          grid: gridOpts,
          ticks: {{ stepSize: 4 }}
        }},
        y: {{
          title: {{ display: true, text: label, font: {{ weight: 600 }} }},
          grid: gridOpts,
          min: 0,
          max: 100
        }}
      }},
      plugins: {{
        legend: {{ display: false }},
        tooltip: {{
          backgroundColor: 'rgba(10,10,30,0.92)',
          borderColor: 'rgba(255,255,255,0.1)',
          borderWidth: 1,
          padding: 12,
          titleFont: {{ weight: 700 }},
          callbacks: {{
            title: (items) => 'Week ' + items[0].parsed.x,
            label: (ctx) => ctx.dataset.label + ': ' + (ctx.parsed.y != null ? ctx.parsed.y + '%' : 'N/A')
          }}
        }}
      }}
    }}
  }});
}}

buildSoilChart('topsoilChart', topsoilData, 'Adequate %');
buildSoilChart('subsoilChart', subsoilData, 'Adequate %');

// ── Download PNG ──────────────────────────────────────────────
function downloadPNG() {{
  const el = document.getElementById('dashboard');
  html2canvas(el, {{
    backgroundColor: '#0a0a1a',
    scale: 2,
    useCORS: true
  }}).then(canvas => {{
    const link = document.createElement('a');
    link.download = 'iowa_corn_dashboard_2021_2025.png';
    link.href = canvas.toDataURL('image/png');
    link.click();
  }});
}}
</script>
</body>
</html>"""

with open(OUT_HTML, 'w', encoding='utf-8') as f:
    f.write(html)

print(f"\nDashboard saved to: {OUT_HTML}")
