<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue';
import { useRoute } from 'vue-router';
import { useAdminLocale } from '../composables/useAdminLocale';
import api from '../api';
import MatchesSubNav from '../components/MatchesSubNav.vue';
import LeagueOutrightOddsPanel from './matches/LeagueOutrightOddsPanel.vue';
import {
  readMatchesListUiState,
  writeMatchesListUiState,
} from '../utils/matchesListState';

const { t } = useAdminLocale();
const route = useRoute();

const leagues = ref<unknown[]>([]);
const total = ref(0);
const page = ref(1);
const pageSize = ref(10);
const keyword = ref('');
const expandedRowKeys = ref<string[]>([]);

function persistListUiState() {
  writeMatchesListUiState({
    expandedLeagueIds: [...expandedRowKeys.value],
    page: page.value,
    pageSize: pageSize.value,
    filterStatus: '',
    keyword: keyword.value,
  });
}

function applyExpandedFromSaved(savedIds: string[]) {
  const allowed = new Set(leagues.value.map((row) => leagueId(row)));
  expandedRowKeys.value = savedIds.filter((id) => allowed.has(id));
}

type LoadOptions = { restoreExpand?: boolean; keepExpand?: boolean };

async function load(options: LoadOptions = {}) {
  const saved = options.restoreExpand ? readMatchesListUiState() : null;
  if (saved) {
    page.value = saved.page;
    pageSize.value = saved.pageSize;
    keyword.value = saved.keyword;
  }

  const { data } = await api.get('/admin/leagues', {
    params: {
      page: page.value,
      pageSize: pageSize.value,
      keyword: keyword.value.trim() || undefined,
    },
  });
  leagues.value = data.data.items;
  total.value = data.data.total;

  if (options.restoreExpand && saved) {
    applyExpandedFromSaved(saved.expandedLeagueIds);
  } else if (!options.keepExpand) {
    expandedRowKeys.value = [];
  } else {
    applyExpandedFromSaved(expandedRowKeys.value);
  }
  persistListUiState();
}

function onSearch() {
  page.value = 1;
  expandedRowKeys.value = [];
  load();
}

async function resolveExpandFromQuery() {
  const qLeague = route.query.leagueId;
  if (typeof qLeague === 'string' && qLeague.trim()) {
    expandedRowKeys.value = [qLeague.trim()];
    persistListUiState();
    return;
  }
  const qMatch = route.query.matchId;
  if (typeof qMatch === 'string' && qMatch.trim()) {
    try {
      const { data } = await api.get(`/admin/outrights/${qMatch.trim()}`);
      const lid = data.data?.leagueId as string | undefined;
      if (lid) {
        expandedRowKeys.value = [lid];
        persistListUiState();
      }
    } catch {
      /* ignore */
    }
  }
}

onMounted(async () => {
  await load({ restoreExpand: true });
  await resolveExpandFromQuery();
});
onBeforeUnmount(persistListUiState);

function onPageChange(p: number) {
  page.value = p;
  load({ keepExpand: true });
}

function onSizeChange(size: number) {
  pageSize.value = size;
  page.value = 1;
  load({ keepExpand: true });
}

function onExpandChange(_row: unknown, expanded: unknown[]) {
  expandedRowKeys.value = expanded.map((r) => leagueId(r));
  persistListUiState();
}

function onRowClick(row: unknown, _column: unknown, event: MouseEvent) {
  if ((event.target as HTMLElement).closest('.el-table__expand-icon')) return;
  const id = leagueId(row);
  expandedRowKeys.value = expandedRowKeys.value.includes(id) ? [] : [id];
  persistListUiState();
}

function rowClassName() {
  return 'row-expandable';
}

function rowOf(row: unknown) {
  return row as Record<string, unknown>;
}
function leagueId(row: unknown) {
  return String(rowOf(row).id ?? '');
}
function leagueNameZh(row: unknown) {
  const zh = String(rowOf(row).leagueZh ?? '').trim();
  return zh || '—';
}
function leagueNameEn(row: unknown) {
  const en = String(rowOf(row).leagueEn ?? '').trim();
  return en || '—';
}
function outrightTeamCount(row: unknown) {
  return Number(rowOf(row).outrightTeamCount ?? 0);
}
function isLeagueExpanded(id: string) {
  return expandedRowKeys.value.includes(id);
}
</script>

<template>
  <div class="admin-list-page matches-page">
    <div class="list-chrome">
      <div class="list-chrome__row">
        <div class="list-chrome__left">
          <MatchesSubNav embedded />
          <div class="list-chrome__filters">
            <div class="list-chrome__field">
              <span class="list-chrome__label">{{ t('common.keyword') }}</span>
              <el-input
                v-model="keyword"
                :placeholder="t('match.filter.keyword_ph')"
                clearable
                style="width: 200px"
                @keyup.enter="onSearch"
              />
            </div>
            <el-button type="primary" class="list-chrome__submit" @click="onSearch">
              {{ t('common.search') }}
            </el-button>
          </div>
        </div>
      </div>
    </div>

    <section class="list-panel">
      <p class="list-hint">{{ t('match.expand_outright_hint') }}</p>
      <div class="table-wrap">
        <el-table
          :data="leagues"
          stripe
          row-key="id"
          :expand-row-keys="expandedRowKeys"
          :row-class-name="rowClassName"
          @expand-change="onExpandChange"
          @row-click="onRowClick"
        >
          <el-table-column type="expand" width="40">
            <template #default="{ row }">
              <LeagueOutrightOddsPanel
                v-if="isLeagueExpanded(leagueId(row))"
                :league-id="leagueId(row)"
                @updated="load({ keepExpand: true })"
              />
            </template>
          </el-table-column>
          <el-table-column type="index" :index="(i: number) => (page - 1) * pageSize + i + 1" :label="t('common.seq')" width="70" align="center" />
          <el-table-column :label="t('match.col.league')" width="148" show-overflow-tooltip>
            <template #default="{ row }">
              <div class="league-cell">
                <img
                  v-if="rowOf(row).logoUrl"
                  :src="String(rowOf(row).logoUrl)"
                  alt=""
                  class="league-logo"
                />
                <span class="matchup-link">{{ leagueNameZh(row) }}</span>
              </div>
            </template>
          </el-table-column>
          <el-table-column :label="t('match.col.league_en')" width="180" show-overflow-tooltip>
            <template #default="{ row }">
              <span class="league-en">{{ leagueNameEn(row) }}</span>
            </template>
          </el-table-column>
          <el-table-column :label="t('outright.col.teams_total')" width="120" align="center">
            <template #default="{ row }">{{ outrightTeamCount(row) }}</template>
          </el-table-column>
          <el-table-column :label="t('match.col.league_code')" width="140" show-overflow-tooltip>
            <template #default="{ row }">{{ rowOf(row).code }}</template>
          </el-table-column>
        </el-table>
      </div>
      <div class="pager">
        <el-pagination
          v-model:current-page="page"
          v-model:page-size="pageSize"
          :total="total"
          :page-sizes="[10, 20, 50, 100]"
          layout="total, sizes, prev, pager, next"
          background
          @current-change="onPageChange"
          @size-change="onSizeChange"
        />
      </div>
    </section>
  </div>
</template>

<style scoped>
.matches-page .table-wrap .el-table {
  height: auto !important;
}
.matches-page .table-wrap :deep(.el-table__header),
.matches-page .table-wrap :deep(.el-table__body) {
  width: 100% !important;
}
.matches-page :deep(.el-table__expanded-cell) {
  padding: 0 !important;
  background: #fbfaf7;
}
.list-panel :deep(.row-expandable) {
  cursor: pointer;
}
.matchup-link {
  color: var(--primary-link);
}
.league-cell {
  display: flex;
  align-items: center;
  gap: 8px;
}
.league-logo {
  width: 28px;
  height: 28px;
  object-fit: contain;
  flex-shrink: 0;
}
.league-en {
  color: var(--text-muted);
  font-size: 13px;
}
</style>
