<template>
  <div class="box">
    <NodeHead :nodeName="props.title" class="item-title" />
    <div class="button-box" v-if="props.config.type === TableType.FORM">
      <div class="item create" @click="openCreate" v-if="config.isShowAdd">新增数据</div>
      <div class="search" @click="showSearch"
        >查询 <BasicArrow class="ml-1" :expand="!searchData.show" up
      /></div>
    </div>
    <div class="search-box" v-if="searchData.show">
      <SearchBox
        v-if="searchData.show"
        :formSchema="searchData.formSchema"
        :fieldMapToTime="searchData.fieldMapToTime"
        @search="SearchFormTableList"
      />
    </div>
    <div
      class="button-box"
      v-if="props.config.type === TableType.API && props.config.associatedForm"
    >
      <div class="item create" @click="openCreate" v-if="config.isShowAdd">新增数据</div>
    </div>
    <div class="content">
      <a-table
        :data-source="state.dataSource"
        :columns="state.columns"
        :pagination="{
          pageSize: page.pageSize,
          total: page.total,
        }"
        position="bottomRight"
        :rowKey="props.config.primaryKey ? props.config.primaryKey : 'id'"
        size="small"
        @change="changePage"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.dataIndex === 'operation'">
            <span class="edit-icon" @click.stop="onEdit(record)">编辑</span>
            <a-popconfirm title="确定删除?" @confirm="onDelete(record)">
              <span class="delete-icon" @click.stop="">删除</span>
            </a-popconfirm>
          </template>
          <template v-else-if="column.isMoneyChinese">
            <span :style="executeListStyle(record, column?.listStyle)">
              {{ moneyChineseData(record[column.dataIndex]) }}
            </span>
          </template>

          <template v-else-if="column.dataIndex && column?.listStyle">
            <span :style="executeListStyle(record, column?.listStyle)">{{
              record[column.dataIndex]
            }}</span>
          </template>
        </template>
      </a-table>
    </div>
    <ModalPanel
      :visible="modalData.modalOpen"
      :title="modalData.title"
      :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 {
    // computed, inject,
    onMounted,
    reactive,
    ref,
    watch,
  } from 'vue';
  import { tableProperties } from '../config/properties';
  import { DesktopComponent, TableType } from '/@/enums/desktop';
  import { TableColumnItem, TableConfig } from '/@/model/desktop/designer';
  import { cloneDeep } from 'lodash-es';
  import { NodeHead } from '/@/components/ModalPanel/index';
  import { getComplexPage } from '/@/api/form/execute';
  import { getFormRelease } from '/@/api/form/release';
  import { ModalPanel } from '/@/components/ModalPanel/index';
  import SimpleForm from '/@/components/SimpleForm/src/SimpleForm.vue';
  import { buildOption } from '/@/utils/helper/designHelper';
  import {
    addComplexFormExecute,
    editComplexFormExecute,
    getComplexInfo,
    getComplexQuery,
  } from '/@/api/form/design/index';
  import { getFormTemplate, deleteComplex } from '/@/api/form/design';
  import { notification } from 'ant-design-vue';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { FormTypeEnum } from '/@/enums/formtypeEnum';
  import { nextTick } from 'vue';
  import { QueryConfig } from '/@/model/generator/listConfig';
  import { whetherNeedToTransform, findSchema } from '/@/utils/helper/generatorHelper';
  import { ComponentOptionModel } from '/@/model/generator/codeGenerator';
  import useComplexApiRequest from './../../../hooks/useComplexApiRequest';
  import { FormSchema } from '/@/components/Table';
  import { handleSearchForm } from '/@/utils/helper/exportHelper';
  import SearchBox from './table/Search.vue';
  import { BasicArrow } from '/@/components/Basic';
  import { FieldMapToTime } from '/@/components/Form/src/types/form';
  import { DesktopForm } from '/@/components/SystemForm/index';
  import { executeListStyle } from '/@/hooks/web/useListStyle';
  import { moneyChineseData } from '/@/utils/event/design';
  interface SearchDate {
    fieldName: string;
    format: string;
  }
  const searchData: {
    formSchema: FormSchema[];
    fieldMapToTime: FieldMapToTime;
    params: { [x: string]: any };
    show: Boolean;
  } = reactive({
    formSchema: [],
    show: false,
    fieldMapToTime: [],
    params: {},
  });
  const { changeApiOptions } = useComplexApiRequest();
  // const changeDataDisplay = inject('changeDataDisplay') as any;
  const enum ActionType {
    ADD = 0,
    EDIT = 1,
  }
  const { t } = useI18n();
  const formRef = ref();
  const props = withDefaults(
    defineProps<{
      type: DesktopComponent;
      id: string;
      w: number;
      h: number;
      title: string;
      config: TableConfig;
      changeDataKey?: number;
    }>(),
    {
      type: DesktopComponent.TABLE,
      w: 0,
      h: 0,
      id: '',
      config: () => {
        return tableProperties;
      },
    },
  );
  watch(
    () => props.config.renderKey,
    (val) => {
      val && resizeLayout();
    },
    {
      deep: true,
    },
  );
  watch(
    () => props.changeDataKey,
    (val) => {
      val && changeData();
    },
    {
      deep: true,
    },
  );
  const modalData = reactive({
    type: ActionType.ADD,
    title: '新增',
    modalOpen: false,
    pkValue: '',
    formModel: {},
    formProps: {},
  });

  // const rowSelection = computed(() => {
  //   return {
  //     checkStrictly: true,
  //     type: 'radio',
  //     selectedRowKeys: state.selectedRowKeys,
  //     onChange: (_selectedRowKeys: string[], selectedRows) => {
  //       let record = selectedRows[0];
  //       changeTableInfo(record);
  //     },
  //   };
  // });
  // const customRow = (record) => {
  //   return {
  //     onClick: () => {
  //       changeTableInfo(record);
  //     },
  //   };
  // };
  const state: {
    dataSource: Array<any>;
    columns: Array<TableColumnItem>;
    selectedRowKeys: Array<string>;
  } = reactive({ dataSource: [], columns: [], selectedRowKeys: [] });
  const page = reactive({ current: 1, pageSize: 5, total: 0 });

  onMounted(() => {
    page.current = 1;
    page.pageSize = props.config.pageSize;
    showList();
  });
  // function changeTableInfo(record) {
  //   if (state.selectedRowKeys.includes(record[props.config.primaryKey])) {
  //     state.selectedRowKeys = [];
  //     if (props.id) {
  //       let tableRecord = window.localStorage.getItem('TableRecord');
  //       if (tableRecord) {
  //         let tableRecordList = JSON.parse(tableRecord);
  //         tableRecordList[props.id] = null;
  //         window.localStorage.setItem('TableRecord', JSON.stringify(tableRecordList));
  //       }
  //     }
  //   } else {
  //     state.selectedRowKeys = [record[props.config.primaryKey]];
  //     if (props.id) {
  //       let tableRecord = window.localStorage.getItem('TableRecord');
  //       if (tableRecord) {
  //         let tableRecordList = JSON.parse(tableRecord);
  //         tableRecordList[props.id] = record;
  //         window.localStorage.setItem('TableRecord', JSON.stringify(tableRecordList));
  //       } else {
  //         let list = {};
  //         list[props.id] = record;
  //         window.localStorage.setItem('TableRecord', JSON.stringify(list));
  //       }
  //     }
  //   }
  //   if (changeDataDisplay) changeDataDisplay();
  // }
  async function changeData() {
    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.current.toString();
            } else if (item.name === 'size') {
              item.value = page.pageSize.toString();
            }
          });
        }
        let res = await changeApiOptions(props.config.apiConfig);
        if (res.list) {
          state.dataSource = res.list;
        } else {
          state.dataSource = [];
        }
        page.total = res.total || 0;
      }
    } else {
      if (props.config.releaseId) {
        // 搜索
        let releaseResult = await getFormRelease(props.config.releaseId);
        const configJson = JSON.parse(releaseResult.configJson);
        const { queryConfigs } = configJson.listConfig!;
        let searchFormSchema: FormSchema[] = []; //搜索框配置
        let searchDate: SearchDate[] = [];
        //获取表单模板数据
        const templateResult = await getFormTemplate(releaseResult.formId);
        const formJson = JSON.parse(templateResult.formJson);
        //构建表单Props
        let formProps = buildOption(formJson.formJson, false);

        //查询配置转换为schema
        [searchFormSchema, searchDate] = ConvertQueryConfigToFormSchema(
          queryConfigs,
          formProps.schemas!,
          formJson.formJson.list,
        );
        searchData.formSchema = searchFormSchema;
        const fieldMapToTime: FieldMapToTime = searchDate.map((date) => {
          return [
            date.fieldName!,
            [date.fieldName + 'Start', date.fieldName + 'End'],
            date.format,
            true,
          ];
        });
        searchData.fieldMapToTime = fieldMapToTime;
      } else {
        if (props.config.formId) {
          let queryConfigs = await getComplexQuery(props.config.formId);
          let searchFormSchema: FormSchema[] = []; //搜索框配置
          let searchDate: SearchDate[] = [];
          //获取表单模板数据
          const templateResult = await getFormTemplate(props.config.formId);
          const formJson = JSON.parse(templateResult.formJson);
          //构建表单Props
          let formProps = buildOption(formJson.formJson, false);

          //查询配置转换为schema
          [searchFormSchema, searchDate] = ConvertQueryConfigToFormSchema(
            queryConfigs,
            formProps.schemas!,
            formJson.formJson.list,
          );
          searchData.formSchema = searchFormSchema;
          const fieldMapToTime: FieldMapToTime = searchDate.map((date) => {
            return [
              date.fieldName!,
              [date.fieldName + 'Start', date.fieldName + 'End'],
              date.format,
              true,
            ];
          });
          searchData.fieldMapToTime = fieldMapToTime;
        }
      }
      // 列表
      await SearchFormTableList(null);
    }
  }
  async function SearchFormTableList(data = null) {
    try {
      if (props.config.formId) {
        let params = {};
        searchData.params = {};
        if (data) {
          params = { params: data };
          searchData.params = data;
        }

        let paramsData = {
          limit: page.current,
          releaseId: props.config.releaseId,
          formId: props.config.formId,
          size: page.pageSize,
          ...params,
        };
        if (
          ((props.config.formType === FormTypeEnum.CUSTOM_FORM && props.config.releaseId) ||
            props.config.formType === FormTypeEnum.SYSTEM_FORM) &&
          props.config.formId
        ) {
          let res = await getComplexPage(paramsData);
          page.total = res.total;
          if (res.list) {
            state.dataSource = res.list;
          } else {
            state.dataSource = [];
          }
        }
      }
    } catch (error) {}
    searchData.show = false;
  }
  /**
   * QueryConfig 转换 为搜索栏 FormSchema
   * 根据查询字段 获取到 当前字段查询组件的类型
   * 普通类型：input
   * 远程组件：ApiSelect
   * 时间字段：RangePicker
   */
  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];
  }
  async function showList() {
    if (props.config.columns) {
      state.columns = cloneDeep(props.config.columns).filter((ele) => {
        return ele.show;
      });
    }
    if (
      (props.config.type === TableType.API && props.config.associatedForm) ||
      props.config.type === TableType.FORM
    ) {
      state.columns.push({
        title: '操作',
        dataIndex: 'operation',
        show: true,
        width: 80,
      });
    }
    await changeData();
  }
  async function onDelete(record) {
    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('删除成功！'),
        }); //提示消息
        page.current = 1;
        await showList();
      } else {
        notification.error({
          message: t('提示'),
          description: t('删除失败！'),
        }); //提示消息
      }
    } catch (error) {}
  }
  async function onEdit(record) {
    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 resizeLayout() {
    page.current = 1;
    page.pageSize = props.config.pageSize;
    showList();
  }
  async function openCreate() {
    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 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;
      page.current = 1;
      await showList();
    } catch (error) {
      console.log('error: ', error);
    }
  }
  function showSearch() {
    // 处理数据
    initSearchBox();
    searchData.show = !searchData.show;
  }
  function initSearchBox() {
    // 时间日期特殊字段处理
    let timeParams = {};
    if (searchData.fieldMapToTime.length > 0) {
      searchData.fieldMapToTime.forEach((element) => {
        if (element[1] && Array.isArray(element[1])) {
          if (
            element[1][0] &&
            element[1][1] &&
            searchData.params[element[1][0]] &&
            searchData.params[element[1][1]]
          ) {
            timeParams[element[0]] = [
              searchData.params[element[1][0]],
              searchData.params[element[1][1]],
            ];
          }
        }
      });
    }
    // 默认值赋值
    for (const key in searchData.formSchema) {
      if (Object.prototype.hasOwnProperty.call(searchData.formSchema, key)) {
        const element = searchData.formSchema[key];
        if (element && element.field) {
          if (timeParams[element.field]) {
            element.defaultValue = timeParams[element.field];
          } else {
            element.defaultValue = searchData.params[element.field];
          }
        }
      }
    }
  }
  function modalClose() {
    modalData.modalOpen = false;
  }
  async function changePage(pagination) {
    page.current = pagination.current;
    await showList();
  }
</script>

<style lang="less" scoped>
  .box {
    padding-top: 50px;

    .item-title {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 50px;
      line-height: 50px;
      color: #262626;
      font-size: 14px;
      padding-left: 16px;
    }

    .content {
      padding: 0 20px;
      overflow: hidden;
      height: 100%;

      :deep(.ant-table) {
        height: calc(100% - 50px);
        overflow: auto;
      }

      :deep(.ant-spin-container),
      :deep(.ant-table-container),
      :deep(.ant-table-content),
      .ant-table-wrapper {
        height: 100%;
      }

      :deep(.ant-table-tbody) {
        overflow-y: scroll;
        height: calc(100% - 40px);
      }
    }
  }

  :deep(.ant-table-pagination.ant-pagination) {
    position: absolute;
    margin: 0;
    right: 0;
  }

  .button-box {
    display: flex;
    align-items: center;
    position: absolute;
    top: 10px;
    right: 20px;

    .item {
      font-size: 14px;
      padding: 2px 10px;
      margin-right: 10px;
      cursor: pointer;
    }

    .create {
      border-radius: 4px;
      color: #fff;
      background-color: #39f;
    }

    .search {
      font-size: 14px;
      color: #39f;
      cursor: pointer;
    }
  }

  .search-box {
    position: absolute;
    top: 40px;
    left: 2px;
    right: 2px;
    background-color: #fff;
    z-index: 2;
    border: 1px solid rgb(204 204 204 / 47%);
    box-shadow: 1px 2px 10px #ccc;
    padding: 0 10px;
    padding-top: 40px;
    margin: 4px;
  }

  .form-model-box {
    padding: 10px 0;
  }
</style>
