<template>
  <el-dialog
    v-model="visible"
    :title="dialogType === 'add' ? $t('page.form.dialogTitleAdd') : $t('page.form.dialogTitleEdit')"
    width="600px"
    align-center
    :close-on-click-modal="false"
    @close="handleClose"
  >
    <el-form ref="formRef" :model="formData" :rules="rules" label-width="120px">
      <el-form-item :label="$t('page.form.username')" prop="username">
        <el-input v-model="formData.username" :placeholder="$t('page.form.placeholderUsername')" />
      </el-form-item>
      <el-form-item :label="$t('page.form.nickname')" prop="name">
        <el-input v-model="formData.name" :placeholder="$t('page.form.placeholderNickname')" />
      </el-form-item>
      <el-form-item :label="$t('page.form.phone')" prop="phone">
        <el-input
          v-model="formData.phone"
          :placeholder="$t('page.form.placeholderPhone')"
          clearable
          maxlength="20"
          show-word-limit
        />
      </el-form-item>
      <el-form-item :label="$t('page.form.password')" prop="password" :rules="passwordRules">
        <el-input
          v-model="formData.password"
          type="password"
          :placeholder="$t('page.form.placeholderPasswordEdit')"
          show-password
        />
      </el-form-item>
      <el-form-item :label="$t('page.form.status')" prop="status">
        <sa-switch v-model="formData.status" />
      </el-form-item>
      <el-form-item :label="$t('page.form.adminId')" prop="admin_id">
        <el-tree-select
          v-if="useAdminTreeSelect"
          v-model="formData.admin_id"
          :data="systemUserTreeOptions"
          :props="systemUserTreeProps"
          :placeholder="$t('page.form.placeholderAdminTree')"
          clearable
          filterable
          check-strictly
          style="width: 100%"
          :loading="systemUserOptionsLoading"
        />
        <el-select
          v-else
          v-model="formData.admin_id"
          :placeholder="$t('page.form.placeholderAdmin')"
          clearable
          filterable
          style="width: 100%"
          :loading="systemUserOptionsLoading"
        >
          <el-option
            v-for="item in systemUserOptions"
            :key="item.id"
            :label="item.label || item.username || `#${item.id}`"
            :value="item.id"
          />
        </el-select>
      </el-form-item>
      <el-form-item :label="$t('page.form.coin')" prop="coin">
        <el-input-number
          v-model="formData.coin"
          :min="0"
          :precision="2"
          :disabled="dialogType === 'add'"
          :placeholder="$t('page.form.placeholderCoinAdd')"
          style="width: 100%"
        />
      </el-form-item>
      <!-- lottery_config_id：空 = 自定义权重，否则 = DiceLotteryConfig.id；选择后该配置的五个 weight 会写入下方 player.*_weight -->
      <el-form-item :label="$t('page.form.lotteryPoolConfig')" prop="lottery_config_id">
        <el-select
          v-model="formData.lottery_config_id"
          :placeholder="$t('page.form.placeholderLotteryPool')"
          clearable
          filterable
          style="width: 100%"
          :loading="lotteryConfigLoading"
          @change="onLotteryConfigChange"
        >
          <el-option
            v-for="item in lotteryConfigOptions"
            :key="item.id"
            :label="lotteryPoolOptionLabel(item)"
            :value="item.id"
          />
        </el-select>
      </el-form-item>
      <!-- 当前选中的 DiceLotteryConfig 数据展示 -->
      <el-form-item v-if="currentLotteryConfig" :label="$t('page.form.currentConfig')" class="current-config-block">
        <div class="current-lottery-config">
          <div class="config-row">
            <span class="config-label">{{ $t('page.form.configLabelPoolName') }}：</span>
            <span>{{ lotteryPoolDisplayLabel(currentLotteryConfig) }}</span>
          </div>
          <div class="config-row">
            <span class="config-label">{{ $t('page.form.configLabelCode') }}：</span>
            <span>{{ currentLotteryConfig.name ?? '-' }}</span>
          </div>
          <div class="config-row">
            <span class="config-label">{{ $t('page.form.configLabelWeights') }}：</span>
            <span>{{ currentLotteryConfigWeightsText }}</span>
          </div>
          <div v-if="currentLotteryConfig.remark" class="config-row">
            <span class="config-label">{{ $t('page.form.configLabelRemark') }}：</span>
            <span>{{ currentLotteryConfig.remark }}</span>
          </div>
        </div>
      </el-form-item>
      <!-- lottery_config_id 为空时自定义权重可编辑；有值时来自所选 DiceLotteryConfig，仅展示不可编辑 -->
      <el-form-item :label="$t('page.form.t1Weight')" prop="t1_weight">
        <el-slider
          v-model="formData.t1_weight"
          :min="0"
          :max="100"
          :step="0.01"
          show-input
          :disabled="!isLotteryConfigEmpty()"
        />
      </el-form-item>
      <el-form-item :label="$t('page.form.t2Weight')" prop="t2_weight">
        <el-slider
          v-model="formData.t2_weight"
          :min="0"
          :max="100"
          :step="0.01"
          show-input
          :disabled="!isLotteryConfigEmpty()"
        />
      </el-form-item>
      <el-form-item :label="$t('page.form.t3Weight')" prop="t3_weight">
        <el-slider
          v-model="formData.t3_weight"
          :min="0"
          :max="100"
          :step="0.01"
          show-input
          :disabled="!isLotteryConfigEmpty()"
        />
      </el-form-item>
      <el-form-item :label="$t('page.form.t4Weight')" prop="t4_weight">
        <el-slider
          v-model="formData.t4_weight"
          :min="0"
          :max="100"
          :step="0.01"
          show-input
          :disabled="!isLotteryConfigEmpty()"
        />
      </el-form-item>
      <el-form-item :label="$t('page.form.t5Weight')" prop="t5_weight">
        <el-slider
          v-model="formData.t5_weight"
          :min="0"
          :max="100"
          :step="0.01"
          show-input
          :disabled="!isLotteryConfigEmpty()"
        />
      </el-form-item>
      <el-form-item v-if="isLotteryConfigEmpty()">
        <div class="text-gray-500 text-sm">
          {{ $t('page.form.weightsSumHint') }}<span :class="Math.abs(weightsSum - 100) > 0.01 ? 'text-red-500' : ''">{{
            weightsSum
          }}</span
          >{{ $t('page.form.weightsSumUnit') }}
        </div>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="handleClose">{{ $t('common.cancel') }}</el-button>
      <el-button type="primary" @click="handleSubmit">{{ $t('table.form.submit') }}</el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
  import api from '../../../api/player/index'
  import lotteryConfigApi, {
    parseLotteryPoolConfigOption,
    type LotteryPoolConfigOption
  } from '../../../api/lottery_pool_config/index'
  import { useI18n } from 'vue-i18n'
  import {
    lotteryPoolDisplayLabel,
    lotteryPoolOptionLabel,
    type LotteryPoolOption
  } from '@/views/plugin/dice/utils/lotteryPoolDisplay'
  import { getChannelDeptRequestParams, withChannelDeptParams } from '@/composables/useChannelDeptScope'
  import { isSuperAdminUser } from '@/utils/channelLayout'
  import { ElMessage } from 'element-plus'
  import type { FormInstance, FormRules } from 'element-plus'

  const { t } = useI18n()
  const WEIGHT_FIELDS = ['t1_weight', 't2_weight', 't3_weight', 't4_weight', 't5_weight'] as const

  interface Props {
    modelValue: boolean
    dialogType: string
    data?: Record<string, any>
  }

  interface Emits {
    (e: 'update:modelValue', value: boolean): void
    (e: 'success'): void
  }

  const props = withDefaults(defineProps<Props>(), {
    modelValue: false,
    dialogType: 'add',
    data: undefined
  })

  const emit = defineEmits<Emits>()

  const formRef = ref<FormInstance>()

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

  const weightsSum = computed(() => {
    return WEIGHT_FIELDS.reduce((sum, key) => sum + Number(formData[key] ?? 0), 0)
  })

  /** 当前彩金池配置的 T1～T5 权重展示文案 */
  const currentLotteryConfigWeightsText = computed(() => {
    const c = currentLotteryConfig.value
    if (!c) return '-'
    const t1 = c.t1_weight ?? 0
    const t2 = c.t2_weight ?? 0
    const t3 = c.t3_weight ?? 0
    const t4 = c.t4_weight ?? 0
    const t5 = c.t5_weight ?? 0
    return `${t1}% / ${t2}% / ${t3}% / ${t4}% / ${t5}%`
  })

  /** 新增时密码必填，编辑时选填 */
  const passwordRules = computed(() =>
    props.dialogType === 'add'
      ? [{ required: true, message: t('page.form.rulePasswordRequired'), trigger: 'blur' }]
      : []
  )

  const rules = computed<FormRules>(() => ({
    username: [{ required: true, message: t('page.form.ruleUsernameRequired'), trigger: 'blur' }],
    name: [{ required: true, message: t('page.form.ruleNicknameRequired'), trigger: 'blur' }],
    phone: [{ required: true, message: t('page.form.rulePhoneRequired'), trigger: 'blur' }],
    status: [{ required: true, message: t('page.form.ruleStatusRequired'), trigger: 'blur' }],
    coin: [{ required: true, message: t('page.form.ruleCoinRequired'), trigger: 'blur' }]
  }))

  const initialFormData = {
    id: null as number | null,
    username: '',
    name: '',
    phone: '',
    password: '',
    status: 1 as number,
    /** 所属后台管理员 ID（SystemUser.id） */
    admin_id: null as number | null,
    coin: 0 as number,
    /** 彩金池配置 ID：空 = 自定义权重，否则 = DiceLotteryConfig.id */
    lottery_config_id: null as number | null,
    t1_weight: 0 as number,
    t2_weight: 0 as number,
    t3_weight: 0 as number,
    t4_weight: 0 as number,
    t5_weight: 0 as number
  }

  const formData = reactive({ ...initialFormData })

  /** 彩金池配置下拉选项（DiceLotteryConfig id、name） */
  const lotteryConfigOptions = ref<LotteryPoolOption[]>([])
  /** 彩金池选项加载中 */
  const lotteryConfigLoading = ref(false)
  /** 后台管理员下拉选项（SystemUser） */
  const systemUserOptions = ref<
    Array<{ id: number; username: string; realname: string; label: string }>
  >([])
  /** 超管：按渠道分组的管理员树 */
  const systemUserTreeOptions = ref<
    Array<{
      id: number | string
      label: string
      disabled?: boolean
      children?: Array<{ id: number; username: string; realname: string; label: string }>
    }>
  >([])
  const useAdminTreeSelect = computed(() => isSuperAdminUser())
  const systemUserTreeProps = {
    label: 'label',
    value: 'id',
    children: 'children',
    disabled: 'disabled'
  }
  /** 管理员选项加载中 */
  const systemUserOptionsLoading = ref(false)
  /** 当前选中的 DiceLotteryConfig 完整数据（用于展示） */
  const currentLotteryConfig = ref<LotteryPoolConfigOption | null>(null)

  function isRecord(value: unknown): value is Record<string, unknown> {
    return value !== null && typeof value === 'object'
  }

  function extractReadPayload(res: unknown): Record<string, unknown> | null {
    if (!isRecord(res)) {
      return null
    }
    if (isRecord(res.data)) {
      return res.data
    }
    return res
  }

  function lotteryConfigTypeText(name: unknown): string {
    const n = String(name ?? '')
    if (n === 'default') return t('page.form.configTypeDefault')
    if (n === 'killScore') return t('page.form.configTypeKillScore')
    if (n === 'up') return t('page.form.configTypeUp')
    return n || '-'
  }

  /** 是否为空/自定义权重（未选彩金池或选 0） */
  function isLotteryConfigEmpty(): boolean {
    const v = formData.lottery_config_id
    return v == null || v === 0
  }

  /** 将彩金池配置的 T1–T5 写入表单（绑定彩金池时展示与提交均以池为准） */
  function applyPoolWeightsToForm(cfg: LotteryPoolConfigOption) {
    WEIGHT_FIELDS.forEach((key) => {
      ;(formData as Record<string, number>)[key] = Number(cfg[key] ?? 0)
    })
  }

  /** 根据当前 lottery_config_id 加载 DiceLotteryConfig，并将五个权重写入当前 player.*_weight */
  async function loadCurrentLotteryConfig() {
    const id = formData.lottery_config_id
    if (id == null || id === 0) {
      currentLotteryConfig.value = null
      return
    }
    try {
      const res = await lotteryConfigApi.read(id)
      const payload = extractReadPayload(res)
      if (payload) {
        const row = parseLotteryPoolConfigOption(payload)
        currentLotteryConfig.value = row
        applyPoolWeightsToForm(row)
      } else {
        currentLotteryConfig.value = null
      }
    } catch {
      currentLotteryConfig.value = null
    }
  }

  watch(
    () => currentLotteryConfig.value,
    (cfg) => {
      if (cfg && !isLotteryConfigEmpty()) {
        applyPoolWeightsToForm(cfg)
      }
    }
  )

  watch(
    () => props.modelValue,
    (newVal) => {
      if (newVal) initPage()
    }
  )

  /** 选择彩金池后，拉取该配置的五个权重并写入当前 player.*_weight，并更新当前配置展示 */
  async function onLotteryConfigChange(lotteryConfigId: number | null | undefined) {
    if (lotteryConfigId == null || lotteryConfigId === 0) {
      currentLotteryConfig.value = null
      return
    }
    try {
      const res = await lotteryConfigApi.read(lotteryConfigId)
      const payload = extractReadPayload(res)
      if (payload) {
        const row = parseLotteryPoolConfigOption(payload)
        applyPoolWeightsToForm(row)
        currentLotteryConfig.value = row
      } else {
        currentLotteryConfig.value = null
      }
    } catch (err) {
      console.warn('拉取彩金池配置失败', err)
      currentLotteryConfig.value = null
    }
  }

  /** 加载后台管理员选项 */
  function normalizeAdminTreeLabels(
    nodes: Array<{
      id: number | string
      label: string
      disabled?: boolean
      children?: Array<{ id: number; username: string; realname: string; label: string }>
    }>
  ) {
    return nodes.map((node) => {
      const item = { ...node }
      if (item.label === '__unassigned__') {
        item.label = t('page.form.unassignedChannel')
      }
      if (item.children?.length) {
        item.children = item.children.map((child) => ({
          ...child,
          label: child.label || child.username || `#${child.id}`
        }))
      }
      return item
    })
  }

  async function loadSystemUserOptions() {
    systemUserOptionsLoading.value = true
    try {
      if (useAdminTreeSelect.value) {
        const tree = await api.getSystemUserTreeOptions(getChannelDeptRequestParams())
        systemUserTreeOptions.value = normalizeAdminTreeLabels(tree)
        systemUserOptions.value = []
      } else {
        systemUserOptions.value = await api.getSystemUserOptions(getChannelDeptRequestParams())
        systemUserTreeOptions.value = []
      }
    } catch {
      systemUserOptions.value = []
      systemUserTreeOptions.value = []
    } finally {
      systemUserOptionsLoading.value = false
    }
  }

  const initPage = async () => {
    currentLotteryConfig.value = null
    Object.assign(formData, initialFormData)
    await Promise.all([loadLotteryConfigOptions(), loadSystemUserOptions()])
    if (props.data) {
      await nextTick()
      initForm()
      if (!isLotteryConfigEmpty()) {
        await loadCurrentLotteryConfig()
      }
    }
  }

  /** 从玩家控制器获取 DiceLotteryConfig id/name 列表，供 lottery_config_id 下拉使用 */
  async function loadLotteryConfigOptions() {
    lotteryConfigLoading.value = true
    try {
      lotteryConfigOptions.value = await api.getLotteryConfigOptions(getChannelDeptRequestParams())
    } catch {
      lotteryConfigOptions.value = []
    } finally {
      lotteryConfigLoading.value = false
    }
  }

  const numKeys = [
    'id',
    'status',
    'coin',
    'lottery_config_id',
    'admin_id',
    't1_weight',
    't2_weight',
    't3_weight',
    't4_weight',
    't5_weight'
  ]

  const initForm = () => {
    if (!props.data) return
    for (const key of Object.keys(formData)) {
      if (!(key in props.data)) continue
      if (key === 'password') {
        ;(formData as any).password = ''
        continue
      }
      const val = props.data[key]
      if (numKeys.includes(key)) {
        if (key === 'id') {
          ;(formData as any)[key] = val != null ? Number(val) || null : null
        } else if (key === 'lottery_config_id' || key === 'admin_id') {
          const num = Number(val)
          ;(formData as any)[key] = val != null && !Number.isNaN(num) && num > 0 ? num : null
        } else {
          ;(formData as any)[key] = Number(val) || 0
        }
      } else {
        ;(formData as any)[key] = val ?? ''
      }
    }
  }

  const handleClose = () => {
    visible.value = false
    formRef.value?.resetFields()
  }

  const handleSubmit = async () => {
    if (!formRef.value) return
    try {
      await formRef.value.validate()
      const useCustomWeights = isLotteryConfigEmpty()
      if (useCustomWeights && Math.abs(weightsSum.value - 100) > 0.01) {
        ElMessage.warning(t('page.form.ruleWeightsSumMustBe100'))
        return
      }
      const payload = { ...formData }
      if (isLotteryConfigEmpty()) {
        ;(payload as any).lottery_config_id = null
      } else if (currentLotteryConfig.value) {
        applyPoolWeightsToForm(currentLotteryConfig.value)
        WEIGHT_FIELDS.forEach((key) => {
          ;(payload as Record<string, number>)[key] = Number(
            (formData as Record<string, number>)[key] ?? 0
          )
        })
      }
      if (props.dialogType === 'edit' && !payload.password) {
        delete (payload as any).password
      }
      if (props.dialogType === 'add') {
        await api.save(withChannelDeptParams(payload))
        ElMessage.success(t('page.form.addSuccess'))
      } else {
        await api.update(withChannelDeptParams(payload))
        ElMessage.success(t('page.form.editSuccess'))
      }
      emit('success')
      handleClose()
    } catch (error) {
      console.log('表单验证失败:', error)
    }
  }
</script>

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

  .current-lottery-config {
    padding: 10px 12px;
    background: var(--el-fill-color-light);
    border-radius: 6px;
    font-size: 13px;
    color: var(--el-text-color-regular);

    .config-row {
      margin-bottom: 6px;
      line-height: 1.5;

      &:last-child {
        margin-bottom: 0;
      }
    }

    .config-label {
      color: var(--el-text-color-secondary);
      margin-right: 4px;
    }
  }
</style>
