import Chart from 'chart.js/auto';

const CONDITIONS = ["Near Mint", "Lightly Played", "Moderately Played", "Heavily Played", "Damaged"];

const CONDITION_COLORS = {
  "Near Mint":         { active: 'hsla(88, 50%, 67%, 1)', muted: 'hsla(88, 50%, 67%, 0.67)' },
  "Lightly Played":    { active: 'hsla(66, 70%, 68%, 1)',  muted: 'hsla(66, 70%, 68%, 0.67)'  },
  "Moderately Played": { active: 'hsla(54, 100%, 73%, 1)',  muted: 'hsla(54, 100%, 73%, 0.67)'  },
  "Heavily Played":    { active: 'hsla(46, 100%, 65%, 1)',  muted: 'hsla(46, 100%, 65%, 0.67)'  },
  "Damaged":           { active: 'hsla(36, 100%, 65%, 1)',  muted: 'hsla(36, 100%, 65%, 0.67)'  },
};

const RANGE_DAYS = { '1m': 30, '3m': 90, '6m': 180, '1y': 365, 'all': Infinity };

let chartInstance = null;
let allHistory = [];
let activeCondition = "Near Mint";
let activeRange = '1m';

function formatDate(dateStr) {
  const [year, month, day] = dateStr.split('-');
  const d = new Date(Number(year), Number(month) - 1, Number(day));
  return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
}

function setEmptyState(isEmpty) {
  const modal = document.getElementById('cardModal');
  const empty = modal?.querySelector('#priceHistoryEmpty');
  const canvasWrapper = empty?.nextElementSibling;
  if (!empty || !canvasWrapper) return;
  empty.classList.toggle('d-none', !isEmpty);
  canvasWrapper.classList.toggle('d-none', isEmpty);
}

function setChartVisible(visible) {
  const modal = document.getElementById('cardModal');
  const chartWrapper = modal?.querySelector('#priceHistoryChart')?.closest('.alert');
  if (chartWrapper) chartWrapper.classList.toggle('d-none', !visible);
}

function buildChartData(history, rangeKey) {
  const cutoff = RANGE_DAYS[rangeKey] === Infinity
    ? new Date(0)
    : new Date(Date.now() - RANGE_DAYS[rangeKey] * 86_400_000);

  const filtered = history.filter(r => new Date(r.calculatedAt) >= cutoff);

  const dataDateSet = new Set(filtered.map(r => r.calculatedAt));
  const allDates = [...dataDateSet].sort((a, b) => new Date(a) - new Date(b));

  let axisLabels = allDates;
  if (allDates.length > 0 && RANGE_DAYS[rangeKey] !== Infinity) {
    const start = new Date(cutoff);
    const end   = new Date();
    const expanded = [];
    for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
      expanded.push(d.toISOString().split('T')[0]);
    }
    axisLabels = expanded;
  }

  const labels = axisLabels.map(formatDate);

  const lookup = {};
  for (const row of filtered) {
    if (!lookup[row.condition]) lookup[row.condition] = {};
    lookup[row.condition][row.calculatedAt] = Number(row.marketPrice);
  }

  const activeConditionHasData = allDates.some(
    date => lookup[activeCondition]?.[date] != null
  );

  const datasets = CONDITIONS.map(condition => {
    const isActive = condition === activeCondition;
    const colors = CONDITION_COLORS[condition];
    const data = axisLabels.map(date => lookup[condition]?.[date] ?? null);
    return {
      label: condition,
      data,
      borderColor: isActive ? colors.active : colors.muted,
      borderWidth: isActive ? 2 : 1,
      pointRadius: isActive ? 2.5 : 0,
      pointHoverRadius: isActive ? 5 : 3,
      pointBackgroundColor: isActive ? colors.active : colors.muted,
      tension: 0.3,
      fill: false,
      spanGaps: true,
      order: isActive ? 0 : 1,
    };
  });

  return {
    labels,
    datasets,
    hasData: allDates.length > 0,
    activeConditionHasData,
  };
}

function updateChart() {
  if (!chartInstance) return;
  const { labels, datasets, hasData, activeConditionHasData } = buildChartData(allHistory, activeRange);
  chartInstance.data.labels   = labels;
  chartInstance.data.datasets = datasets;
  chartInstance.update('none');
  setEmptyState(!hasData || !activeConditionHasData);
}

function initPriceChart(canvas) {
  if (chartInstance) {
    chartInstance.destroy();
    chartInstance = null;
  }

  try {
    allHistory = JSON.parse(canvas.dataset.history ?? '[]');
  } catch (err) {
    console.error('Failed to parse price history:', err);
    return;
  }

  if (!allHistory.length) {
    setEmptyState(true);
    return;
  }

  const { labels, datasets, hasData, activeConditionHasData } = buildChartData(allHistory, activeRange);

  setEmptyState(!hasData || !activeConditionHasData);

  chartInstance = new Chart(canvas.getContext('2d'), {
    type: 'line',
    data: { labels, datasets },
    options: {
      responsive: true,
      maintainAspectRatio: false,
      interaction: {
        mode: 'index',
        intersect: false,
      },
      plugins: {
        legend: { display: false },
        tooltip: {
          backgroundColor: 'rgba(0, 0, 0, 0.85)',
          titleColor: 'rgba(255, 255, 255, 0.9)',
          bodyColor: 'rgba(255, 255, 255, 0.75)',
          borderColor: 'rgba(255, 255, 255, 0.1)',
          borderWidth: 1,
          padding: 10,
          callbacks: {
            labelColor: (ctx) => {
              const colors = CONDITION_COLORS[ctx.dataset.label];
              return {
                borderColor: colors.active,
                backgroundColor: colors.active,
              };
            },
            label: (ctx) => {
              const isActive = ctx.dataset.label === activeCondition;
              const price = ctx.parsed.y != null ? `$${ctx.parsed.y.toFixed(2)}` : '—';
              return isActive
                ? ` ${ctx.dataset.label}: ${price} ◀`
                : ` ${ctx.dataset.label}: ${price}`;
            }
          }
        }
      },
      scales: {
        x: {
          grid: { color: 'rgba(255, 255, 255, 0.05)' },
          ticks: {
            color: 'rgba(255, 255, 255, 0.4)',
            maxTicksLimit: 6,
            maxRotation: 0,
          },
          border: { color: 'rgba(255, 255, 255, 0.1)' },
        },
        y: {
          grid: { color: 'rgba(255, 255, 255, 0.05)' },
          ticks: {
            color: 'rgba(255, 255, 255, 0.4)',
            callback: (val) => `$${Number(val).toFixed(2)}`,
          },
          border: { color: 'rgba(255, 255, 255, 0.1)' },
        }
      }
    }
  });
}

function initFromCanvas(canvas) {
  activeCondition = "Near Mint";
  activeRange = '1m';
  const modal = document.getElementById('cardModal');

  modal?.querySelectorAll('.price-range-btn').forEach(b => {
    b.classList.toggle('active', b.dataset.range === '1m');
  });

  // Hide chart if the vendor tab is already active when the modal opens
  // (e.g. opened via the inventory button)
  const activeTab = modal?.querySelector('.nav-link.active')?.getAttribute('data-bs-target');
  setChartVisible(activeTab !== '#nav-vendor');

  initPriceChart(canvas);
}

function setup() {
  const modal = document.getElementById('cardModal');
  if (!modal) return;

  modal.addEventListener('card-modal:swapped', () => {
    const canvas = modal.querySelector('#priceHistoryChart');
    if (canvas) initFromCanvas(canvas);
  });

  modal.addEventListener('hidden.bs.modal', () => {
    if (chartInstance) { chartInstance.destroy(); chartInstance = null; }
    allHistory = [];
  });

  document.addEventListener('shown.bs.tab', (e) => {
    if (!modal.contains(e.target)) return;
    const target = e.target?.getAttribute('data-bs-target');

    // Hide the chart when the vendor tab is active, show it for all others
    setChartVisible(target !== '#nav-vendor');

    const conditionMap = {
      '#nav-nm':  'Near Mint',
      '#nav-lp':  'Lightly Played',
      '#nav-mp':  'Moderately Played',
      '#nav-hp':  'Heavily Played',
      '#nav-dmg': 'Damaged',
    };
    if (target && conditionMap[target]) {
      activeCondition = conditionMap[target];
      updateChart();
    }
  });

  document.addEventListener('click', (e) => {
    const btn = e.target?.closest('.price-range-btn');
    if (!btn || !modal.contains(btn)) return;
    modal.querySelectorAll('.price-range-btn').forEach(b => b.classList.remove('active'));
    btn.classList.add('active');
    activeRange = btn.dataset.range ?? '1m';
    updateChart();
  });
}

setup();