<script setup lang="ts">
import { dayjs, ElForm, ElInput, ElMessage, UploadProps } from "element-plus";
import { ticketFormItems, ticketAddRules } from "../../config/configs";
import { computed, ref, watch, watchEffect } from "vue";
import { httpAdd } from "/@/api/purchase/ticketReturn";
import { useResponseHandle } from "/@/hooks";
import { httpImageUpload, baseUrl } from "/@/api/other";
import { useUserStore } from "/@/store/modules/user";
import { inv_type_list } from "/@/utils/status";

const visible = ref(false);

//支持的图片格式
const types = ["png", "jpg", "bmp", "jpeg"].map(format => "image/" + format);

const payNo = ref("");
const invType = ref("");
const loading = ref(false);
const formData = ref<Record<string, string>>({});
const formRef = ref<InstanceType<typeof ElForm>>(null);
const formItems = computed(() => ticketFormItems[invType.value] || []);
const showScanInput = computed(() => invType.value === "1");
const scanInputValue = ref("");
const rules = ref({ ...ticketAddRules });

const userStore = useUserStore();
const responseHandle = useResponseHandle();

//图片上传前判断类型大小尺寸
const onBeforeReturnImageUpload: UploadProps["beforeUpload"] = ({
  type,
  size
}) => {
  if (!types.includes(type)) {
    ElMessage.error("请上传jpg.png.bmp.jpeg类型图片");
    return false;
  }

  if (size / 1024 / 1024 > 1) {
    ElMessage.error("图片大小超过1M");
    return false;
  }
};

//保存采购回票
function handleSave() {
  formRef.value.validate(async isValid => {
    if (!isValid) return;
    loading.value = true;

    const { code, message } = await httpAdd({
      payNo: payNo.value,
      invType: invType.value,
      ...formData.value
    });

    responseHandle({
      code,
      message,
      handler: () => (visible.value = false)
    });

    loading.value = false;
  });
}

function handleClose() {
  formData.value = {};
  invType.value = "";
  scanInputValue.value = "";
}

function handleScanKeydown(evt: KeyboardEvent) {
  console.log("123");
  const { keyCode } = evt;

  if (keyCode !== 13) return;

  //校验扫描枪值是否含有中文逗号
  if (scanInputValue.value.indexOf("，") >= 0) {
    ElMessage.error("不能包含中文逗号");
    return (scanInputValue.value = "");
  }

  const [_1, invoiceType, ...chunks] = scanInputValue.value.split(",");
  const [invCode, invNumber, subtotal_amount, open_time, checkNumber] = chunks;

  const year = open_time.slice(0, 4);
  const month = open_time.slice(4, 6);
  const day = open_time.slice(6);

  formData.value = {
    invoiceType,
    invCode,
    subtotal_amount,
    open_time: dayjs(`${year}-${month}-${day}`).format("YYYY-MM-DD HH:mm:ss"),
    invNumber,
    checkNumber
  };

  scanInputValue.value = "";
}

const handleRequeset: UploadProps["httpRequest"] = async ({ file }) => {
  const _formData = new FormData();
  _formData.append("img", file);
  _formData.append("token", userStore.token);
  const { message, code, data } = await httpImageUpload(_formData);

  responseHandle({
    message,
    code,
    handler: () => {
      const { url, name } = data[0];
      formData.value.inv_img = baseUrl + "/" + url;
      formData.value.invName = name;
    }
  });
};

watch(
  () => formItems.value,
  newVal => {
    const newFormData: Record<string, string> = {};
    newVal.forEach(item => (newFormData[item.prop] = ""));
    formData.value = newFormData;
  }
);

//增值税专票校验码不必填
watchEffect(
  () =>
    (rules.value.checkNumber[0].required = formData.value.invoiceType !== "01")
);

const disabledDate = time => {
  return time.getTime() > Date.now();
};

defineExpose({
  onDisplay: (_payNo: string) => {
    visible.value = true;
    payNo.value = _payNo;
  }
});
</script>

<template>
  <el-dialog
    v-model="visible"
    custom-class="ticket__dialog"
    title="添加发票"
    center
    destroy-on-close
    @close="handleClose"
  >
    <el-form label-width="100px" :model="formData" :rules="rules" ref="formRef">
      <el-form-item label="申请类型">
        <el-select v-model="invType">
          <el-option label="手工添加" value="1" />
          <el-option label="ocr识别" value="2" />
        </el-select>
      </el-form-item>

      <!-- 扫码枪识别 -->
      <el-form-item label="扫码枪" v-if="showScanInput">
        <el-input
          type="textarea"
          @keydown="handleScanKeydown"
          v-model="scanInputValue"
        />
      </el-form-item>

      <el-form-item
        v-for="(item, index) in formItems"
        :label="item.label"
        :prop="item.prop"
        :key="index"
      >
        <template v-if="item.prop === 'invName'">
          <el-select v-model="formData[item.prop]" placeholder="请选择发票名称">
            <el-option
              v-for="(type, index) in inv_type_list"
              :label="type.label"
              :value="type.hwy_value"
              :key="index"
            />
          </el-select>
        </template>

        <template v-else-if="item.prop === 'inv_img'">
          <div>
            <el-upload
              class="upload"
              :before-upload="onBeforeReturnImageUpload"
              :http-request="handleRequeset"
              :show-file-list="false"
            >
              <img
                class="avatar"
                :src="formData[item.prop]"
                v-if="formData[item.prop]"
              />
              <div class="text" v-else>点击上传</div>
            </el-upload>
            <span>大小:小于1M; 尺寸:100*100; 类型:jpg.png.bmp.jpeg</span>
          </div>
        </template>

        <template v-else-if="item.prop === 'open_time'">
          <el-date-picker
            v-model="formData[item.prop]"
            :disabled-date="disabledDate"
            value-format="YYYY-MM-DD HH:mm:ss"
            placeholder="请输入开票日期"
          />
        </template>

        <template v-else>
          <el-input v-model="formData[item.prop]" />
        </template>
      </el-form-item>

      <el-form-item justify-end flex w-full>
        <el-button type="primary" :loading="loading" @click="handleSave"
          >保存</el-button
        >
      </el-form-item>
    </el-form>
  </el-dialog>
</template>

<style lang="scss" scoped>
.upload {
  width: 178px;
  height: 178px;
  display: block;
  border: 1px dashed var(--el-border-color);

  .icon {
    font-size: 24px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    text-align: center;
  }

  .text {
    font-size: 20px;
    line-height: 178px;
    width: 178px;
    text-align: center;
  }

  &:hover {
    border-color: #409eff;
  }
}
</style>
