<script setup lang="ts">
import { ref, computed, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { useMatchFilters } from '../../composables/useMatchFilters';
import { useDesktopParlayMatches, type DesktopParlayMatch } from '../../composables/useDesktopParlayMatches';
import { useOutrightEvents } from '../../composables/useOutrightEvents';
import MatchBetCard from '../../components/MatchBetCard.vue';
import DesktopOutrightEventCard from '../../components/desktop/DesktopOutrightEventCard.vue';
import {
  isAfterLocalTodayMatchWindow as isAfterTodayMatchWindow,
  isInLocalTodayMatchWindow as isInTodayMatchWindow,
} from '@thebet365/shared';
import { useAuthStore } from '../../stores/auth';
import type { OutrightEvent, OutrightSelection } from '../../components/outright/OutrightEventSection.vue';
import OutrightBetModal, { type OutrightPick } from '../../components/outright/OutrightBetModal.vue';

type MainTab = 'matches' | 'outright';

const { t } = useI18n();
const route = useRoute();
const router = useRouter();
const { parlayMatches, parlayLoading, loadParlayMatches } = useDesktopParlayMatches();
const { searchQuery, filterState } = useMatchFilters();
const { loading: outrightLoading, loadError: outrightError, events: outrightEvents, load: loadOutrights } =
  useOutrightEvents();

const mainTab = ref<MainTab>('matches');

watch(
  () => route.query.tab,
  (tab) => {
    mainTab.value = tab === 'outright' ? 'outright' : 'matches';
  },
  { immediate: true },
);

function setMainTab(tab: MainTab) {
  if (mainTab.value === tab && (tab === 'outright') === (route.query.tab === 'outright')) {
    return;
  }
  mainTab.value = tab;
  const query = { ...route.query };
  if (tab === 'outright') query.tab = 'outright';
  else delete query.tab;
  router.replace({ path: route.path, query });
}

watch(mainTab, (tab) => {
  if (tab === 'outright') {
    void loadOutrights({ silent: outrightEvents.value.length > 0 });
  }
});

function normalizeLeagueName(name: string): string {
  return name
    .replace(/\.unit$/i, '')
    .replace(/[-_]+/g, ' ')
    .replace(/\s+/g, ' ')
    .trim();
}

function matchesSearchKeyword(m: DesktopParlayMatch, keyword: string) {
  if (!keyword) return true;
  const haystack = `${m.homeTeamName} ${m.awayTeamName} ${m.leagueName}`.toLowerCase();
  return haystack.includes(keyword);
}

const filteredMatches = computed(() => {
  if (mainTab.value !== 'matches') return [];
  const now = new Date();
  const keyword = searchQuery.value.trim().toLowerCase();
  return parlayMatches.value.filter((m) => {
    if (!matchesSearchKeyword(m, keyword)) return false;

    let timeMatch = true;
    if (filterState.value.time === 'today') {
      timeMatch = isInTodayMatchWindow(m.startTime, now);
    } else if (filterState.value.time === 'early') {
      timeMatch = isAfterTodayMatchWindow(m.startTime, now);
    }
    if (!timeMatch) return false;

    if (filterState.value.status === 'open' && m.matchPhase !== 'open' && m.matchPhase !== undefined) return false;
    if (filterState.value.status === 'settled' && m.matchPhase !== 'settled') return false;

    if (filterState.value.leagueIds.length > 0) {
      const id = m.leagueId ?? m.leagueName;
      if (!filterState.value.leagueIds.includes(id)) return false;
    }

    return true;
  });
});

const leagueGroups = computed(() => {
  const groups: Record<string, { leagueName: string; matches: DesktopParlayMatch[] }> = {};
  for (const m of filteredMatches.value) {
    const id = m.leagueId ?? m.leagueName;
    if (!groups[id]) {
      groups[id] = { leagueName: normalizeLeagueName(m.leagueName), matches: [] };
    }
    groups[id].matches.push(m);
  }
  return Object.values(groups).sort((a, b) => a.leagueName.localeCompare(b.leagueName));
});

const filteredOutrightEvents = computed(() => {
  if (mainTab.value !== 'outright') return [];
  const keyword = searchQuery.value.trim().toLowerCase();
  return outrightEvents.value.filter((e) => {
    if (keyword) {
      const haystack = `${e.title} ${e.leagueName || ''}`.toLowerCase();
      if (!haystack.includes(keyword)) return false;
    }
    if (filterState.value.leagueIds.length > 0) {
      const id = e.leagueId ?? e.leagueName;
      if (!filterState.value.leagueIds.includes(id)) return false;
    }
    return true;
  });
});

function goMatch(id: string) {
  router.push(`/match/${id}`);
}

function goOutright(id: string) {
  router.push(`/outright/${id}`);
}

const auth = useAuthStore();
const modalOpen = ref(false);
const activePick = ref<OutrightPick | null>(null);

function openBet(event: OutrightEvent, sel: OutrightSelection) {
  if (event.bettingOpen === false || event.status === 'SETTLED') return;
  if (!auth.token) {
    auth.showLoginPrompt(route.fullPath);
    return;
  }
  activePick.value = {
    selectionId: sel.id,
    oddsVersion: sel.oddsVersion,
    teamCode: sel.teamCode,
    teamName: sel.teamName,
    odds: sel.odds,
    eventTitle: event.title,
  };
  modalOpen.value = true;
}

function closeModal() {
  modalOpen.value = false;
  activePick.value = null;
}

async function refresh() {
  if (mainTab.value === 'outright') {
    await loadOutrights({ silent: false });
    return;
  }
  await loadParlayMatches(true);
}

void loadParlayMatches(true);
</script>

<template>
  <div class="desktop-football-view">
    <div class="view-header">
      <div class="main-tabs">
        <button
          type="button"
          class="main-tab"
          :class="{ active: mainTab === 'matches' }"
          @click="setMainTab('matches')"
        >
          {{ t('bet.tab_matches') }}
        </button>
        <button
          type="button"
          class="main-tab"
          :class="{ active: mainTab === 'outright' }"
          @click="setMainTab('outright')"
        >
          {{ t('bet.tab_outright') }}
        </button>
      </div>
      <button
        type="button"
        class="refresh-btn"
        :disabled="mainTab === 'matches' ? parlayLoading : outrightLoading"
        @click="refresh"
      >
        <span v-if="(mainTab === 'matches' ? parlayLoading : outrightLoading)" class="spin">↻</span>
        <span v-else>↻ {{ t('bet.refresh') }}</span>
      </button>
    </div>

    <div v-if="mainTab === 'matches'" class="matches-list-panel">
      <div v-if="parlayLoading && !leagueGroups.length" class="skeleton-container">
        <div v-for="i in 6" :key="i" class="skeleton-card desktop-skeleton"></div>
      </div>

      <template v-else-if="leagueGroups.length">
        <section v-for="lg in leagueGroups" :key="lg.leagueName" class="league-section">
          <h2 class="league-title">{{ lg.leagueName }}</h2>
          <div class="match-grid">
            <MatchBetCard
              v-for="m in lg.matches"
              :key="m.id"
              class="match-card-dense"
              :match="m"
              @bet="goMatch"
            />
          </div>
        </section>
      </template>

      <div v-else class="empty-state">
        <p>{{ t('bet.no_matches') }}</p>
      </div>
    </div>

    <div v-else class="outright-panel-wrap">
      <div v-if="outrightLoading && !filteredOutrightEvents.length" class="skeleton-container">
        <div v-for="i in 4" :key="i" class="skeleton-card desktop-skeleton"></div>
      </div>

      <template v-else-if="filteredOutrightEvents.length">
        <p v-if="filteredOutrightEvents.length > 1" class="outright-summary">
          {{
            t('bet.outright_events_summary', {
              events: filteredOutrightEvents.length,
              teams: filteredOutrightEvents.reduce((n, e) => n + e.selections.length, 0),
            })
          }}
        </p>
        <div class="outright-event-grid">
          <DesktopOutrightEventCard
            v-for="event in filteredOutrightEvents"
            :key="event.id"
            :event="event"
            @open="goOutright(event.id)"
            @pick="(sel) => openBet(event, sel)"
          />
        </div>
      </template>

      <div v-else class="empty-state">
        <p>{{ outrightError || t('bet.no_outright') }}</p>
        <p v-if="!outrightError" class="empty-hint">{{ t('bet.no_outright_hint') }}</p>
      </div>
    </div>

    <OutrightBetModal :open="modalOpen" :pick="activePick" @close="closeModal" />
  </div>
</template>

<style scoped>
.desktop-football-view {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px;
  box-sizing: border-box;
  min-height: 100%;
}

.view-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid var(--border);
  padding-bottom: 8px;
}

.main-tabs {
  display: flex;
  gap: 10px;
}

.main-tab {
  background: transparent;
  color: var(--text-muted);
  font-size: 12px;
  font-weight: 700;
  padding: 5px 10px;
  border-radius: 4px;
  transition: all 0.2s;
}

.main-tab:hover {
  color: var(--primary);
  background: var(--bg-hover);
}

.main-tab.active {
  color: var(--primary-light);
  background: rgba(0, 102, 204, 0.08);
  border: 1px solid var(--border-active);
}

.refresh-btn {
  background: transparent;
  color: var(--primary-light);
  font-size: 11px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 4px;
}

.spin {
  display: inline-block;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  100% { transform: rotate(360deg); }
}

.skeleton-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 8px;
}

.skeleton-card {
  height: 120px;
  border-radius: 6px;
}

.league-section + .league-section {
  margin-top: 14px;
}

.league-title {
  margin: 0 0 8px;
  padding: 6px 10px;
  font-size: 12px;
  font-weight: 800;
  color: var(--primary-light);
  background: rgba(0, 102, 204, 0.06);
  border-left: 3px solid var(--primary);
  border-radius: 0 4px 4px 0;
}

.match-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 8px;
}

.match-grid :deep(.match-card) {
  padding: 8px 6px;
  gap: 6px;
}

.match-grid :deep(.team-name) {
  font-size: 13px;
}

.match-grid :deep(.team-flag) {
  width: 56px;
  height: 38px;
}

.match-grid :deep(.team-flag.flag-logo) {
  width: 44px;
  height: 44px;
  object-fit: contain;
}

.match-grid :deep(.kickoff) {
  font-size: 10px;
}

.match-grid :deep(.vs) {
  font-size: 11px;
}

.match-grid :deep(.bet-btn) {
  font-size: 11px;
  padding: 5px 10px;
  min-height: 28px;
}

.match-grid :deep(.status-tag) {
  font-size: 9px;
  padding: 2px 6px;
}

.empty-state {
  text-align: center;
  padding: 40px 16px;
  color: var(--text-muted);
  font-size: 13px;
}

.empty-hint {
  margin-top: 8px;
  font-size: 12px;
  opacity: 0.85;
}

.outright-summary {
  margin: 0 0 10px;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
}

.outright-event-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 8px;
}
</style>
