<template>
  <ElDialog
    v-model="visible"
    :title="dialogTitle"
    width="min(1000px, 92vw)"
    :close-on-click-modal="false"
    destroy-on-close
    @closed="handleClosed"
  >
    <div class="policy-body">
      <ElAlert
        :title="t('tenantPackage.featurePolicy.hint')"
        type="info"
        show-icon
        :closable="false"
      />

      <ElAlert
        v-if="!isValidJson"
        :title="t('tenantPackage.featurePolicy.invalidJson')"
        type="warning"
        show-icon
        :closable="false"
      />

      <div class="policy-toolbar">
        <ElSpace wrap>
          <ElSelect v-model="selectedPresetKey" class="preset-select" filterable>
            <ElOption v-for="p in presetOptions" :key="p.key" :label="p.label" :value="p.key" />
          </ElSelect>
          <ElButton :disabled="readonly" type="primary" plain @click="handleApplyPreset">
            {{ t('tenantPackage.featurePolicy.applyPreset') }}
          </ElButton>
          <ElTag :type="errors.length ? 'danger' : 'success'">
            {{
              errors.length
                ? t('tenantPackage.featurePolicy.validationFailed', { count: errors.length })
                : t('tenantPackage.featurePolicy.validationPassed')
            }}
          </ElTag>
        </ElSpace>
      </div>

      <ElTabs v-model="activeTab" class="policy-tabs">
        <ElTabPane :label="t('tenantPackage.featurePolicy.tabs.config')" name="config">
          <ElForm :model="model" label-width="140px" :disabled="readonly">
            <div v-for="section in sections" :key="section.key" class="policy-section">
              <ElDivider content-position="left">
                {{ t(section.titleKey) }}
              </ElDivider>

              <ElRow :gutter="12">
                <ElCol
                  v-for="field in section.fields"
                  :key="field.key"
                  :span="field.type === 'multi_boolean' ? 24 : 12"
                >
                  <ElFormItem :label="t(field.labelKey)">
                    <template v-if="field.type === 'boolean'">
                      <ElSwitch
                        :model-value="getBooleanFieldValue(field.key)"
                        @update:model-value="(v) => setFieldValue(field.key, v)"
                      />
                    </template>

                    <template v-else-if="field.type === 'number'">
                      <ElInputNumber
                        class="w-full"
                        :model-value="getNumberFieldValue(field.key)"
                        :min="field.min ?? 0"
                        :controls="false"
                        :disabled="isFieldDisabled(field)"
                        :placeholder="field.placeholderKey ? t(field.placeholderKey) : undefined"
                        @update:model-value="(v) => setFieldValue(field.key, v)"
                      />
                    </template>

                    <template v-else>
                      <ElInput
                        class="w-full"
                        :model-value="getStringFieldValue(field.key)"
                        @update:model-value="(v) => setFieldValue(field.key, v)"
                      />
                    </template>
                  </ElFormItem>
                </ElCol>
              </ElRow>
            </div>
          </ElForm>
        </ElTabPane>

        <ElTabPane :label="t('tenantPackage.featurePolicy.tabs.custom')" name="custom">
          <div class="custom-body">
            <ElAlert
              :title="t('tenantPackage.featurePolicy.customHint')"
              type="info"
              show-icon
              :closable="false"
            />

            <ElTable :data="model.extra.customItems" class="custom-table" size="small">
              <ElTableColumn :label="t('tenantPackage.featurePolicy.custom.key')" width="220">
                <template #default="{ row }">
                  <ElInput v-model="row.key" :disabled="readonly" />
                </template>
              </ElTableColumn>
              <ElTableColumn :label="t('tenantPackage.featurePolicy.custom.label')" width="220">
                <template #default="{ row }">
                  <ElInput v-model="row.label" :disabled="readonly" />
                </template>
              </ElTableColumn>
              <ElTableColumn :label="t('tenantPackage.featurePolicy.custom.type')" width="160">
                <template #default="{ row }">
                  <ElSelect v-model="row.type" :disabled="readonly" class="w-full">
                    <ElOption
                      value="boolean"
                      :label="t('tenantPackage.featurePolicy.custom.typeBoolean')"
                    />
                    <ElOption
                      value="number"
                      :label="t('tenantPackage.featurePolicy.custom.typeNumber')"
                    />
                    <ElOption
                      value="string"
                      :label="t('tenantPackage.featurePolicy.custom.typeString')"
                    />
                  </ElSelect>
                </template>
              </ElTableColumn>
              <ElTableColumn :label="t('tenantPackage.featurePolicy.custom.value')">
                <template #default="{ row }">
                  <ElSwitch
                    v-if="row.type === 'boolean'"
                    v-model="row.value"
                    :disabled="readonly"
                  />
                  <ElInputNumber
                    v-else-if="row.type === 'number'"
                    v-model="row.value"
                    class="w-full"
                    :disabled="readonly"
                    :min="0"
                    :controls="false"
                  />
                  <ElInput v-else v-model="row.value" :disabled="readonly" />
                </template>
              </ElTableColumn>
              <ElTableColumn v-if="!readonly" :label="t('common.action')" width="90" fixed="right">
                <template #default="{ $index }">
                  <ElButton link type="danger" @click="removeCustomItem($index)">
                    {{ t('common.delete') }}
                  </ElButton>
                </template>
              </ElTableColumn>
            </ElTable>

            <div v-if="!readonly" class="custom-actions">
              <ElButton type="primary" plain @click="addCustomItem">
                {{ t('tenantPackage.featurePolicy.custom.add') }}
              </ElButton>
            </div>
          </div>
        </ElTabPane>

        <ElTabPane :label="t('tenantPackage.featurePolicy.tabs.preview')" name="preview">
          <ElInput :model-value="previewJson" type="textarea" :rows="16" readonly />
        </ElTabPane>
      </ElTabs>
    </div>

    <template #footer>
      <ElButton @click="handleCancel">{{ t('common.cancel') }}</ElButton>
      <ElButton v-if="!readonly" type="primary" :disabled="errors.length > 0" @click="handleSave">
        {{ t('common.confirm') }}
      </ElButton>
    </template>
  </ElDialog>
</template>

<script setup lang="ts">
  import { computed, reactive, ref, watch } from 'vue'
  import { useI18n } from 'vue-i18n'
  import { ElMessage, ElMessageBox } from 'element-plus'
  import type { FeaturePolicyCustomItem, FeaturePolicyFieldDef, FeaturePolicyModel } from '../types'
  import {
    FeaturePolicyPresets,
    FeaturePolicySections,
    createDefaultFeaturePolicy,
    parseFeaturePolicyJson,
    serializeFeaturePolicy,
    validateFeaturePolicy
  } from '../types'

  interface Props {
    modelValue: boolean
    value: string
    readonly?: boolean
  }

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

  const props = defineProps<Props>()
  const emit = defineEmits<Emits>()
  const { t } = useI18n()

  // 1. 弹窗状态
  const visible = computed({
    get: () => props.modelValue,
    set: (val) => emit('update:modelValue', val)
  })
  const readonly = computed(() => !!props.readonly)
  const activeTab = ref<'config' | 'custom' | 'preview'>('config')

  // 2. Schema 与模板
  const sections = FeaturePolicySections
  const selectedPresetKey = ref<string>(FeaturePolicyPresets[0]?.key || 'blank')
  const presetOptions = computed(() =>
    FeaturePolicyPresets.map((p) => ({ key: p.key, label: t(p.labelKey), value: p.value }))
  )

  // 3. 数据模型
  const model = reactive<FeaturePolicyModel>(createDefaultFeaturePolicy())
  const isValidJson = ref(true)

  const dialogTitle = computed(() =>
    readonly.value
      ? t('tenantPackage.featurePolicy.titleView')
      : t('tenantPackage.featurePolicy.titleEdit')
  )

  // 4. 字段绑定（用 key-path 映射到 model）
  const previewJson = computed(() => serializeFeaturePolicy(model))
  const errors = computed(() => validateFeaturePolicy(model))

  function getFieldValue(key: string) {
    // 1. 只支持两级：features.xxx / quotas.xxx
    const [group, name] = key.split('.')
    if (group === 'features') return model.features[name]
    if (group === 'quotas') return model.quotas[name]
    return undefined
  }

  function getBooleanFieldValue(key: string): boolean {
    return !!getFieldValue(key)
  }

  function getNumberFieldValue(key: string): number | undefined {
    const value = getFieldValue(key)
    return typeof value === 'number' ? value : undefined
  }

  function getStringFieldValue(key: string): string {
    const value = getFieldValue(key)
    if (value === null || value === undefined) return ''
    return String(value)
  }

  function setFieldValue(key: string, value: any) {
    const [group, name] = key.split('.')
    if (group === 'features') model.features[name] = !!value
    if (group === 'quotas')
      model.quotas[name] = value === '' || value === null || value === undefined ? undefined : value
  }

  function isFieldDisabled(field: FeaturePolicyFieldDef) {
    if (!field.dependsOnKey) return readonly.value
    const dependsValue = !!getFieldValue(field.dependsOnKey)
    return readonly.value || !dependsValue
  }

  // 5. 生命周期：打开时回填
  watch(
    () => visible.value,
    (val) => {
      if (!val) return

      // 1. 回填 JSON
      const res = parseFeaturePolicyJson(props.value)
      isValidJson.value = res.isValidJson
      Object.assign(model, res.model)

      // 2. 默认选择空白模板
      selectedPresetKey.value = FeaturePolicyPresets[0]?.key || 'blank'
      activeTab.value = 'config'
    }
  )

  const handleApplyPreset = async () => {
    if (readonly.value) return
    const preset = FeaturePolicyPresets.find((p) => p.key === selectedPresetKey.value)
    if (!preset) return

    // 1. 二次确认，避免覆盖用户已编辑内容
    try {
      await ElMessageBox.confirm(
        t('tenantPackage.featurePolicy.applyPresetConfirm'),
        t('tenantPackage.featurePolicy.applyPresetTitle'),
        {
          type: 'warning',
          confirmButtonText: t('common.confirm'),
          cancelButtonText: t('common.cancel')
        }
      )
    } catch {
      return
    }

    // 2. 应用模板（保留 extra.customItems 与 unknown）
    const next = createDefaultFeaturePolicy()
    next.extra = model.extra
    Object.assign(next.features, preset.value.features || {})
    Object.assign(next.quotas, preset.value.quotas || {})
    Object.assign(model, next)

    ElMessage.success(t('tenantPackage.featurePolicy.presetApplied'))
  }

  const addCustomItem = () => {
    const item: FeaturePolicyCustomItem = {
      key: '',
      label: '',
      type: 'string',
      value: ''
    }
    model.extra.customItems.push(item)
  }

  const removeCustomItem = (index: number) => {
    model.extra.customItems.splice(index, 1)
  }

  const handleSave = () => {
    if (readonly.value) return
    if (errors.value.length) {
      ElMessage.error(
        t('tenantPackage.featurePolicy.validationFailed', { count: errors.value.length })
      )
      return
    }

    // 1. 输出 JSON 并同步给父组件
    const value = previewJson.value
    emit('update:value', value)
    emit('save', value)

    // 2. 关闭弹窗
    ElMessage.success(t('tenantPackage.featurePolicy.saved'))
    visible.value = false
  }

  const handleCancel = () => {
    visible.value = false
  }

  const handleClosed = () => {
    activeTab.value = 'config'
  }
</script>

<style scoped>
  .policy-body {
    display: flex;
    flex-direction: column;
    gap: 12px;
  }

  .policy-toolbar {
    display: flex;
    justify-content: flex-start;
    width: 100%;
  }

  .preset-select {
    width: 240px;
  }

  .policy-section {
    margin-bottom: 12px;
  }

  .policy-tabs :deep(.el-tabs__content) {
    padding-top: 6px;
  }

  .custom-body {
    display: flex;
    flex-direction: column;
    gap: 12px;
  }

  .custom-actions {
    display: flex;
    justify-content: flex-end;
  }
</style>
