<template>
  <el-dialog
    v-model="visible"
    title="权重配比"
    width="900px"
    align-center
    :close-on-click-modal="false"
    @close="handleClose"
  >
    <div class="global-tip">
      配置<strong>奖励对照表（dice_reward）</strong>的权重，一级按<strong>方向</strong>（顺时针/逆时针），二级按<strong>档位</strong>（T1-T5）；各条权重
      1-10000，档位内按权重比抽取。
    </div>
    <div v-loading="loading" class="dialog-body">
      <!-- 一级：方向；二级档位放在各方向 pane 内，切换方向时二级能正常显示 -->
      <el-tabs v-model="activeDirection" type="card" class="direction-tabs">
        <el-tab-pane label="顺时针" name="0">
          <el-tabs v-model="activeTier" type="card" class="tier-tabs">
            <el-tab-pane v-for="t in tierKeys" :key="'cw-' + t" :label="t" :name="t">
              <div v-if="getTierItems(t).length === 0" class="empty-tip">该档位暂无配置数据</div>
              <template v-else>
                <div class="chart-wrap" v-if="t !== 'T4' && t !== 'T5'">
                  <ArtBarChart
                    x-axis-name="点数"
                    :x-axis-data="getTierChartLabels(t)"
                    :data="getTierChartDataForCurrentDirection(t)"
                    height="180px"
                  />
                </div>
                <div class="weight-sum" v-if="t !== 'T4' && t !== 'T5'">
                  当前档位权重合计：<strong>{{ getTierSumForCurrentDirection(t) }}</strong>
                  （各条 1-10000，档位内按权重比抽取，和不限制）
                </div>
                <div class="weight-sum weight-sum-t4t5" v-else
                  >T4、T5 仅单一结果，无需配置权重。</div
                >
                <el-table :data="getTierItems(t)" border size="small" class="weight-table">
                  <el-table-column
                    label="点数(grid_number)"
                    prop="grid_number"
                    width="110"
                    align="center"
                    show-overflow-tooltip
                  />
                  <el-table-column
                    label="结束索引(id)"
                    prop="id"
                    width="90"
                    align="center"
                    show-overflow-tooltip
                  />
                  <el-table-column
                    label="实际中奖金额"
                    prop="real_ev"
                    width="90"
                    align="center"
                    show-overflow-tooltip
                  />
                  <el-table-column
                    label="显示文本"
                    prop="ui_text"
                    min-width="70"
                    align="center"
                    show-overflow-tooltip
                  />
                  <el-table-column
                    label="备注"
                    prop="remark"
                    min-width="70"
                    align="center"
                    show-overflow-tooltip
                  />
                  <el-table-column
                    :label="currentDirectionLabel + ' 权重(1-10000)'"
                    min-width="200"
                    align="center"
                  >
                    <template #default="{ row }">
                      <div class="weight-cell-vertical">
                        <div class="weight-slider-wrap">
                          <el-slider
                            :model-value="getItemWeightForCurrentDirection(row)"
                            :min="1"
                            :max="10000"
                            :step="1"
                            size="small"
                            :disabled="isWeightDisabled(row, t)"
                            class="weight-slider"
                            @update:model-value="
                              (v: number | number[]) =>
                                setItemWeightForCurrentDirection(
                                  t,
                                  row,
                                  Array.isArray(v) ? (v[0] ?? 1) : (v ?? 1)
                                )
                            "
                          />
                        </div>
                        <div class="weight-input-wrap">
                          <el-button
                            type="primary"
                            link
                            :disabled="
                              isWeightDisabled(row, t) || getItemWeightForCurrentDirection(row) <= 1
                            "
                            @click="
                              setItemWeightForCurrentDirection(
                                t,
                                row,
                                Math.max(1, getItemWeightForCurrentDirection(row) - 1)
                              )
                            "
                            >－</el-button
                          >
                          <el-input-number
                            :model-value="getItemWeightForCurrentDirection(row)"
                            :min="1"
                            :max="10000"
                            :step="1"
                            :disabled="isWeightDisabled(row, t)"
                            controls-position="right"
                            size="small"
                            class="weight-input"
                            @update:model-value="
                              (v: number | string | undefined) =>
                                setItemWeightForCurrentDirection(
                                  t,
                                  row,
                                  typeof v === 'number' && !Number.isNaN(v) ? v : Number(v) || 1
                                )
                            "
                          />
                          <el-button
                            type="primary"
                            link
                            :disabled="
                              isWeightDisabled(row, t) ||
                              getItemWeightForCurrentDirection(row) >= 10000
                            "
                            @click="
                              setItemWeightForCurrentDirection(
                                t,
                                row,
                                Math.min(10000, getItemWeightForCurrentDirection(row) + 1)
                              )
                            "
                            >＋</el-button
                          >
                        </div>
                      </div>
                    </template>
                  </el-table-column>
                </el-table>
              </template>
            </el-tab-pane>
          </el-tabs>
        </el-tab-pane>
        <el-tab-pane label="逆时针" name="1">
          <el-tabs v-model="activeTier" type="card" class="tier-tabs">
            <el-tab-pane v-for="t in tierKeys" :key="'ccw-' + t" :label="t" :name="t">
              <div v-if="getTierItems(t).length === 0" class="empty-tip">该档位暂无配置数据</div>
              <template v-else>
                <div class="chart-wrap" v-if="t !== 'T4' && t !== 'T5'">
                  <ArtBarChart
                    x-axis-name="点数"
                    :x-axis-data="getTierChartLabels(t)"
                    :data="getTierChartDataForCurrentDirection(t)"
                    height="180px"
                  />
                </div>
                <div class="weight-sum" v-if="t !== 'T4' && t !== 'T5'">
                  当前档位权重合计：<strong>{{ getTierSumForCurrentDirection(t) }}</strong>
                  （各条 1-10000，档位内按权重比抽取，和不限制）
                </div>
                <div class="weight-sum weight-sum-t4t5" v-else
                  >T4、T5 仅单一结果，无需配置权重。</div
                >
                <el-table :data="getTierItems(t)" border size="small" class="weight-table">
                  <el-table-column
                    label="点数(grid_number)"
                    prop="grid_number"
                    width="110"
                    align="center"
                    show-overflow-tooltip
                  />
                  <el-table-column
                    label="结束索引(id)"
                    prop="id"
                    width="90"
                    align="center"
                    show-overflow-tooltip
                  />
                  <el-table-column
                    label="实际中奖金额"
                    prop="real_ev"
                    width="90"
                    align="center"
                    show-overflow-tooltip
                  />
                  <el-table-column
                    label="显示文本"
                    prop="ui_text"
                    min-width="70"
                    align="center"
                    show-overflow-tooltip
                  />
                  <el-table-column
                    label="备注"
                    prop="remark"
                    min-width="70"
                    align="center"
                    show-overflow-tooltip
                  />
                  <el-table-column
                    :label="currentDirectionLabel + ' 权重(1-10000)'"
                    min-width="200"
                    align="center"
                  >
                    <template #default="{ row }">
                      <div class="weight-cell-vertical">
                        <div class="weight-slider-wrap">
                          <el-slider
                            :model-value="getItemWeightForCurrentDirection(row)"
                            :min="1"
                            :max="10000"
                            :step="1"
                            size="small"
                            :disabled="isWeightDisabled(row, t)"
                            class="weight-slider"
                            @update:model-value="
                              (v: number | number[]) =>
                                setItemWeightForCurrentDirection(
                                  t,
                                  row,
                                  Array.isArray(v) ? (v[0] ?? 1) : (v ?? 1)
                                )
                            "
                          />
                        </div>
                        <div class="weight-input-wrap">
                          <el-button
                            type="primary"
                            link
                            :disabled="
                              isWeightDisabled(row, t) || getItemWeightForCurrentDirection(row) <= 1
                            "
                            @click="
                              setItemWeightForCurrentDirection(
                                t,
                                row,
                                Math.max(1, getItemWeightForCurrentDirection(row) - 1)
                              )
                            "
                            >－</el-button
                          >
                          <el-input-number
                            :model-value="getItemWeightForCurrentDirection(row)"
                            :min="1"
                            :max="10000"
                            :step="1"
                            :disabled="isWeightDisabled(row, t)"
                            controls-position="right"
                            size="small"
                            class="weight-input"
                            @update:model-value="
                              (v: number | string | undefined) =>
                                setItemWeightForCurrentDirection(
                                  t,
                                  row,
                                  typeof v === 'number' && !Number.isNaN(v) ? v : Number(v) || 1
                                )
                            "
                          />
                          <el-button
                            type="primary"
                            link
                            :disabled="
                              isWeightDisabled(row, t) ||
                              getItemWeightForCurrentDirection(row) >= 10000
                            "
                            @click="
                              setItemWeightForCurrentDirection(
                                t,
                                row,
                                Math.min(10000, getItemWeightForCurrentDirection(row) + 1)
                              )
                            "
                            >＋</el-button
                          >
                        </div>
                      </div>
                    </template>
                  </el-table-column>
                </el-table>
              </template>
            </el-tab-pane>
          </el-tabs>
        </el-tab-pane>
      </el-tabs>
    </div>
    <template #footer>
      <el-button @click="handleClose">取消</el-button>
      <el-button type="primary" :loading="submitting" @click="handleSubmit">提交</el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
  import api from '../../../api/reward/index'
  import ArtBarChart from '@/components/core/charts/art-bar-chart/index.vue'
  import { ElMessage } from 'element-plus'

  const TIER_KEYS = ['T1', 'T2', 'T3', 'T4', 'T5'] as const
  type DirectionKey = 'clockwise' | 'counterclockwise'

  /** 当前方向下的行：reward_id=DiceReward 主键(用于提交更新)，id=end_index 展示用，weight 为当前方向权重 */
  interface WeightRow {
    reward_id?: number
    id?: number
    grid_number?: number
    real_ev?: number
    ui_text?: string
    remark?: string
    weight: number
  }

  /** 按档位、方向分组：tier -> { '0': 顺时针行列表, '1': 逆时针行列表 } */
  type GroupedByTierDirection = Record<string, { '0': WeightRow[]; '1': WeightRow[] }>

  interface Props {
    modelValue: boolean
  }

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

  const props = withDefaults(defineProps<Props>(), {
    modelValue: false
  })

  const emit = defineEmits<Emits>()

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

  const activeDirection = ref<'0' | '1'>('0')
  const activeTier = ref('T1')
  const submitting = ref(false)
  const loading = ref(false)
  const grouped = ref<GroupedByTierDirection>({
    T1: { '0': [], '1': [] },
    T2: { '0': [], '1': [] },
    T3: { '0': [], '1': [] },
    T4: { '0': [], '1': [] },
    T5: { '0': [], '1': [] }
  })

  const currentDirectionLabel = computed(() =>
    activeDirection.value === '0' ? '顺时针' : '逆时针'
  )

  const tierKeys = TIER_KEYS

  function getTierItems(tier: string): WeightRow[] {
    const dir = activeDirection.value
    const tierData = grouped.value[tier]
    if (!tierData || !tierData[dir]) return []
    return tierData[dir]
  }

  function getTierChartLabels(tier: string): string[] {
    return getTierItems(tier).map((r) => String(r.grid_number ?? ''))
  }

  function getTierChartDataForCurrentDirection(tier: string): number[] {
    return getTierItems(tier).map((r) => toWeightPrecision(r.weight ?? 1))
  }

  function getTierSumForCurrentDirection(tier: string): number {
    return getTierItems(tier).reduce((s, r) => s + toWeightPrecision(r.weight ?? 1), 0)
  }

  function getItemWeightForCurrentDirection(row: WeightRow): number {
    const w = row.weight
    const num = typeof w === 'number' && !Number.isNaN(w) ? w : Number(w)
    if (Number.isNaN(num)) return 1
    return toWeightPrecision(num)
  }

  function toWeightPrecision(value: number): number {
    return Math.max(1, Math.min(10000, Math.floor(value)))
  }

  function setItemWeightForCurrentDirection(tier: string, row: WeightRow, value: number) {
    const v = toWeightPrecision(value)
    const dir = activeDirection.value
    const tierData = grouped.value[tier]
    if (!tierData || !tierData[dir]) return
    const list = tierData[dir]
    const rid = row.reward_id != null ? row.reward_id : undefined
    list.forEach((r) => {
      if (r === row || (rid != null && r.reward_id != null && r.reward_id === rid)) r.weight = v
    })
    grouped.value[tier][dir] = [...list]
  }

  function isWeightDisabled(row: WeightRow, tier: string): boolean {
    if (tier === 'T4' || tier === 'T5') return true
    return false
  }

  function normalizeWeightValue(v: unknown): number {
    const num = typeof v === 'number' && !Number.isNaN(v) ? v : Number(v)
    if (Number.isNaN(num)) return 1
    return Math.max(1, Math.min(10000, Math.floor(num)))
  }

  /** 兼容后端返回 tier -> { 0: [], 1: [] }，每行含 reward_id, id(end_index), grid_number, ui_text, real_ev, remark, weight */
  function parsePayload(res: any): GroupedByTierDirection {
    const empty: GroupedByTierDirection = {
      T1: { '0': [], '1': [] },
      T2: { '0': [], '1': [] },
      T3: { '0': [], '1': [] },
      T4: { '0': [], '1': [] },
      T5: { '0': [], '1': [] }
    }
    if (!res || typeof res !== 'object') return empty
    const raw = res?.data ?? res
    if (!raw || typeof raw !== 'object') return empty
    const out = { ...empty }
    for (const t of TIER_KEYS) {
      const tierData = raw[t]
      if (!tierData || typeof tierData !== 'object') continue
      out[t] = {
        '0': Array.isArray(tierData[0])
          ? tierData[0].map((r: any) => ({
              ...r,
              reward_id: r.reward_id != null ? Number(r.reward_id) : undefined,
              weight: normalizeWeightValue(r.weight)
            }))
          : [],
        '1': Array.isArray(tierData[1])
          ? tierData[1].map((r: any) => ({
              ...r,
              reward_id: r.reward_id != null ? Number(r.reward_id) : undefined,
              weight: normalizeWeightValue(r.weight)
            }))
          : []
      }
    }
    return out
  }

  function loadData() {
    loading.value = true
    api
      .weightRatioListWithDirection()
      .then((res: any) => {
        grouped.value = parsePayload(res)
      })
      .catch(() => {
        ElMessage.error('获取权重数据失败')
      })
      .finally(() => {
        loading.value = false
      })
  }

  /** 按 DiceReward 主键 id 收集：每条记录一条 { id, weight }，直接用于后端按 id 更新 */
  function collectItems(): Array<{ id: number; weight: number }> {
    const items: Array<{ id: number; weight: number }> = []
    for (const t of TIER_KEYS) {
      const tierData = grouped.value[t]
      if (!tierData) continue
      for (const dir of ['0', '1'] as const) {
        const list = tierData[dir] ?? []
        for (const row of list) {
          const rid = row.reward_id != null ? Number(row.reward_id) : 0
          if (rid <= 0) continue
          const w = isWeightDisabled(row, t) ? 10000 : toWeightPrecision(row.weight ?? 1)
          items.push({ id: rid, weight: w })
        }
      }
    }
    return items
  }

  function handleSubmit() {
    const items = collectItems()
    if (items.length === 0) {
      ElMessage.info('没有可提交的配置')
      return
    }
    submitting.value = true
    api
      .batchUpdateWeights(items)
      .then(() => {
        ElMessage.success('保存成功')
        emit('success')
        handleClose()
      })
      .catch((e: { message?: string }) => {
        ElMessage.error(e?.message ?? '保存失败')
      })
      .finally(() => {
        submitting.value = false
      })
  }

  function handleClose() {
    visible.value = false
  }

  watch(
    () => props.modelValue,
    (open) => {
      if (open) {
        loadData()
        activeDirection.value = '0'
        activeTier.value = 'T1'
      }
    }
  )
</script>

<style lang="scss" scoped>
  .direction-tabs {
    margin-bottom: 8px;
  }
  .tier-tabs {
    margin-top: 8px;
  }
  .chart-wrap {
    margin-bottom: 12px;
  }
  .weight-sum {
    margin-bottom: 12px;
    font-size: 13px;
  }
  .weight-sum-t4t5 {
    color: var(--el-text-color-secondary);
  }
  .global-tip {
    margin-bottom: 12px;
    padding: 10px 12px;
    font-size: 13px;
    color: var(--el-text-color-regular);
    background: var(--el-fill-color-light);
    border-radius: 6px;
    line-height: 1.5;
  }
  .weight-table {
    margin-top: 8px;
  }
  .weight-cell-vertical {
    display: flex;
    flex-direction: column;
    gap: 8px;
    align-items: center;
  }
  .weight-slider-wrap {
    width: 100%;
    min-width: 80px;
    padding: 0 8px;
    .weight-slider {
      width: 100%;
    }
  }
  .weight-input-wrap {
    display: flex;
    align-items: center;
    gap: 6px;
  }
  .empty-tip {
    padding: 24px;
    text-align: center;
    color: var(--el-text-color-secondary);
  }
  .dialog-body {
    min-height: 320px;
  }
</style>
