<template>
    <div class="default-main daily-report">
        <section class="report-filter">
            <header>{{ t('user.moneyLog.dailyReport.title') }}</header>
            <div class="filter-content">
                <div class="date-fields">
                    <label>{{ t('user.moneyLog.dailyReport.startDate') }}:</label>
                    <el-date-picker
                        v-model="filters.start"
                        type="date"
                        value-format="YYYY-MM-DD"
                        :clearable="false"
                        @change="loadReport"
                    />
                    <label>{{ t('user.moneyLog.dailyReport.endDate') }}:</label>
                    <el-date-picker
                        v-model="filters.end"
                        type="date"
                        value-format="YYYY-MM-DD"
                        :clearable="false"
                        @change="loadReport"
                    />
                </div>
                <div class="period-tabs">
                    <button
                        v-for="period in periods"
                        :key="period.value"
                        type="button"
                        :class="{ active: filters.period === period.value }"
                        @click="changePeriod(period.value)"
                    >
                        {{ t(period.label) }}
                    </button>
                </div>
            </div>
        </section>

        <div v-loading="loading" class="report-table-wrap">
            <table class="report-table" :style="{ minWidth: `${tableMinWidth}px` }">
                <thead>
                    <tr>
                        <th rowspan="2" class="date-column">{{ t('user.moneyLog.dailyReport.date') }}</th>
                        <th colspan="2">{{ t('user.moneyLog.dailyReport.deposit') }}</th>
                        <th colspan="2">{{ t('user.moneyLog.dailyReport.withdraw') }}</th>
                        <th rowspan="2" class="single-column">{{ t('user.moneyLog.dailyReport.winLose') }}</th>
                        <th colspan="2">{{ t('user.moneyLog.dailyReport.unclaim') }}</th>
                        <th rowspan="2" class="single-column">{{ t('user.moneyLog.dailyReport.activeMember') }}</th>
                        <th rowspan="2" class="single-column">{{ t('user.moneyLog.dailyReport.newDeposit') }}</th>
                        <th rowspan="2" class="single-column">{{ t('user.moneyLog.dailyReport.newRegister') }}</th>
                        <th v-for="game in games" :key="game.id" colspan="2" class="reward-heading">
                            {{ t('user.moneyLog.dailyReport.reward', { game: game.name }) }}
                        </th>
                    </tr>
                    <tr>
                        <template v-for="group in subHeaderGroups" :key="group">
                            <th class="count-column">{{ t('user.moneyLog.dailyReport.count') }}</th>
                            <th class="total-column">{{ t('user.moneyLog.dailyReport.total') }}</th>
                        </template>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="row in rows" :key="row.date">
                        <td class="date-cell">{{ row.date }}</td>
                        <td class="deposit-value">{{ row.depositCount }}</td>
                        <td class="deposit-value">{{ money(row.depositTotal, true) }}</td>
                        <td class="withdraw-value">{{ row.withdrawCount }}</td>
                        <td class="withdraw-value">{{ money(row.withdrawTotal, true) }}</td>
                        <td :class="row.winLose >= 0 ? 'positive-value' : 'negative-value'">{{ signedMoney(row.winLose) }}</td>
                        <td :class="{ 'unclaim-value': row.unclaimCount > 0 }">{{ row.unclaimCount }}</td>
                        <td :class="{ 'unclaim-value': row.unclaimTotal > 0 }">{{ money(row.unclaimTotal, true) }}</td>
                        <td>{{ row.activeMember }}</td>
                        <td>{{ row.newDeposit }}</td>
                        <td>{{ row.newRegister }}</td>
                        <template v-for="reward in row.rewards" :key="reward.gameId">
                            <td class="reward-cell">{{ reward.count }}</td>
                            <td class="reward-cell">{{ money(reward.total) }}</td>
                        </template>
                    </tr>
                    <tr v-if="rows.length === 0">
                        <td class="empty-row" :colspan="columnCount">{{ t('user.moneyLog.dailyReport.noData') }}</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</template>

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

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

type Period = 'daily' | 'monthly' | 'yearly'

interface DailyReportRow {
    date: string
    depositCount: number
    depositTotal: number
    withdrawCount: number
    withdrawTotal: number
    winLose: number
    unclaimCount: number
    unclaimTotal: number
    activeMember: number
    newDeposit: number
    newRegister: number
    rewards: { gameId: string; count: number; total: number }[]
}

interface DailyReportSourceRow {
    date?: string
    deposit_count?: number | string
    deposit_total?: number | string
    withdraw_count?: number | string
    withdraw_total?: number | string
    win_lose?: number | string
    unclaim_count?: number | string
    unclaim_total?: number | string
    active_member?: number | string
    new_deposit?: number | string
    new_register?: number | string
    [key: string]: number | string | undefined
}

const { t } = useI18n()

const formatDate = (date: Date) => {
    const pad = (value: number) => String(value).padStart(2, '0')
    return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`
}

const now = new Date()
const firstDay = new Date(now.getFullYear(), now.getMonth(), 1)
const lastDay = new Date(now.getFullYear(), now.getMonth() + 1, 0)

const filters = reactive({
    start: formatDate(firstDay),
    end: formatDate(lastDay),
    period: 'daily' as Period,
})

const periods: { value: Period; label: string }[] = [
    { value: 'daily', label: 'user.moneyLog.dailyReport.daily' },
    { value: 'monthly', label: 'user.moneyLog.dailyReport.monthly' },
    { value: 'yearly', label: 'user.moneyLog.dailyReport.yearly' },
]

const games = ref<{ id: string; name: string }[]>([])
const subHeaderGroups = computed(() => ['deposit', 'withdraw', 'unclaim', ...games.value.map((game) => game.id)])
const columnCount = computed(() => 11 + games.value.length * 2)
const tableMinWidth = computed(() => 1596 + games.value.length * 230)
const rows = ref<DailyReportRow[]>([])
const loading = ref(false)

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: DailyReportSourceRow) => ({
            date: String(row.date ?? ''),
            depositCount: toNumber(row.deposit_count),
            depositTotal: toNumber(row.deposit_total),
            withdrawCount: toNumber(row.withdraw_count),
            withdrawTotal: toNumber(row.withdraw_total),
            winLose: toNumber(row.win_lose),
            unclaimCount: toNumber(row.unclaim_count),
            unclaimTotal: toNumber(row.unclaim_total),
            activeMember: toNumber(row.active_member),
            newDeposit: toNumber(row.new_deposit),
            newRegister: toNumber(row.new_register),
            rewards: normalizedGames.map((game) => ({
                gameId: game.id,
                count: toNumber(row[`game_${game.id}_count`]),
                total: toNumber(row[`game_${game.id}_total`]),
            })),
        })),
    }
}

const loadReport = async () => {
    loading.value = true
    try {
        const response = await dailyReport({
            start: filters.start,
            end: filters.end,
            type: filters.period,
        })
        const normalized = normalizeResponse(response.data)
        games.value = normalized.games
        rows.value = normalized.rows
    } finally {
        loading.value = false
    }
}

const changePeriod = (period: Period) => {
    if (filters.period === period) return
    filters.period = period
    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
    return `${number >= 0 ? '+' : '-'}${money(Math.abs(number))}`
}

onMounted(loadReport)
</script>

<style scoped lang="scss">
.daily-report {
    --report-dark: #333;
    --report-border: #ddd;
    --report-strong-border: #999;
    --report-muted: #ddd;
    --report-surface: var(--el-bg-color);
    padding: 20px;
    color: var(--el-text-color-primary);
    font-size: 14px;
}

.report-filter {
    margin-bottom: 20px;
    border: 1px solid var(--report-border);
    background: var(--report-surface);

    header {
        min-height: 37px;
        padding: 9px 8px;
        background: var(--report-dark);
        color: #fff;
        font-weight: 700;
    }
}

.filter-content {
    min-height: 92px;
    padding: 13px;
}

.date-fields {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 5px;

    label {
        font-weight: 700;
        white-space: nowrap;
    }

    :deep(.el-date-editor) {
        width: 200px;
        margin-right: 0;
    }
}

.period-tabs {
    display: flex;
    width: fit-content;
    overflow: hidden;
    border: 1px solid #999;
    border-radius: 3px;

    button {
        width: 100px;
        height: 32px;
        border: 0;
        border-right: 1px solid #999;
        background: var(--el-fill-color-light);
        color: var(--el-text-color-primary);
        cursor: pointer;

        &:last-child {
            border-right: 0;
        }

        &:hover {
            background: var(--el-fill-color);
        }

        &.active {
            background: #bbb;
            color: #000;
        }
    }
}

.report-table-wrap {
    overflow-x: auto;
}

.report-table {
    width: 100%;
    min-width: 2516px;
    border-collapse: collapse;

    th,
    td {
        height: 38px;
        padding: 8px;
        border: 1px solid var(--report-border);
        text-align: left;
        white-space: nowrap;
    }

    thead {
        background: var(--report-dark);
        color: #fff;

        th {
            border-color: #eee;
            background: var(--report-dark);
            font-weight: 700;
            vertical-align: middle;
        }
    }

    tbody td {
        background: var(--report-surface);
        color: var(--el-text-color-primary);
    }

    .date-column,
    .date-cell {
        width: 236px;
    }

    .date-cell,
    .reward-cell {
        border-color: var(--report-strong-border);
        background: var(--report-muted);
        color: #333;
    }

    .single-column {
        min-width: 140px;
    }

    .count-column {
        width: 69px;
    }

    .total-column {
        min-width: 145px;
    }

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

    .deposit-value,
    .positive-value {
        color: #3cb371;
    }

    .withdraw-value,
    .negative-value {
        color: #ff5349;
    }

    .unclaim-value {
        color: #9457c5;
    }

    .empty-row {
        height: 150px;
        background: var(--report-surface);
        color: var(--el-text-color-secondary);
        text-align: center;
    }
}

@at-root html.dark {
    .daily-report {
        --report-dark: #2b2b2b;
        --report-border: var(--el-border-color);
        --report-strong-border: #606266;
        --report-muted: #333;
    }

    .period-tabs button.active {
        background: #555;
        color: #fff;
    }

    .report-table .date-cell,
    .report-table .reward-cell {
        color: var(--el-text-color-primary);
    }
}

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

    .date-fields {
        align-items: flex-start;
        flex-direction: column;
    }
}
</style>
