<template>
  <a-modal
    :width="1000"
    v-model:visible="visible"
    :title="state.title"
    :maskClosable="false"
    @ok="handleSubmit"
    @cancel="handleClose"
  >
    <div class="list-title">字段列表</div>
    <a-table
      :dataSource="configDataSource"
      :columns="state.configColumns"
      :pagination="false"
      :scroll="{ y: '300px' }"
    >
      <template #headerCell="{ column }">
        <template v-if="column.key === 'show'">
          是否在弹层列表显示
          <a-checkbox v-model:checked="state.checkedAll" @change="handleChecked" />
        </template>
      </template>
      <template #bodyCell="{ column, record }">
        <template v-if="column.key === 'component'">
          <a-select
            v-model:value="record.bindField"
            style="width: 100%"
            placeholder="请选择填充组件"
            allowClear
          >
            <a-select-option
              :value="val.bindField"
              v-for="(val, index) in selectedList"
              :key="index"
            >
              {{ val.label }}
            </a-select-option>
          </a-select>
        </template>
        <template v-else-if="column.key === 'tableTitle'">
          <a-input v-model:value="record.tableTitle" />
        </template>
        <template v-else-if="column.key === 'show'">
          <a-checkbox v-model:checked="record.show" />
        </template>
        <template v-else-if="column.key === 'width'">
          <a-input v-model:value="record.width" :disabled="!record.show" />
        </template>
      </template>
    </a-table>
  </a-modal>
</template>

<script lang="ts" setup>
  import { watch, reactive, ref } from 'vue';
  import { DataSourceConfig } from '../../../types';
  import { message } from 'ant-design-vue';
  import { ColumnProps } from 'ant-design-vue/lib/table/Column';
  import { cloneDeep } from 'lodash-es';

  const props = defineProps({
    dataSourceAssoDia: { type: Boolean },
    type: { type: String },
    selectedList: { type: Array as any },
    dataSourceOptions: { type: Array as PropType<DataSourceConfig[]> },
  });
  const emit = defineEmits(['update:dataSourceAssoDia', 'update:dataSourceOptions']);
  const state = reactive({
    title: '',
    checkedAll: false as boolean,
    configColumns: [] as ColumnProps[],
  });
  const visible = ref<boolean>(props.dataSourceAssoDia);
  const configDataSource = ref<DataSourceConfig[]>([]);
  const multiplePopupColumns = reactive<ColumnProps[]>([
    {
      title: '#',
      align: 'center',
      customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
      width: 80,
    },
    {
      title: '字段名',
      dataIndex: 'name',
      key: 'name',
      align: 'center',
    },
    {
      title: '表头名称',
      dataIndex: 'tableTitle',
      key: 'tableTitle',
      align: 'center',
      width: 200,
    },
    {
      title: '是否在弹层列表显示',
      dataIndex: 'show',
      key: 'show',
      align: 'center',
      width: 200,
    },
    {
      title: '列表宽度',
      dataIndex: 'width',
      key: 'width',
      align: 'center',
      width: 150,
    },
  ]);

  const associatePopupColumns = reactive<ColumnProps[]>([
    {
      title: '#',
      align: 'center',
      customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
      width: 80,
    },
    {
      title: '字段名',
      dataIndex: 'name',
      key: 'name',
      align: 'center',
    },
    {
      title: '填充组件',
      dataIndex: 'component',
      key: 'component',
      align: 'center',
      width: 250,
    },
    {
      title: '表头名称',
      dataIndex: 'tableTitle',
      key: 'tableTitle',
      align: 'center',
      width: 200,
    },
    {
      title: '是否在弹层列表显示',
      dataIndex: 'show',
      key: 'show',
      align: 'center',
      width: 200,
    },
    {
      title: '列表宽度',
      dataIndex: 'width',
      key: 'width',
      align: 'center',
      width: 150,
    },
  ]);

  const associateSelectColumns = reactive<ColumnProps[]>([
    {
      title: '#',
      align: 'center',
      customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
      width: 80,
    },
    {
      title: '字段名',
      dataIndex: 'name',
      key: 'name',
      align: 'center',
    },
    {
      title: '填充组件',
      dataIndex: 'component',
      key: 'component',
      align: 'center',
    },
    {
      title: '填充组件绑定字段',
      dataIndex: 'bindField',
      key: 'bindField',
      align: 'center',
    },
  ]);

  watch(
    () => props.type,
    (val) => {
      switch (val) {
        case 'associate-popup':
          state.configColumns = associatePopupColumns;
          state.title = '联想数据配置-数据源';
          break;
        case 'multiple-popup':
          state.configColumns = multiplePopupColumns;
          state.title = '多选数据配置-数据源';
          break;
        case 'associate-select':
          state.configColumns = associateSelectColumns;
          state.title = '联想数据配置-数据源';
          break;
      }
    },
    { immediate: true },
  );

  watch(
    () => props.dataSourceOptions,
    (val) => {
      if (!val?.length) return;
      configDataSource.value = cloneDeep(val)!;
    },
    {
      deep: true,
      immediate: true,
    },
  );

  watch(
    configDataSource.value,
    (val) => {
      state.checkedAll = val!.every((item: any) => {
        return item.show;
      });
    },
    {
      deep: true,
      immediate: true,
    },
  );

  function handleClose() {
    emit('update:dataSourceAssoDia', false);
  }
  function handleChecked(e: any) {
    configDataSource.value.map((item: any) => (item.show = e.target.checked));
  }

  function handleSubmit() {
    const bindFieldArr = [] as any;
    configDataSource.value?.map((item: any) => {
      if (item.bindField) {
        bindFieldArr.push(item.bindField);
      }
    });

    if (new Set(bindFieldArr).size !== bindFieldArr.length) {
      message.error('组件存在重复绑定,请更改');
      return;
    }

    emit('update:dataSourceAssoDia', false);
    emit('update:dataSourceOptions', configDataSource.value);
  }
</script>

<style lang="less" scoped>
  .list-title {
    margin: 10px 0 5px 15px;
    font-size: 14px;
    line-height: 16px;
    padding-left: 6px;
    border-left: 6px solid #5e95ff;
  }
</style>
