<!--
/**
 * author: vformAdmin
 * email: vdpadmin@163.com
 * website: https://www.vform666.com
 * date: 2021.08.18
 * remark: 如果要分发VForm源码，需在本文件顶部保留此文件头信息！！
 */
-->

<template>
  <div
    class="field-wrapper"
    :class="{ 'design-time-bottom-margin': !!this.designer }"
    v-show="!field.options.hidden || designState === true"
  >
    <div>
      <template v-if="formItemProp === 'false'">
        <template v-if="!field.options.hidden">
          <template v-if="isShowWidget()">
            <slot></slot>
          </template>
          <template
            v-else-if="
              field.options.widgetTextFlag === 3 &&
              field.options.widgetTextLinkConfig
            "
          >
            <div class="ellipsis">
              <a
                class="a-link"
                :class="getWidgetClass()"
                @click.native="handleClick"
              >
                <span>
                  <i
                    :class="
                      field.options.widgetTextLinkConfig.options.prefixIcon
                    "
                    v-if="
                      !!field.options.widgetTextLinkConfig.options.prefixIcon
                    "
                  ></i>
                  <span>{{ getWidgetValue() }}</span>
                  <i
                    :class="
                      field.options.widgetTextLinkConfig.options.suffixIcon
                    "
                    v-if="
                      !!field.options.widgetTextLinkConfig.options.suffixIcon
                    "
                  ></i>
                </span>
              </a>
            </div>
          </template>
          <template v-else>
            <span>{{ getShowValue() }}</span>
          </template>
        </template>
      </template>
      <template v-else>
        <el-form-item
          v-if="
            !!field.formItemFlag &&
            (!field.options.hidden || designState === true)
          "
          :label="label"
          :label-width="labelWidth"
          :rules="getRules()"
          :prop="getPropName()"
          :class="[
            selected ? 'selected' : '',
            labelAlign,
            customClass,
            field.options.required ? 'required' : '',
          ]"
          @click.native.stop="selectField(field)"
        >
          <span
            v-if="!!field.options.labelIconClass"
            slot="label"
            class="custom-label"
          >
            <template v-if="field.options.labelIconPosition === 'front'">
              <template v-if="!!field.options.labelTooltip">
                <el-tooltip :content="field.options.labelTooltip" effect="dark">
                  <i :class="field.options.labelIconClass"></i></el-tooltip
                ><span :style="{ color: field.options.labelColor }">{{
                  label
                }}</span></template
              >
              <template v-else>
                <i :class="field.options.labelIconClass"></i
                ><span :style="{ color: field.options.labelColor }">{{
                  label
                }}</span></template
              >
            </template>
            <template v-else-if="field.options.labelIconPosition === 'rear'">
              <template v-if="!!field.options.labelTooltip">
                <span :style="{ color: field.options.labelColor }">{{
                  label
                }}</span
                ><el-tooltip
                  :content="field.options.labelTooltip"
                  effect="dark"
                >
                  <i :class="field.options.labelIconClass"></i></el-tooltip
              ></template>
              <template v-else>
                <span :style="{ color: field.options.labelColor }">{{
                  label
                }}</span
                ><i :class="field.options.labelIconClass"></i
              ></template>
            </template>
          </span>
          <span
            v-else-if="!!field.options.labelColor"
            slot="label"
            :style="{ color: field.options.labelColor }"
          >
            {{ label }}
          </span>
          <template v-if="isShowWidget()">
            <slot></slot>
          </template>
          <template
            v-else-if="
              field.options.widgetTextFlag === 3 &&
              field.options.widgetTextLinkConfig
            "
          >
            <div class="ellipsis">
              <a class="a-link" :class="getWidgetClass()" @click="handleClick">
                <span>
                  <i
                    :class="
                      field.options.widgetTextLinkConfig.options.prefixIcon
                    "
                    v-if="
                      !!field.options.widgetTextLinkConfig.options.prefixIcon
                    "
                  ></i>
                  <span>{{ getWidgetValue() }}</span>
                  <i
                    :class="
                      field.options.widgetTextLinkConfig.options.suffixIcon
                    "
                    v-if="
                      !!field.options.widgetTextLinkConfig.options.suffixIcon
                    "
                  ></i>
                </span>
              </a>
            </div>
          </template>
          <template v-else>
            <span>{{ getShowValue() }}</span>
          </template>
        </el-form-item>
      </template>
    </div>
    <template v-if="!!this.designer">
      <div class="field-action" v-if="designer.selectedId === field.id">
        <i
          class="el-icon-back"
          :title="i18nt('designer.hint.selectParentWidget')"
          @click.stop="selectParentWidget(field)"
        ></i>
        <i
          class="el-icon-top"
          v-if="!!parentList && parentList.length > 1"
          :title="i18nt('designer.hint.moveUpWidget')"
          @click.stop="moveUpWidget(field)"
        ></i>
        <i
          class="el-icon-bottom"
          v-if="!!parentList && parentList.length > 1"
          :title="i18nt('designer.hint.moveDownWidget')"
          @click.stop="moveDownWidget(field)"
        ></i>
        <i
          class="el-icon-delete"
          :title="i18nt('designer.hint.remove')"
          @click.stop="removeFieldWidget"
        ></i>
      </div>

      <div
        class="drag-handler background-opacity"
        v-if="designer.selectedId === field.id"
      >
        <i class="el-icon-rank" :title="i18nt('designer.hint.dragHandler')"></i>
        <i>{{
          i18n2t(
            `designer.widgetLabel.${field.type}`,
            `extension.widgetLabel.${field.type}`
          )
        }}</i>
        <i v-if="field.options.hidden === true" class="iconfont icon-hide"></i>
      </div>
    </template>
  </div>
</template>

<script>
import i18n from "../../../../../components/xform/utils/i18n";
import { getSubFormNameByFieldId } from "../../../../../components/xform/utils/util";

export default {
  name: "form-item-wrapper",
  mixins: [i18n],
  props: {
    field: Object,
    designer: Object,
    parentWidget: Object,
    parentList: Array,
    indexOfParentList: Number,

    designState: {
      type: Boolean,
      default: false,
    },
    subFormRowIndex: {
      /* 子表单组件行索引，从0开始计数 */ type: Number,
      default: -1,
    },
    subFormColIndex: {
      /* 子表单组件列索引，从0开始计数 */ type: Number,
      default: -1,
    },
    subFormRowId: {
      /* 子表单组件行Id，唯一id且不可变 */ type: String,
      default: "",
    },

    rules: Array,
  },
  inject: [
    "getFormConfig",
    "getSubFormFieldFlag",
    "getSubFormName",
    "tableParam",
    "formItemProp",
    "getObjectFieldFlag",
    "getObjectName",
  ],
  data() {
    return {
      encryptFormula: null,
    };
  },
  computed: {
    formConfig: function () {
      return this.getFormConfig();
    },
    selected() {
      return !!this.designer && this.field.id === this.designer.selectedId;
    },

    label() {
      if (!!this.field.options.labelHidden) {
        return "";
      }
      return this.getI18nLabel(this.field.options.label);
      // let label = this.field.options.label
      // return label ? this.$t2(label) : label;
    },

    labelWidth() {
      if (!!this.field.options.labelHidden) {
        return (!!this.designState ? 5 : 0) + "px"; //设计期间标签最小宽度5像素，以便于鼠标点击可选中组件！！
      }

      if (!!this.field.options.labelWidth) {
        return this.field.options.labelWidth + "px !important";
      }

      if (!!this.designer) {
        return this.designer.formConfig.labelWidth + "px";
      } else {
        return this.formConfig.labelWidth + "px";
      }
    },

    labelAlign() {
      if (!this?.field?.options?.labelAlign) {
        return "";
      }
      if (!!this.field.options.labelAlign) {
        return this.field.options.labelAlign;
      }

      if (!!this.designer) {
        return this.designer.formConfig.labelAlign || "label-left-align";
      } else {
        return this.formConfig.labelAlign || "label-left-align";
      }
    },

    customClass() {
      return !!this.field.options.customClass
        ? this.field.options.customClass.join(" ")
        : "";
    },

    subFormName() {
      return !!this.parentWidget ? this.parentWidget.options.name : "";
    },

    subFormItemFlag() {
      return (
        this.isSubFormItem() ||
        (!!this.parentWidget ? this.parentWidget.type === "sub-form" : false)
      );
    },
  },
  created() {
    //
    this.initShowType();
  },
  methods: {
    isSubFormItem() {
      return !!this.tableParam;
    },
    selectField(field) {
      if (!!this.designer) {
        this.designer.setSelected(field);
        this.designer.emitEvent("field-selected", this.parentWidget); //发送选中组件的父组件对象
      }
    },

    selectParentWidget() {
      if (this.parentWidget) {
        this.designer.setSelected(this.parentWidget);
      } else {
        this.designer.clearSelected();
      }
    },

    moveUpWidget() {
      this.designer.moveUpWidget(this.parentList, this.indexOfParentList);
      this.designer.emitHistoryChange();
    },

    moveDownWidget() {
      this.designer.moveDownWidget(this.parentList, this.indexOfParentList);
      this.designer.emitHistoryChange();
    },

    removeFieldWidget() {
      if (!!this.parentList) {
        const selectedWidgetName = this.designer.selectedWidgetName;
        let selectedId = this.designer.selectedId;
        let nextSelected = null;
        if (this.parentList.length === 1) {
          if (!!this.parentWidget) {
            nextSelected = this.parentWidget;
          }
        } else if (this.parentList.length === 1 + this.indexOfParentList) {
          nextSelected = this.parentList[this.indexOfParentList - 1];
        } else {
          nextSelected = this.parentList[this.indexOfParentList + 1];
        }

        this.$nextTick(() => {
          const l = getSubFormNameByFieldId(
            this.designer.widgetList,
            selectedId
          );
          this.parentList.splice(this.indexOfParentList, 1);
          //if (!!nextSelected) {
          this.designer.setSelected(nextSelected);
          //}
          this.designer.formWidget.deleteWidgetRef(selectedWidgetName, l);
          this.designer.emitHistoryChange();
          this.designer.emitEvent("canvas-remove-field", selectedWidgetName);
        });
      }
    },
    getIsFormItemUnabled() {
      return (
        this.field.type == "vabUpload" || this.field.type == "baseAttachment"
      );
    },
    getRules() {
      if (this.getIsFormItemUnabled()) {
        return null;
      }
      return this.rules;
    },
    getPropName() {
      if (this.formItemProp === "false" || this.getIsFormItemUnabled()) {
        return null;
      }
      // if (this.formItemProp) {
      //   return this.formItemProp;
      // }
      if (this.tableParam && !this.tableParam.$table?.$parent?.$parent) {
        if (this.formItemProp) {
          return this.formItemProp;
        }
        return null;
      }
      if (this.tableParam && !!this.tableParam.$table?.$parent?.$parent) {
        return this.getColumnProp(this.field, this.tableParam);
      }
      let o = this.field.options.name;
      let propName =
        ((o =
          (this.field.options.keyNameEnabled && this.field.options.keyName) ||
          o),
        this.subFormItemFlag && !this.designState
          ? this.subFormName + "." + this.subFormRowIndex + "." + o
          : this.getObjectFieldFlag() && !this.designState
          ? this.getObjectName() + "." + o
          : o);

      return propName;
    },
    getFieldKeyName(widget) {
      let o = widget.options.name;
      return (widget.options.keyNameEnabled && widget.options.keyName) || o;
    },
    isVabsearchFlagWidget(widget) {
      let type = widget?.type;
      return (
        type === "vabsearch" ||
        type === "singerSearch" ||
        type === "multiSearch"
      );
    },
    getColumnProp(rowWidget, obj) {
      let required = rowWidget.options.required || false;

      let tableRef = obj.$table.$parent.$parent;
      let tableWidget = tableRef.widget;
      let fieldKeyName = this.getFieldKeyName(tableWidget);
      let property = this.getFieldKeyName(rowWidget);
      if (this.isVabsearchFlagWidget(rowWidget)) {
        property = rowWidget.options.vabSearchName || property;
      }
      let rowIndex = Math.max(obj.rowIndex, 0);

      let isTreeTable = tableWidget.options.isTreeTable || false;
      if (isTreeTable) {
        rowIndex = tableRef
          .getValue()
          .findIndex((item) => item._X_ROW_KEY === obj.row._X_ROW_KEY);
        if (rowIndex < 0) {
          return "false";
        }
      }

      let propName = fieldKeyName + "." + rowIndex + "." + property;
      if (!required) {
        propName = "false";
      }
      return propName;
    },
    getI18nLabel(label, path, param) {
      return !this.designState && label ? this.$t2(label, path, param) : label;
    },
    getProcessText(text, pattern) {
      if (pattern == "" || pattern === null || pattern === undefined) {
        return text;
      }

      let result = "";

      // 处理固定模式
      if (pattern === "-") {
        result = "-";
      } else if (pattern === "*") {
        result = "*****";
      }
      // 处理自定义模式
      else if (pattern.includes("*")) {
        text = text ?? "";
        const parts = pattern.split("*");

        // 处理 A*B 模式
        if (parts.length === 2 && parts[0] && parts[1]) {
          const a = parseInt(parts[0]);
          const b = parseInt(parts[1]);

          if (!isNaN(a) && !isNaN(b) && a >= 0 && b >= 0) {
            if (text.length >= a + b) {
              const prefix = text.substring(0, a);
              const suffix = text.substring(text.length - b);
              const stars = "*".repeat(text.length - a - b);
              result = prefix + stars + suffix;
            } else {
              result = "*****";
            }
          } else {
            // result = '无效模式：A和B必须是数字';
            result = text;
          }
        }
        // 处理 A* 模式
        else if (parts.length === 2 && parts[0] && !parts[1]) {
          const a = parseInt(parts[0]);

          if (!isNaN(a) && a >= 0) {
            if (text.length >= a) {
              const prefix = text.substring(0, a);
              const stars = "*".repeat(text.length - a);
              result = prefix + stars;
            } else {
              result = "*****";
            }
          } else {
            // result = '无效模式：A必须是数字';
            result = text;
          }
        }
        // 处理 *B 模式
        else if (parts.length === 2 && !parts[0] && parts[1]) {
          const b = parseInt(parts[1]);

          if (!isNaN(b) && b >= 0) {
            if (text.length >= b) {
              const suffix = text.substring(text.length - b);
              const stars = "*".repeat(text.length - b);
              result = stars + suffix;
            } else {
              result = "*****";
            }
          } else {
            // result = '无效模式：B必须是数字';
            result = text;
          }
        }
        // 处理无效模式
        else {
          result = "*****";
        }
      }
      // 处理其他无效模式
      else {
        result = "*****";
      }

      return result;
    },
    initShowType() {
      if (!!this.designer) return;
      let that = this.$parent;
      let formRef = that.getFormRef ? that.getFormRef() : that;

      if (!formRef) return;
      //详情页，新增页面不加密
      let fJson = formRef.formJson;
      let formConfig = fJson.formConfig;
      if (formConfig.isLoadEntity && !formRef.dataId) return;

      let bdService = formRef.bdService;
      let companyCode = this.$store.getters.companyCode;
      let loginAccount = this.$store.getters.loginAccount;

      let userSaleOrgDTOs = formRef.userSaleOrgDTOs;
      let userRoleDTOs = formRef.userRoleDTOs;

      let saleOrgCodeList = userSaleOrgDTOs.map((item) => item.sn);
      let roleCodeList = userRoleDTOs.map((item) => item.roleCode);

      let optionModel = this.field.options;

      let flag = 0; //0 原本组件，1明文文本，2密文文本
      /*if (optionModel.showTextEnabled) {
        flag = 1;
      } else if (optionModel.showEncryptTextEnabled) {
        flag = 2;
      } else if (optionModel.showLinkTextEnabled) {
        flag = 3;
      }*/
      if (optionModel.userTextRuleEnabled) {
        let userTextRuleConfig = optionModel.userTextRuleConfig || [];
        userTextRuleConfig.forEach((item) => {
          let type = item.type ?? null;
          if (type !== null && type !== "") {
            let companyCodeStr = item.companyCodes;
            let companyCodes = companyCodeStr
              ? companyCodeStr.split(",").filter((item) => !!item)
              : [];
            /*

                        let loginAccountStr = item.loginAccounts;
                        let loginAccounts = loginAccountStr ? loginAccountStr.split(",").filter(item => !!item) : [];

                        let saleOrgCodeStr = item.saleOrgCodes;
                        let saleOrgCodes = saleOrgCodeStr ? saleOrgCodeStr.split(",").filter(item => !!item) : [];
            */

            let roleCodeStr = item.roleCodes;
            let roleCodes = roleCodeStr
              ? roleCodeStr.split(",").filter((item) => !!item)
              : [];

            let flag1 = !item.serveName || item.serveName == bdService;
            let flag2 =
              !companyCodes.length || companyCodes.includes(companyCode);
            // let flag3 = !loginAccounts.length || loginAccounts.includes(loginAccount)
            // let flag4 = this.compareToList(saleOrgCodes, saleOrgCodeList)
            if (flag1 && flag2) {
              this.encryptFormula = item.encryptFormula;
              let flag5 = this.compareToList(roleCodes, roleCodeList);
              if (flag5) {
                //匹配角色
                if (type == 2) flag = 2; //type=2时加密
              } else {
                //角色不匹配
                if (type == 1) flag = 2;
              }
            }
          }
        });
      }
      this.field.options.widgetTextFlag = flag;
      // this.showType = flag;
    },
    compareToList(list1, list2) {
      if (!list1.length) {
        return true;
      }
      if (!list2.length) {
        return false;
      }
      return list1.some((item) => {
        return list2.some((item2) => item == item2);
      });
    },
    isShowWidget() {
      let widgetTextFlag = this.field.options.widgetTextFlag;
      return (
        widgetTextFlag === undefined ||
        widgetTextFlag === null ||
        widgetTextFlag === 0
      );
    },
    getShowValue() {
      let widgetTextFlag = this.field.options.widgetTextFlag;
      let fieldModel = this.$parent.fieldModel;
      if (this.$parent.fieldModelLabel)
        fieldModel = this.$parent.fieldModelLabel();
      let showValue = fieldModel;
      if (widgetTextFlag == 2) {
        showValue = this.getProcessText(showValue, this.encryptFormula);
      }

      return showValue;
    },
    getWidgetClass() {
      let list = [];
      let optionModel = this.field.options.widgetTextLinkConfig?.options || {};
      if (optionModel.colorClass) list.push(optionModel.colorClass);
      if (optionModel.underline) list.push("underLine");
      if (this.field.options.disabled) list.push("is-disabled");
      return list;
    },
    handleClick(event) {
      if (this.field.options.disabled) return;
      this.$parent.handleButtonWidgetClick(event, true);
      if (
        !this.designState &&
        this.field.options.widgetTextLinkConfig?.options.href
      ) {
        window.open(this.field.options.widgetTextLinkConfig?.options.href);
      }
    },
    getWidgetValue() {
      let fieldModel = this.$parent.fieldModel;
      if (this.$parent.fieldModelLabel)
        fieldModel = this.$parent.fieldModelLabel();
      return fieldModel;
    },
  },
};
</script>

<style lang="scss" scoped>
@import "~@/styles/global.scss";

.design-time-bottom-margin {
  margin-bottom: 5px;
}

.field-wrapper {
  position: relative;

  .field-action {
    position: absolute;
    //bottom: -24px;
    bottom: 0;
    right: -1px;
    height: 22px;
    line-height: 22px;
    background: $--color-primary;
    z-index: 9;

    i {
      font-size: 14px;
      color: #fff;
      margin: 0 5px;
      cursor: pointer;
    }
  }

  .drag-handler {
    position: absolute;
    top: 0;
    //bottom: -22px;  /* 拖拽手柄位于组件下方，有时无法正常拖动，原因未明？？ */
    left: -1px;
    height: 20px;
    line-height: 18px;
    //background: $--color-primary;
    z-index: 9;

    i {
      font-size: 12px;
      font-style: normal;
      color: #fff;
      margin: 4px;
      cursor: move;
    }

    &:hover {
      //opacity: 1;
      background: $--color-primary;
    }
  }
}

.el-form-item {
  //margin-bottom: 0 !important;
  //margin-bottom: 6px;

  //margin-top: 2px;
  position: relative;

  ::v-deep .el-form-item__label {
    white-space: nowrap;
    text-overflow: ellipsis;
  }

  ::v-deep .el-form-item__content {
    //position: unset;  /* TODO: 忘了这个样式设置是为了解决什么问题？？ */
  }

  span.custom-label i {
    margin: 0 3px;
  }

  /* 隐藏Chrome浏览器中el-input数字输入框右侧的上下调整小箭头 */
  ::v-deep .hide-spin-button input::-webkit-outer-spin-button,
  ::v-deep .hide-spin-button input::-webkit-inner-spin-button {
    -webkit-appearance: none !important;
  }

  /* 隐藏Firefox浏览器中el-input数字输入框右侧的上下调整小箭头 */
  ::v-deep .hide-spin-button input[type="number"] {
    -moz-appearance: textfield;
  }
}

.required ::v-deep .el-form-item__label::before {
  content: "*";
  color: #f56c6c;
  margin-right: 4px;
}

.static-content-item {
  min-height: 20px;
  display: flex; /* 垂直居中 */
  align-items: center; /* 垂直居中 */

  ::v-deep .el-divider--horizontal {
    margin: 0;
  }
}

.el-form-item.selected,
.static-content-item.selected {
  outline: 2px solid $--color-primary;
}

::v-deep .label-left-align .el-form-item__label {
  text-align: left;
}

::v-deep .label-center-align .el-form-item__label {
  text-align: center;
}

::v-deep .label-right-align .el-form-item__label {
  text-align: right;
}

.a-link.is-disabled {
  cursor: no-drop;
}
</style>
