<template>
  <div>
    <Form :layout="'vertical'" ref="formRef" :model="modelRef">
      <FormItem
        name="selector"
        label="选择方式"
        v-show="!(list.length === 1)"
        :rules="[{ required: true, message: '请选择方式' }]"
      >
        <TopCard :typeList="list" v-model:value="modelRef.selector" @change="onSelectorChange" />
      </FormItem>
      <Device
        v-if="modelRef.selector === 'fixed'"
        :productId="productDetail.id"
        v-model:value="modelRef.selectorValues"
        @change="onDeviceChange"
      />
      <FormItem
        v-else-if="modelRef.selector === 'relation'"
        label="关系"
        name="selectorValues"
        :rules="[{ required: true, message: '请选择关系' }]"
      >
        <RelationSelect @change="onRelationChange" v-model:value="modelRef.selectorValues" />
      </FormItem>
      <FormItem
        v-else-if="modelRef.selector === 'tag' && isTags"
        name="selectorValues"
        :rules="[{ required: true, message: '请选择标签' }]"
      >
        <Tag v-model:value="modelRef.selectorValues" :tagData="tagList" @change="onTagChange" />
      </FormItem>
      <FormItem v-else name="upperKey" label="变量" :rules="[{ required: true, message: '请选择' }]">
        <TreeSelect
          style="width: 100%; height: 100%"
          :tree-data="builtInList"
          v-model:value="modelRef.upperKey"
          placeholder="请选择参数"
          @select="onVariableChange"
          :fieldNames="{ label: 'name', value: 'id' }"
        >
          <template #title="{ name, description }">
            <Space>
              {{ name }}
              <span style="color: grey; margin-left: 5px">{{ description }}</span>
            </Space>
          </template>
        </TreeSelect>
      </FormItem>
    </Form>
  </div>
</template>

<script setup lang="ts" name="Device">
  import { useSceneStore } from '@jdlinker/func';
  import TopCard from './TopCard.vue';
  import { storeToRefs } from 'pinia';
  import { getImage, onlyMessage } from '@jdlinker/utils';
  import NoticeApi from '../../../../../../../api/notice/config';
  import Device from './Device.vue';
  import Tag from './Tag.vue';
  import RelationSelect from './RelationSelect.vue';
  import { getParams } from '../../../util';
  import { handleParamsData } from '../../../components/Terms/util';
  import _ from 'lodash-es';
  import { computed, ref, reactive, unref, watch } from 'vue';
  import { Form, FormItem, Space, TreeSelect } from 'linker-ui-components';

  const props = defineProps({
    values: {
      type: Object,
      default: () => {}
    },
    name: {
      type: Number,
      default: 0
    },
    thenName: {
      type: Number,
      default: 0
    },
    branchesName: {
      type: Number,
      default: 0
    },
    parallel: {
      type: Boolean
    },
    productDetail: {
      type: Object,
      default: () => {}
    }
  });

  // 首次操作标签数据option回显问题
  const isTags = computed(() => {
    return _.map(list.value, 'value').includes('tag');
  });

  // save保存deviceDetail
  const emits = defineEmits(['save', 'cancel']);

  const sceneStore = useSceneStore();
  const { data } = storeToRefs(sceneStore);

  const formRef = ref();

  const modelRef = reactive({
    selector: 'fixed',
    selectorValues: undefined,
    deviceId: '',
    source: '',
    upperKey: ''
  });

  const list = ref<any[]>([]);
  const builtInList = ref<any[]>([]);
  const tagList = ref<any[]>([]);

  const TypeList = [
    {
      label: '自定义',
      value: 'fixed',
      image: getImage('/scene/device-custom.png'),
      tip: '自定义选择当前产品下的任意设备'
    },
    {
      label: '按关系',
      value: 'relation',
      image: getImage('/scene/device-relation.png'),
      tip: '选择与触发设备具有相同关系的设备'
    },
    {
      label: '按标签',
      value: 'tag',
      image: getImage('/scene/device-tag.png'),
      tip: '按标签选择产品下具有特定标签的设备'
    },
    {
      label: '按变量',
      value: 'context',
      image: getImage('/scene/device-variable.png'),
      tip: '选择设备ID为上游变量值的设备'
    }
  ];

  const filterTree = (nodes: any[]) => {
    if (!nodes?.length) {
      return nodes;
    }
    const arr = nodes.filter((it) => {
      if (
        it.children.find((item: any) => item?.id?.indexOf('deviceId' || 'device_id' || 'device_Id') > -1) &&
        !it.children.find((item: any) => item?.id.indexOf('boolean') > -1)
      ) {
        return true;
      }
      return false;
    });
    return arr.map((item) => {
      if (item.children) {
      }
      return {
        ...item,
        title: item.name,
        value: item.id,
        disabled: !!item.children
      };
    });
  };

  const sourceChangeEvent = async () => {
    const _params = {
      branch: props.thenName,
      branchGroup: props.branchesName,
      action: props.name - 1
    };
    //判断相同产品才有按变量
    const productId =
      data.value?.branches?.[props.branchesName].then?.[props.thenName]?.actions?.[props.name > 0 ? props.name - 1 : 0]?.device?.productId;
    if (productId === props?.productDetail?.id) {
      const _data = await getParams(_params, unref(data));
      builtInList.value = handleParamsData(filterTree(_data), 'id');
    } else {
      builtInList.value = [];
    }
  };

  const filterType = async (newVal: any) => {
    const _list = TypeList.filter((item) => item.value === 'fixed');
    if (unref(data)?.trigger?.type === 'device') {
      //关系
      const res = await NoticeApi.getRelationUsers({
        paging: false,
        sorts: [{ name: 'createTime', order: 'desc' }],
        terms: [{ termType: 'eq', column: 'objectTypeName', value: '设备' }]
      });
      if (res.code === 200 && res.result.length !== 0) {
        const array = TypeList.filter((item) => item.value === 'relation');
        _list.push(...array);
      }
      //标签
      const tag = JSON.parse(newVal?.metadata || '{}')?.tags;
      if (tag && tag.length !== 0) {
        tagList.value = tag || [];
        const array = TypeList.filter((item) => item.value === 'tag');
        _list.push(...array);
      }
      //变量
      if (builtInList.value.length !== 0 && !props.parallel && props.name !== 0) {
        const array = TypeList.filter((item) => item.value === 'context');
        _list.push(...array);
      }
      list.value = _list;
    } else {
      if (builtInList.value.length !== 0 && !props.parallel && props.name !== 0) {
        const array = TypeList.filter((item) => item.value === 'context');
        _list.push(...array);
      }
      list.value = _list;
    }
  };

  const onSelectorChange = (val: string) => {
    modelRef.selectorValues = undefined;
    modelRef.selector = val;
  };

  /**
   * 切换设备
   * @param _detail
   */
  const onDeviceChange = (_detail: any) => {
    if (_detail) {
      if (_detail.id) {
        modelRef.deviceId = _detail?.id;
        modelRef.selectorValues = [{ value: _detail.id, name: _detail.name }] as any;
      } else {
        modelRef.deviceId = '';
        modelRef.selectorValues = [] as any;
      }
      modelRef.upperKey = '';
      emits('save', unref(modelRef), { name: _detail.name });
    }
  };

  /**
   * 变量选择
   * @param val
   * @param options
   */
  const onRelationChange = (val: any, options: any) => {
    modelRef.deviceId = 'deviceId';
    modelRef.source = 'upper';
    modelRef.selectorValues = val;
    modelRef.upperKey = 'scene.deviceId';
    emits('save', unref(modelRef), { relationName: options.label });
  };

  /**
   *
   * @param val
   * @param arr
   */
  const onTagChange = (val: any[], arr: any[]) => {
    if (val) {
      modelRef.deviceId = 'deviceId';
      modelRef.source = 'fixed';
    }
    const tagName = arr.map((i, _index) => {
      const _type = _index !== 0 && _index !== (arr || []).length && i.type ? (i.type === 'and' ? '并且' : '或者') : '';
      return `${_type}${i.name}为${i.value}`;
    });
    emits('save', unref(modelRef), { tagName: tagName.join('') });
  };

  const onVariableChange = (val: any, node: any) => {
    modelRef.deviceId = val;
    modelRef.source = 'upper';
    modelRef.upperKey = val;
    modelRef.selectorValues = undefined; // [{ value: val, name: node.description }] as any;
    emits('save', unref(modelRef), { name: node.description });
  };

  watch(
    () => props.values,
    (newVal) => {
      Object.assign(modelRef, newVal);
    },
    {
      immediate: true,
      deep: true
    }
  );

  watch(
    () => props.productDetail,
    async (newVal) => {
      await sourceChangeEvent();
      if (newVal?.id) {
        filterType(newVal);
      }
    },
    {
      immediate: true,
      deep: true
    }
  );

  watch(
    () => [props.values, builtInList.value],
    ([newVal1, newVal2]) => {
      if (newVal2 && newVal2.length) {
        const param = newVal1?.selectorValues?.[0]?.value;
        const isVariable = (newVal2 || [])?.find((item: any) => {
          return item.children.find((i: any) => i.id === param);
        });
        if (isVariable) {
          modelRef.selector = 'context';
        }
      }
    },
    {
      immediate: true,
      deep: true
    }
  );

  const onFormSave = () => {
    return new Promise((resolve, reject) => {
      formRef.value
        .validate()
        .then(async (_data: any) => {
          if (modelRef.selector === 'fixed') {
            if (!modelRef?.selectorValues?.[0]?.value) {
              onlyMessage('请选择设备', 'error');
              reject(false);
            } else {
              resolve({
                ..._data,
                selectorValues: modelRef.selectorValues
              });
            }
          } else {
            resolve({ ..._data });
          }
        })
        .catch((err: any) => {
          reject(err);
        });
    });
  };

  defineExpose({ onFormSave });
</script>

<style scoped lang="less"></style>
