<template>
  <form-item-wrapper
    :designer="designer"
    :field="field"
    :rules="rules"
    :design-state="designState"
    :parent-widget="parentWidget"
    :parent-list="parentList"
    :index-of-parent-list="indexOfParentList"
    :sub-form-row-index="subFormRowIndex"
    :sub-form-col-index="subFormColIndex"
    :sub-form-row-id="subFormRowId"
  >
    <div id="uploadImage" class="upload-img" v-if="designState">
      <div
        class="el-upload el-upload--picture"
        style="vertical-align: middle; display: inline-block; float: left"
      >
        <button type="button" class="avatar-uploader">
          <i class="el-icon-plus avatar-uploader-icon"></i>
        </button>
      </div>
    </div>
    <baseUpload
      accept="file"
      :file.sync="fieldModel"
      :hidePasteArea.sync="isH5"
      :uploadDialogCustomClass="isH5 ? 'dialog-upload-h5' : null"
      :pickPrivateProfile="false"
      :multi="field.options.limit !== 1"
      :limit="field.options.limit"
      resultType="Array"
      :edit="!field.options.disabled"
      :remove="!field.options.hideRemoveButton"
      @callback="submitFile"
      :hideInfo="field.options.hideFileInfo"
      :hideName="field.options.hideFileName"
      :showSize="!!field.options.showFileSize"
      :createBy="!!field.options.showFileCreateBy"
      :createDate="!!field.options.showFileCreateDate"
      :widgetSize="field.options.fileShowImageSize"
      v-else
    ></baseUpload>
  </form-item-wrapper>
</template>

<script>
import FormItemWrapper from "./form-item-wrapper";
import emitter from "../../../../../components/xform/utils/emitter";
import i18n from "../../../../../components/xform/utils/i18n";
import fieldMixin from "../../../../../components/xform/form-designer/form-widget/field-widget/fieldMixin";

export default {
  name: "vabUpload-widget",
  componentName: "FieldWidget", //必须固定为FieldWidget，用于接收父级组件的broadcast事件
  mixins: [emitter, fieldMixin, i18n],
  props: {
    field: Object,
    parentWidget: Object,
    parentList: Array,
    indexOfParentList: Number,
    designer: Object,

    designState: {
      type: Boolean,
      default: false,
    },

    subFormRowIndex: {
      /* 子表单组件行索引，从0开始计数 */ type: Number,
      default: -1,
    },
    subFormColIndex: {
      /* 子表单组件列索引，从0开始计数 */ type: Number,
      default: -1,
    },
    subFormRowId: {
      /* 子表单组件行Id，唯一id且不可变 */ type: String,
      default: "",
    },
  },
  components: {
    FormItemWrapper,
  },
  inject: ["refList", "globalOptionData", "globalModel", "getFormConfig"],
  data() {
    return {
      oldFieldValue: [], //field组件change之前的值
      fieldModel: [],
      rules: [],
      isH5: false,
    };
  },
  watch: {
    fieldModel(val) {
      this.handleChangeEvent(val);
    },
  },
  computed: {
    formDataId() {
      let formRef = this.getFormRef();
      return formRef.dataId;
    },
  },
  beforeCreate() {
    /* 这里不能访问方法和属性！！ */
  },

  created() {
    /* 注意：子组件mounted在父组件created之后、父组件mounted之前触发，故子组件mounted需要用到的prop
       需要在父组件created中初始化！！ */

    this.isH5 = this.getFormConfig().layoutType === "H5";

    this.initFieldModel();
    this.registerToRefList();
    this.initEventHandler();
    this.buildFieldRules();

    this.handleOnCreated();
  },

  mounted() {
    this.handleOnMounted();
  },

  beforeDestroy() {
    this.unregisterFromRefList();
  },
  methods: {
    setValue(val) {
      let data = val || [];
      this.fieldModel = data;
      this.getFormRef().formDataModel[this.fieldKeyName] = data;
    },
    loadDataDefaultHandle() {
      let dataId = this.formDataId;
      if (!dataId) return;
      let reportTemplate = this.getFormRef().reportTemplate;
      let formCode = reportTemplate.formCode;
      let formScriptEnabled = this.field.options.formScriptEnabled || false;
      let scriptCode = this.field.options.formScriptCode || "getList";
      if (!scriptCode) return;
      if (dataId) {
        let accessParam = this.handleCustomEvent(
          this.field.options.formScriptParam
        );
        return this.formHttp({
          // url: "/" + reportTemplate.serviceName + "/form_ins/getList",
          scriptCode: scriptCode,
          data: {
            formCode: formCode,
            formVersion: reportTemplate.formVersion,
            taBm: this.fieldKeyName,
            data: {
              ...accessParam,
              id: dataId,
            },
          },
          callback: (res) => {
            let rows = res.objx || [];
            this.setValue(rows);
            this.handleCustomEvent(
              this.field.options.formScriptSuccess,
              ["res"],
              [res]
            );
          },
        });
      }
    },
    submitFile(rows, fileInfos) {
      // this.handlLineCode(fileInfos);
      let eventParamNames = ["attachments", "fileInfos"];
      let eventParamValues = [rows, fileInfos];
      this.handleCustomEvent(
        this.field.options.onAfterConfirmFile,
        eventParamNames,
        eventParamValues
      );
    },
    setValueByUrl(fileUrl) {
      let value = [];
      if (fileUrl) {
        let row = this.parseFileUrl(fileUrl);
        if (row) {
          value.push(row);
        }
      }
      this.setValue(value);
    },
    parseFileUrl(fileUrl) {
      if (!fileUrl) return null;
      let result = null;

      // 输入校验
      if (typeof fileUrl !== "string") {
        throw new TypeError("输入必须是字符串格式");
      }
      if (!fileUrl.trim()) {
        throw new Error("URL不能为空");
      }

      // 基本URL格式验证
      const urlRegex =
        /^(https?:\/\/)?([\w.-]+)(:\d+)?(\/[^?#]*)?(\?[^#]*)?(#.*)?$/i;
      if (!urlRegex.test(fileUrl)) {
        throw new Error("无效的URL格式");
      }

      // 提取域名部分
      const domainRegex = /^(https?:\/\/[^\/]+)/i;
      const domainMatch = fileUrl.match(domainRegex);
      if (!domainMatch) {
        throw new Error("URL缺少协议或域名部分");
      }
      const domain = domainMatch[0];

      // 提取完整路径
      const url = fileUrl.substring(domain.length);
      if (!url || url === "/") {
        throw new Error("URL缺少文件路径部分");
      }

      // 提取带扩展名的文件名
      const filenameRegex = /[^\/]+$/;
      const filenameMatch = url.match(filenameRegex);
      if (!filenameMatch) {
        throw new Error("无法从路径中提取文件名");
      }
      const fullFilename = filenameMatch[0];

      // 验证文件名格式（至少1字符+扩展名）
      const nameFormat = /^.+\..+$/;
      if (!nameFormat.test(fullFilename)) {
        throw new Error(`无效的文件名格式: ${fullFilename}`);
      }

      // 修复点：更可靠的文件名和扩展名分离
      const lastDotIndex = fullFilename.lastIndexOf(".");
      const filenameBase = fullFilename.substring(0, lastDotIndex); // 点之前部分
      const extension = fullFilename.substring(lastDotIndex + 1).toLowerCase(); // 点之后部分

      // 扩展名验证
      /* const validExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'bmp'];
    if (!validExtensions.includes(extension)) {
      throw new Error(`不支持的扩展名类型: ${extension}`);
    } */

      let thumbnail = null,
        large = null,
        medium = null,
        source = null;
      if (this.$commonFileUtil.isPicture(extension)) {
        thumbnail = url;
        large = url;
        medium = url;
        source = url;
      }

      result = {
        extension,
        domain,
        url,
        thumbnail,
        large,
        medium,
        source,
        name: fullFilename,
      };

      // 返回结构化对象
      return result;
    },
    /*handlLineCode(fileInfos) {
      let allPromise = [];
      fileInfos.forEach(async fileInfo => {
        await this.processFile(fileInfo.file, (lineCode) => {
          fileInfo.lineCode = lineCode;
        })
      })

    },
    processFile(file, callback) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = (e) => this.processImage(e.target.result, (lineCode) => {
          resolve(lineCode)
          callback(lineCode)
        });
        reader.onerror = () => {
          resolve(null)
          callback(null)
          this.setError('文件读取失败')
        };
        reader.readAsDataURL(file);
      })
    },
    async processImage(base64, callback) {
      try {
        // 使用 ZXing 3.x 的 API
        const result = await decode(base64, (result, err) => {
          if (err) {
            this.handleError(`条码识别失败: ${err}`);
            callback && callback(null)
            return;
          }
          this.scannedText = result.text;
          this.loading = false;
          callback && callback(result.text)
        });
      } catch (err) {
        console.error(err);
        callback && callback(null)
        this.handleError(`条码识别失败: ${err.message}`);
      }
    },
    handleLineCode(fileInfos) {
      fileInfos.forEach(fileInfo => {
        let file = fileInfo.file;
      })
    },
    handleImage(base64, fileName, callback) {
      // 创建 ZXing Scanner


      // 将 Base64 转换为 ImageLuminanceSource
      // const imageData = Uint8Array.from(atob(base64), c => c.charCodeAt(0));
      // const source = new ZXing.ImageLuminanceSource(imageData, base64.length);

      decode(base64, (result, err) => {
        if (err) {
          this.handleError(`条码识别失败: ${err}`);
          callback && callback(null)
          return;
        }
        this.scannedText = result.text;
        this.loading = false;
        callback && callback(result.text)
      });
    },

    handleError(errorMessage) {
      this.error = errorMessage;
      this.loading = false;
    },*/
  },
};
</script>

<style lang="scss" scoped>
@import "~@/styles/global.scss"; //* form-item-wrapper已引入，还需要重复引入吗？ *//

.full-width-input {
  width: 100% !important;
}

.hideUploadDiv {
  ::v-deep div.el-upload--picture-card {
    /* 隐藏最后的图片上传按钮 */
    display: none;
  }

  ::v-deep div.el-upload--text {
    /* 隐藏最后的文件上传按钮 */
    display: none;
  }

  ::v-deep div.el-upload__tip {
    /* 隐藏最后的文件上传按钮提示 */
    display: none;
  }
}
</style>
