<script setup lang="ts">
import { ref, computed, onActivated, watch } from 'vue';
import { useRouter } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { usePlayerMatches } from '../composables/usePlayerMatches';
import LeagueAccordionItem from '../components/LeagueAccordionItem.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 {
  isAfterLocalToday as isAfterTodayMatchWindow,
  isInLocalToday as isInTodayMatchWindow,
} from '@thebet365/shared';

type MainTab = 'matches' | 'outright';
type TimeTab = 'today' | 'early';

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 mainTab = ref<MainTab>('matches');
const timeTab = ref<TimeTab>('today');
const showAll = ref(false);
const filterNow = ref(new Date());
const { summaryMatches, summaryLoading, loadSummary } = usePlayerMatches();
const matches = summaryMatches;
const loading = summaryLoading;
const expandedLeagues = ref<Set<string>>(new Set());

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),
});

const filteredMatches = computed(() => {
  if (mainTab.value !== 'matches') return [];
  const now = filterNow.value;
  return matches.value.filter((m) => {
    const timeMatch =
      timeTab.value === 'today'
        ? isInTodayMatchWindow(m.startTime, now)
        : isAfterTodayMatchWindow(m.startTime, now);
    if (!timeMatch) return false;
    if (!showAll.value && m.matchPhase !== 'open' && m.matchPhase !== undefined) return false;
    return true;
  });
});

const leagueGroups = computed<LeagueGroup[]>(() => {
  const map = new Map<string, LeagueGroup>();
  for (const m of filteredMatches.value) {
    const id = m.leagueId ?? m.leagueName;
    if (!map.has(id)) {
      map.set(id, {
        leagueId: id,
        leagueName: 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),
  );
});

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 (ids.size !== expandedLeagues.value.size) expandedLeagues.value = ids;
  // 默认只展开第一个联赛，减少首屏 DOM
  if (groups.length > 0 && expandedLeagues.value.size === 0) {
    expandedLeagues.value = new Set([groups[0].leagueId]);
  }
});

function isLeagueExpanded(leagueId: string) {
  return expandedLeagues.value.has(leagueId);
}

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;
}

onActivated(() => {
  filterNow.value = new Date();
  timeTab.value = 'today';
});

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 v-show="mainTab === 'matches'">
      <div class="time-tabs">
        <button
          type="button"
          class="time-tab"
          :class="{ active: timeTab === 'today', 'tab-gold-active': timeTab === 'today' }"
          @click="timeTab = 'today'"
        >
          {{ t('bet.tab_today') }}
        </button>
        <button
          type="button"
          class="time-tab"
          :class="{ active: timeTab === 'early', 'tab-gold-active': timeTab === 'early' }"
          @click="timeTab = 'early'"
        >
          {{ t('bet.tab_early') }}
        </button>
      </div>

      <div class="phase-filter">
        <button
          type="button"
          class="phase-toggle"
          :class="{ 'phase-toggle--active': !showAll }"
          :aria-pressed="!showAll"
          @click="showAll = !showAll"
        >
          <span class="phase-toggle-dot" />
          {{ t('bet.show_open_only') }}
        </button>
      </div>

      <div v-if="loading" class="state">
        <GoldSpinner :size="36" />
      </div>
      <div v-else-if="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="isLeagueExpanded(group.leagueId)"
          @toggle="toggleLeague(group.leagueId)"
          @bet="goMatch"
        />
      </div>

      <div v-else class="empty">
        <img :src="emptyMatchesImg" alt="" class="empty-icon" />
        <p>{{ t('bet.no_matches') }}</p>
      </div>
    </div>

    <OutrightPanel v-if="mainTab === 'outright'" class="outright-tab" />

  </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;
}

.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: 12px 8px;
  border-radius: 10px;
  background: #1a1a1a;
  border: 1px solid #2a2a2a;
  color: var(--text-muted);
  font-size: 13px;
  font-weight: 700;
  position: relative;
}

.main-tab.active {
  font-weight: 800;
}

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

.time-tabs {
  display: flex;
  gap: 10px;
  padding: 0 12px 14px;
}

.time-tab {
  flex: 1;
  padding: 10px 16px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 800;
  color: var(--primary-light);
  background: #141414;
  border: 1px solid var(--primary);
}

.time-tab.active {
  background: var(--gradient-gold) !important;
  border-color: #fff1a8 !important;
  color: #2a1a00 !important;
  font-weight: 800;
  box-shadow:
    0 0 0 1px rgba(255, 244, 200, 0.28) inset,
    0 4px 16px rgba(212, 175, 55, 0.28);
  text-shadow: 0 1px 0 rgba(255, 252, 235, 0.75);
}

.phase-filter {
  padding: 0 12px 10px;
}

.phase-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  color: #999;
  background: #141414;
  border: 1px solid #333;
  cursor: pointer;
  transition: all 0.2s ease;
}

.phase-toggle--active {
  color: var(--primary-light);
  border-color: var(--primary);
  background: rgba(200, 168, 78, 0.08);
}

.phase-toggle-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #555;
  transition: background 0.2s ease;
}

.phase-toggle--active .phase-toggle-dot {
  background: var(--primary-light);
}

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

.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>
