<template>
  <div>
    <el-dialog
      v-model="details.popUpShow.visible"
      destroy-on-close
      align-center
      :title="props.title"
      :width="props.width"
      :fullscreen="props.isFullscreen && details.isFullscreen"
      :show-close="!props.isFullscreen"
    >
      <!-- 标题 -- 头部控件区 -->
      <template v-if="props.isFullscreen" #header="{ close, titleId, titleClass }">
        <div class="my-header flex-c-sb">
          <div class="fwb" :id="titleId" :class="titleClass">{{ props.title }}</div>
          <div class="flex-c-c">
            <!-- 全屏显示按钮 -->
            <el-button type="text" @click="handleFullScrean()" v-if="!details.isFullscreen">
              <el-icon class=""><FullScreen /></el-icon>
            </el-button>
            <el-button type="text" @click="handleFullScrean()" v-else>
              <el-icon class=""><CopyDocument /></el-icon>
            </el-button>

            <!-- 弹窗关闭按钮 -->
            <el-button type="text">
              <el-icon class="" @click="close"><Close /></el-icon>
            </el-button>
          </div>
        </div>
      </template>

      <div class="printCode" ref="printNodeRef">
        <template v-if="details.html">
          <div v-html="details.html"></div>
        </template>

        <div>
          <slot></slot>
        </div>
      </div>

      <div class="flex-c-c mt10">
        <el-button @click="handleClose" icon="CircleClose"> 关 闭 </el-button>
        <el-button type="primary" v-if="props.isShowExport" @click="handleExport" icon="Download">
          导 出
        </el-button>
        <el-button
          type="primary"
          @click="printTemplate"
          icon="Printer"
          :disabled="details.printLoading"
          :loading="details.printLoading"
        >
          打 印
        </el-button>

        <el-button
          type="primary"
          @click="handleShowEdit"
          icon="Edit"
          :disabled="details.printLoading"
          :loading="details.printLoading"
        >
          编辑打印机
        </el-button>

        <!-- <el-select
          v-model="activeIndex"
          placeholder="打印机"
          style="width: 200px; margin-left: 10px"
        >
          <el-option
            v-for="item in $store.state.print.printList"
            :label="item.label"
            :value="item.value"
            :key="item.label"
          />
        </el-select> -->
      </div>
    </el-dialog>

    <!-- 确认打印机 -->
    <el-dialog v-model="isShow" title="确认打印机" align-center width="fit-content">
      <div style="margin-bottom: 40px" class="flex-c-c">
        <div class="flex-none">编辑打印机：</div>
        <el-select
          v-model="activeIndex"
          placeholder="打印机"
          style="width: 200px; margin-left: 10px"
        >
          <el-option
            v-for="item in $store.state.print.printList"
            :label="item.label"
            :value="item.value"
            :key="item.label"
          />
        </el-select>
      </div>
    </el-dialog>

    <el-dialog
      v-model="details.popUpShow.setNum"
      title="确认打印标签数"
      align-center
      width="50%"
      destroy-on-close
    >
      <template v-for="item in details.waybillInfo.detailList">
        <div class="fwb">品类名：{{ item.productName }}</div>
        <div class="flex mt10 mb20">
          <div class="flex1 align-center mr20">
            <div class="mr10">开始索引</div>
            <el-input-number
              class="flex1"
              v-model="item.start"
              :min="1"
              :max="item.num"
            ></el-input-number>
          </div>

          <div class="flex1 align-center">
            <div class="mr10">结束索引</div>
            <el-input-number
              class="flex1"
              v-model="item.end"
              :min="isNumber(item.start > 1) ? item.start : 0"
              :max="item.num"
            ></el-input-number>
          </div>
        </div>
      </template>

      <div class="flex-c-sb">
        <div></div>
        <div>
          <el-button @click="details.popUpShow.setNum = false">取消</el-button>
          <el-button type="primary" @click="handleShowPrint" icon="Printer">确认</el-button>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { defineProps, computed, ref, nextTick, reactive, watch } from 'vue';
import print from '@/utils/print';
import { ElMessage, ElMessageBox } from 'element-plus';
import { getObjType } from '@/utils/util';
import * as XLSX from 'xlsx';
import { exportExcelByDom } from '@/utils/export';
import { dateNow } from '@/utils/date';
import { postFindZeroWaybillLabelInfo } from '@/api/waybill/WaybillOrderList.js';
import { useStore } from 'vuex';
import { isNumber } from '@antfu/utils';

const $store = useStore();

const props = defineProps({
  /** 弹窗宽度 */
  width: {
    type: String,
    default: '780px',
  },
  /** 标题 */
  title: {
    type: String,
    default: '二维码',
  },
  /** 是否显示导出按钮 */
  isShowExport: {
    type: Boolean,
    default: true,
  },
  /** 打印函数 */
  printFn: {
    type: Function,
    default: null,
  },
  /** 打印类型 */
  type: {
    type: String,
    default: 'titlePrint',
  },
  /** 导出名称 */
  exportName: {
    type: String,
    default: '导出',
  },
  /** 是否开启全屏按钮 */
  isFullscreen: {
    type: Boolean,
    default: false,
  },
});

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

const isShow = ref(false);

const activeIndex = computed({
  get() {
    return $store.state.print[props.type + 'ActiveIndex'];
  },
  set(activeIndex) {
    // 设置打印机
    $store.commit('SET_PRINT_ACTIVE', { activeIndex, type: props.type });
  },
});

const details = reactive({
  /** 打印loading */
  printLoading: false,
  /** 是否全屏 */
  isFullscreen: false,
  /** 运单信息 */
  waybillInfo: {} as any,
  popUpShow: {
    /** 打印 */
    visible: false,
    setNum: false,
  },
  html: '',
  waybillNo: '',
});

const handleClose = () => {
  details.popUpShow.visible = false;
};

const printNodeRef = ref();

/** 生成Excel */
const createExcel = () => {
  // const table = this.$refs.tableRef;

  /* 将表格转换为 Workbook 对象 */
  const wb = XLSX.utils.table_to_book(printNodeRef.value);

  console.log('wb :>> ', wb);

  wb.Sheets.Sheet1;

  //单元格外侧框线
  const borderAll = {
    top: {
      style: 'thin',
    },
    bottom: {
      style: 'thin',
    },
    left: {
      style: 'thin',
    },
    right: {
      style: 'thin',
    },
  };

  for (const key in wb.Sheets.Sheet1) {
    const item = wb.Sheets.Sheet1[key];

    const type = getObjType(item);

    console.log('type :>> ', type);

    if (type !== 'object') continue;

    item.s = {
      border: borderAll,
      font: {
        // name: "微软雅黑",
        // sz: 16,
        color: { rgb: '000000' },
        bold: true,
        italic: false,
        underline: false,
      },
      fill: {
        fgColor: { rgb: 'C5D9F1' },
      },
      alignment: {
        horizontal: 'center',
        vertical: 'center',
        wrapText: false, // 自动换行
      },
    };

    item.t = 's';
  }

  /* 导出 Workbook 到 Excel 文件 */
  XLSX.writeFile(wb, 'data.xlsx');
};

/** 导出 */
const handleExport = () => {
  if (!printNodeRef.value) return ElMessage.warning('数据暂未请求完成, 请稍等');

  ElMessageBox.confirm('确认导出?', '', {
    confirmButtonText: '确认',
    cancelButtonText: '关闭',
    type: 'warning',
  }).then(() => {
    console.log('printNodeRef.value :>> ', printNodeRef.value);

    props.type === 'titlePrint'
      ? createExcel()
      : exportExcelByDom(printNodeRef.value, props.exportName + ' - ' + dateNow() + '.xlsx');
  });
};

/** 打印 */
const printTemplate = () => {
  if (props.printFn) return props.printFn();

  details.printLoading = true;

  const nodeArr = document.querySelectorAll('.printSmallText');

  for (let i = 0; i < nodeArr.length; i++) {
    const val = nodeArr[i] as any;
    val.style.fontSize = '0.5rem';
    val.style.lineHeight = '0.7rem';
  }

  const timer = setTimeout(() => {
    const printNode = document.querySelectorAll('.printCode > div > div');
    console.log('printNode :>> ', printNode);
    print(printNode, props.type);
    handleClose();
    details.printLoading = false;
    clearTimeout(timer);
  }, 500);
};

/**
 * 是否开启床车明细全屏
 * @params(_type) 开启或关闭
 */
const handleFullScrean = () => {
  details.isFullscreen = !details.isFullscreen;
};

const handleGetWaybillInfo = async (waybillNo, loading, loadingKey = 'pageLoading') => {
  try {
    loading[loadingKey] = true;
    details.waybillNo = waybillNo;

    const res = await postFindZeroWaybillLabelInfo({ waybillNo });

    const { code, data } = res.data;

    if (code !== 200) return;
    if (getObjType(data) !== 'object') return;

    details.waybillInfo = data;

    if (getObjType(details.waybillInfo.detailList) !== 'array') details.waybillInfo.detailList = [];

    for (let i = 0; i < details.waybillInfo.detailList.length; i++) {
      const value = details.waybillInfo.detailList[i];

      value.start = value.num > 1 ? 1 : 0;
      value.end = value.num >= 1 ? value.num : 0;
    }

    details.popUpShow.setNum = true;
  } catch (error) {
    console.log('error :>> ', error);
  } finally {
    loading[loadingKey] = false;
  }
};

const handleShowPrint = () => {
  let flag = true;

  let html = '';
  let waybillProductName = '';

  for (let i = 0; i < details.waybillInfo.detailList.length; i++) {
    const value = details.waybillInfo.detailList[i];

    waybillProductName += value.productName + ' - ' + value.num + '<br />';
  }

  for (let i = 0; i < details.waybillInfo.detailList.length; i++) {
    const value = details.waybillInfo.detailList[i];

    if (value.end <= 0) continue;

    flag = false;

    for (let index = value.start; index <= value.end; index++) {
      let template = details.waybillInfo.template;

      template = template.replace('发站仓信息', details.waybillInfo.destinationWarehouseName);
      template = template.replace('目的仓信息', details.waybillInfo.departureWarehouseName);
      template = template.replace('发站信息', details.waybillInfo.destination);
      template = template.replace('到站信息', details.waybillInfo.departure);
      template = template.replace('运单号', details.waybillNo);
      template = template.replace('订单号', details.waybillInfo.orderNo);
      template = template.replace('运单地址', details.waybillInfo.waybillNoCode);
      template = template.replace('总件数值', details.waybillInfo.totalCount);
      template = template.replace('总重量值', details.waybillInfo.totalWeight);
      template = template.replace('总方数值', details.waybillInfo.total_volume);
      template = template.replace('货物单项信息', value.productName + ' - ' + index);
      template = template.replace(
        '寄件人信息',
        details.waybillInfo.shipperName +
          details.waybillInfo.shipperMobile +
          details.waybillInfo.shipperAddress
      );
      template = template.replace('货物信息', waybillProductName);
      template = template.replace(
        '收件人信息',
        details.waybillInfo.consigneeName +
          details.waybillInfo.consigneeMobile +
          details.waybillInfo.consigneeAddress
      );
      template = template.replace('送货方式值', details.waybillInfo.delivery_way);
      template = template.replace('送货时间值', details.waybillInfo.createDate.split(' ')[0]);

      html += template;
    }
  }

  if (flag) return ElMessage.warning('请输入需要打印的范围');

  details.html = html;
  details.popUpShow.visible = true;
};

const handleShowEdit = () => {
  $store.commit('GET_PRINT_LIST');
  isShow.value = true;
};

defineExpose({ handleGetWaybillInfo });
</script>

<style scoped lang="scss">
.printCode {
  max-height: 80vh;
  overflow-y: scroll;
}

.my-header {
  :deep(.el-icon) {
    font-size: 20px;
  }
}
</style>
