<script lang="ts" setup>
  import { Tabs } from 'ant-design-vue';
  import BasicModal from '/@/components/Modal/src/BasicModal.vue';
  import BasicConfiguration from './BasicConfiguration.vue';
  import VisualConfiguration from './VisualConfiguration.vue';
  import { computed, ref, unref } from 'vue';
  import { RouteParams, useRoute } from 'vue-router';
  import { addDataComponent, updateDataComponent } from '/@/api/dataBoard';
  import { useModalInner } from '/@/components/Modal';
  import { DataBoardLayoutInfo } from '../../types/type';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { decode } from '../../config/config';
  import { ComponentInfo } from '/@/api/dataBoard/model';
  import { useCalcGridLayout } from '../../hook/useCalcGridLayout';
  import { FrontComponent } from '../../const/const';
  import { frontComponentMap } from '../../components/help';

  interface DataComponentRouteParams extends RouteParams {
    id: string;
  }

  const props = defineProps<{
    layout: DataBoardLayoutInfo[];
  }>();

  const emit = defineEmits(['update', 'create', 'register']);
  const ROUTE = useRoute();

  const loading = ref(false);
  const { createMessage } = useMessage();

  const boardId = computed(() => {
    return decode((ROUTE.params as DataComponentRouteParams).boardId as string);
  });

  const frontId = ref();

  const isEdit = ref(false);

  const componentRecord = ref<DataBoardLayoutInfo>({} as unknown as DataBoardLayoutInfo);

  const componentDefaultConfig = ref<Partial<ComponentInfo>>({});

  const getComponentCategory = computed(() => {
    return frontComponentMap.get(unref(frontId))?.ComponentCategory;
  });

  const [register, { closeModal, changeOkLoading }] = useModalInner(
    (data: { isEdit: boolean; record?: DataBoardLayoutInfo }) => {
      componentRecord.value = data.record || ({} as unknown as DataBoardLayoutInfo);
      if (!unref(isEdit)) frontId.value = FrontComponent.TEXT_COMPONENT_1;
      frontId.value =
        (data.record?.record?.frontId as FrontComponent) || FrontComponent.TEXT_COMPONENT_1;
      isEdit.value = data.isEdit || false;
    }
  );

  const basicConfigurationEl = ref<{
    getAllDataSourceFieldValue: Fn<any, Recordable>;
    validate: Fn;
  }>();

  const resetForm = () => {
    isEdit.value = false;
    frontId.value = undefined;
    componentRecord.value = {} as unknown as DataBoardLayoutInfo;
    componentDefaultConfig.value = {};
  };

  const handleSubmit = async () => {
    try {
      const { getAllDataSourceFieldValue, validate } = unref(basicConfigurationEl)!;
      await validate();
      const value = getAllDataSourceFieldValue();

      unref(isEdit) ? handleUpdateComponent(value) : handleAddComponent(value);
      resetForm();
    } catch (error: unknown) {
      window.console.error(error);
    }
  };

  const { calcLayoutInfo } = useCalcGridLayout();
  const handleAddComponent = async (value: Recordable) => {
    try {
      if (!unref(frontId)) {
        createMessage.warning('请选择可视化组件');
        return;
      }
      const layout = calcLayoutInfo(unref(props.layout));
      changeOkLoading(true);
      loading.value = true;
      await addDataComponent({
        boardId: unref(boardId),
        record: { dataBoardId: unref(boardId), frontId: unref(frontId), ...value, layout },
      });
      createMessage.success('创建成功');
      closeModal();
      emit('create');
    } catch (error) {
      console.log(error);
      // createMessage.error('创建失败');
    } finally {
      changeOkLoading(false);
      loading.value = false;
    }
  };

  const handleUpdateComponent = async (value: Recordable) => {
    try {
      changeOkLoading(true);
      loading.value = true;
      const res = await updateDataComponent({
        boardId: unref(boardId),
        record: {
          id: unref(componentRecord).i,
          dataBoardId: unref(boardId),
          frontId: unref(frontId),
          ...value,
        },
      });
      createMessage.success('修改成功');
      closeModal();
      // emit('submit');
      emit('update', res.data.id);
    } catch (error) {
      // createMessage.error('修改失败');
    } finally {
      changeOkLoading(false);
      loading.value = false;
    }
  };

  const handleComponentCheckedChange = (record: ComponentInfo) => {
    componentDefaultConfig.value = record;
  };
</script>

<template>
  <BasicModal
    v-bind="$attrs"
    @register="register"
    title="自定义组件"
    width="70%"
    :destroy-on-close="true"
    @ok="handleSubmit"
    @cancel="resetForm"
    :ok-button-props="{ loading }"
  >
    <section>
      <Tabs type="card">
        <Tabs.TabPane key="basicConfig" tab="基础配置">
          <BasicConfiguration
            ref="basicConfigurationEl"
            :front-id="frontId"
            :isEdit="isEdit"
            :record="componentRecord"
            :defaultConfig="componentDefaultConfig"
            :componentCategory="getComponentCategory"
          />
        </Tabs.TabPane>
        <Tabs.TabPane key="visualConfig" tab="可视化配置">
          <VisualConfiguration v-model:value="frontId" @change="handleComponentCheckedChange" />
        </Tabs.TabPane>
      </Tabs>
    </section>
  </BasicModal>
</template>
