<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { useRouter } from 'vue-router';
import { useI18n } from 'vue-i18n';
import api from '../api';
import GoldSpinner from '../components/GoldSpinner.vue';
import { usePullToRefresh } from '../composables/usePullToRefresh';
import { formatMoney } from '../utils/localeDisplay';

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

interface DepositOrder {
  id: string;
  orderNo: string;
  methodType: string;
  amount: string;
  status: string;
  approvedAmount: string | null;
  rejectReason: string | null;
  remark: string | null;
  createdAt: string;
  reviewedAt: string | null;
  paymentMethodName: string | null;
}

const items = ref<DepositOrder[]>([]);
const loading = ref(false);
const initialLoading = ref(true);
const page = ref(1);
const total = ref(0);
const hasMore = ref(true);

const sentinel = ref<HTMLElement | null>(null);
let observer: IntersectionObserver | null = null;

async function fetchOrders(p = 1) {
  if (loading.value) return;
  loading.value = true;
  try {
    const { data } = await api.get('/player/deposit-orders', { params: { page: p } });
    const result = data.data ?? { items: [], total: 0, pageSize: 20 };
    const newItems = result.items ?? [];
    
    if (p === 1) {
      items.value = newItems;
    } else {
      items.value = [...items.value, ...newItems];
    }
    
    total.value = result.total ?? 0;
    const pageSize = result.pageSize ?? 20;
    hasMore.value = newItems.length >= pageSize && items.value.length < total.value;
    page.value = p;
  } catch { /* */ } finally {
    loading.value = false;
    initialLoading.value = false;
  }
}

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

onMounted(() => {
  fetchOrders(1);
  observer = new IntersectionObserver(
    (entries) => {
      if (entries[0].isIntersecting && hasMore.value && !loading.value) {
        fetchOrders(page.value + 1);
      }
    },
    { rootMargin: '200px' },
  );
  if (sentinel.value) observer.observe(sentinel.value);
});

onUnmounted(() => {
  observer?.disconnect();
});

function statusClass(s: string) {
  if (s === 'APPROVED') return 'status-approved';
  if (s === 'REJECTED') return 'status-rejected';
  return 'status-pending';
}

function statusLabel(s: string) {
  if (s === 'APPROVED') return t('recharge.status_approved');
  if (s === 'REJECTED') return t('recharge.status_rejected');
  return t('recharge.status_pending');
}

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

function goRecharge() {
  router.push('/wallet/recharge');
}

onMounted(fetchOrders);
</script>

<template>
  <div class="recharge-history-page">
    <div class="page-header">
      <button class="back-btn" @click="goBack">‹</button>
      <h2>{{ t('recharge.history_title') }}</h2>
      <button class="recharge-btn" @click="goRecharge">+ {{ t('recharge.title') }}</button>
    </div>

    <div
      class="pull-indicator"
      :style="{ height: `${pullDistance}px`, opacity: Math.min(pullDistance / 48, 1) }"
    >
      <GoldSpinner v-if="spinning" :size="28" :progress="progress" :active="spinning" />
    </div>

    <div v-if="loading" class="state">
      <GoldSpinner :size="36" />
    </div>

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

      <div v-else class="order-list">
        <div v-for="order in items" :key="order.id" class="order-card" :class="{ rejected: order.status === 'REJECTED' }">
          <div class="order-header">
            <span class="method-badge" :class="order.methodType === 'BANK' ? 'bank' : 'usdt'">{{ order.methodType }}</span>
            <span :class="['status-badge', statusClass(order.status)]">{{ statusLabel(order.status) }}</span>
          </div>
          <div class="order-body">
            <div class="order-amount">{{ formatMoney(order.amount, locale) }}</div>
            <div v-if="order.approvedAmount && order.approvedAmount !== order.amount" class="approved-amount">
              {{ t('recharge.credited') }}: {{ formatMoney(order.approvedAmount, locale) }}
            </div>
            <div class="order-info-row">
              <span class="info-label">{{ order.paymentMethodName || '-' }}</span>
            </div>
            <div class="order-times">
              <div class="time-row">
                <span class="time-label">{{ t('recharge.apply_time') }}</span>
                <span class="time-value">{{ new Date(order.createdAt).toLocaleString() }}</span>
              </div>
              <div v-if="order.reviewedAt" class="time-row">
                <span class="time-label">{{ t('recharge.review_time') }}</span>
                <span class="time-value">{{ new Date(order.reviewedAt).toLocaleString() }}</span>
              </div>
            </div>
            <div v-if="order.remark" class="order-remark">
              {{ t('recharge.remark') }}: {{ order.remark }}
            </div>
            <div v-if="order.status === 'REJECTED' && order.rejectReason" class="reject-reason">
              {{ t('recharge.reject_reason') }}: {{ order.rejectReason }}
            </div>
          </div>
        </div>
      </div>

      <div ref="sentinel" class="sentinel" />

      <div v-if="loading && items.length > 0" class="load-more-spinner">
        <GoldSpinner :size="24" />
      </div>

      <div v-else-if="!hasMore && items.length > 0" class="end-hint">
        {{ t('common.no_more') }}
      </div>
    </template>
  </div>
</template>

<style scoped>
.recharge-history-page { padding: 0 16px 24px; }
.page-header { display: flex; align-items: center; justify-content: space-between; padding: 12px 0; }
.page-header h2 { margin: 0; font-size: 17px; font-weight: 700; }
.back-btn { background: none; border: none; color: var(--primary-light); font-size: 24px; cursor: pointer; padding: 0 8px; }
.recharge-btn { background: none; border: none; color: var(--primary-light); font-size: 13px; cursor: pointer; font-weight: 600; }
.state { display: flex; justify-content: center; padding: 48px; }
.empty { text-align: center; color: #666; padding: 48px 16px; font-weight: 600; }
.pull-indicator { display: flex; align-items: center; justify-content: center; overflow: hidden; transition: height 0.15s ease; }

.order-list { display: flex; flex-direction: column; gap: 12px; }
.order-card {
  background: linear-gradient(135deg, #1a1810 0%, #1f1b0e 40%, #16140c 100%);
  border: 1px solid rgba(212, 175, 55, 0.2);
  border-radius: 12px;
  padding: 16px;
  position: relative;
  overflow: hidden;
}
.order-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, rgba(212, 175, 55, 0.6), transparent);
}
.order-card.rejected {
  background: linear-gradient(135deg, #1a1a1a 0%, #1f1f1f 40%, #161616 100%);
  border-color: rgba(100, 100, 100, 0.2);
  opacity: 0.7;
}
.order-card.rejected::before {
  background: linear-gradient(90deg, transparent, rgba(100, 100, 100, 0.4), transparent);
}
.order-card.rejected .order-amount {
  background: linear-gradient(135deg, #888, #666);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.order-card.rejected .info-label {
  color: rgba(150, 150, 150, 0.7);
}
.order-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }
.method-badge { padding: 2px 8px; border-radius: 10px; font-size: 11px; font-weight: 700; }
.method-badge.bank { background: rgba(30, 58, 95, 0.6); color: #66b1ff; }
.method-badge.usdt { background: rgba(26, 58, 42, 0.6); color: #67c23a; }
.status-badge { font-size: 12px; font-weight: 700; }
.status-pending { color: #e6a23c; }
.status-approved { color: #67c23a; }
.status-rejected { color: #f56c6c; }
.order-body { }
.order-amount {
  font-size: 22px;
  font-weight: 900;
  margin-bottom: 4px;
  background: linear-gradient(135deg, #f0d060, #d4a830);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.approved-amount { font-size: 12px; color: #67c23a; margin-bottom: 6px; font-weight: 600; }
.order-info-row { margin-bottom: 8px; }
.info-label { font-size: 13px; color: rgba(212, 175, 55, 0.7); font-weight: 600; }
.order-times { display: flex; flex-direction: column; gap: 4px; margin-bottom: 6px; }
.time-row { display: flex; justify-content: space-between; align-items: center; }
.time-label { font-size: 11px; color: #888; }
.time-value { font-size: 11px; color: #aaa; font-variant-numeric: tabular-nums; }
.order-remark {
  font-size: 12px;
  color: rgba(212, 175, 55, 0.8);
  background: rgba(212, 175, 55, 0.06);
  padding: 6px 10px;
  border-radius: 6px;
  margin-top: 6px;
  border-left: 2px solid rgba(212, 175, 55, 0.3);
}
.reject-reason { margin-top: 8px; font-size: 12px; color: #f56c6c; background: #2a1515; padding: 6px 10px; border-radius: 6px; }

.sentinel {
  height: 1px;
}

.load-more-spinner {
  display: flex;
  justify-content: center;
  padding: 20px 0 8px;
}

.end-hint {
  text-align: center;
  font-size: 12px;
  color: #555;
  font-weight: 600;
  padding: 16px 0 4px;
  letter-spacing: 0.03em;
}
</style>
