<script setup lang="ts">
import { ElMessage } from 'element-plus'
import { ref, watch } from 'vue'

import {
  emptyListingPublishOptions,
  mergeListingPublishOptions,
  type ListingPublishOptions,
} from '@/features/listings/api/listingOptions'
import { updateSystemConfig, type SystemConfig } from '@/features/admin/api/systemConfigs'
import { safeParseJSON } from '@/utils/json'

const props = defineProps<{
  modelValue: boolean
  config: SystemConfig
}>()

const emit = defineEmits<{
  (e: 'update:modelValue', val: boolean): void
  (e: 'saved'): void
}>()

const submitting = ref(false)
const description = ref('')
const publishOptionsDraft = ref<ListingPublishOptions>(cloneOptions(emptyListingPublishOptions))

watch(
  () => props.modelValue,
  (val) => {
    if (val) {
      publishOptionsDraft.value = parsePublishOptions(props.config.value)
      description.value = props.config.description || ''
    }
  },
  { immediate: true }
)

function parsePublishOptions(raw: string) {
  const parsed = safeParseJSON(raw, emptyListingPublishOptions)
  return cloneOptions(mergeListingPublishOptions(parsed))
}

function cloneOptions(options: ListingPublishOptions) {
  return JSON.parse(JSON.stringify(options)) as ListingPublishOptions
}

function linesToItems(value: string) {
  return value
    .split('\n')
    .map((item) => item.trim())
    .filter(Boolean)
}

function itemsToLines(items: string[]) {
  return items.join('\n')
}

function updateOptionLines(
  key: keyof Pick<
    ListingPublishOptions,
    | 'server_options'
    | 'face_options'
    | 'rank_options'
    | 'insurance_options'
    | 'level_options'
    | 'login_method_options'
    | 'region_options'
    | 'ban_record_options'
    | 'ban_evidence_options'
  >,
  nextValue: string
) {
  publishOptionsDraft.value[key] = linesToItems(nextValue)
}

function updateSkinGroupOptions(index: number, nextValue: string) {
  const group = publishOptionsDraft.value.skin_groups[index]
  if (group) {
    group.options = linesToItems(nextValue)
  }
}

function addSkinGroup() {
  publishOptionsDraft.value.skin_groups.push({
    key: `group_${Date.now()}`,
    title: '新皮肤分类',
    options: [],
  })
}

function removeSkinGroup(index: number) {
  publishOptionsDraft.value.skin_groups.splice(index, 1)
}

function addQuantityItem() {
  publishOptionsDraft.value.quantity_items.push({
    key: `item_${Date.now()}`,
    label: '',
    price: '',
  })
}

function removeQuantityItem(index: number) {
  publishOptionsDraft.value.quantity_items.splice(index, 1)
}

function addScreenshotSlot() {
  publishOptionsDraft.value.screenshot_slots.push({
    key: `screenshot_${Date.now()}`,
    label: '',
    required: false,
    hint: '',
  })
}

function removeScreenshotSlot(index: number) {
  publishOptionsDraft.value.screenshot_slots.splice(index, 1)
}

function addInsuranceBaseRatio() {
  publishOptionsDraft.value.ratio_config.insurance_base_ratios.push({
    insurance: '',
    ratio: 0,
  })
}

function removeInsuranceBaseRatio(index: number) {
  publishOptionsDraft.value.ratio_config.insurance_base_ratios.splice(index, 1)
}

function addRatioConfigItem() {
  publishOptionsDraft.value.ratio_config.config_items.push({
    key: `config_${Date.now()}`,
    label: '',
    kind: 'skin_group',
    group_key: '',
    missing_penalty: 1,
  })
}

function removeRatioConfigItem(index: number) {
  publishOptionsDraft.value.ratio_config.config_items.splice(index, 1)
}

function addCoinCorrection() {
  publishOptionsDraft.value.ratio_config.coin_corrections.push({
    threshold_m: 0,
    correction: 0,
  })
}

function removeCoinCorrection(index: number) {
  publishOptionsDraft.value.ratio_config.coin_corrections.splice(index, 1)
}

function addDepositSkinGroupRule() {
  publishOptionsDraft.value.deposit_recommend_config.skin_group_rules.push({
    group_key: '',
    label: '',
    amount_per_item: 0,
  })
}

function removeDepositSkinGroupRule(index: number) {
  publishOptionsDraft.value.deposit_recommend_config.skin_group_rules.splice(index, 1)
}

async function handleSave() {
  submitting.value = true
  try {
    const value = JSON.stringify(publishOptionsDraft.value, null, 2)
    await updateSystemConfig(props.config.key, {
      value,
      description: description.value,
    })
    ElMessage.success('配置已更新')
    emit('saved')
    emit('update:modelValue', false)
  } catch (error) {
    ElMessage.error(readError(error, '保存失败'))
  } finally {
    submitting.value = false
  }
}

function readError(error: unknown, fallback: string) {
  if (typeof error === 'object' && error && 'response' in error) {
    const response = (error as { response?: { data?: { message?: string } } }).response
    return response?.data?.message || fallback
  }
  return fallback
}
</script>

<template>
  <el-dialog
    :model-value="modelValue"
    title="编辑发布选项配置"
    width="920px"
    @update:model-value="emit('update:modelValue', $event)"
  >
    <div class="dialog-body">
      <p class="config-key-label"><strong>{{ config.key }}</strong></p>

      <div class="publish-options-editor">
        <div class="editor-toolbar">
          <span>发布页选项配置</span>
        </div>

        <div class="editor-grid">
          <el-form-item label="区服">
            <el-input
              :model-value="itemsToLines(publishOptionsDraft.server_options)"
              type="textarea"
              :rows="4"
              placeholder="一行一个选项"
              @update:model-value="updateOptionLines('server_options', $event)"
            />
          </el-form-item>
          <el-form-item label="段位">
            <el-input
              :model-value="itemsToLines(publishOptionsDraft.rank_options)"
              type="textarea"
              :rows="4"
              placeholder="一行一个选项"
              @update:model-value="updateOptionLines('rank_options', $event)"
            />
          </el-form-item>
          <el-form-item label="保险">
            <el-input
              :model-value="itemsToLines(publishOptionsDraft.insurance_options)"
              type="textarea"
              :rows="4"
              placeholder="一行一个选项"
              @update:model-value="updateOptionLines('insurance_options', $event)"
            />
          </el-form-item>
          <el-form-item label="体力/负重">
            <el-input
              :model-value="itemsToLines(publishOptionsDraft.level_options)"
              type="textarea"
              :rows="4"
              placeholder="一行一个选项"
              @update:model-value="updateOptionLines('level_options', $event)"
            />
          </el-form-item>
          <el-form-item label="人脸选项">
            <el-input
              :model-value="itemsToLines(publishOptionsDraft.face_options)"
              type="textarea"
              :rows="3"
              placeholder="一行一个选项"
              @update:model-value="updateOptionLines('face_options', $event)"
            />
          </el-form-item>
          <el-form-item label="上号方式">
            <el-input
              :model-value="itemsToLines(publishOptionsDraft.login_method_options)"
              type="textarea"
              :rows="3"
              placeholder="一行一个选项"
              @update:model-value="updateOptionLines('login_method_options', $event)"
            />
          </el-form-item>
        </div>

        <el-form-item label="常用登录地区">
          <el-input
            :model-value="itemsToLines(publishOptionsDraft.region_options)"
            type="textarea"
            :rows="5"
            placeholder="一行一个省市"
            @update:model-value="updateOptionLines('region_options', $event)"
          />
        </el-form-item>

        <div class="editor-grid">
          <el-form-item label="封禁记录">
            <el-input
              :model-value="itemsToLines(publishOptionsDraft.ban_record_options)"
              type="textarea"
              :rows="3"
              placeholder="一行一个选项"
              @update:model-value="updateOptionLines('ban_record_options', $event)"
            />
          </el-form-item>
          <el-form-item label="需传安全图">
            <el-input
              :model-value="itemsToLines(publishOptionsDraft.ban_evidence_options)"
              type="textarea"
              :rows="3"
              placeholder="选择这些封禁记录时，腾讯安全中心截图必传"
              @update:model-value="updateOptionLines('ban_evidence_options', $event)"
            />
          </el-form-item>
        </div>

        <div class="editor-block">
          <div class="editor-block-title">
            <strong>发布规则</strong>
          </div>
          <el-form-item label="最低烽火等级">
            <el-input-number v-model="publishOptionsDraft.fire_level_min" :min="1" :step="1" class="full-control" />
          </el-form-item>
        </div>

        <div class="editor-block">
          <div class="editor-block-title">
            <strong>押金与价格提示</strong>
          </div>
          <el-form-item label="押金提示">
            <el-input v-model="publishOptionsDraft.price_config.deposit_placeholder" type="textarea" :rows="3" />
          </el-form-item>
          <el-form-item label="价格提示">
            <el-input v-model="publishOptionsDraft.price_config.price_placeholder" class="full-control" />
          </el-form-item>
          <el-form-item label="比例说明">
            <el-input v-model="publishOptionsDraft.price_config.ratio_description" class="full-control" />
          </el-form-item>
        </div>

        <div class="editor-block">
          <div class="editor-block-title">
            <strong>智能推荐押金</strong>
            <el-button size="small" @click="addDepositSkinGroupRule">添加皮肤规则</el-button>
          </div>
          <el-form-item label="基础押金">
            <el-input-number
              v-model="publishOptionsDraft.deposit_recommend_config.base_amount"
              :min="0"
              :step="5"
              class="full-control"
            />
          </el-form-item>
          <el-table :data="publishOptionsDraft.deposit_recommend_config.skin_group_rules" size="small" border>
            <el-table-column label="皮肤分组 Key" min-width="150">
              <template #default="{ row }"><el-input v-model="row.group_key" placeholder="operatorRed" /></template>
            </el-table-column>
            <el-table-column label="名称" min-width="140">
              <template #default="{ row }"><el-input v-model="row.label" placeholder="干员红皮" /></template>
            </el-table-column>
            <el-table-column label="每个增加押金" min-width="140">
              <template #default="{ row }"><el-input-number v-model="row.amount_per_item" :min="0" :step="5" /></template>
            </el-table-column>
            <el-table-column label="操作" width="90">
              <template #default="{ $index }">
                <el-button size="small" type="danger" plain @click="removeDepositSkinGroupRule($index)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>

        <div class="editor-block">
          <div class="editor-block-title">
            <strong>比例计算配置</strong>
          </div>
          <div class="editor-block-title subtle-title">
            <span>保险基础比例</span>
            <el-button size="small" @click="addInsuranceBaseRatio">添加保险比例</el-button>
          </div>
          <el-table :data="publishOptionsDraft.ratio_config.insurance_base_ratios" size="small" border>
            <el-table-column label="保险" min-width="160">
              <template #default="{ row }"><el-input v-model="row.insurance" placeholder="3*3" /></template>
            </el-table-column>
            <el-table-column label="基础比例" min-width="120">
              <template #default="{ row }"><el-input-number v-model="row.ratio" :min="0" :step="0.5" /></template>
            </el-table-column>
            <el-table-column label="操作" width="90">
              <template #default="{ $index }">
                <el-button size="small" type="danger" plain @click="removeInsuranceBaseRatio($index)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>

          <div class="editor-block-title subtle-title">
            <span>配置项缺失加成</span>
            <el-button size="small" @click="addRatioConfigItem">添加配置项</el-button>
          </div>
          <el-table :data="publishOptionsDraft.ratio_config.config_items" size="small" border>
            <el-table-column label="Key" min-width="140">
              <template #default="{ row }"><el-input v-model="row.key" /></template>
            </el-table-column>
            <el-table-column label="名称" min-width="140">
              <template #default="{ row }"><el-input v-model="row.label" /></template>
            </el-table-column>
            <el-table-column label="类型" min-width="160">
              <template #default="{ row }">
                <el-select v-model="row.kind">
                  <el-option label="皮肤分组" value="skin_group" />
                  <el-option label="满体力" value="max_stamina" />
                  <el-option label="满负重" value="max_load" />
                </el-select>
              </template>
            </el-table-column>
            <el-table-column label="皮肤分组 Key" min-width="150">
              <template #default="{ row }"><el-input v-model="row.group_key" /></template>
            </el-table-column>
            <el-table-column label="缺失加成" min-width="120">
              <template #default="{ row }"><el-input-number v-model="row.missing_penalty" :min="0" :step="0.5" /></template>
            </el-table-column>
            <el-table-column label="操作" width="90">
              <template #default="{ $index }">
                <el-button size="small" type="danger" plain @click="removeRatioConfigItem($index)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>

          <div class="editor-block-title subtle-title">
            <span>大额币修正</span>
            <el-button size="small" @click="addCoinCorrection">添加修正</el-button>
          </div>
          <el-table :data="publishOptionsDraft.ratio_config.coin_corrections" size="small" border>
            <el-table-column label="大于 M" min-width="130">
              <template #default="{ row }"><el-input-number v-model="row.threshold_m" :min="0" :step="10" /></template>
            </el-table-column>
            <el-table-column label="比例加成" min-width="130">
              <template #default="{ row }"><el-input-number v-model="row.correction" :min="0" :step="0.5" /></template>
            </el-table-column>
            <el-table-column label="操作" width="90">
              <template #default="{ $index }">
                <el-button size="small" type="danger" plain @click="removeCoinCorrection($index)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>

        <div class="editor-block">
          <div class="editor-block-title">
            <strong>皮肤分类</strong>
            <el-button size="small" @click="addSkinGroup">添加分类</el-button>
          </div>
          <div v-for="(group, index) in publishOptionsDraft.skin_groups" :key="`${group.key}-${index}`" class="skin-config-row">
            <el-input v-model="group.key" placeholder="分类 key" />
            <el-input v-model="group.title" placeholder="分类名称" />
            <el-input
              :model-value="itemsToLines(group.options)"
              type="textarea"
              :rows="4"
              placeholder="皮肤名称，一行一个"
              @update:model-value="updateSkinGroupOptions(index, $event)"
            />
            <el-button type="danger" plain @click="removeSkinGroup(index)">删除</el-button>
          </div>
        </div>

        <div class="editor-block">
          <div class="editor-block-title">
            <strong>额外消耗品</strong>
            <el-button size="small" @click="addQuantityItem">添加消耗品</el-button>
          </div>
          <el-table :data="publishOptionsDraft.quantity_items" size="small" border>
            <el-table-column label="Key" min-width="150">
              <template #default="{ row }"><el-input v-model="row.key" /></template>
            </el-table-column>
            <el-table-column label="名称" min-width="150">
              <template #default="{ row }"><el-input v-model="row.label" /></template>
            </el-table-column>
            <el-table-column label="价格" min-width="130">
              <template #default="{ row }"><el-input v-model="row.price" /></template>
            </el-table-column>
            <el-table-column label="提示" min-width="220">
              <template #default="{ row }"><el-input v-model="row.placeholder" /></template>
            </el-table-column>
            <el-table-column label="操作" width="90">
              <template #default="{ $index }">
                <el-button size="small" type="danger" plain @click="removeQuantityItem($index)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>

        <div class="editor-block">
          <div class="editor-block-title">
            <strong>截图材料</strong>
            <el-button size="small" @click="addScreenshotSlot">添加截图项</el-button>
          </div>
          <el-table :data="publishOptionsDraft.screenshot_slots" size="small" border>
            <el-table-column label="Key" min-width="150">
              <template #default="{ row }"><el-input v-model="row.key" /></template>
            </el-table-column>
            <el-table-column label="名称" min-width="150">
              <template #default="{ row }"><el-input v-model="row.label" /></template>
            </el-table-column>
            <el-table-column label="必填" width="90">
              <template #default="{ row }"><el-switch v-model="row.required" /></template>
            </el-table-column>
            <el-table-column label="提示" min-width="260">
              <template #default="{ row }"><el-input v-model="row.hint" /></template>
            </el-table-column>
            <el-table-column label="操作" width="90">
              <template #default="{ $index }">
                <el-button size="small" type="danger" plain @click="removeScreenshotSlot($index)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>

      <el-form-item label="配置说明" class="desc-item">
        <el-input v-model="description" type="textarea" :rows="3" placeholder="配置说明" />
      </el-form-item>
    </div>
    <template #footer>
      <el-button @click="emit('update:modelValue', false)">取消</el-button>
      <el-button type="primary" :loading="submitting" @click="handleSave">保存</el-button>
    </template>
  </el-dialog>
</template>

<style scoped>
.dialog-body {
  display: grid;
  gap: 16px;
  max-height: 65vh;
  overflow-y: auto;
  padding-right: 8px;
}

.config-key-label {
  margin: 0;
  color: #374151;
}

.publish-options-editor {
  display: grid;
  gap: 16px;
}

.editor-toolbar,
.editor-block-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.editor-toolbar span {
  color: #30343a;
  font-weight: 700;
}

.editor-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.editor-block {
  display: grid;
  gap: 10px;
}

.subtle-title {
  margin-top: 6px;
  color: #4b5563;
  font-size: 13px;
}

.skin-config-row {
  display: grid;
  grid-template-columns: 140px 180px minmax(0, 1fr) 72px;
  gap: 8px;
  align-items: start;
}

.full-control {
  width: 100%;
}

.desc-item {
  margin-top: 14px;
  margin-bottom: 0;
}
</style>
