<script setup>
import { ref, computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { executionLogRepository } from '../db/repositories/executionLogRepository.js'
import { formatDate, formatDuration, formatItemDuration } from '../utils/dateFormatter.js'
import { useHtmlExport } from '../composables/useHtmlExport.js'
import i18next from 'i18next'

const router = useRouter()
const { exportHomeAsHtml } = useHtmlExport()

const recentSessions = ref([])
const allLogs = ref([])
const count7Days = ref(0)
const count30Days = ref(0)
const loading = ref(true)

const today = new Date().toISOString().substring(0, 10)
const historyFrom = ref(new Date(Date.now() - 30 * 86400000).toISOString().substring(0, 10))
const historyTo = ref(today)

onMounted(async () => {
  try {
    const now = new Date()
    const date7DaysAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000).toISOString()
    const date30DaysAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000).toISOString()

    ;[recentSessions.value, allLogs.value, count7Days.value, count30Days.value] = await Promise.all(
      [
        executionLogRepository.getRecentWithItems(4),
        executionLogRepository.getAllWithItems(),
        executionLogRepository.getCountSince(date7DaysAgo),
        executionLogRepository.getCountSince(date30DaysAgo),
      ],
    )
  } catch (e) {
    console.error('Failed to load home data:', e)
  } finally {
    loading.value = false
  }
})

const historyByDay = computed(() => {
  const groups = {}
  for (const log of allLogs.value) {
    const day = log.started_at.substring(0, 10)
    if (day < historyFrom.value || day > historyTo.value) continue
    if (!groups[day]) groups[day] = []
    groups[day].push(log)
  }
  return Object.entries(groups)
    .sort(([a], [b]) => b.localeCompare(a))
    .map(([day, logs]) => ({ day, logs }))
})

// Adds duration_ms to each item using consecutive timestamp deltas
function enrichItemsWithTiming(log) {
  const items = log.items || []
  return items.map((item, i) => {
    const curr = item.timestamp ? new Date(item.timestamp).getTime() : null
    const prev =
      i === 0
        ? log.started_at
          ? new Date(log.started_at).getTime()
          : null
        : items[i - 1].timestamp
          ? new Date(items[i - 1].timestamp).getTime()
          : null
    return { ...item, duration_ms: curr && prev ? curr - prev : null }
  })
}

// Groups enriched items into standalone exercises and combo blocks
function groupItems(items) {
  if (!items || items.length === 0) return []
  const result = []
  const comboMap = {}
  for (const item of items) {
    if (!item.combo_id) {
      result.push({ type: 'exercise', item })
    } else {
      if (!comboMap[item.combo_id]) {
        comboMap[item.combo_id] = {
          type: 'combo',
          combo_id: item.combo_id,
          combo_title: item.combo_title,
          combo_type: item.combo_type,
          exercises: [],
        }
        result.push(comboMap[item.combo_id])
      }
      comboMap[item.combo_id].exercises.push(item)
    }
  }
  return result
}

// Returns combo exercises grouped by round as an array of arrays
function comboRounds(group) {
  const hasRounds = group.exercises.some((ex) => ex.round_number != null)
  if (!hasRounds) return [group.exercises]
  const map = {}
  for (const ex of group.exercises) {
    const rn = ex.round_number ?? 0
    if (!map[rn]) map[rn] = []
    map[rn].push(ex)
  }
  return Object.entries(map)
    .sort(([a], [b]) => Number(a) - Number(b))
    .map(([, exes]) => exes)
}

// Formats the (reps,weight[,timing]) parenthesis for an item
function itemParens(item) {
  const parts = [item.reps_done, item.weight_used]
  const dur = formatItemDuration(item.duration_ms)
  if (dur) parts.push(dur)
  return `(${parts.join(',')})`
}

function getDuration(log) {
  return formatDuration(log.started_at, log.finished_at)
}

function formatDateLocalized(dateStr) {
  return formatDate(dateStr, i18next.language)
}

function goToSession(sessionId) {
  router.push({ name: 'session-detail', params: { id: sessionId } })
}

function goToExecute(sessionId, event) {
  event.stopPropagation()
  router.push({ name: 'session-execute', params: { id: sessionId } })
}

async function onExportHtml() {
  await exportHomeAsHtml({
    count7Days: count7Days.value,
    count30Days: count30Days.value,
    recentSessions: recentSessions.value,
    historyByDay: historyByDay.value,
    historyFrom: historyFrom.value,
    historyTo: historyTo.value,
  })
}
</script>

<template>
  <Teleport to="#actionbar-actions" defer>
    <button
      v-if="!loading && allLogs.length > 0"
      data-testid="home-export-html-btn"
      :title="$t('home.exportHtml')"
      :aria-label="$t('home.exportHtml')"
      @click="onExportHtml"
    >
      <i class="bi bi-filetype-html"></i>
    </button>
  </Teleport>

  <div class="home-view">
    <p v-if="loading" class="text-muted">{{ $t('app.loading') }}</p>

    <template v-else>
      <!-- Stats cards -->
      <div class="stats-cards">
        <div class="stat-card" data-testid="home-stat-7days">
          <span class="stat-value">{{ count7Days }}</span>
          <span class="stat-label">{{ $t('home.sessionsLast7Days') }}</span>
        </div>
        <div class="stat-card" data-testid="home-stat-30days">
          <span class="stat-value">{{ count30Days }}</span>
          <span class="stat-label">{{ $t('home.sessionsLast30Days') }}</span>
        </div>
      </div>

      <!-- Empty state -->
      <p v-if="allLogs.length === 0" class="text-muted" data-testid="home-empty">
        {{ $t('home.empty') }}
      </p>

      <template v-else>
        <!-- Last 4 sessions with details -->
        <div class="recent-section">
          <h3>{{ $t('home.recentSessions') }}</h3>
          <div
            v-for="log in recentSessions"
            :key="log.id"
            class="card recent-session-card"
            :data-testid="'home-recent-session-' + log.id"
            @click="goToSession(log.session_id)"
          >
            <div class="session-header">
              <h4 data-testid="home-recent-session-title">{{ log.session_title }}</h4>
              <span class="session-meta">
                <span class="session-date" data-testid="home-recent-session-date">
                  {{ formatDateLocalized(log.started_at) }}
                </span>
                <span v-if="getDuration(log)" class="session-duration">
                  <i class="bi bi-clock"></i> {{ getDuration(log) }}
                </span>
              </span>
              <button
                class="card-play-btn"
                :data-testid="'home-recent-session-play-' + log.session_id"
                :title="$t('execution.start')"
                :aria-label="$t('execution.start')"
                @click="goToExecute(log.session_id, $event)"
              >
                <i class="bi bi-play-fill"></i>
              </button>
            </div>
            <div v-if="log.items && log.items.length > 0" class="session-items-inline">
              <template
                v-for="(group, gi) in groupItems(enrichItemsWithTiming(log))"
                :key="group.type === 'exercise' ? group.item.id : group.combo_id"
              >
                <span v-if="gi > 0">, </span>
                <span v-if="group.type === 'exercise'"
                  >{{ group.item.exercise_title }} {{ itemParens(group.item) }}</span
                >
                <span v-else
                  >{{ group.combo_title }} ×{{ comboRounds(group).length }} :
                  <span class="combo-inline"
                    >{{ '{'
                    }}<template v-for="(round, ri) in comboRounds(group)" :key="ri"
                      ><strong v-if="ri > 0"> // </strong
                      ><template v-for="(ex, ei) in round" :key="ex.id"
                        ><template v-if="ri > 0 || ei > 0">, </template>{{ ex.exercise_title }}
                        {{ itemParens(ex) }}</template
                      ></template
                    >{{ '}' }}</span
                  ></span
                >
              </template>
            </div>
          </div>
        </div>

        <!-- History by day -->
        <div class="history-section">
          <div class="history-header">
            <h3>{{ $t('home.history') }}</h3>
            <div class="history-filter">
              <input v-model="historyFrom" type="date" :max="historyTo" class="input-date" />
              <span class="history-filter-sep">–</span>
              <input
                v-model="historyTo"
                type="date"
                :min="historyFrom"
                :max="today"
                class="input-date"
              />
            </div>
          </div>
          <div v-for="dayGroup in historyByDay" :key="dayGroup.day" class="history-day">
            <h4 class="history-day-label">{{ formatDateLocalized(dayGroup.day) }}</h4>
            <div
              v-for="log in dayGroup.logs"
              :key="log.id"
              class="card history-session-card"
              :data-testid="'home-history-session-' + log.id"
              @click="goToSession(log.session_id)"
            >
              <div class="session-header session-header--sm">
                <span class="history-session-title">{{ log.session_title }}</span>
                <span class="session-meta">
                  <span v-if="getDuration(log)" class="session-duration">
                    <i class="bi bi-clock"></i> {{ getDuration(log) }}
                  </span>
                </span>
                <button
                  class="card-play-btn card-play-btn-sm"
                  :title="$t('execution.start')"
                  :aria-label="$t('execution.start')"
                  @click="goToExecute(log.session_id, $event)"
                >
                  <i class="bi bi-play-fill"></i>
                </button>
              </div>
              <div
                v-if="log.items && log.items.length > 0"
                class="session-items-inline session-items-inline--sm"
              >
                <template
                  v-for="(group, gi) in groupItems(enrichItemsWithTiming(log))"
                  :key="group.type === 'exercise' ? group.item.id : group.combo_id"
                >
                  <span v-if="gi > 0">, </span>
                  <span v-if="group.type === 'exercise'"
                    >{{ group.item.exercise_title }} {{ itemParens(group.item) }}</span
                  >
                  <span v-else
                    >{{ group.combo_title }} ×{{ comboRounds(group).length }} :
                    <span class="combo-inline"
                      >{{ '{'
                      }}<template v-for="(round, ri) in comboRounds(group)" :key="ri"
                        ><strong v-if="ri > 0"> // </strong
                        ><template v-for="(ex, ei) in round" :key="ex.id"
                          ><template v-if="ri > 0 || ei > 0">, </template>{{ ex.exercise_title }}
                          {{ itemParens(ex) }}</template
                        ></template
                      >{{ '}' }}</span
                    ></span
                  >
                </template>
              </div>
            </div>
          </div>
        </div>
      </template>
    </template>
  </div>
</template>

<style scoped>
.home-view {
  max-width: 800px;
}

/* Stats */

.stats-cards {
  display: flex;
  gap: 16px;
  margin-bottom: 24px;
}

.stat-card {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 16px;
  border-radius: 8px;
  background-color: var(--color-background);
  border: 1px solid var(--border-color);
}

.stat-value {
  font-size: 32px;
  font-weight: 700;
  color: var(--btn-primary-bg);
}

.stat-label {
  font-size: 13px;
  color: var(--color-text-muted);
  text-align: center;
  margin-top: 4px;
}

/* Section headings */

.recent-section {
  margin-bottom: 28px;
}

.recent-section h3,
.history-header h3 {
  font-size: 16px;
  font-weight: 600;
  margin-bottom: 10px;
}

/* Session cards */

.recent-session-card,
.history-session-card {
  cursor: pointer;
  transition: border-color 0.15s;
  margin-bottom: 8px;
}

.recent-session-card:hover,
.history-session-card:hover {
  border-color: var(--btn-primary-bg);
}

/* Session header row */

.session-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}

.session-header h4 {
  flex: 1;
  font-size: 15px;
  font-weight: 600;
  margin: 0;
}

.session-header--sm {
  margin-bottom: 4px;
}

.history-session-title {
  flex: 1;
  font-size: 14px;
  font-weight: 600;
}

.session-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.session-date {
  font-size: 13px;
  color: var(--color-text-muted);
  white-space: nowrap;
}

.session-duration {
  font-size: 12px;
  color: var(--color-text-muted);
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 3px;
}

/* Play buttons */

.card-play-btn {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: none;
  background: var(--btn-primary-bg);
  color: var(--btn-primary-color);
  cursor: pointer;
  flex-shrink: 0;
  font-size: 14px;
  transition: opacity 0.15s;
}

.card-play-btn:hover {
  opacity: 0.8;
}

.card-play-btn-sm {
  width: 26px;
  height: 26px;
  font-size: 12px;
}

/* History day groups */

.history-section {
  margin-bottom: 20px;
}

.history-day {
  margin-bottom: 16px;
}

.history-day-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text-muted);
  margin-bottom: 6px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Inline item line */

.session-items-inline {
  font-size: 13px;
  color: var(--front-color1);
  line-height: 1.6;
}

.session-items-inline--sm {
  font-size: 12px;
}

.combo-inline {
  font-style: italic;
}

/* History header with date filter */

.history-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}

.history-header h3 {
  margin-bottom: 0;
}

.history-filter {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
}

.history-filter-sep {
  color: var(--color-text-muted);
  font-size: 13px;
}

.input-date {
  font-size: 12px;
  padding: 3px 6px;
  border: 1px solid var(--border-color);
  border-radius: 4px;
  background: var(--bg-color2);
  color: var(--front-color1);
}
</style>
