<template>
  <div
    v-if="modelData && modelData.data != undefined && field.visible"
    v-show="showField"
    class="form-group"
    :class="formGroupClass"
  >
    <label
      v-tooltip.right="field.help"
      class="control-label"
      :class="formGroupLabelClass"
      :style="field.cssStyle"
    >
      <span v-if="field.mandatory" class="required-mark">*</span>
      <font size="2">{{ Language.getDisplayNameTrl($i18n.locale, field) }}</font><br />
      <font v-if="isChineseEnglish && $i18n.locale == 'zh-CN'" size="0.5">{{ field.displayNameEng }}</font>
    </label>
    <div class="input-group" :class="inputGroupClass">
      <input
        v-if="fieldUtil.isTextType(field)"
        v-model="displayValue"
        autocomplete="off"
        type="text"
        class="form-control"
        :name="field.displayName"
        :readonly="readOnly"
        :disabled="readOnly"
      />

      <input
        v-if="fieldUtil.isNumberType(field)"
        v-model="displayValue"
        autocomplete="off"
        type="number"
        class="form-control"
        :name="field.displayName"
        :readonly="readOnly"
        :disabled="readOnly"
        onmousewheel="return false;"
        @mousewheel="mouseWheelEvent"
        @change="numberFormat"
      />

      <switches
        v-if="fieldUtil.isCheckBoxType(field)"
        v-model="displayValue"
        :selected="displayValue"
        color="green"
        :type-bold="true"
        :disabled="readOnly"
      />

      <RedGreenSelect
        v-if="fieldUtil.isRedGreenEditorType(field)"
        v-model="displayValue"
        type="string"
        :disabled="readOnly"
      />

      <input
        v-if="fieldUtil.isPasswordType(field)"
        v-model="displayValue"
        autocomplete="off"
        type="password"
        class="form-control"
        :name="field.displayName"
        :readonly="readOnly"
        :disabled="readOnly"
      />

      <textarea
        v-if="fieldUtil.isTextAreaType(field)"
        v-model="displayValue"
        class="form-control"
        rows="3"
        :name="field.displayName"
        :style="field.cssStyle"
        :readonly="readOnly"
        :disabled="readOnly"
      />

      <Date
        v-if="fieldUtil.isDateType(field)"
        :model-value="displayValue"
        :data-vv-name="field.displayName"
        :name="field.displayName"
        :data-vv-value-path="displayValue"
        :readonly="readOnly"
        style="width:100%"
        @update:model-value="textChanged"
      />

      <Time
        v-if="fieldUtil.isTimeType(field)"
        v-model="displayValue"
        class="form-control"
        :data-vv-name="field.displayName"
        :name="field.displayName"
        :data-vv-value-path="displayValue"
        :readonly="readOnly"
      />

      <DateTime
        v-if="fieldUtil.isDateTimeType(field)"
        :model-value="displayValue"
        :readonly="readOnly"
        style="width:100%"
        @update:model-value="textChanged"
      />

      <YearPicker
        v-if="fieldUtil.isYearType(field)"
        :value="displayValue"
        :readonly="readOnly"
        @selected="textChanged"
      />

      <VueMonthlyPicker
        v-if="fieldUtil.isYearMonthType(field)"
        id="month-picker"
        v-model="month"
        date-format="YYYY-MM"
        class="vue-monthly-picker m-date-fieldEditView"
        @selected="refresh"
      />

      <ImageWidget
        v-if="fieldUtil.isImageType(field)"
        :uuid="uuid1"
        :pattern-json="field.pattern"
        :field="field"
        :field-value="fieldValue"
        :class-name="className"
        :readonly="readOnly"
        @value-changed="valueChanged"
      />

      <ImageListWidget
        v-if="fieldUtil.isImageListType(field)"
        :field="field"
        :field-value="fieldValue"
        :class-name="className"
        :readonly="readOnly"
        @value-changed="valueChanged"
      />

      <VideoListWidget
        v-if="fieldUtil.isVideoType(field)"
        :field="field"
        :field-value="fieldValue"
        :class-name="className"
        :readonly="readOnly"
        @value-changed="valueChanged"
      />

      <FileListWidget
        v-if="fieldUtil.isFileType(field)"
        :field="field"
        :field-value="fieldValue"
        :class-name="className"
        :readonly="readOnly"
        @value-changed="valueChanged"
      />

      <EnumRadioGroupWidget
        v-if="fieldUtil.isRadioButtonGroupType(field)"
        :field="field"
        :field-value="fieldValue"
        :data-vv-name="field.displayName"
        :name="field.displayName"
        :data-vv-value-path="displayValue"
        :readonly="readOnly"
        @value-changed="valueChanged"
      />

      <ManyToManySetSearchWidget
        v-if="fieldUtil.isManyToManySetType(field)"
        :info-window-no="field.infoWindowNo"
        :field="field"
        :field-value="fieldValue"
        :readonly="readOnly"
        :model-data="modelData"
        :window-no="windowNo"
        :tab-index="tabIndex"
        @value-changed="valueChanged"
      />

      <SearchWidget
        v-if="fieldUtil.isSearchType(field)"
        :info-window-no="field.infoWindowNo"
        :field="field"
        :field-value="fieldValue"
        :readonly="readOnly"
        :model-data="modelData"
        :window-no="windowNo"
        :tab-index="tabIndex"
        @value-changed="valueChanged"
      />

      <EnumSelectWidget
        v-if="fieldUtil.isEnumListType(field)"
        :field="field"
        :field-value="fieldValue"
        :name="field.displayName"
        :readonly="readOnly"
        @value-changed="valueChanged"
      />

      <EnumMultiSelectWidget
        v-if="fieldUtil.isEnumMultiType(field)"
        :field="field"
        :field-value="fieldValue"
        :name="field.displayName"
        :readonly="readOnly"
        @value-changed="valueChanged"
      />

      <SelectWidget
        v-if="fieldUtil.isSelectType(field)"
        ref="selectWidget"
        :field="field"
        :field-value="fieldValue"
        :window-no="windowNo"
        :tab-index="tabIndex"
        :readonly="readOnly"
        :model-data="modelData"
        @value-changed="valueChanged"
      />

      <ButtonWidget
        v-if="fieldUtil.isButtonType(field)"
        :field="field"
        :field-value="fieldValue"
        :readonly="readOnly"
        @value-changed="valueChanged"
        @execute-callout="executeCallout"
      />

      <RichTextAreaEditorWidget
        v-if="fieldUtil.isRichTextAreaEditor(field)"
        :display-value="displayValue"
        :class-name="className"
        :field-value="fieldValue"
        :readonly="isReadOnly"
        @value-changed="valueChanged"
      />

      <p v-show="!validateMandatory" class="required-mark required-error">
        该字段为必填字段
      </p>
    </div>
  </div>
</template>

<script>
import fieldUtil from '../../resource/dictionary/FieldUtil.js';

import WindowClientUtil from '../../resource/dictionary/WindowClientUtil.js';
import Language from '../../common/Language.js';
import Context from '../common/Context.js';

import SearchWidget from '../tabFormWidget/SearchWidget.vue';
import ImageListWidget from '../tabFormWidget/ImageListWidget.vue';
import EnumSelectWidget from '../tabFormWidget/EnumSelectWidget.vue';
import SelectWidget from '../tabFormWidget/SelectWidget.vue';
import EnumRadioGroupWidget from '../tabFormWidget/EnumRadioGroupWidget.vue';
import VideoListWidget from '../tabFormWidget/VideoListWidget.vue';
import FileListWidget from '../tabFormWidget/FileListWidget.vue';
import ButtonWidget from '../tabFormWidget/ButtonWidget.vue';

import EnumMultiSelectWidget from '../tabFormWidget/EnumMultiSelectWidget.vue';
import ManyToManySetSearchWidget from '../tabFormWidget/ManyToManySetSearchWidget.vue';
import RedGreenSelect from '../../widget/RedGreenSelect.vue';
import ImageWidget from '../tabFormWidget/ImageWidget.vue';
import RichTextAreaEditorWidget from '../tabFormWidget/RichTextAreaEditorWidget.vue';
import JsUtil from '../../common/JsUtil.js';
import { Notify, Uuid } from 'pc-component-v3';









export default {

  components: {
    SearchWidget,
    ImageListWidget,
    EnumSelectWidget,
    SelectWidget,
    EnumRadioGroupWidget,
    VideoListWidget,
    FileListWidget,
    EnumMultiSelectWidget,
    ManyToManySetSearchWidget,
    ImageWidget,
    RedGreenSelect,
    ButtonWidget,
    RichTextAreaEditorWidget,
  },
  
  props: {
   
    windowNo: {
      type: String,
      default: null,
    },
    tabIndex: {
      type: Number,
      default: null,
    },
    className: {
      type: String,
      default: null,
    },
    multipleColumn: {
      type: Boolean,
      default: null,
    },
    jsUrl: {
      type: String,
      default: null,
    },
    field: {
      type: Object,
      default : function(){
        return null;
      },
    },
    modelData: {
      type: Object,
      default : function(){
        return null;
      },
    },
    isChineseEnglish: {
      type: Boolean,
      default: null,
    },
  },

  
  emits: ['executeCallout', 'valueChanged'],

  data: function () {
    this.Language = Language;
    // eslint-disable-next-line
    var value =
      this.modelData == undefined ||
      this.modelData.data == undefined ||
      this.modelData.data[this.field.fieldName] == undefined
        ? ''
        : this.modelData.data[this.field.fieldName].displayValue[
          this.field.entityFieldIndex
        ];

    var fieldValue =
      this.modelData == undefined || this.modelData.data == undefined
        ? []
        : this.modelData.data[this.field.fieldName];

    return {
      displayValue: value,
      fieldValue: fieldValue,
      fieldUtil: fieldUtil,
      validateMandatory: true, // 验证强制字段是否通过
      month: undefined,
      uuid1: Uuid.createUUID(),
      showField: true, // 显示字段
    };
  },

  computed: {
    readOnly: function () {
      if (this.field == undefined) {
        return true;
      }

      if (this.field != undefined && this.field.readOnly == true) {
        return true;
      }

      if (this.field != undefined && this.field.entityFieldIndex > 0) {
        return true;
      }

      if (
        this.modelData != undefined &&
        this.modelData.id > 0 &&
        (this.field.updatable == undefined || this.field.updatable == false)
      ) {
        return true;
      }

      return this.field.readOnly;
    },

    /**
     * 表单组的CSS样式
     * 对应 bootstrap 表单 form-group
     */
    formGroupClass: function () {
      return {
        'form-group-single-row':
          this.field != undefined && this.field.singleRow,
        'form-group-multiple-row':
          this.field != undefined && !this.field.singleRow,
        'form-group-multiple-column':
          this.field != undefined && this.multipleColumn == true, // 多列
      };
    },

    /**
     * 标题的CSS样式
     * 对应 bootstrap 表单 label 样式
     */
    formGroupLabelClass: function () {
      return {
        'm-sr-only':
          this.field == null || !this.field.visible || !this.field.showLabel, // 显示/隐藏
        'col-xs-5 col-sm-4 col-md-3 col-lg-2':
          this.field != null && this.multipleColumn == false, // 单列
        'label-multiple-column':
          this.field != null && this.multipleColumn == true, // 多列
      };
    },

    /**
     * 控件的CSS样式
     * 对应 bootstrap 表单 input-group
     */
    inputGroupClass: function () {
      return {
        'col-xs-7 col-sm-8 col-md-9 col-lg-10':
          this.field != null && this.multipleColumn == false, // 单列
        'input-group-multiple-column': this.multipleColumn, // 多列
        'input-group-single-row':
          this.field != undefined &&
          this.field.singleRow == true &&
          this.multipleColumn, // 单独一行
      };
    },

    /**
     * 控件的CSS样式
     * 对应 bootstrap 表单 input-group 内的元素
     */
    inputGroupItemClass: function () {
      return {};
    },
  },

  watch: {
    displayValue: function (currentValue, oldValue) {
      if (
        fieldUtil.isSearchType(this.field) == false &&
        this.field.entityFieldIndex == 0 &&
        fieldUtil.isSelectType(this.field) == false &&
        fieldUtil.isRadioButtonGroupType(this.field) == false &&
        fieldUtil.isEnumListType(this.field) == false &&
        fieldUtil.isManyToManySetType(this.field) == false
      ) {
        // add by jack 20240220
        // 修复bug：当modelData.data的值从外部修改以后，修改执行 watch->'modelData.data'  中的 this.displayValue = ? 方法
        // 执行完成以后，watch->displayValue 又会执行，会触发valueChanged事件，这会导致 callout/calloutjs 会被多次执行。
        // 所以在触发 valueChanged 的之前，先判断currentValue与modelData中的值是否相等，
        // 如果相等，说明是外部修改了modelData，然后执行了 watch->'modelData.data' 方法修改了 displayValue，此时不触发valueChanged事件。
        // 如果不相等，说明是DOM修改了，触发修改了displayValue，此时触发valueChanged事件。

        const modelDataFieldDisplayValue = this.getModelDataFieldDisplayValue();

        if (currentValue !== oldValue && currentValue !== modelDataFieldDisplayValue) {
          var newFieldValue = {
            displayValue: [currentValue],
            fieldType: 'String',
          };
          this.$emit('valueChanged', newFieldValue);
        }
      }
    },

    'modelData.data': {
      deep: true,
      handler(curVal, oldVal) {
        if(curVal == undefined ||
            curVal[this.field.fieldName] == undefined ||
            curVal[this.field.fieldName].displayValue == undefined ||
            curVal[this.field.fieldName].displayValue.length < this.field.entityFieldIndex + 1){
          this.displayValue = '';
        }else{
          let tempValue = curVal[this.field.fieldName].displayValue[this.field.entityFieldIndex];
          if(fieldUtil.isCheckBoxType(this.field)){
            if(typeof(tempValue) =='string'){
              this.displayValue = (tempValue === 'true') ? true : false;
            }
            if(typeof(tempValue) =='boolean'){
              this.displayValue = (tempValue === true) ? true : false;
            }
          }else{
            this.displayValue = tempValue;
          }          
        }
        this.fieldValue = curVal == undefined ? [] : curVal[this.field.fieldName];
        this.showLogical();
      },
    },

    month: function () {
      this.textChanged(this.month);
    },
  },

  mounted: function () {},

  methods: {
    /**
     * 获取Context
     */
    getContext: Context,


    /**
     * 获取modelData中字段的显示值
     */
    getModelDataFieldDisplayValue : function(){
      if(this.modelData == null 
          || this.field == null
          || this.modelData[this.field.fieldName] == undefined
          || this.modelData[this.field.fieldName].displayValue == undefined
          || this.modelData[this.field.fieldName].displayValue.length < this.field.entityFieldIndex + 1){
        return null;
      }
      return this.modelData[this.field.fieldName].displayValue[this.field.entityFieldIndex];
    },


    // 值改变事件
    valueChanged: function (newFieldValue) {
      // this.fieldValue = newFieldValue;
      this.$emit('valueChanged', newFieldValue);
    },

    /**
     * 执行Callout
     */
    executeCallout: function (field) {
      this.$emit('executeCallout', field);
    },

    //年份选择器值改变
    textChanged: function (value) {
      var newFieldValue = {
        displayValue: [value],
        fieldType: 'String',
      };
      this.$emit('valueChanged', newFieldValue);
    },

    validateRule: function (field) {
      return field.mandatory ? 'required' : '';
    },

    performValide: function () {
      var _self = this;
      _self.validateMandatory = true;

      if (this.field.mandatory == true) {
        if (
          fieldUtil.isRadioButtonGroupType(this.field) ||
          fieldUtil.isSelectType(this.field) ||
          fieldUtil.isSearchType(this.field)
        ) {
          var idValue =
            this.modelData == undefined ||
            this.modelData.data == undefined ||
            this.modelData.data[this.field.fieldName] == undefined
              ? undefined
              : this.modelData.data[this.field.fieldName].id;
          if (idValue == null || idValue == '' || idValue < 1) {
            _self.validateMandatory = false;
          }
        } else if (fieldUtil.isCheckBoxType(this.field)) {
          return true;
        } else if (fieldUtil.isRedGreenEditorType(this.field)) {
          return true;
        } else {
          var stringValue =
            this.modelData == undefined ||
            this.modelData.data == undefined ||
            this.modelData.data[this.field.fieldName] == undefined
              ? ''
              : this.modelData.data[this.field.fieldName].displayValue[0];
          if (stringValue == undefined || stringValue === '') {
            _self.validateMandatory = false;
          }
        }
      }
      return _self.validateMandatory;
    },

    /**
     * 年份变化
     */
    yearChange: function () {},

    /**
     * 年月选择完成
     */
    refresh: function () {},

    numberFormat: function () {
      if (
        this.fieldItem &&
        this.fieldItem.pattern &&
        this.fieldItem.pattern != ''
      ) {
        var _self = this;
        fieldUtil.formatNumber(
          this.displayValue,
          this.fieldItem.pattern,
          function (formatValue) {
            _self.displayValue = formatValue;
          },
        );
      }
    },

    /**
     * 禁止滚轮滚动影响数字
     */
    mouseWheelEvent: function (event) {
      if (event || Window.event) {
        event.preventDefault();
      }
    },

    /**
     * 响应显示逻辑
     */
    showLogical: function () {
      let _self = this;
      var logic = this.field.showLogical;
      if (logic == null || logic == '') {
        this.showField = true;
        return;
      }

      const functionName =
        this.field.fieldName.replace('.', '_') + '_showLogical';


      let executeFunction = function(){
        try{
          let context = new _self.getContext(_self.modelData);
          _self.showField = _self[functionName](context);
        }catch(error){
          console.error(error);
          Notify.error('数据字典定义异常', '【' + logic + '】前端列显示逻辑定义异常,请联系管理员检查数据字典的定义。', false);
        }
      };

      if (_self[functionName] == null) {
        const jsUrl = _self.jsUrl;
        if(jsUrl == null || jsUrl == undefined){
          Notify.error('数据字典定义异常', '【' + logic + '】前端列显示逻辑的JS文件不存在,请联系管理员检查数据字典是否JS文件。', false);
          return;
        }

        let promise = JsUtil.dynamicLoadJsFunction(jsUrl, logic);

        promise.then(targetFunction => {
          _self[functionName] = targetFunction;
          if(_self[functionName] == null){
            Notify.error('数据字典定义异常', '【' + logic + '】前端列显示逻辑方法不存在,请联系管理员检查数据字典。', false);
            return;
          }
          executeFunction();
        }, errorData => {
          console.error(errorData);
        });
      }else{
        executeFunction();
      }
    },
  },
};
</script>
<style scoped>
.required-mark {
  color: red;
  margin-right: 10px;
}

input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
  -webkit-appearance: none !important;
  margin: 0;
}

input[type="number"] {
  -moz-appearance: textfield;
}
textarea {
  overflow-y: auto !important;
  overflow-x: hidden !important;
}

.form-group-single-row {
  display: block;
  width: 100%;
}

.input-group-item {
  word-break: break-all;
}

.input-group-item-manytomany {
  color: #333;
  background-color: #f0f0f0;
  border: 1px solid #ccc;
  border-radius: 4px;
  height: 26px;
  margin: 4px 4px 0px 0px;
  padding: 6px 0.25em;
}

.label-multiple-column {
  width: 120px;
}

.form-group-multiple-column {
  margin-top: 5px;
}

@media (max-width: 768px) {
  .input-group-single-row {
    width: 100%;
  }

  .input-group-item {
    padding-top: 0px;
  }
}

@media (min-width: 768px) {
  .label-multiple-column {
    text-overflow: ellipsis;
    text-align: right;
    padding-right: 5px;
  }

  .input-group-multiple-column {
    width: 230px;
  }

  .input-group-single-row {
    width: calc(100% - 200px) !important;
    word-wrap: break-word;
  }
}

.m-sr-only {
  visibility: hidden;
}
</style>


<style>
.m-date-fieldEditView > div:first-child {
  width: 100%;
}
</style>