<script lang="ts" setup>
  import { Select, Button } from 'ant-design-vue';
  import { basicProps } from './props';
  import StepContainer from './StepContainer.vue';
  import { BasicTable, useTable } from '/@/components/Table';
  import {
    columnTypeSchema,
    ColumnFileEnum,
    ColumTypeEnum,
    generateColumnTypeOptions,
  } from './config';
  import { nextTick, onMounted, ref, unref, watch } from 'vue';
  import { ColumnDataRecord, Options, UploadFileParseValue } from './type';
  import { DEVICE_NAME_INDEX } from './const';
  import { buildUUID } from '/@/utils/uuid';

  const props = defineProps({
    ...basicProps,
    value: {
      required: true,
      type: Array as PropType<Record<'type', string>[]>,
    },
    fileParseValue: {
      require: true,
      type: Object as PropType<UploadFileParseValue>,
    },
  });

  const emit = defineEmits(['update:value']);

  const columnTypeRepeatWhiteList = [
    ColumTypeEnum.SERVER_ATTRIBUTE,
    ColumTypeEnum.SHARED_ATTRIBUTE,
    ColumTypeEnum.TIMESERIES,
  ];

  const [register, { setProps, getDataSource }] = useTable({
    size: 'small',
    rowKey: 'id',
    showIndexColumn: false,
    columns: columnTypeSchema,
    resizeHeightOffset: -300,
  });

  const parseValueToTableData = () => {
    const { header = [], content = [] } = props.fileParseValue || {};
    const exampleRow = content.at(0) || {};

    const getColumnType = (index: number) => {
      return index === DEVICE_NAME_INDEX ? ColumTypeEnum.NAME : ColumTypeEnum.SERVER_ATTRIBUTE;
    };

    const dataSource = header.map((columnKey, index) => {
      return {
        [ColumnFileEnum.EXAMPLE_VALUE]: exampleRow[columnKey],
        [ColumnFileEnum.TYPE]: getColumnType(index),
        [ColumnFileEnum.KEY]: columnKey,
        id: buildUUID(),
      } as ColumnDataRecord;
    });

    setProps({
      dataSource,
      pagination: { pageSize: dataSource.length },
      maxHeight: 40 * dataSource.length,
    });
  };

  const columnTypeOptions = ref(generateColumnTypeOptions());

  const handleDisableSelectedOption = () => {
    let dataSource = getDataSource().reduce<string[]>(
      (prev, next) => [...prev, next[ColumnFileEnum.TYPE], next[ColumnFileEnum.OLD_VALUE]],
      []
    );

    dataSource = [...new Set(dataSource.filter(Boolean))];

    const disableSelectedOptions = (
      options: Options[],
      whiteList: string[] = columnTypeRepeatWhiteList
    ) => {
      for (const item of options) {
        if (item.options?.length) {
          disableSelectedOptions(item.options);
          continue;
        }
        if (whiteList.includes(item.value!)) continue;
        item.disabled = dataSource.includes(item.value!);
      }
    };

    disableSelectedOptions(unref(columnTypeOptions));
  };

  const getColumnNeedDisabled = (index: number) => {
    return index === DEVICE_NAME_INDEX;
  };

  const handleGoPreviousStep = () => {
    props.goPreviousStep?.();
  };

  const handleGoNextStep = () => {
    const columns = getDataSource<ColumnDataRecord>().map((item) => ({ type: item.type }));
    emit('update:value', columns);
    props.goNextStep?.();
  };

  watch(
    () => props.fileParseValue,
    () => {
      parseValueToTableData();
    }
  );

  onMounted(async () => {
    parseValueToTableData();
    await nextTick();
    handleDisableSelectedOption();
  });
</script>

<template>
  <StepContainer>
    <BasicTable class="import-device-column-type-table" @register="register">
      <template #type="{ record, index }">
        <section
          class="select-column-type-container flex relative"
          :class="!record.editable && 'justify-center'"
        >
          <Select
            v-model:value="record[ColumnFileEnum.TYPE]"
            @change="handleDisableSelectedOption"
            :disabled="getColumnNeedDisabled(index)"
            :options="columnTypeOptions"
            :dropdown-match-select-width="false"
          />
        </section>
      </template>
      <template #key="{ record }">
        <div>
          <span>{{ record[ColumnFileEnum.KEY] }}</span>
        </div>
      </template>
    </BasicTable>
    <section class="flex justify-end gap-4 mt-4">
      <Button type="primary" @click="handleGoPreviousStep">上一步</Button>
      <Button type="primary" @click="handleGoNextStep">下一步</Button>
    </section>
  </StepContainer>
</template>

<style lang="less" scoped>
  .import-device-column-type-table {
    .ant-select {
      width: 80%;
    }
  }
</style>

<style lang="less">
  .import-device-column-type-table {
    .ant-select,
    .ant-input,
    .ant-select-selector {
      height: 22px !important;
    }

    .ant-select-selection-item {
      line-height: 22px !important;
    }
  }
</style>
