<template>
  <a-modal
    v-model:visible="visible"
    title="打印预览"
    width="100%"
    wrap-class-name="full-modal"
    :bodyStyle="{ padding: '10px' }"
    @cancel="emits('update:isShowPrint', false)"
  >
    <div class="btn-box">
      <a-button style="color: #606266; font-size: 13px" @click="handlePrint">
        <template #icon>
          <PrinterOutlined />
        </template>
        打印
      </a-button>
    </div>
    <div v-if="printData?.style === '1' && !!configs?.formProps">
      <SimpleForm
        class="print-style1-box"
        :formProps="configs?.formProps"
        :formModel="configs?.formModel"
        :isWorkFlow="true"
      />
    </div>
    <div :class="`print-style${props.printData?.style}-box`" v-else>
      <template v-for="(item, index) in formInfo" :key="index">
        <TableStyle :item="item" :componentType="item.type" />
      </template>
    </div>
  </a-modal>
</template>
<script lang="ts" setup>
  import { ref, computed, Ref, StyleValue, provide, inject, onMounted } from 'vue';
  import SimpleForm from '/@/components/SimpleForm/src/SimpleForm.vue';
  import TableStyle from './TableStyle.vue';
  import { getUserMulti } from '/@/api/system/user';
  import { getDicItemDetail } from '/@/api/system/dic';
  import { getDepartment } from '/@/api/system/department';
  import { getAreaMulti } from '/@/api/system/area';
  import { PrinterOutlined } from '@ant-design/icons-vue';
  import { buildComponentType } from '/@/utils/helper/designHelper';
  import html2canvas from 'html2canvas';
  import printJS from 'print-js';
  import { cloneDeep, isNil } from 'lodash-es';
  import domtoimage from 'dom-to-image';
  const props = defineProps({
    formConfigs: Object,
    printData: Object,
    isShowPrint: Boolean,
  });

  const emits = defineEmits(['update:isShowPrint']);
  const configs = ref({
    formProps: {} as any,
    formModel: {},
  });
  const formInfo = ref<any>([]);
  const activeKey = inject<Ref<number>>('tabActiveKey');
  const visible = ref<boolean>(props.isShowPrint);
  const borderColorStyle = computed(() => {
    return { 'border-color': `${props.printData?.borderColor} !important` };
  });
  const underlineStyle = computed(() => {
    return { 'border-bottom': props.printData?.underline === '1' ? '1px solid' : 0 };
  });

  provide<Ref<StyleValue>>('borderColorStyle', borderColorStyle);
  provide<Ref<StyleValue>>('underlineStyle', underlineStyle);
  onMounted(async () => {
    configs.value.formProps = cloneDeep(props.formConfigs?.formProps);
    formInfo.value = [];
    if (props.printData?.style !== '1') {
      await changeFormat(configs.value.formProps.schemas, formInfo.value);
    }
  });
  configs.value.formModel = cloneDeep(props.formConfigs?.formModel);

  const handlePrint = async () => {
    let element: HTMLElement = window.document.querySelector(
      `.print-style${props.printData?.style || 1}-box`,
    )!;

    let url;
    if (props.printData?.style === '1') {
      url = await domtoimage.toPng(element);
    } else {
      let canvas = await html2canvas(element, {
        backgroundColor: null,
        useCORS: true,
        windowHeight: document.body.scrollHeight,
      });
      url = canvas.toDataURL();
    }
    printJS({
      printable: url,
      type: 'image',
      documentTitle: '打印',
    });
  };
  const changeFormat = async (schemas, info) => {
    if (!configs.value) return;
    const keys = Object.keys(configs.value.formModel);
    for (const item of schemas) {
      if (['tab', 'grid', 'card'].includes(item.type)) {
        const layoutChildren = {};
        for (let index = 0; index < item.children.length; index++) {
          const name =
            item.type === 'grid'
              ? index
              : item.type === 'card'
              ? item.componentProps?.title
              : item.children[index].name;
          layoutChildren[name] = [];
          if ((index === activeKey?.value && item.type === 'tab') || item.type !== 'tab') {
            await changeFormat(item.children[index].list, layoutChildren[name]);
          }
        }
        info.push({
          type: item.type,
          value: layoutChildren,
        });
      } else if (item.type === 'form') {
        if (keys.includes(item.componentProps.mainKey)) {
          // const children: object[] = [];
          // configs.value.formModel[item.componentProps.mainKey].forEach((sub) => {
          //   const subInfo = {};
          //   item.componentProps.columns.forEach((col) => {
          //     if (Object.keys(sub).includes(col.dataIndex) && !!col.show) {
          //       subInfo[col.title] = sub[col.dataIndex];
          //     }
          //   });
          //   children.push(subInfo);
          // });
          const columns: any[] = [];
          const value: any[] = [];
          configs.value.formModel[item.componentProps.mainKey].forEach((sub) => {
            let val = {};
            item.componentProps.columns.forEach(async (col) => {
              if (Object.keys(sub).includes(col.dataIndex) && !!col.show) {
                if (!columns.map((x) => x.key).includes(col.dataIndex)) {
                  columns.push({
                    title: col.title,
                    key: col.dataIndex,
                    dataIndex: col.dataIndex,
                  });
                }

                val[col.dataIndex] = await changeValue(col, sub[col.dataIndex]);
              }
            });
            value.push(val);
          });
          info.push({
            type: item.type,
            label: item.label,
            value,
            columns,
          });
        }
      } else if (keys.includes(item.field) && !!item.show) {
        let value = await changeValue(item, configs.value.formModel[item.field]);
        info.push({
          label: item.label,
          type: item.type,
          componentProps: item.componentProps,
          value,
        });
      }
    }
  };

  const changeValue = async (item, fieldValue) => {
    const type = item.type ? buildComponentType(item.type) : item.componentType;
    if (isNil(fieldValue)) return fieldValue;
    if (type === 'User' || (type === 'Info' && item.componentProps?.infoType === 0)) {
      const res = await getUserMulti(fieldValue);
      return res?.map((x) => x.name).toString();
    } else if (type === 'Dept' || (type === 'Info' && item.componentProps?.infoType === 1)) {
      const res = await getDepartment(fieldValue);
      return res?.name;
    } else if (type === 'Area') {
      const res = await getAreaMulti(fieldValue);
      return res?.map((x) => x.name).join(' / ');
    } else if (item.componentProps?.datasourceType === 'dic') {
      const res = await getDicItemDetail(item.componentProps?.params.itemId, fieldValue);
      return res?.map((x) => x.name).toString();
    }
    return fieldValue;
  };
</script>
<style lang="less" scoped>
  .btn-box {
    width: 100%;
    text-align: right;
    margin-bottom: 10px;
  }

  .borderClass {
    border: 0 !important;
  }

  .print-style2-box,
  .print-style3-box,
  .print-style4-box {
    margin: 10px 20px;

    :deep(.ant-row) {
      font-size: 16px;
      border: 1px solid !important;

      .ant-col {
        padding: 15px 5px;
      }
    }
  }

  .print-style3-box {
    :deep(.ant-col:last-child) {
      border-left: 0 !important;
    }
  }

  .print-style2-box {
    :deep(.ant-col:first-child) {
      border-right: 1px solid;
    }
  }

  .print-style4-box {
    :deep(.ant-row) {
      border-left: 0 !important;
      border-right: 0 !important;
      border-top: 0 !important;
    }
  }
</style>
<style lang="less">
  .full-modal {
    .ant-modal {
      max-width: 100%;
      top: 0 !important;
      padding-bottom: 0;
      margin: 0;
      height: 100%;
    }

    .ant-modal-content {
      display: flex;
      flex-direction: column;
      min-height: 100%;
    }

    .ant-modal-body {
      flex: 1;
    }

    .ant-modal-footer {
      display: none !important;
    }
  }
</style>
