<script setup lang="ts">
import { ref, computed, watch } from 'vue';
import { useAuthStore } from '../stores/auth';
import { useAdminLocale } from '../composables/useAdminLocale';
import api from '../api';
import AdminTableEmpty from './AdminTableEmpty.vue';
import { formatAmount, formatAmountFull } from '../utils/format-amount';
import { walletTxTypeKey } from '../utils/walletTx';

interface WalletTxRow {
  id: string;
  transactionId: string;
  transactionType: string;
  amount: string;
  balanceBefore: string;
  balanceAfter: string;
  frozenBefore: string;
  frozenAfter: string;
  betNo: string | null;
  operatorUsername: string | null;
  remark: string | null;
  createdAt: string;
}

const props = defineProps<{
  modelValue: boolean;
  playerId: string;
  playerUsername?: string | null;
}>();

const emit = defineEmits<{
  'update:modelValue': [value: boolean];
}>();

const { t, locale, localeTag } = useAdminLocale();
const auth = useAuthStore();

const visible = computed({
  get: () => props.modelValue,
  set: (v: boolean) => emit('update:modelValue', v),
});

const dialogTitle = computed(() => {
  const name = props.playerUsername?.trim() || props.playerId;
  return t('user.wallet_ledger_dialog_title', { name });
});

const walletApiPath = computed(() =>
  auth.isAdmin.value ? '/admin/wallet/transactions' : '/agent/wallet/ledger-transactions',
);

const items = ref<WalletTxRow[]>([]);
const total = ref(0);
const page = ref(1);
const pageSize = ref(20);
const loading = ref(false);
const typeCategory = ref('');
const dateRange = ref<[Date, Date] | null>(null);

function walletTypeLabel(type: string) {
  const key = walletTxTypeKey(type);
  return key ? t(key) : type;
}

function formatTime(v: string) {
  return new Date(v).toLocaleString(localeTag.value, {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
  });
}

function dateParams() {
  if (!dateRange.value?.length) return {};
  const [from, to] = dateRange.value;
  const end = new Date(to);
  end.setHours(23, 59, 59, 999);
  return {
    dateFrom: from.toISOString(),
    dateTo: end.toISOString(),
  };
}

async function load() {
  if (!props.playerId) return;
  loading.value = true;
  try {
    const { data } = await api.get(walletApiPath.value, {
      params: {
        page: page.value,
        pageSize: pageSize.value,
        playerId: props.playerId,
        typeCategory: typeCategory.value || undefined,
        ...dateParams(),
      },
    });
    items.value = (data.data?.items ?? []) as WalletTxRow[];
    total.value = data.data?.total ?? 0;
  } catch {
    items.value = [];
    total.value = 0;
  } finally {
    loading.value = false;
  }
}

function onSearch() {
  page.value = 1;
  void load();
}

function resetFilters() {
  typeCategory.value = '';
  dateRange.value = null;
  page.value = 1;
}

watch(
  () => [props.modelValue, props.playerId] as const,
  ([open, id]) => {
    if (open && id) {
      resetFilters();
      void load();
    }
  },
);
</script>

<template>
  <el-dialog
    v-model="visible"
    :title="dialogTitle"
    width="980px"
    destroy-on-close
    class="player-wallet-ledger-dialog"
    append-to-body
  >
    <el-form inline class="ledger-filter">
      <el-form-item :label="t('finance.filter.date_range')">
        <el-date-picker
          v-model="dateRange"
          type="daterange"
          :start-placeholder="t('common.to')"
          :end-placeholder="t('common.to')"
          value-format="YYYY-MM-DD"
          style="width: 240px"
        />
      </el-form-item>
      <el-form-item :label="t('finance.filter.type_category')">
        <el-select v-model="typeCategory" clearable :placeholder="t('finance.filter.type_category_all')" style="width: 120px">
          <el-option :label="t('finance.filter.type_category_deposit')" value="deposit" />
          <el-option :label="t('finance.filter.type_category_bet')" value="bet" />
          <el-option :label="t('finance.filter.type_category_cashback')" value="cashback" />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onSearch">{{ t('common.search') }}</el-button>
      </el-form-item>
    </el-form>

    <div class="table-wrap">
      <el-table v-loading="loading" :key="`${locale}-${playerId}`" :data="items" stripe max-height="420">
        <template #empty>
          <AdminTableEmpty />
        </template>
        <el-table-column :label="t('audit.col.time')" min-width="150">
          <template #default="{ row }">{{ formatTime(row.createdAt) }}</template>
        </el-table-column>
        <el-table-column :label="t('finance.col.tx_id')" min-width="120" show-overflow-tooltip>
          <template #default="{ row }">{{ row.transactionId }}</template>
        </el-table-column>
        <el-table-column :label="t('agent.col.credit_type')" min-width="88">
          <template #default="{ row }">{{ walletTypeLabel(row.transactionType) }}</template>
        </el-table-column>
        <el-table-column :label="t('finance.col.balance_change')" min-width="96" align="right">
          <template #default="{ row }">
            <el-tooltip :content="formatAmountFull(row.amount)" placement="top">
              <span :class="parseFloat(row.amount) >= 0 ? 'amt-pos' : 'amt-neg'">
                {{ formatAmount(row.amount) }}
              </span>
            </el-tooltip>
          </template>
        </el-table-column>
        <el-table-column :label="t('finance.col.balance_before')" min-width="92" align="right">
          <template #default="{ row }">
            <el-tooltip :content="formatAmountFull(row.balanceBefore)" placement="top">
              <span>{{ formatAmount(row.balanceBefore) }}</span>
            </el-tooltip>
          </template>
        </el-table-column>
        <el-table-column :label="t('finance.col.balance_after')" min-width="92" align="right">
          <template #default="{ row }">
            <el-tooltip :content="formatAmountFull(row.balanceAfter)" placement="top">
              <span>{{ formatAmount(row.balanceAfter) }}</span>
            </el-tooltip>
          </template>
        </el-table-column>
        <el-table-column :label="t('finance.col.frozen_before')" min-width="92" align="right">
          <template #default="{ row }">
            <el-tooltip :content="formatAmountFull(row.frozenBefore)" placement="top">
              <span>{{ formatAmount(row.frozenBefore) }}</span>
            </el-tooltip>
          </template>
        </el-table-column>
        <el-table-column :label="t('finance.col.frozen_after')" min-width="92" align="right">
          <template #default="{ row }">
            <el-tooltip :content="formatAmountFull(row.frozenAfter)" placement="top">
              <span>{{ formatAmount(row.frozenAfter) }}</span>
            </el-tooltip>
          </template>
        </el-table-column>
        <el-table-column :label="t('finance.col.reference')" min-width="110" show-overflow-tooltip>
          <template #default="{ row }">
            <router-link
              v-if="row.betNo"
              :to="{ path: '/bets', query: { keyword: row.betNo } }"
              class="bet-link"
              @click="visible = false"
            >
              {{ row.betNo }}
            </router-link>
            <span v-else>—</span>
          </template>
        </el-table-column>
        <el-table-column :label="t('agent.credit_tx.col.operator')" min-width="88">
          <template #default="{ row }">{{ row.operatorUsername ?? '—' }}</template>
        </el-table-column>
        <el-table-column :label="t('user.field.remark')" min-width="100" show-overflow-tooltip>
          <template #default="{ row }">{{ row.remark ?? '—' }}</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]"
        layout="total, sizes, prev, pager, next"
        @current-change="() => load()"
        @size-change="() => { page = 1; load(); }"
      />
    </div>
  </el-dialog>
</template>

<style scoped>
.ledger-filter {
  margin-bottom: 8px;
}

.ledger-filter :deep(.el-form-item) {
  margin-bottom: 0;
  margin-right: 8px;
}

.table-wrap {
  margin: 0 -2px;
}

.pager {
  display: flex;
  justify-content: flex-end;
  margin-top: 8px;
}

.amt-pos {
  color: var(--el-color-success);
  font-weight: 600;
}

.amt-neg {
  color: var(--el-color-danger);
  font-weight: 600;
}

.bet-link {
  color: var(--el-color-primary);
  text-decoration: none;
}

.bet-link:hover {
  text-decoration: underline;
}
</style>

<style>
.player-wallet-ledger-dialog .el-dialog__header {
  padding: 12px 16px 6px;
  margin-right: 0;
}

.player-wallet-ledger-dialog .el-dialog__body {
  padding: 10px 12px;
}

.player-wallet-ledger-dialog .el-dialog__headerbtn {
  top: 10px;
}
</style>
