<template>
    <div class="default-main ba-table-box">
        <el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />

        <TableHeader
            :buttons="['refresh', 'add', 'edit', 'delete', 'comSearch', 'quickSearch', 'columnDisplay']"
            :quick-search-placeholder="t('Quick search placeholder', { fields: t('channel.quick Search Fields') })"
        ></TableHeader>
        <div class="channel-top-actions">
            <div class="channel-stats-cards">
                <el-card shadow="never" class="channel-stat-card">
                    <div class="label">{{ t('channel.settle_stats_channel_total') }}</div>
                    <div class="value">{{ settleStats.channel_total }}</div>
                </el-card>
                <el-card shadow="never" class="channel-stat-card">
                    <div class="label">{{ t('channel.settle_stats_enabled') }}</div>
                    <div class="value">{{ settleStats.enabled_count }}</div>
                </el-card>
                <el-card shadow="never" class="channel-stat-card">
                    <div class="label">{{ t('channel.settle_stats_pending_dividend') }}</div>
                    <div class="value">{{ settleStats.carryover_positive_count }}</div>
                </el-card>
                <el-card shadow="never" class="channel-stat-card">
                    <div class="label">{{ t('channel.settle_stats_pending_amount') }}</div>
                    <div class="value">{{ settleStats.carryover_positive_total }}</div>
                </el-card>
            </div>
            <div class="channel-action-row">
                <el-radio-group v-model="settleFilterMode" size="small" @change="onSettleFilterChange">
                    <el-radio-button label="all">{{ t('channel.settle_filter_all') }}</el-radio-button>
                    <el-radio-button label="with_balance">{{ t('channel.settle_filter_with_balance') }}</el-radio-button>
                    <el-radio-button label="no_balance">{{ t('channel.settle_filter_no_balance') }}</el-radio-button>
                    <el-radio-button label="enabled">{{ t('channel.settle_filter_enabled') }}</el-radio-button>
                    <el-radio-button label="disabled">{{ t('channel.settle_filter_disabled') }}</el-radio-button>
                </el-radio-group>
                <el-button v-if="adminInfo.super && auth('batchSettlePending')" type="warning" @click="onBatchSettlePending">
                    {{ t('channel.batch_settle_pending') }}
                </el-button>
            </div>
        </div>

        <Table ref="tableRef"></Table>

        <PopupForm />

        <el-dialog
            class="ba-operate-dialog manual-settle-dialog"
            :close-on-click-modal="false"
            :model-value="manualSettle.visible"
            width="860px"
            @close="closeManualSettleDialog"
        >
            <template #header>
                <div class="title">{{ t('channel.manual_settle') }}</div>
            </template>
            <div v-loading="manualSettle.previewLoading" class="manual-settle-dialog-body">
                <el-form :model="manualSettle.form" label-width="140px" class="manual-settle-form">
                    <el-form-item :label="t('channel.manual_settle_settlement_no')">
                        <el-input v-model="manualSettle.form.settlement_no" readonly />
                    </el-form-item>
                    <el-form-item :label="t('channel.manual_settle_period_start')">
                        <el-input v-model="manualSettle.form.period_start_at" readonly />
                    </el-form-item>
                    <el-form-item :label="t('channel.manual_settle_period_end')">
                        <el-input v-model="manualSettle.form.period_end_at" readonly />
                    </el-form-item>
                    <el-form-item :label="t('channel.manual_settle_total_bet')">
                        <el-input v-model="manualSettle.form.total_bet_amount" readonly />
                    </el-form-item>
                    <el-form-item :label="t('channel.manual_settle_total_payout')">
                        <el-input v-model="manualSettle.form.total_payout_amount" readonly />
                    </el-form-item>
                    <el-form-item :label="t('channel.manual_settle_platform_profit')">
                        <el-input v-model="manualSettle.form.platform_profit_amount" readonly />
                    </el-form-item>
                    <el-form-item :label="t('channel.manual_settle_commission_rate')">
                        <el-input v-model="manualSettle.form.commission_rate" readonly />
                    </el-form-item>
                    <el-form-item :label="t('channel.manual_settle_calc_base')">
                        <el-input v-model="manualSettle.form.calc_base_amount" readonly />
                    </el-form-item>
                    <el-form-item :label="t('channel.manual_settle_commission_amount')">
                        <el-input v-model="manualSettle.form.commission_amount" readonly />
                    </el-form-item>
                    <el-form-item :label="t('channel.share_config')" class="manual-settle-form-item-full">
                        <el-table :data="manualSettle.form.commission_split" border size="small" class="w100" max-height="220">
                            <el-table-column prop="admin_username" :label="t('channel.admin__username')" min-width="100" />
                            <el-table-column prop="share_rate" :label="t('channel.share_rate_percent')" min-width="90">
                                <template #default="scope">{{ scope.row.share_rate }}%</template>
                            </el-table-column>
                            <el-table-column prop="commission_amount" :label="t('channel.manual_settle_commission_amount')" min-width="110" />
                        </el-table>
                    </el-form-item>
                    <el-form-item :label="t('channel.manual_settle_remark')" class="manual-settle-form-item-full">
                        <el-input v-model="manualSettle.form.remark" type="textarea" :rows="2" />
                    </el-form-item>
                </el-form>
            </div>
            <template #footer>
                <div class="manual-settle-footer">
                    <el-button @click="closeManualSettleDialog">{{ t('Cancel') }}</el-button>
                    <el-button type="primary" :disabled="manualSettle.previewLoading" :loading="manualSettle.loading" @click="submitManualSettle">
                        {{ t('channel.manual_settle_submit') }}
                    </el-button>
                </div>
            </template>
        </el-dialog>

        <el-dialog class="ba-operate-dialog" :close-on-click-modal="false" :model-value="shareDialog.visible" @close="closeShareDialog">
            <template #header>
                <div class="title">{{ t('channel.share_config_title') }}</div>
            </template>
            <div v-loading="shareDialog.loading" class="manual-settle-dialog-body">
                <el-alert type="info" :closable="false" show-icon class="mb-12">
                    {{ t('channel.share_config_tip') }}
                </el-alert>
                <el-table :data="shareDialog.list" border size="small">
                    <el-table-column :label="t('channel.admin_group_names')" min-width="260">
                        <template #default="scope">
                            <span v-if="scope.row.role_group_name" class="share-group-single">{{ scope.row.role_group_name }}</span>
                            <span v-else class="share-group-empty">-</span>
                        </template>
                    </el-table-column>
                    <el-table-column prop="username" :label="t('channel.admin__username')" min-width="120" />
                    <el-table-column :label="t('channel.status')" width="120">
                        <template #default="scope">
                            <el-switch v-model="scope.row.status" :active-value="1" :inactive-value="0" />
                        </template>
                    </el-table-column>
                    <el-table-column :label="t('channel.share_rate_percent')" min-width="180">
                        <template #default="scope">
                            <el-input-number
                                v-model="scope.row.share_rate"
                                :disabled="scope.row.status !== 1"
                                :min="0"
                                :max="100"
                                :step="0.01"
                                :precision="2"
                                class="w100"
                            />
                        </template>
                    </el-table-column>
                </el-table>
                <div class="share-total-row">
                    <span>{{ t('channel.share_total_enabled') }}: </span>
                    <el-tag :type="shareEnabledTotal === '100.00' ? 'success' : 'danger'">{{ shareEnabledTotal }}%</el-tag>
                </div>
            </div>
            <template #footer>
                <el-button @click="closeShareDialog">{{ t('Cancel') }}</el-button>
                <el-button type="primary" :loading="shareDialog.saving" @click="saveShareDialog">{{ t('Save') }}</el-button>
            </template>
        </el-dialog>
    </div>
</template>

<script setup lang="ts">
import { computed, onMounted, provide, reactive, ref, useTemplateRef } from 'vue'
import { useI18n } from 'vue-i18n'
import { ElMessage } from 'element-plus'
import PopupForm from './popupForm.vue'
import { baTableApi } from '/@/api/common'
import { auth } from '/@/utils/common'
import { useAdminInfo } from '/@/stores/adminInfo'
import { defaultOptButtons } from '/@/components/table'
import TableHeader from '/@/components/table/header/index.vue'
import Table from '/@/components/table/index.vue'
import baTableClass from '/@/utils/baTable'
import createAxios from '/@/utils/axios'

defineOptions({
    name: 'channel',
})

const { t } = useI18n()
const adminInfo = useAdminInfo()
const tableRef = useTemplateRef('tableRef')
let optButtons: OptButton[] = [
    {
        render: 'tipButton',
        name: 'shareConfig',
        title: 'channel.share_config',
        text: '',
        type: 'primary',
        icon: 'el-icon-Setting',
        class: 'table-row-share-config',
        disabledTip: false,
        display: () => auth('edit'),
        click: (row: TableRow) => {
            void openShareDialog(row)
        },
    },
    {
        render: 'tipButton',
        name: 'manualSettle',
        title: 'channel.manual_settle',
        text: '',
        type: 'warning',
        icon: 'el-icon-Clock',
        class: 'table-row-manual-settle',
        disabledTip: false,
        display: () => adminInfo.super && auth('manualSettle'),
        click: (row: TableRow) => {
            void openManualSettleDialog(row)
        },
    },
]
optButtons = optButtons.concat(defaultOptButtons(['edit', 'delete']))
const formatAmountInt = (_row: any, _column: any, cellValue: number | string | null) => {
    if (cellValue === null || cellValue === undefined || cellValue === '') return '-'
    const num = Number(cellValue)
    if (Number.isNaN(num)) return '-'
    return `${num}`
}
const formatSettleDay = (row: anyObj) => {
    if (row.settle_cycle === 'weekly') {
        return t(`channel.weekday ${row.settle_weekday ?? 1}`)
    }
    if (row.settle_cycle === 'monthly') {
        return `${row.settle_monthday ?? 1}${t('channel.day_suffix')}`
    }
    return t('channel.settle_day_daily')
}

const manualSettle = reactive({
    visible: false,
    loading: false,
    previewLoading: false,
    channelId: 0,
    form: {
        settlement_no: '',
        period_start_at: '',
        period_end_at: '',
        total_bet_amount: '',
        total_payout_amount: '',
        platform_profit_amount: '',
        commission_rate: '',
        calc_base_amount: '',
        commission_amount: '',
        commission_split: [] as Array<{ admin_id: number; admin_username: string; share_rate: string; commission_amount: string }>,
        remark: '',
    },
})

const shareDialog = reactive({
    visible: false,
    loading: false,
    saving: false,
    channelId: 0,
    list: [] as Array<{ admin_id: number; username: string; role_group_name: string; role_level: number; status: number; share_rate: number | null }>,
})
const settleFilterMode = ref<'all' | 'with_balance' | 'no_balance' | 'enabled' | 'disabled'>('all')
const settleStats = reactive({
    channel_total: 0,
    enabled_count: 0,
    disabled_count: 0,
    carryover_positive_count: 0,
    carryover_total: '0.00',
    carryover_positive_total: '0.00',
})

const shareEnabledTotal = computed(() => {
    let sum = 0
    for (const row of shareDialog.list) {
        if (row.status === 1) {
            const n = Number(row.share_rate ?? 0)
            if (Number.isFinite(n)) {
                sum += n
            }
        }
    }
    return sum.toFixed(2)
})

const closeShareDialog = () => {
    shareDialog.visible = false
    shareDialog.channelId = 0
    shareDialog.list = []
}

const openShareDialog = async (row: TableRow) => {
    shareDialog.channelId = Number(row.id || 0)
    shareDialog.visible = true
    shareDialog.loading = true
    try {
        const res = await createAxios(
            {
                url: '/admin/channel/channelAdminShareList',
                method: 'get',
                params: { id: row.id },
            },
            { showErrorMessage: true }
        )
        if (res.code !== 1 || !res.data) {
            closeShareDialog()
            return
        }
        const list = Array.isArray(res.data.list) ? res.data.list : []
        shareDialog.list = list.map((item: anyObj) => {
            const rate = item.share_rate
            return {
                admin_id: Number(item.admin_id || 0),
                username: String(item.username || ''),
                role_group_name: String(item.role_group_name || ''),
                role_level: Number(item.role_level ?? 9999),
                status: Number(item.status ?? 1) === 1 ? 1 : 0,
                share_rate: rate === null || rate === undefined || rate === '' ? null : Number(rate),
            }
        })
    } finally {
        shareDialog.loading = false
    }
}

const saveShareDialog = async () => {
    if (!shareDialog.channelId) {
        return
    }
    if (shareEnabledTotal.value !== '100.00') {
        ElMessage.error(t('channel.share_total_must_100'))
        return
    }
    shareDialog.saving = true
    try {
        await createAxios(
            {
                url: '/admin/channel/saveChannelAdminShare',
                method: 'post',
                data: {
                    id: shareDialog.channelId,
                    list: shareDialog.list.map((row) => ({
                        admin_id: row.admin_id,
                        status: row.status,
                        share_rate: Number(row.share_rate || 0).toFixed(2),
                    })),
                },
            },
            { showSuccessMessage: true }
        )
        closeShareDialog()
    } finally {
        shareDialog.saving = false
    }
}

const resetManualSettleForm = () => {
    manualSettle.form.settlement_no = ''
    manualSettle.form.period_start_at = ''
    manualSettle.form.period_end_at = ''
    manualSettle.form.total_bet_amount = ''
    manualSettle.form.total_payout_amount = ''
    manualSettle.form.platform_profit_amount = ''
    manualSettle.form.commission_rate = ''
    manualSettle.form.calc_base_amount = ''
    manualSettle.form.commission_amount = ''
    manualSettle.form.commission_split = []
    manualSettle.form.remark = ''
}

const closeManualSettleDialog = () => {
    manualSettle.visible = false
    resetManualSettleForm()
}

const openManualSettleDialog = async (row: TableRow) => {
    manualSettle.channelId = row.id
    resetManualSettleForm()
    manualSettle.visible = true
    manualSettle.previewLoading = true
    try {
        const res = await createAxios(
            {
                url: '/admin/channel/manualSettlePreview',
                method: 'get',
                params: { id: row.id },
            },
            { showErrorMessage: true }
        )
        if (res.code !== 1 || !res.data) {
            manualSettle.visible = false
            return
        }
        const d = res.data as anyObj
        manualSettle.form.settlement_no = d.settlement_no ?? ''
        manualSettle.form.period_start_at = d.period_start_at ?? ''
        manualSettle.form.period_end_at = d.period_end_at ?? ''
        manualSettle.form.total_bet_amount = d.total_bet_amount ?? ''
        manualSettle.form.total_payout_amount = d.total_payout_amount ?? ''
        manualSettle.form.platform_profit_amount = d.platform_profit_amount ?? ''
        manualSettle.form.commission_rate = d.commission_rate ?? ''
        manualSettle.form.calc_base_amount = d.calc_base_amount ?? ''
        manualSettle.form.commission_amount = d.commission_amount ?? ''
        manualSettle.form.commission_split = Array.isArray(d.commission_split) ? d.commission_split : []
        manualSettle.form.remark = `${t('channel.manual_settle')}-CH${row.id}`
    } catch {
        manualSettle.visible = false
    } finally {
        manualSettle.previewLoading = false
    }
}

const submitManualSettle = async () => {
    if (!manualSettle.channelId) return
    manualSettle.loading = true
    try {
        await createAxios(
            {
                url: '/admin/channel/manualSettle',
                method: 'post',
                data: {
                    id: manualSettle.channelId,
                    remark: manualSettle.form.remark,
                },
            },
            { showSuccessMessage: true }
        )
        closeManualSettleDialog()
        baTable.onTableHeaderAction('refresh', { event: 'manual-settle' })
    } finally {
        manualSettle.loading = false
    }
}

const onBatchSettlePending = async () => {
    await createAxios(
        {
            url: '/admin/channel/batchSettlePending',
            method: 'post',
        },
        { showSuccessMessage: true }
    )
    await loadSettleStats()
    baTable.onTableHeaderAction('refresh', { event: 'batch-settle' })
}

const onSettleFilterChange = () => {
    baTable.getData()
}

const loadSettleStats = async () => {
    const res = await createAxios({ url: '/admin/channel/settleStats', method: 'get' })
    if (res.code !== 1 || !res.data) {
        return
    }
    settleStats.channel_total = Number(res.data.channel_total ?? 0)
    settleStats.enabled_count = Number(res.data.enabled_count ?? 0)
    settleStats.disabled_count = Number(res.data.disabled_count ?? 0)
    settleStats.carryover_positive_count = Number(res.data.carryover_positive_count ?? 0)
    settleStats.carryover_total = String(res.data.carryover_total ?? '0.00')
    settleStats.carryover_positive_total = String(res.data.carryover_positive_total ?? '0.00')
}

const baTable = new baTableClass(
    new baTableApi('/admin/channel/'),
    {
        pk: 'id',
        column: [
            { type: 'selection', align: 'center', operator: false },
            { label: t('channel.id'), prop: 'id', align: 'center', width: 70, operator: 'RANGE', sortable: 'custom' },
            {
                label: t('channel.code'),
                prop: 'code',
                align: 'center',
                operatorPlaceholder: t('Fuzzy query'),
                sortable: false,
                operator: 'LIKE',
            },
            {
                label: t('channel.name'),
                prop: 'name',
                align: 'center',
                operatorPlaceholder: t('Fuzzy query'),
                sortable: false,
                operator: 'LIKE',
            },
            {
                label: t('channel.agent_mode'),
                prop: 'agent_mode',
                align: 'center',
                minWidth: 120,
                operator: 'eq',
                sortable: false,
                render: 'tag',
                custom: {
                    turnover: 'primary',
                    affiliate: 'success',
                },
                replaceValue: {
                    turnover: t('channel.agent_mode turnover'),
                    affiliate: t('channel.agent_mode affiliate'),
                },
            },
            {
                label: t('channel.carryover_balance'),
                prop: 'carryover_balance',
                align: 'center',
                minWidth: 130,
                sortable: false,
                operator: 'RANGE',
                formatter: formatAmountInt,
            },
            {
                label: t('channel.affiliate_contract_no'),
                prop: 'affiliate_contract_no',
                align: 'center',
                minWidth: 140,
                sortable: false,
                operator: 'LIKE',
                operatorPlaceholder: t('Fuzzy query'),
                showOverflowTooltip: true,
            },
            {
                label: t('channel.settle_cycle'),
                prop: 'settle_cycle',
                align: 'center',
                width: 110,
                operator: 'eq',
                sortable: false,
                render: 'tag',
                custom: { daily: 'info', weekly: 'primary', monthly: 'success' },
                replaceValue: {
                    daily: t('channel.settle_cycle daily'),
                    weekly: t('channel.settle_cycle weekly'),
                    monthly: t('channel.settle_cycle monthly'),
                },
            },
            {
                label: t('channel.settle_weekday'),
                prop: 'settle_day',
                align: 'center',
                width: 110,
                operator: false,
                sortable: false,
                formatter: (row: anyObj) => formatSettleDay(row),
            },
            {
                label: t('channel.settle_time'),
                prop: 'settle_time',
                align: 'center',
                width: 100,
                operator: 'LIKE',
                sortable: false,
            },
            {
                label: t('channel.affiliate_effective_start_at'),
                prop: 'affiliate_effective_start_at',
                align: 'center',
                render: 'datetime',
                operator: 'RANGE',
                comSearchRender: 'datetime',
                sortable: 'custom',
                width: 160,
                timeFormat: 'yyyy-mm-dd hh:MM:ss',
            },
            {
                label: t('channel.affiliate_effective_end_at'),
                prop: 'affiliate_effective_end_at',
                align: 'center',
                render: 'datetime',
                operator: 'RANGE',
                comSearchRender: 'datetime',
                sortable: 'custom',
                width: 160,
                timeFormat: 'yyyy-mm-dd hh:MM:ss',
            },
            {
                label: t('channel.user_count'),
                prop: 'user_count',
                align: 'center',
                sortable: false,
                operator: 'RANGE',
            },
            {
                label: t('channel.profit_amount'),
                prop: 'profit_amount',
                align: 'center',
                minWidth: 110,
                sortable: false,
                operator: 'RANGE',
                formatter: formatAmountInt,
            },
            {
                label: t('channel.total_profit_amount'),
                prop: 'total_profit_amount',
                align: 'center',
                minWidth: 110,
                sortable: false,
                operator: 'RANGE',
                formatter: formatAmountInt,
            },
            {
                label: t('channel.commission_pool_amount'),
                prop: 'commission_pool_amount',
                align: 'center',
                minWidth: 110,
                sortable: false,
                operator: 'RANGE',
                formatter: formatAmountInt,
            },
            {
                label: t('channel.status'),
                prop: 'status',
                align: 'center',
                operator: 'eq',
                sortable: false,
                render: 'switch',
                replaceValue: { '0': t('channel.status 0'), '1': t('channel.status 1') },
            },
            {
                label: t('channel.create_time'),
                prop: 'create_time',
                align: 'center',
                render: 'datetime',
                operator: 'RANGE',
                comSearchRender: 'datetime',
                sortable: 'custom',
                width: 160,
                timeFormat: 'yyyy-mm-dd hh:MM:ss',
            },
            {
                label: t('channel.update_time'),
                prop: 'update_time',
                align: 'center',
                render: 'datetime',
                operator: 'RANGE',
                comSearchRender: 'datetime',
                sortable: 'custom',
                width: 160,
                timeFormat: 'yyyy-mm-dd hh:MM:ss',
            },
            { label: t('Operate'), align: 'center', width: 120, render: 'buttons', buttons: optButtons, operator: false, fixed: 'right' },
        ],
        dblClickNotEditColumn: [undefined, 'status'],
    },
    {
        defaultItems: {
            status: '1',
            agent_mode: 'turnover',
            settle_cycle: 'weekly',
            settle_weekday: 1,
            settle_monthday: 1,
            settle_time: '02:00:00',
        },
    }
)

baTable.before.getData = () => {
    const filter = baTable.table.filter || {}
    const searchRaw = filter.search
    const search = Array.isArray(searchRaw) ? searchRaw.filter((item: any) => item && item.field !== 'carryover_balance' && item.field !== 'status') : []
    if (settleFilterMode.value === 'with_balance') {
        search.push({ field: 'carryover_balance', operator: 'gt', val: 0 })
    } else if (settleFilterMode.value === 'no_balance') {
        search.push({ field: 'carryover_balance', operator: 'elt', val: 0 })
    } else if (settleFilterMode.value === 'enabled') {
        search.push({ field: 'status', operator: 'eq', val: 1 })
    } else if (settleFilterMode.value === 'disabled') {
        search.push({ field: 'status', operator: 'eq', val: 0 })
    }
    filter.search = search
    baTable.table.filter = filter
}

baTable.after.getData = () => {
    void loadSettleStats()
}

provide('baTable', baTable)

onMounted(() => {
    baTable.table.ref = tableRef.value
    baTable.mount()
    baTable.getData()?.then(() => {
        baTable.initSort()
        baTable.dragSort()
    })
    void loadSettleStats()
})
</script>

<style scoped lang="scss">
.mb-12 {
    margin-bottom: 12px;
}

.share-total-row {
    margin-top: 12px;
    display: flex;
    align-items: center;
    gap: 8px;
}

.share-group-single {
    font-size: 12px;
    line-height: 1.4;
    color: var(--el-text-color-regular);
}

.share-group-empty {
    color: var(--el-text-color-placeholder);
}

.channel-top-actions {
    margin: 8px 0 12px;
}

.channel-stats-cards {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 10px;
    margin-bottom: 10px;
}

.channel-stat-card .label {
    font-size: 12px;
    color: var(--el-text-color-secondary);
}

.channel-stat-card .value {
    margin-top: 6px;
    font-size: 20px;
    font-weight: 600;
    color: var(--el-text-color-primary);
}

.channel-action-row {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    align-items: center;
    flex-wrap: wrap;
}

.manual-settle-dialog-body {
    max-height: min(70vh, 680px);
    overflow: auto;
    padding-right: 2px;
}

.manual-settle-form {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 16px;
}

.manual-settle-form :deep(.el-form-item) {
    margin-bottom: 12px;
}

.manual-settle-form-item-full {
    grid-column: 1 / -1;
}

.manual-settle-footer {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

@media (max-width: 900px) {
    .channel-stats-cards {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .manual-settle-form {
        grid-template-columns: 1fr;
    }
}
</style>
