<template>
    <div class="default-main admin-report-page customer-report">
        <section class="admin-report-filter report-filter">
            <header class="admin-report-heading">{{ t('user.moneyLog.customerReport.title') }}</header>
            <div class="admin-report-filter-content filter-content">
                <div class="filter-item">
                    <label>{{ t('user.moneyLog.customerReport.startDate') }}:</label>
                    <el-date-picker v-model="filters.start" type="date" value-format="YYYY-MM-DD" clearable />
                </div>
                <div class="filter-item">
                    <label>{{ t('user.moneyLog.customerReport.endDate') }}:</label>
                    <el-date-picker v-model="filters.end" type="date" value-format="YYYY-MM-DD" clearable />
                </div>
                <div class="filter-item">
                    <label>{{ t('user.moneyLog.customerReport.fullUsername') }}:</label>
                    <el-input v-model="filters.username" :placeholder="t('user.moneyLog.customerReport.options')" clearable />
                </div>
                <div class="filter-item">
                    <label>{{ t('user.moneyLog.customerReport.loseRebate') }}:</label>
                    <el-input v-model="filters.loseRebate" :placeholder="t('user.moneyLog.customerReport.rebatePlaceholder')" clearable />
                </div>
                <div class="admin-report-actions filter-actions">
                    <el-button type="primary" @click="search">{{ t('user.moneyLog.customerReport.search') }}</el-button>
                    <el-button @click="clear">{{ t('user.moneyLog.customerReport.clear') }}</el-button>
                </div>
            </div>
        </section>

        <div class="admin-report-summary date-summary">
            <strong>{{ t('user.moneyLog.customerReport.dateOfData') }}:</strong>
            {{ dateSummary }}
        </div>

        <div v-loading="loading" class="admin-report-table-wrap report-table-wrap">
            <table class="admin-report-table report-table" :style="{ minWidth: `${tableMinWidth}px` }">
                <thead>
                    <tr>
                        <th rowspan="2" class="date-column">{{ t('user.moneyLog.customerReport.registerDate') }} ↓</th>
                        <th rowspan="2" class="username-column">{{ t('user.moneyLog.customerReport.username') }}</th>
                        <th colspan="2">{{ t('user.moneyLog.customerReport.deposit') }}</th>
                        <th colspan="2">{{ t('user.moneyLog.customerReport.withdraw') }}</th>
                        <th rowspan="2">{{ t('user.moneyLog.customerReport.winLose') }} ↕</th>
                        <th rowspan="2">
                            {{ t('user.moneyLog.customerReport.loseRebate') }}
                            <small>({{ t('user.moneyLog.customerReport.option') }})</small>
                        </th>
                        <th rowspan="2">{{ t('user.moneyLog.customerReport.referral') }} ↕</th>
                        <th v-for="game in games" :key="game.id" colspan="2" class="reward-heading">
                            {{ t('user.moneyLog.customerReport.reward', { game: game.name }) }}
                        </th>
                    </tr>
                    <tr>
                        <template v-for="group in subHeaderGroups" :key="group">
                            <th>{{ t('user.moneyLog.customerReport.count') }} ↕</th>
                            <th>{{ t('user.moneyLog.customerReport.amount') }} ↕</th>
                        </template>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="row in rows" :key="`${row.registerDate}-${row.username}`">
                        <td>{{ row.registerDate }}</td>
                        <td class="username-cell"><span class="user-icon">♟</span>{{ row.username }}</td>
                        <td class="deposit-value">{{ row.depositCount }}</td>
                        <td class="deposit-value">{{ money(row.depositAmount, true) }}</td>
                        <td class="withdraw-value">{{ row.withdrawCount }}</td>
                        <td class="withdraw-value">{{ money(row.withdrawAmount, true) }}</td>
                        <td :class="row.winLose >= 0 ? 'positive-value' : 'negative-value'">{{ signedMoney(row.winLose) }}</td>
                        <td>{{ money(row.loseRebate) }}</td>
                        <td>{{ row.referral }}</td>
                        <template v-for="reward in row.rewards" :key="reward.gameId">
                            <td class="reward-cell">{{ reward.count }}</td>
                            <td class="reward-cell">{{ money(reward.amount) }}</td>
                        </template>
                    </tr>
                    <tr v-if="rows.length === 0">
                        <td class="empty-row" :colspan="columnCount">{{ t('user.moneyLog.customerReport.noData') }}</td>
                    </tr>
                </tbody>
            </table>
        </div>

        <div class="admin-report-footer table-footer">
            <div>{{ t('user.moneyLog.customerReport.totalRecords', { total }) }}</div>
            <el-pagination
                v-model:current-page="currentPage"
                small
                background
                layout="prev, pager, next"
                :page-size="pageSize"
                :page-count="lastPage"
                @current-change="loadReport"
            />
            <div class="admin-report-page-size page-size">
                <span>{{ t('user.moneyLog.customerReport.show') }}</span>
                <el-select v-model="pageSize" @change="changePageSize">
                    <el-option v-for="size in pageSizes" :key="size" :label="size" :value="size" />
                </el-select>
                <span>{{ t('user.moneyLog.customerReport.entries') }}</span>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { customerReport } from '/@/api/backend/user/moneyLog'

defineOptions({
    name: 'user/moneyLog/customerReport',
})

interface CustomerReportRow {
    registerDate: string
    username: string
    depositCount: number
    depositAmount: number
    withdrawCount: number
    withdrawAmount: number
    winLose: number
    loseRebate: number
    referral: number
    rewards: { gameId: string; count: number; amount: number }[]
}

interface CustomerReportSourceRow {
    register_date?: string
    username?: string
    deposit_count?: number | string
    deposit_total?: number | string
    withdraw_count?: number | string
    withdraw_total?: number | string
    win_lose?: number | string
    lose_rebate?: number | string
    referral_count?: number | string
    [key: string]: number | string | undefined
}

const { t } = useI18n()
const games = ref<{ id: string; name: string }[]>([])
const subHeaderGroups = computed(() => ['deposit', 'withdraw', ...games.value.map((game) => game.id)])
const columnCount = computed(() => 9 + games.value.length * 2)
const tableMinWidth = computed(() => 1580 + games.value.length * 250)
const pageSizes = [100, 500, 1000, 5000]
const rows = ref<CustomerReportRow[]>([])
const total = ref(0)
const currentPage = ref(1)
const lastPage = ref(1)
const pageSize = ref(100)
const loading = ref(false)

const filters = reactive({
    start: '',
    end: '',
    username: '',
    loseRebate: '',
})

const appliedFilters = reactive({ ...filters })

const dateSummary = computed(() => {
    if (appliedFilters.start && appliedFilters.end) return `${appliedFilters.start} to ${appliedFilters.end}`
    if (appliedFilters.start) return `${appliedFilters.start} -`
    if (appliedFilters.end) return `- ${appliedFilters.end}`
    return t('user.moneyLog.customerReport.allTime')
})

const toNumber = (value: unknown) => {
    const number = Number(value)
    return Number.isFinite(number) ? number : 0
}

const normalizeResponse = (responseData: any) => {
    const source = responseData?.data ?? responseData ?? {}
    const gameMap = source.games && typeof source.games === 'object' ? source.games : {}
    const normalizedGames = Object.entries(gameMap).map(([id, name]) => ({
        id,
        name: String(name),
    }))
    const list = Array.isArray(source.list) ? source.list : []

    return {
        games: normalizedGames,
        rows: list.map((row: CustomerReportSourceRow) => ({
            registerDate: String(row.register_date ?? ''),
            username: String(row.username ?? ''),
            depositCount: toNumber(row.deposit_count),
            depositAmount: toNumber(row.deposit_total),
            withdrawCount: toNumber(row.withdraw_count),
            withdrawAmount: toNumber(row.withdraw_total),
            winLose: toNumber(row.win_lose),
            loseRebate: toNumber(row.lose_rebate),
            referral: toNumber(row.referral_count),
            rewards: normalizedGames.map((game) => ({
                gameId: game.id,
                count: toNumber(row[`game_${game.id}_count`]),
                amount: toNumber(row[`game_${game.id}_total`]),
            })),
        })),
        total: toNumber(source.count ?? source.total ?? list.length),
        currentPage: toNumber(source.current_page) || currentPage.value,
        lastPage: toNumber(source.last_page) || 1,
    }
}

const loadReport = async () => {
    loading.value = true
    try {
        const response = await customerReport({
            start: appliedFilters.start,
            end: appliedFilters.end,
            username: appliedFilters.username,
            lose_rebate: appliedFilters.loseRebate,
            page: currentPage.value,
            limit: pageSize.value,
        })
        const normalized = normalizeResponse(response.data)
        games.value = normalized.games
        rows.value = normalized.rows
        total.value = normalized.total
        currentPage.value = normalized.currentPage
        lastPage.value = normalized.lastPage
    } finally {
        loading.value = false
    }
}

const search = async () => {
    Object.assign(appliedFilters, filters)
    currentPage.value = 1
    await loadReport()
}

const clear = async () => {
    Object.assign(filters, {
        start: '',
        end: '',
        username: '',
        loseRebate: '',
    })
    await search()
}

const changePageSize = async () => {
    currentPage.value = 1
    await loadReport()
}

const money = (value: number, currency = false) => {
    const formatted = new Intl.NumberFormat(undefined, {
        minimumFractionDigits: 2,
        maximumFractionDigits: 2,
    }).format(Number(value) || 0)
    return currency ? `AUD${formatted}` : formatted
}

const signedMoney = (value: number) => {
    const number = Number(value) || 0
    if (number === 0) return money(0)
    return `${number > 0 ? '+' : '-'}${money(Math.abs(number))}`
}

onMounted(loadReport)
</script>

<style scoped lang="scss">
.customer-report {
    padding: var(--ba-main-space);
}

.filter-content {
    display: grid;
    grid-template-columns: repeat(2, minmax(280px, 350px));
    gap: 12px 18px;
}

.filter-item {
    label {
        width: 118px;
        flex-shrink: 0;
        text-align: right;
    }

    :deep(.el-date-editor),
    :deep(.el-input) {
        width: 200px;
    }
}

.filter-actions {
    grid-column: 2;
    justify-content: flex-start;
}

.report-table {
    min-width: 2500px;

    .date-column {
        width: 225px;
    }

    .username-column {
        width: 160px;
    }

    .reward-heading {
        min-width: 250px;
    }

    .username-cell {
        display: flex;
        align-items: center;
        gap: 8px;
    }

    .user-icon {
        color: var(--el-text-color-secondary);
    }
}

.table-footer {
    :deep(.el-pagination) {
        margin-left: auto;
    }
}

@media (max-width: 768px) {
    .customer-report {
        padding: 12px;
    }

    .filter-content {
        display: flex;
        flex-direction: column;
    }

    .filter-item {
        display: flex;

        label {
            width: auto;
            text-align: left;
        }
    }

    .filter-actions {
        grid-column: auto;
        width: 100%;
    }
}
</style>
