<template>
  <ElDialog
    v-model="visible"
    :title="$t('page.configPage.createRefPreviewTitle')"
    width="860px"
    align-center
    :close-on-click-modal="false"
    @close="handleClose"
  >
    <div v-loading="loading" class="dialog-body">
      <div class="preview-tip">
        <div v-if="meta.unchanged" class="tip-line">
          {{ $t('page.configPage.createRefPreviewTipUnchanged') }}
        </div>
        <div v-else class="tip-line">
          {{ $t('page.configPage.createRefPreviewTipChanged') }}
        </div>
        <div class="tip-line" v-if="meta.skipped > 0">
          {{ $t('page.configPage.createRefPreviewSkipped', { n: meta.skipped }) }}
        </div>
      </div>

      <ElTabs v-model="activeDirection" type="card" class="direction-tabs">
        <ElTabPane :label="$t('page.configPage.createRefPreviewClockwise')" name="0">
          <ElTabs v-model="activeTier" type="card" class="tier-tabs">
            <ElTabPane v-for="t in tierKeys" :key="'cw-' + t" :label="t" :name="t">
              <ElTable
                :data="getTierItems(t, 0)"
                :row-class-name="rowClassName"
                border
                size="small"
                class="preview-table"
              >
                <ElTableColumn :label="$t('page.table.dicePoints')" prop="grid_number" width="90" align="center" />
                <ElTableColumn label="start" prop="start_index" width="78" align="center" />
                <ElTableColumn :label="$t('page.table.endIndex')" prop="id" width="78" align="center" />
                <ElTableColumn :label="$t('page.table.displayText')" prop="ui_text" width="90" align="center" show-overflow-tooltip />
                <ElTableColumn :label="$t('page.table.remark')" prop="remark" min-width="80" align="center" show-overflow-tooltip />
                <ElTableColumn :label="$t('page.table.weight')" width="130" align="center">
                  <template #default="{ row }">
                    <ElInputNumber
                      v-model="row.weight"
                      :min="1"
                      :max="10000"
                      :step="1"
                      controls-position="right"
                      size="small"
                      class="weight-input"
                    />
                  </template>
                </ElTableColumn>
                <ElTableColumn :label="$t('page.configPage.createRefPreviewDiff')" min-width="120" align="center">
                  <template #default="{ row }">
                    <span v-if="row?.diff_changed" class="diff-text">
                      {{ formatDiff(row) }}
                    </span>
                    <span v-else class="diff-text diff-text-ok">{{ $t('page.configPage.createRefPreviewNoDiff') }}</span>
                  </template>
                </ElTableColumn>
              </ElTable>
            </ElTabPane>
          </ElTabs>
        </ElTabPane>

        <ElTabPane :label="$t('page.configPage.createRefPreviewCounterclockwise')" name="1">
          <ElTabs v-model="activeTier" type="card" class="tier-tabs">
            <ElTabPane v-for="t in tierKeys" :key="'ccw-' + t" :label="t" :name="t">
              <ElTable
                :data="getTierItems(t, 1)"
                :row-class-name="rowClassName"
                border
                size="small"
                class="preview-table"
              >
                <ElTableColumn :label="$t('page.table.dicePoints')" prop="grid_number" width="90" align="center" />
                <ElTableColumn label="start" prop="start_index" width="78" align="center" />
                <ElTableColumn :label="$t('page.table.endIndex')" prop="id" width="78" align="center" />
                <ElTableColumn :label="$t('page.table.displayText')" prop="ui_text" width="90" align="center" show-overflow-tooltip />
                <ElTableColumn :label="$t('page.table.remark')" prop="remark" min-width="80" align="center" show-overflow-tooltip />
                <ElTableColumn :label="$t('page.table.weight')" width="120" align="center">
                  <template #default="{ row }">
                    <ElInputNumber
                      v-model="row.weight"
                      :min="1"
                      :max="10000"
                      :step="1"
                      controls-position="right"
                      size="small"
                      class="weight-input"
                    />
                  </template>
                </ElTableColumn>
                <ElTableColumn :label="$t('page.configPage.createRefPreviewDiff')" min-width="120" align="center">
                  <template #default="{ row }">
                    <span v-if="row?.diff_changed" class="diff-text">
                      {{ formatDiff(row) }}
                    </span>
                    <span v-else class="diff-text diff-text-ok">{{ $t('page.configPage.createRefPreviewNoDiff') }}</span>
                  </template>
                </ElTableColumn>
              </ElTable>
            </ElTabPane>
          </ElTabs>
        </ElTabPane>
      </ElTabs>
    </div>

    <template #footer>
      <ElButton @click="refreshPreview" :loading="loading" v-ripple>{{
        $t('page.configPage.createRefPreviewRefresh')
      }}</ElButton>
      <ElButton @click="handleClose" v-ripple>{{ $t('common.cancel') }}</ElButton>
      <ElButton type="primary" :loading="submitting" @click="handleImport" v-ripple>{{
        $t('page.configPage.createRefPreviewImport')
      }}</ElButton>
    </template>
  </ElDialog>
</template>

<script setup lang="ts">
  import { ElMessage } from 'element-plus'
  import { useI18n } from 'vue-i18n'
  import api from '../../../api/reward_config/index'

  const { t } = useI18n()

  const TIER_KEYS = ['T1', 'T2', 'T3', 'T4', 'T5'] as const
  const tierKeys = TIER_KEYS

  interface Props {
    modelValue: boolean
    deptId: number
  }

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

  const props = withDefaults(defineProps<Props>(), {
    modelValue: false,
    deptId: 0
  })
  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 loading = ref(false)
  const submitting = ref(false)

  const meta = reactive<{ unchanged: boolean; skipped: number }>({ unchanged: false, skipped: 0 })
  const preview = ref<Record<string, { 0: any[]; 1: any[] }>>({})

  function rowClassName({ row }: { row: any }): string {
    return row?.diff_changed ? 'row-diff' : ''
  }

  function formatDiff(row: any): string {
    if (!row) return ''
    const oldStart = row.old_start_index != null ? String(row.old_start_index) : '-'
    const oldEnd = row.old_end_index != null ? String(row.old_end_index) : '-'
    const oldTier = row.old_tier != null ? String(row.old_tier) : '-'
    const newStart = row.start_index != null ? String(row.start_index) : '-'
    const newEnd = row.id != null ? String(row.id) : '-'
    const newTier = row.tier != null ? String(row.tier) : '-'
    return `${oldStart}/${oldEnd}/${oldTier} → ${newStart}/${newEnd}/${newTier}`
  }

  function getTierItems(tier: string, direction: 0 | 1): any[] {
    const tierData = preview.value?.[tier]
    if (!tierData) return []
    const rows = direction === 0 ? tierData[0] : tierData[1]
    return Array.isArray(rows) ? rows : []
  }

  async function refreshPreview() {
    loading.value = true
    try {
      const res: any = await api.createRewardReferencePreview({ dept_id: props.deptId })
      const data = res?.data ?? res
      meta.unchanged = Boolean(data?.unchanged)
      meta.skipped = Number(data?.skipped ?? 0)
      preview.value = (data?.preview ?? {}) as any
      activeDirection.value = '0'
      activeTier.value = 'T1'
    } catch (e: any) {
      ElMessage.error(e?.message ?? 'preview failed')
    } finally {
      loading.value = false
    }
  }

  function toWeight(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)))
  }

  function collectDesiredWeights(): Record<string, number> {
    const map: Record<string, number> = {}
    for (const t of tierKeys) {
      const tierData = preview.value?.[t]
      if (!tierData) continue
      const cw = Array.isArray(tierData[0]) ? tierData[0] : []
      const ccw = Array.isArray(tierData[1]) ? tierData[1] : []
      for (const r of cw) {
        const gn = r?.grid_number != null ? Number(r.grid_number) : NaN
        if (!Number.isNaN(gn)) map[`0:${gn}`] = toWeight(r?.weight)
      }
      for (const r of ccw) {
        const gn = r?.grid_number != null ? Number(r.grid_number) : NaN
        if (!Number.isNaN(gn)) map[`1:${gn}`] = toWeight(r?.weight)
      }
    }
    return map
  }

  async function applyWeights(desired: Record<string, number>) {
    const res: any = await api.weightRatioList({ dept_id: props.deptId })
    const raw = res?.data ?? res
    const items: Array<{ id: number; weight: number }> = []
    for (const t of tierKeys) {
      const tierData = raw?.[t]
      if (!tierData) continue
      const list0 = Array.isArray(tierData[0]) ? tierData[0] : []
      const list1 = Array.isArray(tierData[1]) ? tierData[1] : []
      for (const r of list0) {
        const rid = r?.reward_id != null ? Number(r.reward_id) : 0
        const gn = r?.grid_number != null ? Number(r.grid_number) : NaN
        if (rid > 0 && !Number.isNaN(gn)) {
          const w = desired[`0:${gn}`]
          if (w != null) items.push({ id: rid, weight: w })
        }
      }
      for (const r of list1) {
        const rid = r?.reward_id != null ? Number(r.reward_id) : 0
        const gn = r?.grid_number != null ? Number(r.grid_number) : NaN
        if (rid > 0 && !Number.isNaN(gn)) {
          const w = desired[`1:${gn}`]
          if (w != null) items.push({ id: rid, weight: w })
        }
      }
    }
    if (items.length > 0) {
      await api.batchUpdateWeights(items, { dept_id: props.deptId })
    }
  }

  async function handleImport() {
    submitting.value = true
    try {
      const desired = collectDesiredWeights()
      if (!meta.unchanged) {
        await api.createRewardReference({ dept_id: props.deptId })
        await applyWeights(desired)
        ElMessage.success(t('page.configPage.createRefPreviewImportOk'))
      } else {
        // 映射未变化：直接保存权重即可
        await applyWeights(desired)
        ElMessage.success(t('page.configPage.createRefPreviewWeightsSaved'))
      }
      emit('success')
      handleClose()
    } catch (e: any) {
      ElMessage.error(e?.message ?? 'import failed')
    } finally {
      submitting.value = false
    }
  }

  function handleClose() {
    visible.value = false
  }

  watch(
    () => props.modelValue,
    (open) => {
      if (open) {
        refreshPreview()
      }
    }
  )
</script>

<style scoped lang="scss">
  .dialog-body {
    min-height: 120px;
  }
  .preview-tip {
    margin-bottom: 8px;
    padding: 8px 10px;
    font-size: 12px;
    color: var(--el-text-color-regular);
    background: var(--el-fill-color-light);
    border-radius: 6px;
    line-height: 1.5;
  }
  .tip-line + .tip-line {
    margin-top: 4px;
  }
  .preview-table {
    margin-top: 4px;
  }
  .weight-input {
    width: 110px;
  }
  :deep(.row-diff td) {
    background: var(--el-color-warning-light-9);
  }
  .diff-text {
    color: var(--el-text-color-regular);
    font-size: 12px;
    line-height: 1.2;
    word-break: break-all;
  }
  .diff-text-ok {
    color: var(--el-text-color-secondary);
  }

  /* 减少弹窗内容区与表格留白 */
  :deep(.el-dialog__body) {
    padding: 12px 14px;
  }
  :deep(.el-tabs__header) {
    margin: 0 0 8px 0;
  }
  :deep(.el-tabs__item) {
    height: 34px;
    line-height: 34px;
  }
  :deep(.el-table .cell) {
    padding: 4px 6px;
  }
  :deep(.el-table__row) {
    height: 34px;
  }
</style>

