<template>
  <div class="step1-box">
    <a-modal
      :width="1200"
      v-model:visible="state.configDia"
      :title="t('查询配置')"
      :maskClosable="false"
      :bodyStyle="state.modalBodyStyle"
      destroyOnClose
      @ok="handleConfirm"
      @cancel="handleClose"
    >
      <div class="step1">
        <div class="flex justify-end mb-3">
          <a-button type="primary" @click="addInParams">添加查询</a-button>
        </div>
        <a-table
          class="search-config"
          :key="queryTableKey"
          :columns="intableColumns"
          :data-source="intableData"
          :pagination="false"
        >
          <template #bodyCell="{ column, record, index }">
            <template v-if="column.dataIndex === 'sort'">
              <svg class="icon queryDraggable-icon" aria-hidden="true" style="cursor: move">
                <use xlink:href="#icon-paixu" />
              </svg>
            </template>
            <template v-if="column.dataIndex === 'name'">
              <a-input
                v-model:value="record.name"
                :placeholder="t('请填写查询名称')"
                @blur="handleBlur(record)"
              />
            </template>
            <template v-else-if="column.dataIndex === 'type'">
              <a-select
                v-model:value="record.type"
                style="width: 180px"
                :options="options1"
                @change="record.from = null"
              />
            </template>
            <template v-else-if="column.dataIndex === 'from'">
              <a-select
                v-if="record.type == searchCompType.select"
                v-model:value="record.from"
                style="width: 180px"
                :options="options2"
              />
              <div v-else-if="record.type === null" class="text-[#999]">请先选择查询类别</div>
              <div v-else class="text-[#999]">无</div>
            </template>
            <template v-else-if="column.dataIndex === 'component'">
              <SelectApi
                v-if="record.from == datasourceType.api"
                v-model:apiConfig="record.apiConfig"
              />
              <template v-else-if="record.from === datasourceType.dic">
                <DicTreeSelect class="text-left" v-model:value="record.dictionaryItemId" />
              </template>
              <div
                @click="showStaticDialog(index)"
                v-else-if="record.from == datasourceType.static"
                class="inline-block w-full"
              >
                <InputModel
                  :value="record.staticOptions.length > 0 ? t('已配置') : ''"
                  :placeholder="t('点击进行静态数据配置')"
                  style="width: 100%; min-width: 100px"
                />
              </div>
              <div
                v-else-if="
                  record.type === searchCompType.date ||
                  record.type === searchCompType.time ||
                  record.type === searchCompType.cycle
                "
                ><a-select
                  v-model:value="record.format"
                  style="width: 100%"
                  :options="options3(record.type)"
              /></div>
              <div v-else-if="record.type === null" class="text-[#999]">请先选择查询类别</div>
              <div v-else class="text-[#999]">无</div>
            </template>
            <template v-else-if="column.dataIndex === 'action'">
              <a-button danger type="link" @click="deleteInData(index)">删除</a-button>
            </template>
          </template>
        </a-table>
      </div>
    </a-modal>

    <StaticData
      v-if="dataDialog"
      v-model:configDialog="dataDialog"
      v-model:config="intableData[curDataidx].staticOptions"
    />
  </div>
</template>
<script lang="ts" setup>
  import { reactive, ref } from 'vue';
  import { InputModel } from '/@/components/ApiConfig';
  import { useI18n } from '/@/hooks/web/useI18n';
  import SelectApi from './SelectApi.vue';
  import StaticData from './staticData.vue';
  import { DicTreeSelect } from '/@/components/DicTreeSelect';
  import { notification, type SelectProps } from 'ant-design-vue';
  import { datasourceType, searchCompType } from '../../types';
  import { cloneDeep, random } from 'lodash-es';
  import { changeToPinyin } from '/@/utils/event/design';
  import { watch } from 'vue';
  import { isNullAndUnDef } from '/@/utils/is';
  import Sortable from 'sortablejs';
  import { nextTick } from 'vue';
  const { t } = useI18n();
  const props = defineProps({
    configDialog: { type: Boolean },
    config: { type: Object },
  });
  const state = reactive({
    configDia: props.configDialog as boolean,
    modalBodyStyle: {
      padding: '15px 15px 10px 10px',
      minHeight: '400px',
    },
  });
  const intableData = ref<any>(cloneDeep(props.config) || []);

  const dataDialog = ref<boolean>(false);
  const curDataidx = ref(0);
  const queryTableKey = ref(1);
  const options1 = ref<SelectProps['options']>([
    {
      value: searchCompType.text,
      label: '文本',
    },
    {
      value: searchCompType.select,
      label: '下拉选择',
    },
    {
      value: searchCompType.cycle,
      label: '时间周期',
    },
    {
      value: searchCompType.date,
      label: '日期',
    },
    {
      value: searchCompType.time,
      label: '时间',
    },
  ]);
  const options2 = ref<SelectProps['options']>([
    {
      value: datasourceType.api,
      label: 'API',
    },
    {
      value: datasourceType.dic,
      label: '数据字典',
    },
    {
      value: datasourceType.static,
      label: '静态数据',
    },
  ]);

  const intableColumns = [
    { title: t('排序'), dataIndex: 'sort', align: 'center', width: 70 },
    {
      title: t('查询名称'),
      dataIndex: 'name',
      align: 'center',
    },
    {
      title: t('查询类别'),
      dataIndex: 'type',
      align: 'center',
      width: 200,
    },
    {
      title: t('数据来源'),
      dataIndex: 'from',
      align: 'center',
      width: 260,
    },
    {
      title: t('数据配置'),
      dataIndex: 'component',
      align: 'center',
      width: 260,
    },
    {
      title: t('操作'),
      dataIndex: 'action',
      align: 'center',
    },
  ];

  const emit = defineEmits([
    'update:configDialog',
    'update:config',
    'update:schemas',
    'update:fieldMapToTime',
  ]);
  function options3(type) {
    let fomat1 = [
      {
        value: 'YYYY-MM-DD HH:mm:ss',
        label: 'YYYY-MM-DD HH:mm:ss',
      },
      {
        value: 'YYYY-MM-DD',
        label: 'YYYY-MM-DD',
      },
    ];
    let fomat2 = [
      {
        value: 'HH:mm:ss',
        label: 'HH:mm:ss',
      },
    ];
    if (type == searchCompType.date) {
      return fomat1;
    } else if (type == searchCompType.time) {
      return fomat2;
    } else {
      return fomat1.concat(fomat2);
    }
  }
  watch(
    () => intableData.value,
    (val) => {
      if (val && val.length) {
        nextTick(() => {
          const tbody: any = document.querySelector('.search-config .ant-table-tbody');
          if (!tbody) return;
          Sortable.create(tbody, {
            handle: '.queryDraggable-icon',
            onEnd: ({ oldIndex, newIndex }) => {
              if (isNullAndUnDef(oldIndex) || isNullAndUnDef(newIndex) || newIndex === oldIndex) {
                return;
              }
              const columns = cloneDeep(intableData.value);
              if (oldIndex > newIndex) {
                columns.splice(newIndex, 0, columns[oldIndex]);
                columns.splice(oldIndex + 1, 1);
              } else {
                columns.splice(newIndex + 1, 0, columns[oldIndex]);
                columns.splice(oldIndex, 1);
              }
              intableData.value = cloneDeep(columns);
              queryTableKey.value++;
            },
          });
        });
      }
    },
    {
      deep: true,
      immediate: true,
    },
  );
  //验证当前步骤的数据
  const validateStep = async (): Promise<boolean> => {
    const inarray = findDuplicates(intableData.value);

    if (inarray.length > 0) {
      let msg = t(`${inarray.length > 0 ? '查询名称' + inarray.join(',') + '重复;' : ''} `);
      notification.warning({
        message: t('提示'),
        description: msg,
      });
      return false;
    }
    return true;
  };
  function findDuplicates(arr) {
    let seen = new Set();
    let duplicates: string[] = [];

    arr.forEach((item) => {
      if (seen.has(item.name)) {
        duplicates.push(item.name);
      } else {
        seen.add(item.name);
      }
    });

    return duplicates;
  }

  const showStaticDialog = (index) => {
    dataDialog.value = true;
    curDataidx.value = index;
  };
  function addInParams() {
    intableData.value.push({
      name: '',
      type: null,
      from: null,
      apiConfig: {
        path: 'CodeGeneration/selection',
        method: 'GET',
        apiId: '93d735dcb7364a0f8102188ec4d77ac7',
      },
      staticOptions: [],
    });
  }
  function deleteInData(idx) {
    intableData.value.splice(idx, 1);
  }
  const handleClose = () => {
    state.configDia = false;
    emit('update:configDialog', false);
  };
  const handleConfirm = async () => {
    let res = await validateStep();

    if (res) {
      emit('update:config', intableData.value);
      emit('update:schemas', changeComps());
      emit('update:fieldMapToTime', searchDate());
      handleClose();
    }
  };
  function changeComps() {
    let schemas: any = [];

    intableData.value.forEach((o) => {
      let obj: any = {
        field: o.bindField,
        component: getCompType(o),
        label: o.name,
      };
      if (o.type !== searchCompType.text) {
        obj.componentProps = getCompProps(o);
      }
      schemas.push(obj);
    });

    return schemas;
  }
  function searchDate() {
    let schemas: any = [];

    intableData.value.forEach((o) => {
      if (o.type == searchCompType.cycle) {
        let obj = [o.bindField!, [o.bindField + 'Start', o.bindField + 'End'], o.format, true];
        schemas.push(obj);
      }
    });

    return schemas;
  }
  function getCompType(o) {
    if (o.type == searchCompType.text) return 'Input';
    if (o.type == searchCompType.select) return 'XjrSelect';
    if (o.type == searchCompType.cycle) {
      if (o.fomat == 'HH:mm:ss') {
        return 'TimeRangePicker';
      } else {
        return 'RangePicker';
      }
    }
    if (o.type == searchCompType.date) return 'DatePicker';
    if (o.type == searchCompType.time) return 'TimePicker';
  }
  function getCompProps(obj) {
    if (obj.type == searchCompType.select) {
      if (obj.from === datasourceType.static) {
        return {
          datasourceType: 'staticData',
          staticOptions: obj.staticOptions,
          labelField: 'label',
          valueField: 'value',
          showSearch: true,
          getPopupContainer: () => document.body,
        };
      } else if (obj.from === datasourceType.dic) {
        return {
          datasourceType: 'dic',
          params: {
            itemId: obj.dictionaryItemId,
          },
          labelField: 'name',
          valueField: 'value',
          showSearch: true,
          getPopupContainer: () => document.body,
        };
      } else if (obj.from === datasourceType.api) {
        return {
          datasourceType: 'pageDesignApi',
          apiConfig: obj.apiConfig,
          labelField: 'label',
          valueField: 'value',
          showSearch: true,
          getPopupContainer: () => document.body,
        };
      }
    }
    if (
      obj.type == searchCompType.cycle ||
      obj.type == searchCompType.date ||
      obj.type == searchCompType.time
    ) {
      return {
        format: obj.format,
        style: { width: '100%' },
        getPopupContainer: () => document.body,
      };
    }
  }
  function handleBlur(record) {
    if (!record.bindField)
      record.bindField = changeToPinyin(record.name, false) + random(1000, 9999);
  }
</script>
<style lang="less" scoped>
  :deep(.ant-input-affix-wrapper) {
    height: auto;
  }

  .icon {
    width: 1em;
    height: 1em;
    vertical-align: -0.15em;
    fill: currentcolor;
    overflow: hidden;
    display: inline-block;
  }
</style>
