<template>
  <div
    v-if="loading"
    class="text-center absolute left-0 right-0 m-auto"
    style="top: calc(100vh - 50%)"
    ><a-spin size="large"
  /></div>
  <div v-else style="height: 100%">
    <div class="right-contarin">
      <div class="right-bottom">
        <CollapseContainer>
          <template #title>
            <NodeHead :node-name="t('列表配置')" class="ml-10px" />
          </template>
          <a-table
            size="middle"
            :columns="listColumns"
            :pagination="false"
            :data-source="generatorConfig?.columnConfigs"
            :key="columnTableKey"
            class="list-config"
          >
            <template #headerCell="{ column }">
              <div
                v-if="column.key === 'sort'"
                style="height: 20px; margin: 15px 0; border-right: 1px solid #ddd; padding: 0 16px"
              >
                <svg class="icon" aria-hidden="true">
                  <use xlink:href="#icon-fangxiang1" />
                </svg>
              </div>
              <div
                v-else
                style="height: 20px; margin: 15px 0; border-right: 1px solid #ddd; padding: 0 16px"
                >{{ column.title }}</div
              >
            </template>
            <template #bodyCell="{ column, record, index }">
              <template v-if="column.key !== 'action'">
                <template v-if="column.key === 'sort'">
                  <svg class="icon columnDraggable-icon" aria-hidden="true" style="cursor: move">
                    <use xlink:href="#icon-paixu" />
                  </svg>
                </template>
                <template v-if="column.key === 'columnName'">
                  <a-select
                    v-model:value="record[column.dataIndex]"
                    style="width: 100%"
                    :options="selectOption"
                    @change="(_, option) => handleColumnNameChange(option, index)"
                    :disabled="record[column.dataIndex] === 'create_date'"
                  />
                </template>
                <template v-if="column.key === 'alignType'">
                  <a-select v-model:value="record[column.dataIndex]" style="width: 100%">
                    <a-select-option value="left"> {{ t('左对齐') }} </a-select-option>
                    <a-select-option value="center"> {{ t('居中') }} </a-select-option>
                    <a-select-option value="right"> {{ t('右对齐') }} </a-select-option>
                  </a-select>
                </template>
                <template v-if="column.key === 'columnWidth'">
                  <a-input v-model:value="record[column.dataIndex]" :disabled="record.autoWidth" />
                </template>

                <template v-if="column.key === 'autoWidth'">
                  <Switch
                    v-model:checked="record[column.dataIndex]"
                    @change="record.columnWidth = '100'"
                  />
                </template>
              </template>
              <template v-if="column.key === 'action'">
                <div
                  class="text-[#ff8080]"
                  @click="columnRemove(index)"
                  v-if="record.key !== 'create_date'"
                  >{{ t('删除') }}</div
                >
              </template>
            </template>
          </a-table>
          <div class="mt-2 mx-10px pb-4">
            <a-button type="dashed" block @click="columnAdd">
              <PlusOutlined />
              {{ t('新增') }}
            </a-button>
          </div>
        </CollapseContainer>
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>
  import { computed, inject, Ref, ref, watch, nextTick } from 'vue';
  import { PlusOutlined } from '@ant-design/icons-vue';
  import { QuestionnaireConfig } from '/@/model/generator/generatorConfig';
  import { ColumnConfig } from '/@/model/generator/listConfig';
  import { ComponentOptionModel } from '/@/model/generator/codeGenerator';
  import { CollapseContainer } from '/@/components/Container/index';
  import { cloneDeep } from 'lodash-es';
  import { Switch } from 'ant-design-vue';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { isNullAndUnDef } from '/@/utils/is';
  import Sortable from 'sortablejs';
  import { BasicColumn } from '/@/components/Table';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { NodeHead } from '/@/components/ModalPanel/index';

  const { t } = useI18n();
  const props = defineProps({
    //是否是编辑状态
    isUpdate: {
      type: Boolean,
      default: false,
    },
  });
  const { notification } = useMessage();
  const generatorConfig = inject<QuestionnaireConfig>('generatorConfig') as QuestionnaireConfig;
  const current = inject<Ref<number>>('current') as Ref<number>;

  const listColumns: BasicColumn[] = [
    {
      dataIndex: 'sort',
      key: 'sort',
      align: 'center',
      width: 50,
    },
    {
      title: t('列表字段'),
      dataIndex: 'columnName',
      key: 'columnName',
      align: 'center',
    },
    {
      title: t('对齐方式'),
      dataIndex: 'alignType',
      key: 'alignType',
      align: 'center',
    },
    {
      title: t('自适应宽度'),
      dataIndex: 'autoWidth',
      width: 200,
      key: 'autoWidth',
      align: 'center',
    },
    {
      title: t('宽度'),
      dataIndex: 'columnWidth',
      key: 'columnWidth',
      width: 200,
      align: 'center',
    },
    {
      title: t('操作'),
      key: 'action',
      fixed: 'right',
      align: 'center',
      width: 90,
    },
  ];

  const columnTableKey = ref<number>(0);

  const loading = ref(true);

  //过滤出 所有主表数据字段  不在列表页展示的不需要
  const filterMainComponent = (list: ComponentOptionModel[] | null): Recordable[] => {
    if (!list) return [];
    let mainComponents = [] as Recordable[];

    for (const item of list) {
      if (item.type !== 'title') {
        mainComponents.push({
          key: item.key,
          value: item.bindField,
          label: item.label,
          type: item.type,
          componentProps: item.options,
        });
      }
    }
    return mainComponents;
  };
  const getConfigInfo = () => {
    let listComponent = filterMainComponent(generatorConfig!.formJson!.list);
    let columnConfigs: ColumnConfig[] = [];
    // 编辑时 列表配置需要判断key和绑定字段都相同时 则不进行处理
    // key不同并且绑定字段相同（数据优先换了组件但绑定的字段是绑定过的）、key相同绑定字段不同（数据优先已存在的组件换绑字段）
    if (props.isUpdate) {
      //新增时列表配置的组件
      const addColumns = generatorConfig.columnConfigs.map((x) => {
        return { key: x.key, field: x.columnName, label: x.label };
      });
      //编辑时列表配置的组件
      const editColumns = listComponent.map((x) => {
        return { key: x.key, field: x.value, label: x.label, componentProps: x.componentProps };
      });
      //编辑时列表配置没有被删除的组件（已经删除的组件删掉）
      columnConfigs = generatorConfig.columnConfigs.filter((x) => {
        return editColumns.some((clm) => {
          if (clm.key === x.key && clm.field === x.columnName) {
            x.label = clm.label;
            x.componentProps = clm.componentProps;
            return true;
          }
        });
      });
      //除去列表配置新增时已经设置好的组件
      listComponent = listComponent.filter(
        (x) => !addColumns.some((clm) => clm.key === x.key && clm.field === x.value),
      );
    }

    generatorConfig.columnConfigs = listComponent.map((component) => {
      const columnConfig: ColumnConfig = {
        key: component.key, //数据优先存在编辑时 绑定字段相同的情况 所以需要唯一标识
        columnName: component.value,
        label: component.label,
        columnWidth: '100',
        alignType: '',
        autoWidth: true,
        componentType: component.type,
        componentProps: component.componentProps,
      };
      return columnConfig;
    });
    generatorConfig.columnConfigs.push({
      key: 'create_date',
      columnName: 'create_date',
      label: '提交时间',
      columnWidth: '100',
      alignType: '',
      autoWidth: true,
    });

    if (props.isUpdate) {
      generatorConfig.columnConfigs.unshift(...columnConfigs);
    }
  };

  watch(
    () => current.value,
    () => {
      if (current.value === 2) {
        loading.value = false;
        getConfigInfo();
      }
    },
    {
      immediate: true,
    },
  );

  watch(
    () => generatorConfig?.columnConfigs,
    (val) => {
      if (val && val.length) {
        nextTick(() => {
          const tbody: any = document.querySelector('.list-config .ant-table-tbody');
          Sortable.create(tbody, {
            handle: '.columnDraggable-icon',
            onEnd: ({ oldIndex, newIndex }) => {
              if (isNullAndUnDef(oldIndex) || isNullAndUnDef(newIndex) || newIndex === oldIndex) {
                return;
              }
              const columns = cloneDeep(generatorConfig?.columnConfigs);
              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);
              }
              generatorConfig!.columnConfigs = cloneDeep(columns);
              columnTableKey.value++;
            },
          });
        });
      }
    },
    {
      deep: true,
      immediate: true,
    },
  );

  const columnAdd = () => {
    //给各个组件赋默认值
    const pushObj: ColumnConfig = {
      key: '',
      label: '',
      columnName: '',
      columnWidth: '100',
      alignType: '',
      autoWidth: true,
      componentType: '',
    };
    generatorConfig?.columnConfigs.push(pushObj);
  };

  const columnRemove = (index) => {
    generatorConfig?.columnConfigs.splice(index, 1);
  };

  const selectOption = computed(() => {
    return filterMainComponent(generatorConfig?.formJson?.list);
  });

  const handleColumnNameChange = (option, index) => {
    generatorConfig!.columnConfigs[index].componentType = option.type;
    generatorConfig!.columnConfigs[index].label = option.label;
  };

  //验证当前步骤的数据
  const validateStep = async (): Promise<boolean> => {
    const { columnConfigs } = generatorConfig;

    if (!columnConfigs || columnConfigs.length === 0) {
      notification.error({
        message: t('提示'),
        description: t('列表字段配置不能为空!'),
      }); //提示消息
      return false;
    }

    const columnNameAll = [] as string[];

    //验证列表配置
    for (let i = 0; i < columnConfigs.length; i++) {
      columnNameAll.push(columnConfigs[i].columnName);
      if (!columnConfigs[i].columnName) {
        notification.error({
          message: t('提示'),
          description: t(`列表配置第{index}条，未选择列名！`, { index: i + 1 }),
        }); //提示消息
        return false;
      }
    }

    //判断列表配置列表字段是否有重复值
    if ([...new Set(columnNameAll)].length < columnNameAll.length) {
      notification.error({
        message: t('提示'),
        description: t('列表配置 列表字段不能重复'),
      }); //提示消息
      return false;
    }
    return true;
  };

  defineExpose({ validateStep });
</script>
<style lang="less" scoped>
  :deep(.ant-tabs-nav-wrap) {
    width: 100% !important;
    display: block !important;
    border-top: 8px solid #f0f2f5;
    border-bottom: 3px solid #f0f2f5;
  }

  :deep(.ant-tabs-tab) {
    width: 100% !important;
    text-align: center !important;
  }

  :deep(.ant-tabs-tabpane) {
    padding: 0 8px;
  }

  :deep(.ant-radio-button-wrapper) {
    flex: 1;
    text-align: center;
    padding: 0 4px;
    display: block;
  }

  .tab-list {
    height: 100%;
  }

  .tree-left-contain {
    width: 350px;
    float: left;
    height: calc(100%);
    border-right: 8px solid #f0f2f5;
    overflow-y: auto;
  }

  .right-contarin {
    padding-left: 15px;
    overflow-y: auto;
    height: calc(100%);
  }

  :deep(.ant-tabs-content) {
    height: 100% !important;
    overflow-y: auto;
  }

  .right-top-list {
    display: inline-block;
    padding-right: 15px;
  }

  .right-top-file {
    display: inline-block;
    padding-right: 10px;
  }

  .right-top-list > div {
    width: 140px !important;
    display: inline-block;
  }

  .right-top {
    border-bottom: 1px solid #e5e7eb;
    padding: 15px 0;
  }

  .tree-title-one {
    padding: 8px 0 5px;
  }

  .tree-node {
    display: flex;
    justify-content: space-between;
  }

  .static-box {
    margin: 20px 0;

    .static-empty {
      text-align: center;
    }

    .add-box {
      color: #5e95ff;
      margin-top: 10px;
    }
  }

  .tree-left-container {
    margin: 20px 10px 0 0;

    :deep(.ant-form-item) {
      margin-bottom: 10px;
    }
  }

  :deep(.vben-collapse-container__header) {
    border-bottom: 1px solid #e5e7eb;
  }

  :deep(.ant-tabs-nav) {
    margin-bottom: 0;
  }

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