<template>
  <div class="bg-white rounded-2xl">
    <BasicTable @register="registerTable" @change="changeData">
      <template #toolbar>
        <template v-for="button in buttonList" :key="button.code">
          <a-button v-if="button.isDefault" type="primary" @click="handleCreate">
            <template #icon><Icon :icon="button.icon" /></template>
            {{ button.name }}
          </a-button>
          <a-button v-else type="primary" @click="customButtonClick(button)">
            <template #icon><Icon :icon="button.icon" /></template>
            {{ button.name }}
          </a-button>
        </template>
      </template>
      <template #action="{ record, index }">
        <TableAction
          :actions="getLessActions(record, index)"
          :dropDownActions="getMoreActions(record, index)"
        />
      </template>
    </BasicTable>
    <ModalPanel
      :visible="modalData.modalOpen"
      :title="modalData.title"
      :width="1200"
      :contentStyle="{ overflow: 'auto' }"
      @submit="modalSubmit"
      @close="modalClose"
    >
      <div class="form-model-box">
        <SimpleForm
          v-if="modalData.modalOpen && props.config.formType == FormTypeEnum.CUSTOM_FORM"
          ref="formRef"
          :formProps="modalData.formProps"
          :formModel="modalData.formModel"
        />
        <DesktopForm
          v-else-if="modalData.modalOpen && props.config.formType == FormTypeEnum.SYSTEM_FORM"
          ref="formRef"
          :systemComponent="props.config.systemComponent"
          :formModel="modalData.formModel"
        />
      </div>
    </ModalPanel>
  </div>
</template>
<script setup lang="ts">
  import { BasicTable, useTable, TableAction, FormSchema, ActionItem } from '/@/components/Table';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { inject, nextTick, onMounted, reactive, ref, unref, watch, computed } from 'vue';
  import { ModalPanel } from '/@/components/ModalPanel/index';
  import { FormTypeEnum } from '/@/enums/formtypeEnum';
  import {
    addComplexFormExecute,
    deleteComplex,
    editComplexFormExecute,
    getComplexInfo,
    getComplexQuery,
    getFormTemplate,
  } from '/@/api/form/design';
  import { buildOption } from '/@/utils/helper/designHelper';
  import SimpleForm from '/@/components/SimpleForm/src/SimpleForm.vue';
  import { DesktopForm } from '/@/components/SystemForm/index';
  import { cloneDeep, isBoolean } from 'lodash-es';
  import { TableType } from '/@/enums/desktop';

  import { getFormRelease } from '/@/api/form/release';
  import { SearchDate } from '../../types';
  import { QueryConfig } from '/@/model/generator/listConfig';
  import { ComponentOptionModel } from '/@/model/generator/codeGenerator';
  import { findSchema, whetherNeedToTransform } from '/@/utils/helper/generatorHelper';
  import { handleSearchForm } from '/@/utils/helper/exportHelper';
  import { getComplexPage } from '/@/api/form/execute';
  import { changePageDesignApiOptions } from '../../types/tool';
  import { executePageButtonEvent } from '/@/utils/event/data';

  const { t } = useI18n();
  const props = defineProps({
    config: {
      type: Object,
      default: () => {
        return {};
      },
    },
    compkey: String,
  });
  const emit = defineEmits(['refreshComp']);
  const widgetFormModel = inject('widgetFormModel', ref<any>({}));
  const page = ref({
    current: 1,
    pageSize: props.config.pageSize,
  });
  const formRef = ref();
  const listSpliceNum = ref(3);
  const buttonList = computed(() => {
    return props.config.buttonList.filter((o) => {
      return o.isUse && o.showType !== 'inline';
    });
  });

  const actionButtonConfig = computed(() => {
    return props.config.buttonList.filter((x) => x.isUse && x.showType === 'inline');
  });
  const { notification } = useMessage();
  const isVisible = ref<boolean>(false);
  const deleteIndex = ref();
  const enum ActionType {
    ADD = 0,
    EDIT = 1,
  }
  const modalData = reactive({
    type: ActionType.ADD,
    title: '新增',
    modalOpen: false,
    pkValue: '',
    formModel: {},
    formProps: {},
  });

  const [
    registerTable,
    { reload, setTableData, getPaginationRef, setProps, setColumns, setPagination },
  ] = useTable({
    title: props.config.label,
    showTitle: true,
    columns: [],
    rowKey: props.config.type == TableType.API ? props.config.primaryKey : 'id',
    pagination: {
      pageSize: props.config.pageSize || 20,
    },
    striped: false,
    useSearchForm: false,
    showTableSetting: false,
    showIndexColumn: false,
    rowSelection: { type: 'radio', onChange: onSelectChange },
  });
  watch(
    () => props.config.dataList,
    (val) => {
      setTableData(val);
    },
    { deep: true },
  );

  watch(
    () => props.config,
    (val) => {
      initTable(val);
    },
    { deep: true },
  );
  onMounted(() => {
    initTable(props.config);
    changeData({
      current: 1,
      pageSize: props.config.pageSize,
    });
  });
  function onSelectChange(_, rowData) {
    if (props.compkey) widgetFormModel.value[props.compkey] = rowData[0];
    emit('refreshComp', rowData[0]);
  }
  async function changeApiConfig(val) {
    if (val && val.path) {
      let res = await changePageDesignApiOptions(val, widgetFormModel.value);
      if (res && res.columns) {
        let cols: any = [];
        res.columns.forEach((o) => {
          cols.push({
            dataIndex: o.prop,
            title: o.label,
            width: 80,
            align: 'left',
            show: true,
          });
        });
        setColumns(cols);
      } else {
        setColumns([]);
      }
    }
  }
  function initTable(val) {
    let cols: any = [];
    if (val.type === TableType.API && val.columns?.length <= 0) {
      changeApiConfig(val.apiConfig);
    }
    if (val.columns?.length > 0) {
      cols = cloneDeep(val.columns).filter((ele) => {
        return ele.show;
      });
      setColumns(cols);
    }
    if ((val.type === TableType.API && val.associatedForm) || val.type === TableType.FORM) {
      if (val.type === TableType.FORM) {
        setTableData([]);
        setPagination({ total: 0 });
        if (val.releaseId) {
          // 搜索
          getFormRelease(val.releaseId).then(async (releaseResult) => {
            const configJson = JSON.parse(releaseResult.configJson);
            const { queryConfigs } = configJson.listConfig!;
            setSearchSchema(releaseResult.formId, queryConfigs);
          });
        } else if (val.formId) {
          getComplexQuery(val.formId).then(async (queryConfigs) => {
            setSearchSchema(val.formId, queryConfigs);
          });
        }
        SearchFormTableList();
      } else {
        setProps({
          useSearchForm: false,
        });
      }
      setProps({
        actionColumn: {
          width:
            (actionButtonConfig.value!.length > 3
              ? listSpliceNum.value
              : actionButtonConfig.value!.length) * 65,
          title: t('操作'),
          dataIndex: 'action',
          slots: { customRender: 'action' },
        },
      });
    } else {
      setProps({
        actionColumn: undefined,
      });
    }
    if (val.type === TableType.API && val.total !== undefined) {
      setPagination({ total: val.total || 0 });
    }
  }
  async function setSearchSchema(formId, queryConfigs) {
    let searchFormSchema: FormSchema[] = []; //搜索框配置
    let searchDate: SearchDate[] = [];
    //获取表单模板数据
    const templateResult = await getFormTemplate(formId);
    const formJson = JSON.parse(templateResult.formJson);
    //构建表单Props
    let formProps = buildOption(formJson.formJson, false);

    //查询配置转换为schema
    [searchFormSchema, searchDate] = ConvertQueryConfigToFormSchema(
      queryConfigs,
      formProps.schemas!,
      formJson.formJson.list,
    );
    setProps({
      formConfig: {
        rowProps: {
          gutter: 16,
        },
        schemas: searchFormSchema,
        fieldMapToTime: searchDate.map((date) => {
          return [
            date.fieldName!,
            [date.fieldName + 'Start', date.fieldName + 'End'],
            date.format,
            true,
          ];
        }),
        showResetButton: false,
      },
      useSearchForm: true,
    });
  }
  async function changeData(val?) {
    const getPagination: any = unref(getPaginationRef);
    if (!isBoolean(getPagination)) {
      const { current, pageSize } = getPagination;
      page.value = {
        current: val ? val.current : current,
        pageSize: val ? val.pageSize : pageSize,
      };
    }
    if (props.config.type === TableType.API) {
      if (props.config && props.config.apiConfig && props.config.apiConfig.path) {
        if (props.config.apiConfig.requestParamsConfigs) {
          props.config.apiConfig.requestParamsConfigs.map((item) => {
            if (item.name === 'limit') {
              item.value = page.value.current;
            } else if (item.name === 'size') {
              item.value = page.value.pageSize;
            }
          });
        }
        let res = await changePageDesignApiOptions(props.config.apiConfig, widgetFormModel.value);
        if (res?.list) {
          setTableData(res.list);
        } else {
          setTableData([]);
        }
        setPagination({ total: res?.total || 0 });
      }
    }
  }
  async function SearchFormTableList() {
    try {
      if (props.config.releaseId && props.config.formId) {
        if (
          ((props.config.formType === FormTypeEnum.CUSTOM_FORM && props.config.releaseId) ||
            props.config.formType === FormTypeEnum.SYSTEM_FORM) &&
          props.config.formId
        ) {
          setProps({
            beforeFetch: (pageParams) => {
              //发送请求默认新增  左边树结构所选机构id
              const newParams = {
                releaseId: props.config.releaseId,
                formId: props.config.formId,
                ...pageParams,
              };
              return newParams;
            },
            api: getComplexPage,
          });
          reload();
        }
      }
    } catch (error) {}
  }
  async function handleCreate() {
    modalData.formModel = {};
    if (props.config.formId) {
      modalData.type = ActionType.ADD;
      modalData.modalOpen = true;
      modalData.title = '新增数据';
      try {
        const templateResult = await getFormTemplate(props.config.formId);
        const formJson = JSON.parse(templateResult.formJson);
        let formProps = buildOption(formJson.formJson, false);
        modalData.formProps = formProps;
      } catch (error) {
        // console.log('error: ', error);
      }
    } else {
      //console.log('你未选择表单');
    }
  }
  async function handleEdit(record: Recordable) {
    if (!props.config.primaryKey) {
      return false;
    }
    if (props.config.formId) {
      modalData.type = ActionType.EDIT;
      modalData.modalOpen = true;
      modalData.title = '编辑数据';
      modalData.pkValue = record[props.config.primaryKey];

      try {
        if (props.config.formType == FormTypeEnum.SYSTEM_FORM) {
          // 系统表单直接走页面的formModel
          modalData.formModel = cloneDeep(record);
        } else {
          const templateResult = await getFormTemplate(props.config.formId);
          const formJson = JSON.parse(templateResult.formJson);
          let formProps = buildOption(formJson.formJson, false);
          modalData.formProps = formProps;
          let formData = await getComplexInfo({
            formId: props.config.formId,
            pkValue: modalData.pkValue,
            pkName: props.config.primaryKey,
          });
          await nextTick();
          await formRef.value?.setFieldsValue(formData);
        }
      } catch (error) {
        // console.log('error: ', error);
      }
    } else {
      // console.log('你未选择表单');
    }
  }
  function popVisible(index) {
    return isVisible.value && index === deleteIndex.value;
  }
  function handleVisibleChange(index, bool) {
    if (!bool) {
      isVisible.value = false;
      return;
    }
    isVisible.value = true;
    deleteIndex.value = index;
  }
  async function handleDelete(record: Recordable) {
    isVisible.value = false;
    try {
      if (!props.config.primaryKey || !props.config.formId || !record[props.config.primaryKey]) {
        return false;
      }
      let res = await deleteComplex({
        formId: props.config.formId,
        pkName: props.config.primaryKey,
        pkValue: record[props.config.primaryKey],
      });
      if (res) {
        notification.success({
          message: t('提示'),
          description: t('删除成功！'),
        }); //提示消息
        reload;
      } else {
        notification.error({
          message: t('提示'),
          description: t('删除失败！'),
        }); //提示消息
      }
    } catch (error) {}
  }
  function handleCancel() {
    isVisible.value = false;
  }
  async function modalSubmit() {
    try {
      if (props.config.formType == FormTypeEnum.SYSTEM_FORM) {
        // 系统表单直接走页面的formModel
        await formRef.value?.submit();
      } else {
        const values = await formRef.value?.validate();
        if (modalData.type == ActionType.ADD) {
          await addComplexFormExecute(props.config.formId, values);
          notification.success({
            message: t('提示'),
            description: t('新增成功！'),
          }); //提示消息
        } else {
          values[props.config.primaryKey] = modalData.pkValue;
          await editComplexFormExecute({
            formId: props.config.formId,
            formData: values,
            pkName: props.config.primaryKey,
          });
          notification.success({
            message: t('提示'),
            description: t('编辑成功！'),
          }); //提示消息
        }
      }

      modalData.modalOpen = false;
      if (props.config.type == TableType.API) {
        setPagination({ current: 1 });
        changeData({
          current: 1,
          pageSize: props.config.pageSize,
        });
      } else {
        reload();
      }
    } catch (error) {
      //console.log('error: ', error);
    }
  }
  function modalClose() {
    modalData.modalOpen = false;
  }
  function ConvertQueryConfigToFormSchema(
    queryConfigs: QueryConfig[],
    schemas: FormSchema[],
    list: ComponentOptionModel[],
  ): [FormSchema[], SearchDate[]] {
    const searchDate: SearchDate[] = [];
    if (!queryConfigs) {
      return [[], []];
    }
    const searchFormSchema = queryConfigs.map((config) => {
      if (!!config.isDate) {
        searchDate.push({
          fieldName: config.fieldName,
          format: config.format!,
        });
      }
      const schema = findSchema(schemas, config.fieldName);
      const [isNeedTrans, option] = whetherNeedToTransform(config, list);

      return handleSearchForm(option, schema, config, isNeedTrans, false) as FormSchema;
    });
    return [searchFormSchema, searchDate];
  }
  function customButtonClick(item) {
    executePageButtonEvent(item.setting, widgetFormModel.value);
  }
  function getLessActions(record: Recordable, index) {
    let list = getActions(record, index);
    return list.slice(0, listSpliceNum.value);
  }
  function getMoreActions(record: Recordable, index) {
    let list = getActions(record, index);
    return list.slice(listSpliceNum.value);
  }
  function getActions(record: Recordable, index): ActionItem[] {
    let actionsList: ActionItem[] = [];
    let editAndDelBtn: ActionItem[] = [];

    actionButtonConfig.value?.map((button) => {
      if (['edit', 'delete'].includes(button.code)) {
        editAndDelBtn = [
          {
            label: '编辑',
            onClick: handleEdit.bind(null, record),
          },
          {
            label: '删除',
            color: 'error',
            popConfirm: {
              title: t('是否确认删除'),
              visible: popVisible(index),
              onVisibleChange: handleVisibleChange.bind(null, index),
              confirm: handleDelete.bind(null, record),
              cancel: handleCancel,
            },
          },
        ];
      } else {
        actionsList.push({
          label: button?.name,
          onClick: customButtonClick.bind(null, button),
        });
      }
    });

    actionsList = actionsList.concat(editAndDelBtn);

    return actionsList;
  }
</script>
<style scoped>
  :deep(.vben-basic-table-header__toolbar) {
    margin-right: 16px;
  }
</style>
