<script setup lang="ts">
import { ref, onActivated, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import { useI18n } from 'vue-i18n';
import api from '../api';
import { formatMoney, formatMoneyCompact } from '../utils/localeDisplay';
import { txTypeKey, txDisplayType, txSummaryLabel } from '../utils/walletTx';
import { parseCashbackApiData, sumCashbackAmount } from '../utils/cashback';
import GoldSpinner from '../components/GoldSpinner.vue';
import { usePullToRefresh } from '../composables/usePullToRefresh';

const router = useRouter();
const { t, locale } = useI18n();

type Transaction = {
  transactionType: string;
  displayType?: string;
  summary?: string | null;
  summaryKind?: 'opening_bonus' | null;
  referenceType?: string | null;
  amount: string;
  createdAt: string;
  transactionId: string;
};

const items = ref<Transaction[]>([]);
const cashbackTotal = ref<string>('0');
const loading = ref(true);
const PREVIEW_COUNT = 15;

function txLabel(tx: Transaction): string {
  const key = txTypeKey(txDisplayType(tx));
  if (key) {
    const translated = t(key);
    if (translated !== key) return translated;
  }
  return tx.transactionType;
}

function txSubtitle(tx: Transaction): string {
  return txSummaryLabel(tx, t);
}

function goDetail(tx: Transaction) {
  if (!tx.transactionId) return;
  router.push(`/wallet/transactions/${tx.transactionId}`);
}

function goCashbacks() {
  router.push('/wallet/cashbacks');
}

async function fetchData() {
  loading.value = true;
  try {
    const [txRes, cbRes] = await Promise.all([
      api.get('/player/wallet/transactions', { params: { page: 1 } }),
      api.get('/player/cashbacks').catch(() => ({ data: { data: [] } })),
    ]);
    const result = txRes.data.data ?? { items: [] };
    items.value = (result.items ?? []).slice(0, PREVIEW_COUNT);
    const cbRows = parseCashbackApiData(cbRes.data?.data);
    cashbackTotal.value = sumCashbackAmount(cbRows).toString();
  } catch {
    /* ignore */
  } finally {
    loading.value = false;
  }
}

const { pullDistance, spinning, progress } = usePullToRefresh({
  onRefresh: fetchData,
});

onMounted(fetchData);
onActivated(fetchData);

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

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

    <div v-if="loading" class="state">
      <GoldSpinner :size="36" />
      <span class="loading-text">{{ t('bet.loading') }}</span>
    </div>

    <template v-else>
      <div class="top-bar">
        <button type="button" class="more-link secondary" @click="goCashbacks">
          {{ t('wallet.view_cashbacks_detail') }} &#x203A;
        </button>
        <button
          v-if="items.length"
          type="button"
          class="more-link"
          @click="router.push('/wallet/detail')"
        >{{ t('wallet.view_all') }} &#x203A;</button>
      </div>

      <div v-if="items.length" class="tx-list">
        <button
          v-for="tx in items"
          :key="tx.transactionId"
          type="button"
          class="tx-row"
          @click="goDetail(tx)"
        >
          <div class="tx-main">
            <div class="tx-text">
              <span class="tx-type">{{ txLabel(tx) }}</span>
              <span v-if="txSubtitle(tx)" class="tx-summary">{{ txSubtitle(tx) }}</span>
            </div>
            <span :class="parseFloat(tx.amount) >= 0 ? 'pos' : 'neg'">
              {{ formatMoney(tx.amount, locale) }}
            </span>
          </div>
          <div class="tx-meta">
            <span class="tx-time">{{ new Date(tx.createdAt).toLocaleString() }}</span>
            <span class="tx-arrow">&#x203A;</span>
          </div>
        </button>
      </div>

      <div v-if="!items.length" class="empty">
        {{ t('wallet.no_records') }}
      </div>
    </template>
  </div>
</template>

<style scoped>
.wallet-page {
  padding-bottom: 24px;
}

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

.state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  text-align: center;
  color: var(--text-muted);
  padding: 56px 20px;
  font-weight: 600;
  font-size: 14px;
}

.loading-text {
  font-size: 13px;
}

.tx-list {
  margin-bottom: 0;
}

.tx-row {
  display: block;
  width: 100%;
  text-align: left;
  font-size: 14px;
  padding: 8px 12px;
  border: none;
  border-bottom: 1px solid var(--border);
  background: transparent;
  cursor: pointer;
}

.tx-row:last-child {
  border-bottom: none;
}

.tx-row:active {
  background: rgba(255, 255, 255, 0.03);
}

.tx-main {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}

.tx-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.tx-summary {
  font-size: 11px;
  color: var(--text-muted);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tx-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 4px;
}

.tx-type { font-weight: 700; color: var(--text); }
.pos { color: var(--primary-light); font-weight: 800; font-size: 15px; }
.neg { color: var(--danger); font-weight: 700; }
.tx-time { font-size: 11px; color: var(--text-muted); }
.tx-arrow { font-size: 16px; color: #555; font-weight: 700; line-height: 1; }

.top-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 4px 2px;
  margin-top: -8px;
}

.top-bar .more-link.secondary {
  color: #f0b90b;
}

.more-link {
  background: none;
  border: none;
  color: var(--primary-light);
  font-size: 12px;
  font-weight: 600;
  padding: 2px 6px;
  cursor: pointer;
  opacity: 0.8;
  transition: opacity 0.2s;
}

.more-link:active {
  opacity: 1;
}

.empty { text-align: center; color: var(--text-muted); padding: 40px 16px; font-weight: 600; }
</style>
