<template>
  <ElDialog
    v-model="visible"
    :title="$t('page.weightTest.title')"
    width="960px"
    top="4vh"
    class="weight-test-dialog"
    :close-on-click-modal="false"
    destroy-on-close
    @close="onClose"
  >
    <div class="weight-test-dialog-body">
      <ElAlert type="info" :closable="false" show-icon class="weight-test-tip compact-tip">
        <div class="tip-lines">
          <div>{{ $t('page.weightTest.alertBody') }}</div>
          <div>{{ $t('page.weightTest.chainModeHint') }}</div>
          <div>{{ $t('page.weightTest.killModeHint') }}</div>
        </div>
      </ElAlert>

      <ElForm :model="form" label-width="108px" class="weight-test-form">
        <ElRow :gutter="16">
          <ElCol :span="12">
            <ElFormItem :label="$t('page.weightTest.labelAnte')" prop="ante_config_id" required>
              <ElSelect
                v-model="form.ante_config_id"
                :placeholder="$t('page.weightTest.placeholderAnte')"
                filterable
                style="width: 100%"
                @change="syncAnteFromSelect"
              >
                <ElOption
                  :label="$t('page.weightTest.anteRandomOption')"
                  :value="RANDOM_ANTE_CONFIG_ID"
                />
                <ElOption
                  v-for="item in anteOptions"
                  :key="item.id"
                  :label="anteOptionLabel(item)"
                  :value="item.id"
                />
              </ElSelect>
            </ElFormItem>
          </ElCol>
        </ElRow>

        <div class="kill-mode-panel">
          <div class="kill-mode-head">
            <div class="kill-mode-title">{{ $t('page.weightTest.killModePanelTitle') }}</div>
            <ElSwitch
              v-model="form.kill_mode_enabled"
              :active-text="$t('page.weightTest.killModeSwitchOn')"
              :inactive-text="$t('page.weightTest.killModeSwitchOff')"
              inline-prompt
            />
          </div>
          <div v-if="form.kill_mode_enabled" class="kill-mode-body">
            <div class="kill-mode-field">
              <div class="kill-mode-field-label">{{ $t('page.weightTest.labelTestSafetyLine') }}</div>
              <ElInputNumber
                v-model="form.test_safety_line"
                :min="0"
                :step="100"
                controls-position="right"
                class="kill-mode-field-input"
              />
            </div>
            <div class="kill-mode-hint">{{ $t('page.weightTest.testSafetyLineHint') }}</div>
            <div v-if="defaultPoolInfo" class="kill-mode-ref">
              {{ $t('page.weightTest.poolProfitRef', {
                profit: defaultPoolInfo.profit_amount,
                line: defaultPoolInfo.safety_line
              }) }}
            </div>
          </div>
          <div v-else class="kill-mode-off-hint">{{ $t('page.weightTest.killModeOffHint') }}</div>
        </div>

        <ElRow :gutter="20" class="section-row">
          <ElCol :span="12">
            <div class="section-title">{{ $t('page.weightTest.sectionPaid') }}</div>
            <ElForm :model="form" label-position="top" class="section-form">
              <ElFormItem :label="$t('page.weightTest.labelLotteryTypePaid')" prop="paid_lottery_config_id">
                <ElSelect
                  v-model="form.paid_lottery_config_id"
                  :placeholder="$t('page.weightTest.placeholderPaidPool')"
                  clearable
                  filterable
                  style="width: 100%"
                >
                  <ElOption
                    v-for="item in lotteryOptions"
                    :key="'paid-pool-' + item.id"
                    :label="lotteryPoolOptionLabel(item)"
                    :value="item.id"
                  />
                </ElSelect>
                <div v-if="selectedPaidPool" class="pool-selected-hint">
                  {{ $t('page.weightTest.selectedPoolHint', { name: lotteryPoolDisplayLabel(selectedPaidPool) }) }}
                </div>
                <div v-if="selectedPaidPool" class="pool-weights-preview">
                  {{ poolTierWeightsText(selectedPaidPool) }}
                </div>
              </ElFormItem>
              <template v-if="form.paid_lottery_config_id == null">
                <div class="tier-label">{{ $t('page.weightTest.tierProbHint') }}</div>
                <ElRow :gutter="8" class="tier-row">
                  <ElCol v-for="t in tierKeys" :key="'paid-' + t" :span="8">
                    <div class="tier-field">
                      <label class="tier-field-label">{{
                        $t('page.weightTest.tierFieldLabel', { tier: t })
                      }}</label>
                      <input
                        type="number"
                        :value="getPaidTier(t)"
                        min="0"
                        max="100"
                        placeholder="0"
                        class="tier-input"
                        @input="setPaidTier(t, $event)"
                      />
                    </div>
                  </ElCol>
                </ElRow>
                <div v-if="paidTierSum > 100" class="tier-error">{{
                  $t('page.weightTest.tierSumError', { sum: paidTierSum })
                }}</div>
              </template>
              <ElRow :gutter="12">
                <ElCol :span="12">
                  <ElFormItem :label="$t('page.weightTest.labelCwCount')" prop="paid_s_count" required>
                    <ElSelect
                      v-model="form.paid_s_count"
                      :placeholder="$t('page.weightTest.placeholderSelect')"
                      style="width: 100%"
                    >
                      <ElOption v-for="c in countOptions" :key="c" :label="String(c)" :value="c" />
                    </ElSelect>
                  </ElFormItem>
                </ElCol>
                <ElCol :span="12">
                  <ElFormItem :label="$t('page.weightTest.labelCcwCount')" prop="paid_n_count" required>
                    <ElSelect
                      v-model="form.paid_n_count"
                      :placeholder="$t('page.weightTest.placeholderSelect')"
                      style="width: 100%"
                    >
                      <ElOption v-for="c in countOptions" :key="'n-' + c" :label="String(c)" :value="c" />
                    </ElSelect>
                  </ElFormItem>
                </ElCol>
              </ElRow>
            </ElForm>
          </ElCol>

          <ElCol :span="12">
            <div class="section-title">{{ $t('page.weightTest.sectionFreeAfterPlayAgain') }}</div>
            <ElForm :model="form" label-position="top" class="section-form">
              <ElFormItem :label="$t('page.weightTest.labelLotteryTypeFree')" prop="free_lottery_config_id">
                <ElSelect
                  v-model="form.free_lottery_config_id"
                  :placeholder="$t('page.weightTest.placeholderFreePool')"
                  clearable
                  filterable
                  style="width: 100%"
                >
                  <ElOption
                    v-for="item in lotteryOptions"
                    :key="'free-pool-' + item.id"
                    :label="lotteryPoolOptionLabel(item)"
                    :value="item.id"
                  />
                </ElSelect>
                <div v-if="selectedFreePool" class="pool-selected-hint">
                  {{ $t('page.weightTest.selectedPoolHint', { name: lotteryPoolDisplayLabel(selectedFreePool) }) }}
                </div>
                <div v-if="selectedFreePool" class="pool-weights-preview">
                  {{ poolTierWeightsText(selectedFreePool) }}
                </div>
              </ElFormItem>
              <template v-if="form.free_lottery_config_id == null">
                <div class="tier-label">{{ $t('page.weightTest.tierProbHintFreeChain') }}</div>
                <ElRow :gutter="8" class="tier-row">
                  <ElCol v-for="t in tierKeys" :key="'free-' + t" :span="8">
                    <div class="tier-field">
                      <label class="tier-field-label">{{
                        $t('page.weightTest.tierFieldLabel', { tier: t })
                      }}</label>
                      <input
                        type="number"
                        :value="getFreeTier(t)"
                        min="0"
                        max="100"
                        placeholder="0"
                        class="tier-input"
                        @input="setFreeTier(t, $event)"
                      />
                    </div>
                  </ElCol>
                </ElRow>
                <div v-if="freeTierSum > 100" class="tier-error">{{
                  $t('page.weightTest.tierSumError', { sum: freeTierSum })
                }}</div>
              </template>
            </ElForm>
          </ElCol>
        </ElRow>
      </ElForm>
    </div>

    <template #footer>
      <ElButton
        v-permission="'dice:reward:index:startWeightTest'"
        type="primary"
        :loading="running"
        @click="handleStart"
        >{{ $t('page.weightTest.btnStart') }}</ElButton
      >
      <ElButton :disabled="running" @click="visible = false">{{
        $t('page.weightTest.btnCancel')
      }}</ElButton>
    </template>
  </ElDialog>
</template>

<script setup lang="ts">
  import api from '../../../api/reward/index'
  import anteConfigApi from '../../../api/ante_config/index'
  import lotteryPoolApi, { type LotteryPoolConfigOption } from '../../../api/lottery_pool_config/index'
  import { ElMessage } from 'element-plus'
  import { useI18n } from 'vue-i18n'
  import {
    getChannelDeptRequestParams,
    useInjectedChannelDept,
    withChannelDeptParams
  } from '@/composables/useChannelDeptScope'
  import {
    lotteryPoolDisplayLabel,
    lotteryPoolOptionLabel
  } from '@/views/plugin/dice/utils/lotteryPoolDisplay'

  /** 底注下拉「随机」选项值（非真实 ante_config.id） */
  const RANDOM_ANTE_CONFIG_ID = -1

  const props = defineProps<{
    /** 父页面渠道栏选中值（弹窗 teleport 后 inject 可能失效） */
    channelDeptId?: number
  }>()

  const { t } = useI18n()
  const channelScope = useInjectedChannelDept()

  const countOptions = [0, 100, 500, 1000, 5000]
  const tierKeys = ['T1', 'T2', 'T3', 'T4', 'T5'] as const

  const visible = defineModel<boolean>({ default: false })
  const emit = defineEmits<{ (e: 'success'): void }>()

  const anteOptions = ref<
    Array<{ id: number; name: string; title: string; mult: number; is_default: number }>
  >([])

  const form = reactive({
    ante: 1,
    ante_config_id: undefined as number | undefined,
    paid_lottery_config_id: undefined as number | undefined,
    free_lottery_config_id: undefined as number | undefined,
    paid_tier_weights: { T1: 20, T2: 20, T3: 20, T4: 20, T5: 20 } as Record<string, number>,
    free_tier_weights: { T1: 20, T2: 20, T3: 20, T4: 20, T5: 20 } as Record<string, number>,
    paid_s_count: 100,
    paid_n_count: 100,
    kill_mode_enabled: false,
    test_safety_line: 0
  })
  const lotteryOptions = ref<LotteryPoolConfigOption[]>([])
  const selectedPaidPool = computed(() =>
    lotteryOptions.value.find((r) => r.id === form.paid_lottery_config_id) ?? null
  )
  const selectedFreePool = computed(() =>
    lotteryOptions.value.find((r) => r.id === form.free_lottery_config_id) ?? null
  )
  const defaultPoolInfo = ref<{ safety_line: number; kill_enabled: number; profit_amount: number } | null>(null)
  const running = ref(false)

  function onClose() {
    running.value = false
  }

  function getPaidTier(t: string): string {
    const v = form.paid_tier_weights[t]
    return v !== undefined && v !== null ? String(v) : ''
  }
  function setPaidTier(t: string, val: string | Event) {
    const raw =
      typeof val === 'string'
        ? val
        : ((val as Event & { target: HTMLInputElement }).target?.value ?? '')
    const num = raw === '' ? 0 : Math.max(0, Math.min(100, Number(raw) || 0))
    form.paid_tier_weights[t] = num
  }
  const paidTierSum = computed(() =>
    tierKeys.reduce((s, t) => s + (form.paid_tier_weights[t] ?? 0), 0)
  )
  function getFreeTier(t: string): string {
    const v = form.free_tier_weights[t]
    return v !== undefined && v !== null ? String(v) : ''
  }
  function setFreeTier(t: string, val: string | Event) {
    const raw =
      typeof val === 'string'
        ? val
        : ((val as Event & { target: HTMLInputElement }).target?.value ?? '')
    const num = raw === '' ? 0 : Math.max(0, Math.min(100, Number(raw) || 0))
    form.free_tier_weights[t] = num
  }
  const freeTierSum = computed(() =>
    tierKeys.reduce((s, t) => s + (form.free_tier_weights[t] ?? 0), 0)
  )

  function resolveDeptParams(): { dept_id?: number } {
    if (props.channelDeptId !== undefined && props.channelDeptId !== null) {
      return { dept_id: props.channelDeptId }
    }
    const extra = getChannelDeptRequestParams()
    if (extra.dept_id !== undefined) {
      return extra
    }
    if (channelScope) {
      return { dept_id: channelScope.selectedDeptId.value }
    }
    return {}
  }

  function resolveSubmitDeptId(): number | undefined {
    const params = resolveDeptParams()
    if (params.dept_id !== undefined) {
      return params.dept_id
    }
    return undefined
  }

  function anteOptionLabel(item: { name: string; title: string; mult: number }): string {
    const label = (item.title || item.name || '').trim()
    return label ? `${label} (×${item.mult})` : `×${item.mult}`
  }

  function poolTierWeightsText(pool: LotteryPoolConfigOption): string {
    const parts = tierKeys.map((t) => {
      const key = `${t.toLowerCase()}_weight` as keyof LotteryPoolConfigOption
      const v = pool[key]
      return `${t} ${v ?? 0}%`
    })
    return parts.join(' · ')
  }

  function syncAnteFromSelect() {
    const opt = anteOptions.value.find((o) => o.id === form.ante_config_id)
    if (opt) {
      form.ante = opt.mult
    }
  }

  async function loadAnteOptions() {
    try {
      const list = await anteConfigApi.getOptions(resolveDeptParams())
      anteOptions.value = list
      const def = list.find((i) => i.is_default === 1) ?? list[0]
      if (def) {
        form.ante_config_id = def.id
        form.ante = def.mult
      } else {
        form.ante_config_id = undefined
        form.ante = 1
      }
    } catch {
      anteOptions.value = []
      form.ante_config_id = undefined
    }
  }

  async function loadDefaultPoolInfo() {
    try {
      const pool = await lotteryPoolApi.getCurrentPool(resolveDeptParams())
      const safetyLine = Number(pool?.safety_line ?? 0)
      defaultPoolInfo.value = {
        safety_line: safetyLine,
        kill_enabled: Number(pool?.kill_enabled ?? 1),
        profit_amount: Number(pool?.profit_amount ?? 0)
      }
      form.test_safety_line = safetyLine
    } catch {
      defaultPoolInfo.value = null
    }
  }

  async function loadLotteryOptions() {
    try {
      const list = await lotteryPoolApi.getOptions(resolveDeptParams())
      lotteryOptions.value = list
      const playerDefault = list.find((r) => r.name === 'playerDefault')
      const normal = list.find((r) => r.name === 'default')
      if (playerDefault) {
        form.paid_lottery_config_id = playerDefault.id
      } else if (normal) {
        form.paid_lottery_config_id = normal.id
      }
      const freePool = list.find((r: { name?: string }) => r.name === 'free')
      if (freePool) {
        form.free_lottery_config_id = freePool.id
      } else if (list.length > 0) {
        form.free_lottery_config_id = list[0].id
      }
    } catch {
      lotteryOptions.value = []
    }
  }

  function buildPayload() {
    const payload: Record<string, unknown> = {
      ante: form.ante,
      paid_s_count: form.paid_s_count,
      paid_n_count: form.paid_n_count,
      free_s_count: 0,
      free_n_count: 0,
      chain_free_mode: true,
      kill_mode_enabled: form.kill_mode_enabled,
      test_safety_line: form.test_safety_line
    }
    if (form.ante_config_id === RANDOM_ANTE_CONFIG_ID) {
      payload.ante_random = true
    } else {
      payload.ante_config_id = form.ante_config_id
    }
    if (form.paid_lottery_config_id != null) {
      payload.paid_lottery_config_id = form.paid_lottery_config_id
    } else {
      payload.paid_tier_weights = { ...form.paid_tier_weights }
    }
    if (form.free_lottery_config_id != null) {
      payload.free_lottery_config_id = form.free_lottery_config_id
    } else {
      payload.free_tier_weights = { ...form.free_tier_weights }
    }
    return payload
  }

  function validateForm(): boolean {
    const isRandomAnte = form.ante_config_id === RANDOM_ANTE_CONFIG_ID
    if (!isRandomAnte && (form.ante_config_id == null || form.ante_config_id <= 0)) {
      ElMessage.warning(t('page.weightTest.warnAnte'))
      return false
    }
    if (!isRandomAnte) {
      syncAnteFromSelect()
    }
    if (!isRandomAnte && (form.ante == null || form.ante <= 0)) {
      ElMessage.warning(t('page.weightTest.warnAnte'))
      return false
    }
    if (form.paid_s_count + form.paid_n_count <= 0) {
      ElMessage.warning(t('page.weightTest.warnPaidSpins'))
      return false
    }
    if (form.kill_mode_enabled && (form.test_safety_line == null || form.test_safety_line < 0)) {
      ElMessage.warning(t('page.weightTest.warnTestSafetyLine'))
      return false
    }
    const needPaidTier = form.paid_lottery_config_id == null
    const needFreeTier = form.free_lottery_config_id == null
    if (needPaidTier) {
      const sum = paidTierSum.value
      if (sum <= 0) {
        ElMessage.warning(t('page.weightTest.warnPaidTierSumPositive'))
        return false
      }
      if (sum > 100) {
        ElMessage.warning(t('page.weightTest.warnPaidTierSumMax'))
        return false
      }
    }
    if (needFreeTier) {
      const sum = freeTierSum.value
      if (sum <= 0) {
        ElMessage.warning(t('page.weightTest.warnFreeTierSumPositive'))
        return false
      }
      if (sum > 100) {
        ElMessage.warning(t('page.weightTest.warnFreeTierSumMax'))
        return false
      }
    }
    return true
  }

  async function handleStart() {
    if (!validateForm()) return
    running.value = true
    try {
      const payload = buildPayload()
      const deptId = resolveSubmitDeptId()
      if (deptId !== undefined) {
        payload.dept_id = deptId
      }
      await api.startWeightTest(withChannelDeptParams(payload))
      ElMessage.success(t('page.weightTest.successCreated'))
      visible.value = false
      emit('success')
    } catch (e: any) {
      ElMessage.error(e?.message || t('page.weightTest.failCreate'))
    } finally {
      running.value = false
    }
  }

  watch(visible, (v) => {
    if (v) {
      void loadAnteOptions()
      void loadLotteryOptions()
      void loadDefaultPoolInfo()
    } else {
      onClose()
    }
  })

  watch(
    () => props.channelDeptId ?? channelScope?.selectedDeptId.value,
    () => {
      if (visible.value) {
        void loadAnteOptions()
        void loadLotteryOptions()
        void loadDefaultPoolInfo()
      }
    }
  )
</script>

<style lang="scss" scoped>
  .weight-test-dialog-body {
    max-height: calc(100vh - 168px);
    overflow: visible;
  }

  .compact-tip {
    margin-bottom: 12px;
    :deep(.el-alert__content) {
      line-height: 1.45;
    }
  }

  .tip-lines {
    font-size: 12px;
    color: var(--el-text-color-regular);
    div + div {
      margin-top: 4px;
    }
  }

  .weight-test-form {
    :deep(.el-form-item) {
      margin-bottom: 12px;
    }
    :deep(.el-form-item__label) {
      white-space: nowrap;
    }
  }

  .section-form {
    :deep(.el-form-item) {
      margin-bottom: 12px;
    }
    :deep(.el-form-item__label) {
      white-space: nowrap;
      line-height: 1.4;
      padding-bottom: 4px;
    }
  }

  .kill-mode-panel {
    margin-bottom: 14px;
    padding: 12px 14px;
    border: 1px solid var(--el-border-color-lighter);
    border-radius: var(--el-border-radius-base);
    background: var(--el-fill-color-light);
  }

  .kill-mode-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
  }

  .kill-mode-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--el-text-color-primary);
    line-height: 1.4;
  }

  .kill-mode-body {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px dashed var(--el-border-color);
  }

  .pool-selected-hint {
    margin-top: 6px;
    font-size: 12px;
    color: var(--el-text-color-secondary);
    line-height: 1.4;
  }

  .pool-weights-preview {
    margin-top: 4px;
    font-size: 12px;
    color: var(--el-text-color-regular);
    font-family: ui-monospace, monospace;
  }

  .kill-mode-field {
    max-width: 280px;
  }

  .kill-mode-field-label {
    font-size: 13px;
    color: var(--el-text-color-regular);
    line-height: 1.4;
    margin-bottom: 6px;
    white-space: nowrap;
  }

  .kill-mode-field-input {
    width: 100%;
  }

  .kill-mode-hint,
  .kill-mode-off-hint,
  .kill-mode-ref {
    font-size: 12px;
    line-height: 1.5;
    color: var(--el-text-color-secondary);
  }

  .kill-mode-ref {
    margin-top: 4px;
    color: var(--el-text-color-placeholder);
  }

  .section-row {
    margin-top: 4px;
  }

  .section-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--el-text-color-primary);
    margin: 0 0 10px;
    padding-bottom: 4px;
    border-bottom: 1px solid var(--el-border-color-lighter);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .tier-label {
    font-size: 12px;
    color: var(--el-text-color-secondary);
    margin-bottom: 6px;
  }

  .tier-row {
    margin-bottom: 8px;
  }

  .tier-field {
    margin-bottom: 6px;
  }

  .tier-field-label {
    display: block;
    font-size: 12px;
    color: var(--el-text-color-regular);
    margin-bottom: 2px;
    line-height: 1.4;
  }

  .tier-input {
    display: block;
    width: 100%;
    padding: 4px 8px;
    font-size: 13px;
    line-height: 1.4;
    color: var(--el-text-color-regular);
    background-color: var(--el-fill-color-blank);
    border: 1px solid var(--el-border-color);
    border-radius: var(--el-border-radius-base);
    box-sizing: border-box;
  }

  .tier-input:hover {
    border-color: var(--el-border-color-hover);
  }

  .tier-input:focus {
    outline: none;
    border-color: var(--el-color-primary);
    box-shadow: 0 0 0 2px var(--el-color-primary-light-7);
  }

  .tier-error {
    font-size: 12px;
    color: var(--el-color-danger);
    margin-bottom: 6px;
  }
</style>

<style lang="scss">
  .weight-test-dialog.el-dialog {
    margin-bottom: 4vh;
  }
  .weight-test-dialog .el-dialog__body {
    padding-top: 12px;
    padding-bottom: 8px;
  }
</style>
