<script setup lang="ts">
import { ref, computed, onActivated, watch } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { usePlayerMatches } from '../composables/usePlayerMatches';
import LeagueAccordionItem from '../components/LeagueAccordionItem.vue';
import MatchBetCard from '../components/MatchBetCard.vue';
import OutrightPanel from '../components/outright/OutrightPanel.vue';
import emptyMatchesImg from '../assets/images/empty-matches.svg';
import { useOnLocaleChange } from '../composables/useOnLocaleChange';
import GoldSpinner from '../components/GoldSpinner.vue';
import { usePullToRefresh } from '../composables/usePullToRefresh';
import type { MatchPhase } from '../utils/matchPhase';
import {
  isAfterLocalTodayMatchWindow as isAfterTodayMatchWindow,
  isInLocalTodayMatchWindow as isInTodayMatchWindow,
} from '@thebet365/shared';

type MainTab = 'matches' | 'outright';

interface Match {
  id: string;
  leagueId?: string;
  homeTeamName: string;
  awayTeamName: string;
  homeTeamCode?: string;
  awayTeamCode?: string;
  homeTeamLogoUrl?: string | null;
  awayTeamLogoUrl?: string | null;
  startTime: string;
  leagueName: string;
  leagueLogoUrl?: string | null;
  displayOrder?: number;
  isHot?: boolean;
  status?: string;
  bettingOpen?: boolean;
  matchPhase?: MatchPhase;
  score?: {
    htHome: number | null;
    htAway: number | null;
    ftHome: number | null;
    ftAway: number | null;
    homeCorners?: number | null;
    awayCorners?: number | null;
    homeYellowCards?: number | null;
    awayYellowCards?: number | null;
    homeRedCards?: number | null;
    awayRedCards?: number | null;
    homeCards?: number | null;
    awayCards?: number | null;
  } | null;
}

interface LeagueGroup {
  leagueId: string;
  leagueName: string;
  leagueLogoUrl?: string | null;
  matches: Match[];
}

const { t } = useI18n();
const router = useRouter();
const route = useRoute();

const mainTab = ref<MainTab>('matches');
const searchQuery = ref('');
const filterState = ref({
  time: 'all' as 'all' | 'today' | 'early',
  status: 'open' as 'all' | 'open' | 'settled',
  leagueIds: [] as string[]
});
const outrightActivated = ref(false);
const filterNow = ref(new Date());
const { summaryMatches, summaryLoading, loadSummary } = usePlayerMatches();
const matches = summaryMatches;
const loading = summaryLoading;

async function loadMatches() {
  filterNow.value = new Date();
  await loadSummary(true);
}

useOnLocaleChange(() => loadSummary(true));

const { pullDistance, refreshing, spinning, progress } = usePullToRefresh({
  onRefresh: async () => { await loadMatches(); },
});

const pullIndicatorStyle = () => ({
  height: `${pullDistance.value}px`,
  opacity: Math.min(pullDistance.value / 48, 1),
});

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

function syncSearchFromRoute() {
  const q = route.query.search;
  searchQuery.value = typeof q === 'string' ? q : '';
}

function matchesSearchKeyword(m: Match, 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 = filterNow.value;
  const keyword = searchQuery.value.trim().toLowerCase();
  return matches.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 availableLeagues = computed(() => {
  const map = new Map<string, { id: string, name: string }>();
  for (const m of matches.value) {
    let timeMatch = true;
    if (filterState.value.time === 'today') {
      timeMatch = isInTodayMatchWindow(m.startTime, filterNow.value);
    } else if (filterState.value.time === 'early') {
      timeMatch = isAfterTodayMatchWindow(m.startTime, filterNow.value);
    }
    if (!timeMatch) continue;
    
    const id = m.leagueId ?? m.leagueName;
    if (!map.has(id)) {
      map.set(id, { id, name: normalizeLeagueName(m.leagueName) });
    }
  }
  return [...map.values()].sort((a, b) => a.name.localeCompare(b.name));
});

watch(() => filterState.value.time, () => {
  filterState.value.leagueIds = [];
});

const dropdownOpen = ref(false);

const selectedLeagueName = computed(() => {
  if (filterState.value.leagueIds.length === 0) return '';
  const firstId = filterState.value.leagueIds[0];
  const lg = availableLeagues.value.find(l => l.id === firstId);
  return lg ? lg.name : '';
});

function selectLeague(id: string) {
  if (id === '') {
    filterState.value.leagueIds = [];
  } else {
    filterState.value.leagueIds = [id];
  }
  dropdownOpen.value = false;
}

function toggleStatusOpen() {
  filterState.value.status = filterState.value.status === 'open' ? 'all' : 'open';
}

function buildLeagueGroups(source: Match[]): LeagueGroup[] {
  const map = new Map<string, LeagueGroup>();
  for (const m of source) {
    const id = m.leagueId ?? m.leagueName;
    if (!map.has(id)) {
      map.set(id, {
        leagueId: id,
        leagueName: normalizeLeagueName(m.leagueName),
        leagueLogoUrl: m.leagueLogoUrl ?? null,
        matches: [],
      });
    }
    map.get(id)!.matches.push(m);
  }
  const groups = [...map.values()];
  for (const g of groups) {
    g.matches.sort(
      (a, b) =>
        (a.displayOrder ?? 0) - (b.displayOrder ?? 0) ||
        new Date(a.startTime).getTime() - new Date(b.startTime).getTime(),
    );
  }
  return groups.sort(
    (a, b) =>
      (a.matches[0]?.displayOrder ?? 0) - (b.matches[0]?.displayOrder ?? 0) ||
      a.leagueName.localeCompare(b.leagueName),
  );
}

const leagueGroups = computed(() => buildLeagueGroups(filteredMatches.value));

const isSearchActive = computed(() => searchQuery.value.trim().length > 0);

const sortedFilteredMatches = computed(() =>
  [...filteredMatches.value].sort(
    (a, b) =>
      (a.displayOrder ?? 0) - (b.displayOrder ?? 0) ||
      new Date(a.startTime).getTime() - new Date(b.startTime).getTime(),
  ),
);

const expandedLeagues = ref(new Set<string>());

watch(leagueGroups, (groups) => {
  const ids = new Set(expandedLeagues.value);
  for (const id of [...ids]) {
    if (!groups.some((g) => g.leagueId === id)) ids.delete(id);
  }
  if (groups.length > 0 && ids.size === 0) {
    ids.add(groups[0].leagueId);
  }
  if (ids.size !== expandedLeagues.value.size || [...ids].some((id) => !expandedLeagues.value.has(id))) {
    expandedLeagues.value = ids;
  }
});

function toggleLeague(leagueId: string) {
  const next = new Set(expandedLeagues.value);
  if (next.has(leagueId)) next.delete(leagueId);
  else next.add(leagueId);
  expandedLeagues.value = next;
}

function selectMainTab(tab: MainTab) {
  mainTab.value = tab;
  if (tab === 'outright') outrightActivated.value = true;
}

onActivated(() => {
  filterNow.value = new Date();
  filterState.value.time = 'all';
  syncSearchFromRoute();
  void loadSummary(true, true);
});

watch(
  () => route.query.search,
  () => syncSearchFromRoute(),
);

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

<template>
  <div class="bet-page">
    <div
      class="pull-indicator"
      :style="pullIndicatorStyle()"
    >
      <GoldSpinner v-if="spinning" :size="28" :progress="progress" :active="spinning" />
    </div>

    <div class="main-tabs">
      <button
        type="button"
        class="main-tab"
        :class="{ active: mainTab === 'matches', 'tab-gold-active': mainTab === 'matches' }"
        @click="selectMainTab('matches')"
      >
        <span class="tab-icon">⚽</span>
        {{ t('bet.tab_matches') }}
      </button>
      <button
        type="button"
        class="main-tab"
        :class="{ active: mainTab === 'outright', 'tab-gold-active': mainTab === 'outright' }"
        @click="selectMainTab('outright')"
      >
        <span class="tab-icon">🏆</span>
        {{ t('bet.tab_outright') }}
      </button>
    </div>

    <div :class="['tab-panel', { 'tab-panel--hidden': mainTab !== 'matches' }]">
      <div class="search-bar">
        <span class="search-icon" aria-hidden="true">⌕</span>
        <input
          v-model="searchQuery"
          type="search"
          :placeholder="t('search.placeholder')"
          enterkeyhint="search"
          autocomplete="off"
        />
      </div>

      <div class="filters-bar">
        <div class="phase-filter">
          <div class="league-dropdown">
            <button type="button" class="dropdown-trigger" @click="dropdownOpen = !dropdownOpen">
              <span class="dropdown-text">{{ selectedLeagueName || t('bet.filter_leagues_all') }}</span>
              <span class="arrow-icon" :class="{ open: dropdownOpen }">▼</span>
            </button>
            <div v-if="dropdownOpen" class="dropdown-backdrop" @click="dropdownOpen = false"></div>
            <div v-if="dropdownOpen" class="dropdown-menu">
              <div 
                class="dropdown-item" 
                :class="{ active: filterState.leagueIds.length === 0 }"
                @click="selectLeague('')"
              >
                {{ t('bet.filter_leagues_all') }}
              </div>
              <div 
                v-for="lg in availableLeagues" 
                :key="lg.id"
                class="dropdown-item" 
                :class="{ active: filterState.leagueIds.includes(lg.id) }"
                @click="selectLeague(lg.id)"
              >
                {{ lg.name }}
              </div>
            </div>
          </div>
        </div>

        <div class="right-filters">
          <div class="time-tabs">
            <button 
              type="button" 
              class="time-tab" 
              :class="{ active: filterState.time === 'all' }"
              @click="filterState.time = 'all'"
            >
              {{ t('bet.filter_status_all') }}
            </button>
            <button 
              type="button" 
              class="time-tab" 
              :class="{ active: filterState.time === 'today' }"
              @click="filterState.time = 'today'"
            >
              {{ t('bet.tab_today') }}
            </button>
            <button 
              type="button" 
              class="time-tab" 
              :class="{ active: filterState.time === 'early' }"
              @click="filterState.time = 'early'"
            >
              {{ t('bet.tab_early') }}
            </button>
          </div>
          
          <div class="divider"></div>

          <button
            type="button"
            class="status-toggle-btn"
            :class="{ active: filterState.status === 'open' }"
            @click="toggleStatusOpen"
          >
            {{ t('bet.filter_status_open') }}
          </button>
        </div>
      </div>

      <div v-if="loading" class="state">
        <GoldSpinner :size="36" />
      </div>
      <template v-else>
        <div>
          <div v-if="isSearchActive && sortedFilteredMatches.length" class="search-results">
            <p class="search-results-meta">
              {{ t('search.results_count', { count: sortedFilteredMatches.length }) }}
            </p>
            <div class="search-match-list">
              <article
                v-for="match in sortedFilteredMatches"
                :key="match.id"
                class="search-result-item"
              >
                <p class="search-result-league">{{ normalizeLeagueName(match.leagueName) }}</p>
                <MatchBetCard :match="match" @bet="goMatch" />
              </article>
            </div>
          </div>
          <div v-else-if="!isSearchActive && leagueGroups.length" class="league-list">
            <LeagueAccordionItem
              v-for="group in leagueGroups"
              :key="group.leagueId"
              :league-id="group.leagueId"
              :league-name="group.leagueName"
              :league-logo-url="group.leagueLogoUrl"
              :matches="group.matches"
              :expanded="expandedLeagues.has(group.leagueId)"
              @toggle="toggleLeague(group.leagueId)"
              @bet="goMatch"
            />
          </div>
          <div v-else class="empty">
            <img :src="emptyMatchesImg" alt="" class="empty-icon" />
            <p>{{ isSearchActive ? t('search.no_results') : t('bet.no_matches') }}</p>
          </div>
        </div>
      </template>
    </div>

    <OutrightPanel
      v-if="outrightActivated"
      :class="['outright-tab', 'tab-panel', { 'tab-panel--hidden': mainTab !== 'outright' }]"
      :activated="mainTab === 'outright'"
    />



  </div>
</template>

<style scoped>
.pull-indicator {
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  transition: height 0.15s ease;
}

.bet-page {
  margin: 0 -16px;
  padding-bottom: 8px;
  background: var(--bg-body);
}

/* Tab panel toggle: avoid display:none to prevent browser releasing image resources */
.tab-panel {
  display: block;
}
.tab-panel--hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
  opacity: 0;
  pointer-events: none;
}

.main-tabs {
  display: flex;
  gap: 8px;
  padding: 0 12px 12px;
}

.main-tab {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 10px 8px;
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 13px;
  font-weight: 600;
  position: relative;
  box-shadow: var(--shadow);
  transition: background 0.2s, border-color 0.2s, color 0.2s;
}

.main-tab.active {
  font-weight: 700;
  background: rgba(244, 162, 97, 0.1);
  border-color: var(--primary);
  color: var(--primary-light);
}

.tab-icon {
  font-size: 16px;
  line-height: 1;
}

.search-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 12px 8px;
  padding: 0 10px;
  height: 32px;
  box-sizing: border-box;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-card);
}

.search-icon {
  color: var(--gold);
  font-size: 14px;
  line-height: 1;
  flex-shrink: 0;
}

.search-bar input {
  flex: 1;
  min-width: 0;
  height: 100%;
  border: none;
  background: transparent;
  color: #fff;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.2;
  outline: none;
  -webkit-appearance: none;
  appearance: none;
}

.search-bar input::placeholder {
  color: var(--text-muted);
}

.filters-bar {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  padding: 0 12px 12px;
}

.phase-filter {
  padding: 0;
  display: flex;
  align-items: center;
  flex: 1;
  min-width: 0;
}

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

.time-tabs {
  display: flex;
  align-items: center;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 2px;
  height: 24px;
  box-sizing: border-box;
  flex-shrink: 0;
}

.time-tab {
  padding: 0 8px;
  height: 100%;
  font-size: 11px;
  font-weight: 500;
  color: var(--text-muted);
  background: transparent;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  flex-shrink: 0;
}

.time-tab.active {
  color: var(--primary-light);
  background: rgba(244, 162, 97, 0.15);
  font-weight: 600;
}

.right-filters .divider {
  width: 1px;
  height: 12px;
  background: var(--border);
}

.status-toggle-btn {
  padding: 0 8px;
  height: 24px;
  box-sizing: border-box;
  font-size: 11px;
  font-weight: 500;
  color: var(--text-muted);
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.2s ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  flex-shrink: 0;
}

.status-toggle-btn.active {
  color: var(--primary-light);
  background: rgba(244, 162, 97, 0.15);
  border-color: var(--primary);
  font-weight: 600;
}

/* League Dropdown Selector */
.league-dropdown {
  position: relative;
  display: inline-block;
  width: 100%;
}

.dropdown-trigger {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 10px;
  font-size: 11px;
  font-weight: 500;
  color: var(--text);
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
  height: 24px;
  box-sizing: border-box;
  width: 100%;
  max-width: 100%;
}

.dropdown-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dropdown-trigger .arrow-icon {
  font-size: 8px;
  color: var(--text-muted);
  transition: transform 0.2s ease;
  display: inline-block;
  transform: scale(0.8);
}

.dropdown-trigger .arrow-icon.open {
  transform: scale(0.8) rotate(180deg);
}

.dropdown-backdrop {
  position: fixed;
  inset: 0;
  z-index: 98;
  background: transparent;
}

.dropdown-menu {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 99;
  min-width: 170px;
  max-width: 240px;
  max-height: 200px;
  overflow-y: auto;
  background: #0f1217;
  border: 1px solid #2a3240;
  border-radius: 8px;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.65);
  padding: 6px 0;
}

.dropdown-item {
  padding: 8px 14px;
  font-size: 13px;
  color: #e5e7eb;
  cursor: pointer;
  transition: background 0.2s;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  border-bottom: 1px solid #1f2937;
}

.dropdown-item:last-child {
  border-bottom: none;
}

.dropdown-item:hover,
.dropdown-item:active {
  background: #1b2330;
}

.dropdown-item.active {
  color: #f4d06f;
  background: #242f42;
  font-weight: 700;
}

.league-list {
  padding: 4px 12px 0;
}

.search-results {
  padding: 0 12px;
}

.search-results-meta {
  margin: 0 0 8px;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
}

.search-match-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.search-result-item {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.search-result-league {
  margin: 0;
  padding: 0 2px;
  font-size: 11px;
  font-weight: 700;
  color: var(--primary-light);
  line-height: 1.3;
}

.state,
.placeholder,
.empty {
  text-align: center;
  color: var(--text-muted);
  padding: 48px 20px;
  font-weight: 600;
}

.empty-icon {
  width: 96px;
  height: 96px;
  margin-bottom: 14px;
}

.placeholder {
  padding: 80px 20px;
}

.outright-tab {
  min-height: 0;
}
</style>
