(function($) {
  'use strict';
  var D = window.ElsDash;
  var H = D.helpers;
  var CONFIG = D.CONFIG;

  D.analysisCharts = {};
  D.analysisCharts.sparklines = [];

  // ============================================================
  // ANALYSIS TAB
  // ============================================================
  function updateAnalysis() {
    var period = $('#analysis-period-selector').val() || 'monthly';
    var now = new Date();
    var periodStart, priorStart;
    var periodLabel;
    if (period === 'weekly') {
      var dow = now.getDay();
      var daysBack = (dow + 1) % 7;
      var thisSat = new Date(now.getFullYear(), now.getMonth(), now.getDate() - daysBack);
      periodStart = new Date(thisSat.getFullYear(), thisSat.getMonth(), thisSat.getDate() - 7);
      priorStart = new Date(thisSat.getFullYear(), thisSat.getMonth(), thisSat.getDate() - 14);
      periodLabel = 'week over week';
    } else if (period === 'quarterly') {
      periodStart = new Date(now.getFullYear(), now.getMonth() - 3, now.getDate());
      priorStart = new Date(now.getFullYear(), now.getMonth() - 6, now.getDate());
      periodLabel = 'quarter over quarter';
    } else {
      periodStart = new Date(now.getFullYear(), now.getMonth() - 1, now.getDate());
      priorStart = new Date(now.getFullYear(), now.getMonth() - 2, now.getDate());
      periodLabel = 'month over month';
    }
    $('#trend-period-label').text('(' + periodLabel + ')');

    var recent = D.filteredApps.filter(function(a) { return a.receiptDate && a.receiptDate >= periodStart; });
    var prior = D.filteredApps.filter(function(a) { return a.receiptDate && a.receiptDate >= priorStart && a.receiptDate < periodStart; });

    function countBy(apps, keyFn) {
      var counts = {};
      apps.forEach(function(a) {
        var k = keyFn(a);
        if (k) counts[k] = (counts[k] || 0) + 1;
      });
      return counts;
    }

    // Predefined ITU frequency bands (lo/hi in MHz)
    var FREQ_BANDS = [
      { key: 'vlf-mf', label: 'VLF/LF/MF', lo: 0, hi: 3, binCount: 60, fmtFn: function(mhz) { return Math.round(mhz * 1000) + ' kHz'; } },
      { key: 'hf', label: 'HF', lo: 3, hi: 30, binCount: 54, fmtFn: function(mhz) { return (Math.round(mhz * 10) / 10) + ' MHz'; } },
      { key: 'vhf', label: 'VHF', lo: 30, hi: 300, binCount: 54, fmtFn: function(mhz) { return Math.round(mhz) + ' MHz'; } },
      { key: 'uhf', label: 'UHF', lo: 300, hi: 3000, binCount: 54, fmtFn: function(mhz) { return Math.round(mhz) + ' MHz'; } },
      { key: 'shf', label: 'SHF', lo: 3000, hi: 30000, binCount: 54, fmtFn: function(mhz) { return (Math.round(mhz / 100) / 10) + ' GHz'; } },
      { key: 'ehf', label: 'EHF', lo: 30000, hi: 300000, binCount: 54, fmtFn: function(mhz) { return Math.round(mhz / 1000) + ' GHz'; } }
    ];

    function freqBandLabel(mhz) {
      for (var i = 0; i < FREQ_BANDS.length; i++) {
        if (mhz >= FREQ_BANDS[i].lo && mhz < FREQ_BANDS[i].hi) return FREQ_BANDS[i].label;
      }
      if (mhz >= FREQ_BANDS[FREQ_BANDS.length - 1].hi) return FREQ_BANDS[FREQ_BANDS.length - 1].label;
      return null;
    }

    var allIntervals = [];
    var bandAppCounts = {};
    FREQ_BANDS.forEach(function(b) { bandAppCounts[b.key] = 0; });
    D.filteredApps.forEach(function(a) {
      var seenBands = {};
      a.frequencies.forEach(function(f) {
        var lo = parseFloat(f.lo) || 0;
        var hi = parseFloat(f.hi) || 0;
        if (lo > 0) {
          if (hi <= 0 || hi < lo) hi = lo;
          allIntervals.push({ lo: lo, hi: hi });
          FREQ_BANDS.forEach(function(b) {
            if (hi >= b.lo && lo < b.hi && !seenBands[b.key]) {
              seenBands[b.key] = true;
              bandAppCounts[b.key]++;
            }
          });
        }
      });
    });

    var activeBands = FREQ_BANDS.filter(function(b) { return bandAppCounts[b.key] > 0; });
    var bandColors = ['#13418A', '#2e8540', '#e86e00', '#981b1e', '#4a90d9', '#4c2c92'];

    var $btns = $('#freq-band-btns');
    $btns.empty();
    if (activeBands.length === 0) {
      $btns.html('<span style="color:#888;font-size:0.9rem">No frequency data in filtered applications.</span>');
      if (D.analysisCharts.freq) { D.analysisCharts.freq.destroy(); D.analysisCharts.freq = null; }
    } else {
      var defaultBand = activeBands[0];
      activeBands.forEach(function(b) {
        if (bandAppCounts[b.key] > bandAppCounts[defaultBand.key]) defaultBand = b;
      });

      activeBands.forEach(function(b, idx) {
        var isActive = b.key === defaultBand.key;
        var btnStyle = 'display:inline-block;padding:5px 14px;margin:0 4px 4px 0;border:2px solid ' + bandColors[idx % bandColors.length] + ';border-radius:3px;font-size:0.85rem;font-weight:600;cursor:pointer;';
        btnStyle += isActive ? 'background:' + bandColors[idx % bandColors.length] + ';color:#fff' : 'background:#fff;color:' + bandColors[idx % bandColors.length];
        var $btn = $('<button class="freq-band-btn" data-band="' + b.key + '" style="' + btnStyle + '">' + b.label + ' (' + bandAppCounts[b.key] + ')</button>');
        $btn.on('click', function() {
          $btns.find('.freq-band-btn').each(function(i2) {
            var c = bandColors[i2 % bandColors.length];
            $(this).css({ background: '#fff', color: c });
          });
          $(this).css({ background: bandColors[idx % bandColors.length], color: '#fff' });
          renderFreqChart(b);
        });
        $btns.append($btn);
      });

      function renderFreqChart(band) {
        var binCount = band.binCount;
        var binW = (band.hi - band.lo) / binCount;
        var bins = [];
        for (var i = 0; i < binCount; i++) bins.push(0);

        allIntervals.forEach(function(iv) {
          if (iv.lo === iv.hi) {
            if (iv.lo < band.lo || iv.lo >= band.hi) return;
            var ptBin = Math.min(binCount - 1, Math.floor((iv.lo - band.lo) / binW));
            bins[ptBin]++;
            return;
          }
          var overlapLo = Math.max(iv.lo, band.lo);
          var overlapHi = Math.min(iv.hi, band.hi);
          if (overlapLo >= overlapHi) return;
          var loBin = Math.max(0, Math.floor((overlapLo - band.lo) / binW));
          var hiBin = Math.min(binCount - 1, Math.floor((overlapHi - band.lo) / binW));
          for (var b = loBin; b <= hiBin; b++) bins[b]++;
        });

        var labels = [];
        for (var j = 0; j < binCount; j++) {
          labels.push(band.fmtFn(band.lo + j * binW));
        }

        $('#chart-freq-dist').parent().css('height', '300px');
        if (D.analysisCharts.freq) D.analysisCharts.freq.destroy();
        D.analysisCharts.freq = new Chart(document.getElementById('chart-freq-dist'), {
          type: 'line',
          data: {
            labels: labels,
            datasets: [{
              label: 'Applications',
              data: bins,
              borderColor: CONFIG.COLORS.PRIMARY,
              borderWidth: 2,
              pointRadius: 0,
              pointHitRadius: 8,
              tension: 0.2,
              fill: false
            }]
          },
          options: {
            responsive: true,
            maintainAspectRatio: false,
            animation: D.filteredApps.length > 500 ? false : undefined,
            plugins: {
              legend: { display: false },
              tooltip: {
                callbacks: {
                  title: function(items) {
                    var idx = items[0].dataIndex;
                    var lo = band.lo + idx * binW;
                    var hi = lo + binW;
                    return band.fmtFn(lo) + ' - ' + band.fmtFn(hi);
                  }
                }
              }
            },
            scales: {
              x: { title: { display: true, text: 'Frequency (' + band.label + ')' }, ticks: { maxTicksLimit: 12, maxRotation: 45 } },
              y: { beginAtZero: true, title: { display: true, text: 'Applications' }, ticks: { stepSize: 1 } }
            }
          }
        });
      }

      renderFreqChart(defaultBand);
    }

    var dimensions = [
      { label: 'Experiment Type', key: function(a) { return a.experimentType; } },
      { label: 'Frequency Band', key: function(a) {
        var lo = a.frequencies.length ? (parseFloat(a.frequencies[0].lo) || 0) : 0;
        return lo > 0 ? freqBandLabel(lo) : null;
      }},
      { label: 'Applicant', key: function(a) { return a.name; } },
      { label: 'Referral Entity', key: function(a) {
        return a.charges.length ? a.charges[0].charge : null;
      }}
    ];

    var insights = [];
    dimensions.forEach(function(dim) {
      var recentCounts = countBy(recent, dim.key);
      var priorCounts = countBy(prior, dim.key);
      var allKeys = {};
      Object.keys(recentCounts).forEach(function(k) { allKeys[k] = true; });
      Object.keys(priorCounts).forEach(function(k) { allKeys[k] = true; });

      Object.keys(allKeys).forEach(function(k) {
        var rc = recentCounts[k] || 0;
        var pc = priorCounts[k] || 0;
        var delta = rc - pc;
        if (delta > 0) {
          var pct = pc > 0 ? Math.round((delta / pc) * 100) : null;
          insights.push({ dim: dim.label, item: k, recent: rc, prior: pc, delta: delta, pct: pct, keyFn: dim.key });
        }
      });
    });

    insights.sort(function(a, b) { return b.delta - a.delta; });
    var topInsights = insights.slice(0, 6);

    var $cards = $('#trend-cards');
    if (topInsights.length === 0) {
      $cards.html('<div class="col-md-12" style="color:#888;font-size:0.95rem;padding:10px">No notable trends in the current filtered data.</div>');
    } else {
      var trendHtml = '';
      topInsights.forEach(function(t) {
        var arrow, cssClass;
        if (t.prior === 0) {
          arrow = '<i class="fa fa-star"></i> NEW';
          cssClass = 'trend-new';
        } else {
          arrow = '<i class="fa fa-arrow-up"></i> +' + t.pct + '%';
          cssClass = 'trend-up';
        }
        trendHtml += '<div class="col-md-4 col-sm-6" style="padding:0 7px">' +
          '<div class="trend-card">' +
          '<div class="trend-label" title="' + t.item + '">' + t.item + '</div>' +
          '<div class="trend-value ' + cssClass + '">' + arrow + '</div>' +
          '<div class="trend-detail">' + t.recent + ' recent vs ' + t.prior + ' prior &middot; ' + t.dim + '</div>' +
          '</div></div>';
      });
      $cards.html(trendHtml);

      // Destroy existing sparkline charts before re-rendering
      (D.analysisCharts.sparklines || []).forEach(function(c) { c.destroy(); });
      D.analysisCharts.sparklines = [];

      // Sparklines on trend cards
      topInsights.forEach(function(t, tIdx) {
        var $card = $cards.find('.trend-card').eq(tIdx);
        if (!$card.length) return;

        var sparkId = 'sparkline-' + tIdx;
        $card.append('<div style="position:relative;width:100%;height:40px;margin-top:4px"><canvas id="' + sparkId + '"></canvas></div>');

        var sparkPeriod = $('#analysis-period-selector').val() || 'monthly';
        var sparkNow = new Date();
        var sparkPeriods = [];
        for (var sp = 5; sp >= 0; sp--) {
          var d = new Date(sparkNow.getFullYear(), sparkNow.getMonth() - (sparkPeriod === 'quarterly' ? sp * 3 : sp), sparkNow.getDate());
          sparkPeriods.push(H.periodKey(d, sparkPeriod));
        }

        var sparkData = sparkPeriods.map(function(pk) {
          var count = 0;
          D.filteredApps.forEach(function(a) {
            if (!a.receiptDate) return;
            if (H.periodKey(a.receiptDate, sparkPeriod) !== pk) return;
            var val = t.keyFn ? t.keyFn(a) : null;
            if (val === t.item) count++;
          });
          return count;
        });

        D.analysisCharts.sparklines.push(new Chart(document.getElementById(sparkId), {
          type: 'line',
          data: {
            labels: sparkPeriods,
            datasets: [{
              data: sparkData,
              borderColor: t.prior === 0 ? '#13428b' : '#2e8540',
              borderWidth: 1,
              pointRadius: 0,
              tension: 0.3,
              fill: false
            }]
          },
          options: {
            responsive: true,
            maintainAspectRatio: false,
            animation: false,
            plugins: { legend: { display: false }, tooltip: { enabled: false } },
            scales: {
              x: { display: false },
              y: { display: false, beginAtZero: true }
            }
          }
        }));
      });
    }

    // Experiment type counts -- horizontal bar, scales with number of types
    var typeCounts = {};
    D.filteredApps.forEach(function(a) {
      var t = a.experimentType || 'Unknown';
      typeCounts[t] = (typeCounts[t] || 0) + 1;
    });
    var typeLabels = Object.keys(typeCounts).sort();
    var typeHeight = Math.max(200, typeLabels.length * 28 + 60);
    $('#chart-exp-type-container').css('height', typeHeight + 'px');

    if (D.analysisCharts.expType) D.analysisCharts.expType.destroy();
    D.analysisCharts.expType = new Chart(document.getElementById('chart-exp-type'), {
      type: 'bar',
      data: {
        labels: typeLabels,
        datasets: [{ label: 'Applications', data: typeLabels.map(function(l) { return typeCounts[l]; }), backgroundColor: '#13428b', borderRadius: 3 }]
      },
      options: {
        indexAxis: 'y',
        responsive: true,
        maintainAspectRatio: false,
        plugins: { legend: { display: false } },
        scales: {
          x: { beginAtZero: true, title: { display: true, text: 'Count' }, ticks: { stepSize: 1 } },
          y: { ticks: { font: { size: 11 } } }
        }
      }
    });

    // Median processing time by experiment type -- horizontal bar
    var typeGroups = {};
    D.filteredApps.forEach(function(a) {
      if (!a.statusDate || !a.receiptDate || H.isPending(a.status)) return;
      var t = a.experimentType || 'Unknown';
      if (!typeGroups[t]) typeGroups[t] = [];
      typeGroups[t].push(H.daysBetween(a.receiptDate, a.statusDate));
    });
    var ptLabels = Object.keys(typeGroups).sort();
    var ptMedians = ptLabels.map(function(t) { return H.median(typeGroups[t]); });
    var ptHeight = Math.max(200, ptLabels.length * 28 + 60);
    $('#chart-processing-time-container').css('height', ptHeight + 'px');

    if (D.analysisCharts.procTime) D.analysisCharts.procTime.destroy();
    D.analysisCharts.procTime = new Chart(document.getElementById('chart-processing-time'), {
      type: 'bar',
      data: {
        labels: ptLabels,
        datasets: [{ label: 'Median Days', data: ptMedians, backgroundColor: '#2e8540', borderRadius: 3 }]
      },
      options: {
        indexAxis: 'y',
        responsive: true,
        maintainAspectRatio: false,
        plugins: { legend: { display: false } },
        scales: {
          x: { beginAtZero: true, title: { display: true, text: 'Days' } },
          y: { ticks: { font: { size: 11 } } }
        }
      }
    });

    // Referral entity performance (bottleneck analysis)
    var entityStats = {};
    var longestOpen = { age: 0, entity: '', app: null };
    var totalOpen = 0;

    D.filteredApps.forEach(function(a) {
      a.charges.forEach(function(c) {
        if (!c.charge) return;
        if (!entityStats[c.charge]) entityStats[c.charge] = { closed: [], openCount: 0 };
        if (c.openDate && c.closeDate) {
          entityStats[c.charge].closed.push(H.daysBetween(c.openDate, c.closeDate));
        } else if (c.openDate && !c.closeDate) {
          entityStats[c.charge].openCount++;
          totalOpen++;
          var age = H.daysBetween(c.openDate, now);
          if (age > longestOpen.age) {
            longestOpen = { age: age, entity: c.charge, app: a };
          }
        }
      });
    });

    var entityKeys = Object.keys(entityStats).filter(function(e) {
      return entityStats[e].closed.length > 0;
    });
    entityKeys.sort(function(a, b) {
      return H.median(entityStats[b].closed) - H.median(entityStats[a].closed);
    });

    // Summary cards
    var slowest = entityKeys.length > 0 ? entityKeys[0] : null;
    var slowestMedian = slowest ? H.median(entityStats[slowest].closed) : 0;
    var slowColor = slowestMedian > 90 ? '#ff253a' : slowestMedian > 60 ? '#e86e00' : '#2e8540';

    var cardsHtml = '<div class="col-md-4"><div class="kpi-card kpi-secondary" style="padding:12px">' +
      '<div class="kpi-label">Slowest Entity</div>' +
      '<div class="kpi-value" style="font-size:1.3rem;color:' + slowColor + '">' + (slowest || '--') + '</div>' +
      '<div style="font-size:0.85rem;color:#888">' + (slowest ? slowestMedian + 'd median' : 'No closed referrals') + '</div>' +
      '</div></div>';
    cardsHtml += '<div class="col-md-4"><div class="kpi-card kpi-secondary" style="padding:12px">' +
      '<div class="kpi-label">Longest Open Referral</div>' +
      '<div class="kpi-value" style="font-size:1.3rem;color:' + (longestOpen.age > 90 ? '#ff253a' : '#13418A') + '">' + longestOpen.age + 'd</div>' +
      '<div style="font-size:0.85rem;color:#888">' + (longestOpen.app ? longestOpen.entity + ' - ' + H.appLabel(longestOpen.app) : '--') + '</div>' +
      '</div></div>';
    cardsHtml += '<div class="col-md-4"><div class="kpi-card kpi-secondary" style="padding:12px">' +
      '<div class="kpi-label">Total Open Referrals</div>' +
      '<div class="kpi-value" style="font-size:1.3rem;color:#13418A">' + totalOpen + '</div>' +
      '<div style="font-size:0.85rem;color:#888">across all filtered apps</div>' +
      '</div></div>';
    $('#bottleneck-cards').html(cardsHtml);

    // Bar chart
    var bnLabels = entityKeys.map(function(e) { return e + ' (n=' + entityStats[e].closed.length + ')'; });
    var bnData = entityKeys.map(function(e) { return H.median(entityStats[e].closed); });
    var bnColors = bnData.map(function(d) {
      if (d > 90) return '#ff253a';
      if (d > 60) return '#e86e00';
      if (d > 30) return '#ffbe2e';
      return '#2e8540';
    });

    var bnHeight = Math.max(200, entityKeys.length * 32 + 60);
    $('#chart-bottleneck-container').css('height', bnHeight + 'px');

    if (D.analysisCharts.bottleneck) D.analysisCharts.bottleneck.destroy();
    if (entityKeys.length > 0) {
      D.analysisCharts.bottleneck = new Chart(document.getElementById('chart-bottleneck'), {
        type: 'bar',
        data: {
          labels: bnLabels,
          datasets: [{
            label: 'Median Days to Close',
            data: bnData,
            backgroundColor: bnColors,
            borderRadius: 3
          }]
        },
        options: {
          indexAxis: 'y',
          responsive: true,
          maintainAspectRatio: false,
          animation: D.filteredApps.length > 500 ? false : undefined,
          plugins: { legend: { display: false } },
          scales: {
            x: { beginAtZero: true, title: { display: true, text: 'Median Days to Close' } },
            y: { ticks: { font: { size: 11 } } }
          }
        }
      });
    }

  }

  D.updateAnalysis = updateAnalysis;
})(jQuery);
