<script setup lang="ts">
import type { DataPushRule } from '#/api-client';

import { ref, toRaw, watch } from 'vue';

import { Button, Input, Select, Switch } from 'ant-design-vue';

defineOptions({
  name: 'DataPushRuleEditor',
});

const props = defineProps<{
  // 是否禁用编辑（如设备未开启"覆盖产品配置"时）
  disabled?: boolean;
  rules?: DataPushRule[] | null;
}>();

const emit = defineEmits<{
  (e: 'update:rules', value: DataPushRule[]): void;
}>();

// 数据类型 / 推送方式：与后端字符串枚举一一对应（生成的契约为字符串字面量）
const dataTypeOptions = [
  { label: '属性', value: 'Property' },
  { label: '事件', value: 'Event' },
  { label: '状态', value: 'Status' },
];
const pushTypeOptions = [
  { label: 'HTTP POST', value: 'HttpPost' },
  { label: 'Redis 普通订阅', value: 'NormalReisSubscription' },
  { label: 'Redis 可靠订阅', value: 'ReliableReisSubscription' },
  { label: 'Redis List', value: 'RedisListPush' },
];

// 内部维护一份可编辑副本，变更后回抛给父级
let seed = 0;
// 记录最近一次抛出的数组引用：用于识别 v-model 回环，避免重建 list 导致输入框失焦
let lastEmitted: DataPushRule[] | null = null;
const list = ref<(DataPushRule & { _key: number })[]>([]);

watch(
  () => props.rules,
  (val) => {
    // 跳过自身 emit 造成的回环，仅在外部真正替换数据时重建。
    // 注意：父级用 ref 存储时会把数组包成 reactive 代理，故须用 toRaw 比较原始引用。
    if (toRaw(val) === lastEmitted) {
      return;
    }
    list.value = Array.isArray(val)
      ? val.map((r) => ({ ...r, _key: seed++ }))
      : [];
  },
  { immediate: true },
);

function emitChange() {
  // 抛出时剥离内部 _key，仅回传契约字段
  const out = list.value.map((r) => ({
    ruleName: r.ruleName,
    enabled: r.enabled,
    dataType: r.dataType,
    includeNames: r.includeNames ?? null,
    pushType: r.pushType,
    pushServer: r.pushServer,
    pushInfo: r.pushInfo,
  }));
  lastEmitted = out;
  emit('update:rules', out);
}

function addRule() {
  list.value.push({
    _key: seed++,
    ruleName: '',
    enabled: true,
    dataType: 'Property',
    includeNames: null,
    pushType: 'HttpPost',
    pushServer: '',
    pushInfo: '',
  });
  emitChange();
}

function removeRule(index: number) {
  list.value.splice(index, 1);
  emitChange();
}
</script>

<template>
  <div>
    <!-- 表头 -->
    <div class="mb-1 flex items-center gap-2 text-xs text-gray-500">
      <span class="w-[44px] flex-shrink-0">启用</span>
      <span class="w-[96px] flex-shrink-0">数据类型</span>
      <span class="w-[150px] flex-shrink-0">推送方式</span>
      <span class="flex-1">服务地址</span>
      <span class="flex-1">路径 / 主题 / KEY</span>
      <span class="w-[120px] flex-shrink-0">备注</span>
      <span class="w-[48px] flex-shrink-0">操作</span>
    </div>
    <!-- 规则行：用稳定 key 的 v-for，避免输入时被重建导致失焦 -->
    <div
      v-for="(item, index) in list"
      :key="item._key"
      class="mb-2 flex items-center gap-2"
    >
      <span class="w-[44px] flex-shrink-0">
        <Switch
          v-model:checked="item.enabled"
          size="small"
          :disabled="disabled"
          @change="emitChange"
        />
      </span>
      <Select
        v-model:value="item.dataType"
        :options="dataTypeOptions"
        :disabled="disabled"
        class="w-[96px] flex-shrink-0"
        @change="emitChange"
      />
      <Select
        v-model:value="item.pushType"
        :options="pushTypeOptions"
        :disabled="disabled"
        class="w-[150px] flex-shrink-0"
        @change="emitChange"
      />
      <Input
        v-model:value="item.pushServer"
        :disabled="disabled"
        class="flex-1"
        placeholder="HTTP：http://ip:port，Redis：ip:port"
        @change="emitChange"
      />
      <Input
        v-model:value="item.pushInfo"
        :disabled="disabled"
        class="flex-1"
        placeholder="HTTP 为路径，Redis 为主题或 key"
        @change="emitChange"
      />
      <Input
        v-model:value="item.ruleName"
        :disabled="disabled"
        class="w-[120px] flex-shrink-0"
        placeholder="可空"
        @change="emitChange"
      />
      <span class="w-[48px] flex-shrink-0">
        <Button
          type="link"
          danger
          size="small"
          :disabled="disabled"
          @click="removeRule(index)"
        >
          删除
        </Button>
      </span>
    </div>
    <Button type="dashed" block :disabled="disabled" @click="addRule">
      + 添加推送规则
    </Button>
  </div>
</template>
