<template>
  <div class="rule-editor">
    <a-form ref="ruleFormRef" :model="{ rules: localRules }" layout="vertical">
      <div v-if="localRules.length === 0" class="empty-rules">
        <a-empty description="暂无规则，请点击上方按钮添加" />
      </div>

      <div v-else class="rules-container">
        <a-card
          v-for="(rule, index) in localRules"
          :key="index"
          class="rule-card"
          :title="`规则 ${index + 1}: ${rule.name || '未命名'}`"
        >
          <template #extra>
            <a-button type="text" size="small" status="danger" @click="handleRemoveRule(index)">
              <template #icon><icon-delete /></template>
              删除
            </a-button>
          </template>

          <!-- 第一行：基本信息 -->
          <div class="rule-section">
            <div class="section-title">基本信息</div>
            <a-row :gutter="16">
              <a-col :xs="24" :sm="12" :md="6">
                <a-form-item label="规则名称" :field="`rules[${index}].name`" :rules="getRuleFieldRules('name')">
                  <a-input v-model="rule.name" placeholder="请输入规则名称" @change="syncUpdate(index)" />
                </a-form-item>
              </a-col>
              <a-col :xs="24" :sm="12" :md="6">
                <a-form-item label="数据源" :field="`rules[${index}].data_source`" :rules="getRuleFieldRules('data_source')">
                  <a-select v-model="rule.data_source" placeholder="请选择" @change="handleRuleDataSourceChange(index)">
                    <a-option v-for="item in DATA_SOURCES" :key="item.value" :value="item.value">
                      {{ item.label }}
                    </a-option>
                  </a-select>
                </a-form-item>
              </a-col>
              <a-col :xs="24" :sm="12" :md="6">
                <a-form-item label="指标名称" :field="`rules[${index}].metric_name`" :rules="getRuleFieldRules('metric_name')">
                  <a-select
                    v-model="rule.metric_name"
                    placeholder="请选择指标"
                    allow-search
                    :loading="rule._metricsLoading"
                    @dropdown-visible-change="handleMetricsDropdownChange($event, index)"
                    @change="syncUpdate(index)"
                  >
                    <a-option v-for="metric in rule._metrics" :key="metric.metric_name" :value="metric.metric_name">
                      {{ metric.metric_name }} ({{ metric.metric_unit || '无单位' }})
                    </a-option>
                  </a-select>
                </a-form-item>
              </a-col>
              <a-col :xs="24" :sm="12" :md="6">
                <a-form-item label="告警级别" :field="`rules[${index}].severity_code`" :rules="getRuleFieldRules('severity_code')">
                  <a-select
                    v-model="rule.severity_code"
                    placeholder="请选择"
                    :loading="severityLoading"
                    allow-search
                    :filter-option="false"
                    @search="handleSeveritySearch"
                    @dropdown-visible-change="handleSeverityDropdownChange"
                    @change="syncUpdate(index)"
                  >
                    <a-option v-for="item in localSeverityOptions" :key="item.code" :value="item.code">
                      {{ item.name }}
                    </a-option>
                  </a-select>
                </a-form-item>
              </a-col>
            </a-row>
          </div>

          <!-- 第二行：条件配置 -->
          <div class="rule-section">
            <div class="section-title">触发条件</div>
            <a-row :gutter="16">
              <a-col :xs="24" :sm="12" :md="6">
                <a-form-item label="规则类型" :field="`rules[${index}].rule_type`" :rules="getRuleFieldRules('rule_type')">
                  <a-select v-model="rule.rule_type" placeholder="请选择" @change="syncUpdate(index)">
                    <a-option v-for="item in RULE_TYPES" :key="item.value" :value="item.value">
                      {{ item.label }}
                    </a-option>
                  </a-select>
                </a-form-item>
              </a-col>
              <a-col :xs="24" :sm="12" :md="6">
                <a-form-item label="比较运算符" :field="`rules[${index}].compare_op`" :rules="getRuleFieldRules('compare_op')">
                  <a-select v-model="rule.compare_op" placeholder="请选择" @change="syncUpdate(index)">
                    <a-option v-for="item in COMPARE_OPERATORS" :key="item.value" :value="item.value">
                      {{ item.label }}
                    </a-option>
                  </a-select>
                </a-form-item>
              </a-col>
              <a-col :xs="24" :sm="12" :md="6">
                <a-form-item label="阈值" :field="`rules[${index}].threshold`" :rules="getRuleFieldRules('threshold')">
                  <a-input-number v-model="rule.threshold" placeholder="请输入阈值" style="width: 100%" @change="syncUpdate(index)" />
                </a-form-item>
              </a-col>
              <a-col :xs="24" :sm="12" :md="6">
                <a-form-item label="持续时间" :field="`rules[${index}].duration`" :rules="getRuleFieldRules('duration')">
                  <a-input-number v-model="rule.duration" placeholder="请输入" :min="0" style="width: 100%" @change="syncUpdate(index)">
                    <template #suffix>秒</template>
                  </a-input-number>
                </a-form-item>
              </a-col>
            </a-row>
          </div>

          <!-- 第三行：评估配置 -->
          <div class="rule-section">
            <div class="section-title">评估配置</div>
            <a-row :gutter="16">
              <a-col :xs="24" :sm="12" :md="6">
                <a-form-item label="评估间隔" :field="`rules[${index}].eval_interval`" :rules="getRuleFieldRules('eval_interval')">
                  <a-input-number v-model="rule.eval_interval" placeholder="请输入" :min="0" style="width: 100%" @change="syncUpdate(index)">
                    <template #suffix>秒</template>
                  </a-input-number>
                </a-form-item>
              </a-col>
            </a-row>
          </div>
        </a-card>
      </div>
    </a-form>
  </div>
</template>

<script lang="ts" setup>
import { ref, watch } from 'vue'
import type { FormInstance } from '@arco-design/web-vue'
import {
  fetchSeverityOptions,
  fetchMetricsMeta,
  DATA_SOURCES,
  COMPARE_OPERATORS,
  RULE_TYPES,
  type AlertRule,
  type AlertSeverity,
  type MetricMeta,
} from '@/api/ops/alertTemplate'

interface RuleItem extends AlertRule {
  _metrics?: MetricMeta[]
  _metricsLoading?: boolean
}

const props = defineProps<{
  rules: RuleItem[]
  severityOptions: AlertSeverity[]
}>()

const emit = defineEmits<{
  (e: 'update:rules', value: RuleItem[]): void
  (e: 'remove', index: number): void
}>()

// 表单引用
const ruleFormRef = ref<FormInstance | null>(null)

// 本地规则数据（深拷贝）
const localRules = ref<RuleItem[]>([])

// 告警级别下拉选项（支持搜索后局部刷新）
const baseSeverityOptions = ref<AlertSeverity[]>([])
const localSeverityOptions = ref<AlertSeverity[]>([])
const severityLoading = ref(false)

// 监听 props 变化，深拷贝到本地
watch(
  () => props.rules,
  (val) => {
    localRules.value = JSON.parse(JSON.stringify(val))
  },
  { immediate: true, deep: true }
)

// 初始化/同步告警级别选项
watch(
  () => props.severityOptions,
  (val) => {
    baseSeverityOptions.value = val || []
    localSeverityOptions.value = val || []
  },
  { immediate: true },
)

let severitySearchTimer: ReturnType<typeof setTimeout> | null = null

const loadSeverityOptions = async (keyword?: string) => {
  severityLoading.value = true
  try {
    const res: any = await fetchSeverityOptions({
      keyword: keyword || undefined,
      enabled: 'true',
    })

    const list = Array.isArray(res?.details)
      ? res.details
      : res?.details?.data || res?.details?.list || res?.data || res
    const fetchedOptions = Array.isArray(list) ? list : []

    // 合并当前已选值，防止搜索后 options 缩小导致已选项标签无法展示
    const selectedCodes = new Set(
      localRules.value
        .map((r) => r?.severity_code)
        .filter((v): v is string => typeof v === 'string' && v.length > 0),
    )
    const selectedOptions = baseSeverityOptions.value.filter((s) => selectedCodes.has(s.code))

    const mergedMap = new Map<string, AlertSeverity>()
    ;[...fetchedOptions, ...selectedOptions].forEach((item) => {
      if (item?.code) {
        mergedMap.set(item.code, item)
      }
    })

    localSeverityOptions.value = Array.from(mergedMap.values())
  } catch (error) {
    console.error('加载告警级别下拉选项失败:', error)
  } finally {
    severityLoading.value = false
  }
}

const handleSeverityDropdownChange = (visible: boolean) => {
  if (visible && localSeverityOptions.value.length === 0) {
    loadSeverityOptions()
  }
}

const handleSeveritySearch = (keyword: string) => {
  if (severitySearchTimer) {
    clearTimeout(severitySearchTimer)
  }

  severitySearchTimer = setTimeout(() => {
    loadSeverityOptions(keyword)
  }, 300)
}

// 动态生成验证规则
const getRuleFieldRules = (field: string) => {
  const messages: Record<string, string> = {
    name: '请输入规则名称',
    data_source: '请选择数据源',
    metric_name: '请选择指标名称',
    rule_type: '请选择规则类型',
    compare_op: '请选择比较运算符',
    threshold: '请输入阈值',
    duration: '请输入持续时间',
    eval_interval: '请输入评估间隔',
    severity_code: '请选择告警级别',
  }
  return [{ required: true, message: messages[field] || '该字段为必填项' }]
}

// 暴露验证方法给父组件
const validate = async () => {
  return ruleFormRef.value?.validate()
}

defineExpose({
  validate,
})

// 同步更新到父组件
const syncUpdate = (index: number) => {
  const newRules = [...props.rules]
  const { _metrics, _metricsLoading, ...rest } = localRules.value[index]
  newRules[index] = { ...rest, _metrics, _metricsLoading } as RuleItem
  emit('update:rules', newRules)
}

// 移除规则
const handleRemoveRule = (index: number) => {
  emit('remove', index)
}

// 规则数据源变化
const handleRuleDataSourceChange = (index: number) => {
  localRules.value[index].metric_name = ''
  localRules.value[index]._metrics = []
  syncUpdate(index)
  // 数据源变化后自动加载指标
  handleLoadMetrics(index)
}

// 下拉框展开时加载指标（备用触发）
const handleMetricsDropdownChange = (visible: boolean, index: number) => {
  if (visible) {
    handleLoadMetrics(index)
  }
}

// 加载指标
const handleLoadMetrics = async (index: number) => {
  // 每次都重新获取引用，避免引用失效
  if (!localRules.value[index]?.data_source) {
    return
  }
  if (localRules.value[index]._metrics && localRules.value[index]._metrics!.length > 0) {
    return
  }

  localRules.value[index]._metricsLoading = true
  
  try {
    const res: any = await fetchMetricsMeta({
      data_source: localRules.value[index].data_source,
      limit: 500,
    })

    if (res.code === 0) {
      localRules.value[index]._metrics = res.details?.metrics || []
      // 同步更新到父组件
      syncUpdate(index)
    }
  } catch (error) {
    console.error('加载指标失败:', error)
  } finally {
    localRules.value[index]._metricsLoading = false
  }
}
</script>

<script lang="ts">
export default {
  name: 'RuleEditor',
}
</script>

<style scoped lang="less">
.rule-editor {
  height: 100%;
}

.empty-rules {
  padding: 40px 20px;
  text-align: center;
}

.rules-container {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.rule-card {
  :deep(.arco-card-header) {
    border-bottom: 1px solid var(--color-border);
    background-color: var(--color-fill-1);
  }
  
  :deep(.arco-card-body) {
    padding: 16px;
  }
}

.rule-section {
  margin-bottom: 16px;
  
  &:last-child {
    margin-bottom: 0;
  }
  
  .section-title {
    font-size: 13px;
    font-weight: 500;
    color: var(--color-text-2);
    margin-bottom: 12px;
    padding-left: 8px;
    border-left: 3px solid rgb(var(--primary-6));
  }
}

// 表单项样式
:deep(.arco-form-item) {
  margin-bottom: 0;
}

// 响应式布局
@media (max-width: 768px) {
  .rule-card {
    :deep(.arco-card-body) {
      padding: 12px;
    }
  }
  
  .rule-section {
    .section-title {
      margin-bottom: 8px;
    }
  }
  
  :deep(.arco-form-item) {
    margin-bottom: 12px;
  }
}
</style>