<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { useTranslation } from 'i18next-vue'
import { Bar, Line } from 'vue-chartjs'
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  BarElement,
  LineElement,
  PointElement,
  Title,
  Tooltip,
  Legend,
} from 'chart.js'
import { useSettings } from '../composables/useSettings.js'
import { useStats } from '../composables/useStats.js'
import { formatDate } from '../utils/dateFormatter.js'

ChartJS.register(
  CategoryScale,
  LinearScale,
  BarElement,
  LineElement,
  PointElement,
  Title,
  Tooltip,
  Legend,
)

const { t, i18next } = useTranslation()
const { get } = useSettings()
const {
  dateRange,
  frequencyGroupBy,
  selectedExerciseId,
  totalSessions,
  totalExercises,
  streak,
  loggedExercises,
  frequencyRaw,
  volumeRaw,
  progressionRaw,
  loadAll,
} = useStats()

const dbCreatedAt = ref(null)
const language = ref(i18next.language || 'en')

const DATE_RANGES = ['7d', '30d', '3m', 'all']

const formattedDate = computed(() => {
  if (!dbCreatedAt.value) return ''
  return formatDate(dbCreatedAt.value, language.value)
})

function shortDate(dateStr) {
  if (!dateStr) return ''
  const d = new Date(dateStr)
  if (isNaN(d.getTime())) return dateStr
  const dd = String(d.getDate()).padStart(2, '0')
  const mm = String(d.getMonth() + 1).padStart(2, '0')
  return language.value === 'fr' ? `${dd}/${mm}` : `${mm}/${dd}`
}

// ── Chart data ────────────────────────────────────────────────────────────────

const frequencyChartData = computed(() => ({
  labels: frequencyRaw.value.map((r) => r.period),
  datasets: [
    {
      label: t('stats.charts.frequency.yLabel'),
      data: frequencyRaw.value.map((r) => r.count),
      backgroundColor: 'rgba(59, 130, 246, 0.75)',
    },
  ],
}))

const frequencyChartOptions = {
  responsive: true,
  maintainAspectRatio: false,
  plugins: { legend: { display: false } },
  scales: { y: { beginAtZero: true, ticks: { stepSize: 1 } } },
}

const volumeChartData = computed(() => ({
  labels: volumeRaw.value.map((r) => shortDate(r.day)),
  datasets: [
    {
      label: t('stats.charts.volume.yLabel'),
      data: volumeRaw.value.map((r) => r.volume),
      backgroundColor: 'rgba(16, 185, 129, 0.75)',
    },
  ],
}))

const volumeChartOptions = {
  responsive: true,
  maintainAspectRatio: false,
  plugins: { legend: { display: false } },
  scales: { y: { beginAtZero: true } },
}

const progressionChartData = computed(() => ({
  labels: progressionRaw.value.map((r) => shortDate(r.started_at)),
  datasets: [
    {
      label: t('stats.charts.progression.reps'),
      data: progressionRaw.value.map((r) => r.total_reps),
      borderColor: 'rgb(59, 130, 246)',
      backgroundColor: 'rgba(59, 130, 246, 0.1)',
      yAxisID: 'y',
      tension: 0.3,
    },
    {
      label: t('stats.charts.progression.weight'),
      data: progressionRaw.value.map((r) => r.max_weight),
      borderColor: 'rgb(249, 115, 22)',
      backgroundColor: 'rgba(249, 115, 22, 0.1)',
      yAxisID: 'y1',
      tension: 0.3,
    },
  ],
}))

const progressionChartOptions = computed(() => ({
  responsive: true,
  maintainAspectRatio: false,
  plugins: { legend: { display: true, position: 'top' } },
  scales: {
    y: {
      type: 'linear',
      position: 'left',
      beginAtZero: true,
      title: { display: true, text: t('stats.charts.progression.reps') },
    },
    y1: {
      type: 'linear',
      position: 'right',
      beginAtZero: true,
      grid: { drawOnChartArea: false },
      title: { display: true, text: t('stats.charts.progression.weight') },
    },
  },
}))

// ── Lifecycle ────────────────────────────────────────────────────────────────

function onLanguageChanged(lang) {
  language.value = lang
}

onMounted(async () => {
  language.value = i18next.language || 'en'
  i18next.on('languageChanged', onLanguageChanged)
  dbCreatedAt.value = null
  const createdAtStr = await get('db_created_at')
  if (createdAtStr) {
    dbCreatedAt.value = new Date(createdAtStr)
  }
  await loadAll()
})

onUnmounted(() => {
  i18next.off('languageChanged', onLanguageChanged)
})
</script>

<template>
  <div class="stats-view">
    <h2>{{ $t('stats.title') }}</h2>

    <p v-if="dbCreatedAt" class="text-muted using-since" data-testid="stats-using-since">
      {{ $t('stats.usingSince', { date: formattedDate }) }}
    </p>

    <!-- Date range filter -->
    <div class="stats-date-range" data-testid="stats-date-range">
      <button
        v-for="r in DATE_RANGES"
        :key="r"
        :class="['btn-range', { active: dateRange === r }]"
        :data-testid="`date-range-${r}`"
        @click="dateRange = r"
      >
        {{ $t(`stats.dateRange.${r}`) }}
      </button>
    </div>

    <!-- Summary cards -->
    <div class="stats-cards">
      <div class="stat-card" data-testid="stats-total-sessions">
        <span class="stat-value">{{ totalSessions }}</span>
        <span class="stat-label">{{ $t('stats.summary.sessions') }}</span>
      </div>
      <div class="stat-card" data-testid="stats-total-exercises">
        <span class="stat-value">{{ totalExercises }}</span>
        <span class="stat-label">{{ $t('stats.summary.exercises') }}</span>
      </div>
      <div class="stat-card" data-testid="stats-streak">
        <span class="stat-value">{{ streak }}</span>
        <span class="stat-label">{{ $t('stats.summary.streak') }}</span>
      </div>
    </div>

    <!-- Frequency chart -->
    <div class="stats-section">
      <div class="stats-section-header">
        <h3>{{ $t('stats.charts.frequency.title') }}</h3>
        <select
          v-model="frequencyGroupBy"
          class="stats-select"
          data-testid="stats-frequency-groupby"
        >
          <option value="week">{{ $t('stats.charts.frequency.week') }}</option>
          <option value="month">{{ $t('stats.charts.frequency.month') }}</option>
        </select>
      </div>
      <div
        v-if="frequencyRaw.length > 0"
        class="chart-container"
        data-testid="stats-frequency-chart"
      >
        <Bar :data="frequencyChartData" :options="frequencyChartOptions" />
      </div>
      <p v-else class="no-data" data-testid="stats-frequency-nodata">
        {{ $t('stats.charts.frequency.noData') }}
      </p>
    </div>

    <!-- Volume chart -->
    <div class="stats-section">
      <div class="stats-section-header">
        <h3>{{ $t('stats.charts.volume.title') }}</h3>
      </div>
      <div v-if="volumeRaw.length > 0" class="chart-container" data-testid="stats-volume-chart">
        <Bar :data="volumeChartData" :options="volumeChartOptions" />
      </div>
      <p v-else class="no-data" data-testid="stats-volume-nodata">
        {{ $t('stats.charts.volume.noData') }}
      </p>
    </div>

    <!-- Progression chart -->
    <div class="stats-section">
      <div class="stats-section-header">
        <h3>{{ $t('stats.charts.progression.title') }}</h3>
        <select
          v-model="selectedExerciseId"
          class="stats-select"
          data-testid="stats-progression-exercise"
          :disabled="loggedExercises.length === 0"
        >
          <option value="">{{ $t('stats.charts.progression.selectExercise') }}</option>
          <option v-for="ex in loggedExercises" :key="ex.id" :value="ex.id">
            {{ ex.title }}
          </option>
        </select>
      </div>
      <div
        v-if="selectedExerciseId && progressionRaw.length > 0"
        class="chart-container"
        data-testid="stats-progression-chart"
      >
        <Line :data="progressionChartData" :options="progressionChartOptions" />
      </div>
      <p v-else class="no-data" data-testid="stats-progression-nodata">
        {{
          selectedExerciseId
            ? $t('stats.charts.progression.noData')
            : $t('stats.charts.progression.selectExercise')
        }}
      </p>
    </div>
  </div>
</template>

<style scoped>
.stats-view {
  padding: 1rem;
  max-width: 900px;
}

.using-since {
  color: var(--front-color2);
  margin-bottom: 1rem;
}

/* Date range buttons */
.stats-date-range {
  display: flex;
  gap: 0.4rem;
  margin-bottom: 1.5rem;
  flex-wrap: wrap;
}

.btn-range {
  padding: 0.3rem 0.9rem;
  border: 1px solid var(--border-color);
  border-radius: 4px;
  background: var(--bg-color2);
  color: var(--front-color1);
  cursor: pointer;
  font-size: 0.875rem;
  font-weight: 500;
  transition:
    background 0.12s,
    color 0.12s,
    border-color 0.12s;
}

.btn-range:hover:not(.active) {
  border-color: var(--btn-primary-bg);
  color: var(--btn-primary-bg);
}

.btn-range.active {
  background: var(--btn-primary-bg);
  color: var(--btn-primary-color);
  border-color: var(--btn-primary-bg);
}

/* Summary cards */
.stats-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
  margin-bottom: 2rem;
}

.stat-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 1rem;
  border: 1px solid var(--border-color);
  border-radius: 6px;
  background: var(--bg-color2);
  text-align: center;
}

.stat-value {
  font-size: 2rem;
  font-weight: 700;
  line-height: 1;
  color: var(--btn-primary-bg);
}

.stat-label {
  margin-top: 0.4rem;
  font-size: 0.75rem;
  color: var(--front-color2);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Chart sections */
.stats-section {
  margin-bottom: 2rem;
}

.stats-section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.75rem;
}

.stats-section-header h3 {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
}

.stats-select {
  padding: 0.25rem 0.5rem;
  border: 1px solid var(--input-border);
  border-radius: 4px;
  background: var(--input-bg);
  color: var(--front-color1);
  font-size: 0.875rem;
}

.chart-container {
  position: relative;
  height: 220px;
}

.no-data {
  color: var(--front-color2);
  font-size: 0.9rem;
  padding: 1.5rem 0;
  text-align: center;
}

@media (max-width: 500px) {
  .stats-cards {
    grid-template-columns: 1fr;
  }
}
</style>
