<template>
    <div class="default-main">
        <el-row v-loading="state.loading">
            <el-col :xs="24" :sm="18">
                <el-alert v-if="state.remark" :title="state.remark" type="info" show-icon />
                <el-form
                    v-if="!state.loading"
                    ref="formRef"
                    :model="state.form"
                    :label-position="'top'"
                    @submit.prevent=""
                    @keyup.enter="onSubmit()"
                >
                    <el-tabs v-model="state.activeTab" type="border-card">
                        <el-tab-pane :label="t('config.gameConfig.form tab label')" name="game_config">
                            <div class="config-form-item" v-for="item in state.configList" :key="item.id">
                                <template v-if="item.config_key === BET_CHIPS_KEY">
                                    <el-form-item :label="resolveFieldLabel(item.config_key)">
                                        <div class="bet-chips-editor">
                                            <div
                                                v-for="slot in CHIP_SLOTS"
                                                :key="slot"
                                                class="bet-chips-row"
                                            >
                                                <span class="bet-chips-key">{{ slot }}</span>
                                                <span class="bet-chips-sep">{{ t('config.gameConfig.bet_chips_colon') }}</span>
                                                <el-input-number
                                                    v-model="state.betChipsAmounts[slot]"
                                                    :min="0.01"
                                                    :max="99999999"
                                                    :precision="2"
                                                    :step="1"
                                                    controls-position="right"
                                                    class="bet-chips-input"
                                                />
                                            </div>
                                        </div>
                                        <div v-if="resolveFieldTip(item.config_key, item.remark)" class="bet-chips-tip">
                                            {{ resolveFieldTip(item.config_key, item.remark) }}
                                        </div>
                                    </el-form-item>
                                    <div class="config-form-item-name">{{ item.config_key }}</div>
                                </template>
                                <template v-else>
                                    <FormItem
                                        :label="resolveFieldLabel(item.config_key)"
                                        :type="resolveFormType(item.value_type)"
                                        v-model="state.form[item.config_key]"
                                        :input-attr="resolveInputAttr(item.value_type)"
                                        :tip="resolveFieldTip(item.config_key, item.remark)"
                                    />
                                    <div class="config-form-item-name">{{ item.config_key }}</div>
                                </template>
                            </div>
                            <el-button @click="onReset">{{ t('Reset') }}</el-button>
                            <el-button v-if="canSave" type="primary" :loading="state.submitLoading" @click="onSubmit()">{{ t('Save') }}</el-button>
                        </el-tab-pane>
                    </el-tabs>
                </el-form>
            </el-col>
        </el-row>
    </div>
</template>

<script setup lang="ts">
import { ElMessage } from 'element-plus'
import { onMounted, reactive, useTemplateRef } from 'vue'
import { useI18n } from 'vue-i18n'
import { baTableApi } from '/@/api/common'
import FormItem from '/@/components/formItem/index.vue'
import createAxios from '/@/utils/axios'
import { auth } from '/@/utils/common'

defineOptions({
    name: 'config/gameConfig',
})

interface GameConfigItem {
    id: number
    config_key: string
    config_value: string
    value_type: 'string' | 'int' | 'decimal' | 'json'
    remark: string
}

const BET_CHIPS_KEY = 'bet_chips'
const CHIP_SLOTS = [1, 2, 3, 4, 5, 6] as const

const defaultBetChipsAmounts = (): Record<number, number> => ({
    1: 1,
    2: 5,
    3: 10,
    4: 25,
    5: 50,
    6: 100,
})

const parseBetChipsFromServer = (raw: string): Record<number, number> => {
    const out = defaultBetChipsAmounts()
    if (!raw || typeof raw !== 'string') {
        return out
    }
    try {
        const o = JSON.parse(raw) as unknown
        if (typeof o !== 'object' || o === null) {
            return out
        }
        const rec = o as Record<string, unknown>
        for (const slot of CHIP_SLOTS) {
            const rawVal = rec[String(slot)]
            const n = Number(rawVal)
            if (Number.isFinite(n) && n > 0) {
                out[slot] = n
            }
        }
    } catch {
        /* 使用内置默认 */
    }
    return out
}

const serializeBetChips = (amounts: Record<number, number>): string => {
    const o: Record<string, string> = {}
    for (const slot of CHIP_SLOTS) {
        const n = Number(amounts[slot])
        o[String(slot)] = Number.isFinite(n) ? n.toFixed(2) : '0.00'
    }
    return JSON.stringify(o)
}

const { t, te } = useI18n()
const formRef = useTemplateRef('formRef')
const api = new baTableApi('/admin/config.GameConfig/')
const excludedConfigKeys = new Set(['period_auto_create_enabled', 'period_manual_create_enabled'])
const canSave =
    auth('save') ||
    auth({ name: '/admin/config/gameConfig', subNodeName: '/admin/config/game_config/save' })

const state: {
    loading: boolean
    submitLoading: boolean
    activeTab: string
    remark: string
    configList: GameConfigItem[]
    form: Record<string, string | number>
    betChipsAmounts: Record<number, number>
} = reactive({
    loading: true,
    submitLoading: false,
    activeTab: 'game_config',
    remark: '',
    configList: [],
    form: {},
    betChipsAmounts: defaultBetChipsAmounts(),
})

const getData = () => {
    state.loading = true
    api.index({ page: 1, limit: 999 }).then((res) => {
        const allList = (res.data.list || []) as GameConfigItem[]
        const list = allList.filter((item) => !excludedConfigKeys.has(item.config_key))
        const displayOrder: Record<string, number> = {
            period_seconds: 10,
            bet_seconds: 20,
            payout_seconds: 30,
        }
        list.sort((a, b) => {
            const orderA = displayOrder[a.config_key] ?? 1000 + a.id
            const orderB = displayOrder[b.config_key] ?? 1000 + b.id
            return orderA - orderB
        })
        state.configList = list
        state.remark = res.data.remark || ''
        const nextForm: Record<string, string | number> = {}
        for (const item of list) {
            if (item.config_key === BET_CHIPS_KEY) {
                state.betChipsAmounts = parseBetChipsFromServer(item.config_value ?? '')
                continue
            }
            if (item.value_type === 'int' || item.value_type === 'decimal') {
                const parsed = Number(item.config_value)
                nextForm[item.config_key] = Number.isNaN(parsed) ? 0 : parsed
                continue
            }
            nextForm[item.config_key] = item.config_value ?? ''
        }
        state.form = nextForm
    }).finally(() => {
        state.loading = false
    })
}

const resolveFormType = (valueType: GameConfigItem['value_type']) => {
    if (valueType === 'json') return 'textarea'
    if (valueType === 'int' || valueType === 'decimal') return 'number'
    return 'string'
}

const resolveInputAttr = (valueType: GameConfigItem['value_type']) => {
    if (valueType === 'json') {
        return { rows: 5 }
    }
    if (valueType === 'decimal') {
        return { precision: 4 }
    }
    return {}
}

const resolveFieldLabel = (configKey: string) => {
    const langKey = `config.gameConfig.field ${configKey}`
    if (te(langKey)) {
        return t(langKey)
    }
    return configKey
}

const resolveFieldTip = (configKey: string, fallbackRemark: string) => {
    const langKey = `config.gameConfig.field_tip ${configKey}`
    if (te(langKey)) {
        return t(langKey)
    }
    return fallbackRemark || ''
}

const validateBetChips = (): boolean => {
    for (const slot of CHIP_SLOTS) {
        const v = state.betChipsAmounts[slot]
        const n = Number(v)
        if (!Number.isFinite(n) || n <= 0) {
            ElMessage.error(t('config.gameConfig.bet_chips_validate_slot', { slot }))
            return false
        }
    }
    return true
}

const onSubmit = async () => {
    const valid = await formRef.value?.validate().catch(() => false)
    if (!valid) return
    if (!validateBetChips()) {
        return
    }

    state.submitLoading = true
    try {
        const items = JSON.parse(JSON.stringify(state.form)) as Record<string, string | number>
        items[BET_CHIPS_KEY] = serializeBetChips(state.betChipsAmounts)
        await createAxios({
            url: '/admin/config.GameConfig/save',
            method: 'post',
            data: {
                items,
            },
            showSuccessMessage: true,
        })
        getData()
    } finally {
        state.submitLoading = false
    }
}

const onReset = () => {
    getData()
}

onMounted(() => {
    getData()
})
</script>

<style scoped lang="scss">
.el-tabs--border-card {
    border: none;
    box-shadow: var(--el-box-shadow-light);
    border-radius: var(--el-border-radius-base);
}
.el-tabs--border-card :deep(.el-tabs__header) {
    background-color: var(--ba-bg-color);
    border-bottom: none;
    border-top-left-radius: var(--el-border-radius-base);
    border-top-right-radius: var(--el-border-radius-base);
}
.el-tabs--border-card :deep(.el-tabs__item.is-active) {
    border: 1px solid transparent;
}
.el-tabs--border-card :deep(.el-tabs__nav-wrap) {
    border-top-left-radius: var(--el-border-radius-base);
    border-top-right-radius: var(--el-border-radius-base);
}
.config-form-item {
    display: flex;
    align-items: flex-start;
    .el-form-item {
        flex: 13;
    }
    .config-form-item-name {
        flex: 3;
        font-size: 13px;
        color: var(--el-text-color-disabled);
        padding-left: 20px;
        opacity: 0;
        padding-top: 28px;
    }
    &:hover .config-form-item-name {
        opacity: 1;
    }
}
.bet-chips-editor {
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: 100%;
    max-width: 420px;
}
.bet-chips-row {
    display: flex;
    align-items: center;
    gap: 6px;
}
.bet-chips-key {
    min-width: 18px;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--el-text-color-regular);
}
.bet-chips-sep {
    color: var(--el-text-color-secondary);
    user-select: none;
}
.bet-chips-input {
    flex: 1;
    min-width: 0;
}
.bet-chips-tip {
    margin-top: 8px;
    font-size: 12px;
    color: var(--el-text-color-secondary);
    line-height: 1.5;
}
</style>
