<template>
  <div style="width: 100%">
    <a-input
      v-if="fieldUtil.isTextType(fieldItem)"
      v-model:value="displayValue" style="width: 100%" autocomplete="off"
      :name="fieldItem.displayName" :readonly="readOnly" :disabled="readOnly"
    />

    <a-input-number
      v-if="fieldUtil.isNumberType(fieldItem)"
      v-model:value="displayValue"
      autocomplete="off"
      style="width: 100%"
      :name="fieldItem.displayName"
      :readonly="readOnly"
      :disabled="readOnly"
      @mousewheel="mouseWheelEvent"
      @change="numberFormat"
    />

    <div
      v-if="fieldUtil.isCheckBoxType(fieldItem)"
      style="text-align: center; padding-bottom: 6px"
    >
      <a-switch v-if="fieldUtil.isCheckBoxType(field)" v-model:checked="displayValue" :disabled="readOnly" />
    </div>

    <RedGreenSelect
      v-if="fieldUtil.isRedGreenEditorType(fieldItem)"
      v-model="displayValue"
      type="string"
      :readonly="readOnly"
      :disabled="readOnly"
    />
    <a-input-password
      v-if="fieldUtil.isPasswordType(fieldItem)"
      v-model:value="displayValue" :name="fieldItem.displayName" :disabled="readOnly"
    />
    <a-textarea
      v-if="fieldUtil.isTextAreaType(fieldItem)" v-model:value="displayValue" 
      :auto-size="{ minRows: 1, maxRows: 3 }"
      :name="fieldItem.displayName" :disabled="readOnly"
    />

    <TimeWidget
      v-if="fieldUtil.isTimeType(fieldItem)"
      :value="displayValue"
      class="form-control"
      :readonly="readOnly"
      :disabled="readOnly"
      @on-value-change="textChanged"
    />

    <Date
      v-if="fieldUtil.isDateType(fieldItem)"
      :model-value="displayValue"
      :readonly="readOnly"
      :disabled="readOnly"
      style="width:100%; min-width: auto;"
      @update:model-value="textChanged"
    />

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

    <YearPicker
      v-if="fieldUtil.isYearType(fieldItem)"
      :value="displayValue"
      :readonly="readOnly"
      class="form-control"
      @selected="yearChange($event)"
    />

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

    <SelectCell
      v-if="fieldUtil.isSelectType(fieldItem)"
      :model-data="modelData"
      :window-no="windowNo"
      :tab-index="tabIndex"
      :key-values="fieldItem.keyValues"
      :field="fieldItem"
      :field-value="fieldValue"
      :readonly="readOnly"
      @value-changed="valueChanged"
    />

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

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

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

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

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

    <EnumRadioGroupCell
      v-if="fieldUtil.isRadioButtonGroupType(fieldItem)"
      :field="fieldItem"
      :field-value="fieldValue"
      :readonly="readOnly"
      @value-changed="valueChanged"
    />

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

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

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

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

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

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

import WindowClientUtil from '../../resource/dictionary/WindowClientUtil.js';

import SearchCell from '../tabGridWidget/SearchCell.vue';
import SelectCell from '../tabGridWidget/SelectCell.vue';
import EnumSelectCell from '../tabGridWidget/EnumSelectCell.vue';
import EnumRadioGroupCell from '../tabGridWidget/EnumRadioGroupCell.vue';
import ImageCell from '../tabGridWidget/ImageCell.vue';

import { Uuid } from 'pc-component-v3';




import VideoListCell from '../tabGridWidget/VideoListCell.vue';
import FileListWidget from '../tabFormWidget/FileListWidget.vue';
import EnumMultiSelectCell from '../tabGridWidget/EnumMultiSelectCell.vue';
import ManyToManySetCell from '../tabGridWidget/ManyToManySetCell.vue';
import ButtonCell from '../tabGridWidget/ButtonCell.vue';

import ImageWidget from '../tabFormWidget/ImageWidget.vue';

import RedGreenSelect from '../../widget/RedGreenSelect.vue';



export default {

  components: {
    SearchCell,
    SelectCell,
    EnumSelectCell,
    EnumRadioGroupCell,
    ImageCell,
    VideoListCell,
    FileListWidget,
    EnumMultiSelectCell,
    ManyToManySetCell,
    ImageWidget,
    RedGreenSelect,
    ButtonCell,
  },
  
  props: {
   
    windowNo: {
      type: String,
      default: null,
    },
    tabIndex: {
      type: Number,
      default: null,
    },
    fieldItem: {
      type: Object,
      default : function(){
        return null;
      },
    },
    modelData: {
      type: Object,
      default : function(){
        return null;
      },
    },
    parentModelData: {
      type: Object,
      default : function(){
        return null;
      },
    },
    className: {
      type: String,
      default: null,
    },
    scrollObject: {
      type: String,
      default: null,
    },
  },

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



  data: function () {
    var value =
      this.fieldItem == null ||
      this.modelData.data == undefined ||
      this.modelData.data[this.fieldItem.fieldName] == undefined
        ? ''
        : this.modelData.data[this.fieldItem.fieldName].displayValue[
          this.fieldItem.entityFieldIndex
        ];

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

    return {
      displayValue: value,
      fieldValue: fieldValue,
      fieldUtil: fieldUtil,
      validateMandatory: true,
      month: undefined,
      uuid1: Uuid.createUUID(),
      timer:null,
    };
  },

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

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

      // bug fixed by jack 20190729
      // 修复表格中，搜索框字段，显示多个字段的时候，字段应该不可以编辑。
      if (this.fieldItem != undefined && this.fieldItem.entityFieldIndex >= 1) {
        return true;
      }

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

      return this.fieldItem.readOnly;
    },
  },

  watch: {
    displayValue: function (currentValue, oldValue) {
      if (
        fieldUtil.isSearchType(this.fieldItem) == false &&
        this.fieldItem.entityFieldIndex == 0 &&
        fieldUtil.isSelectType(this.fieldItem) == false &&
        fieldUtil.isEnumListType(this.fieldItem) == false &&
        fieldUtil.isManyToManySetType(this.fieldItem) == 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',
          };
          clearTimeout(this.timer); // 清除旧定时器
          this.timer = setTimeout(() => {
            this.$emit('valueChanged', newFieldValue);
          }, 800); 
        }
      }
    },

    'modelData.data': {
      deep: true,
      handler(curVal, oldVal) {
        console.log('modelDate changed');

        if((this.fieldItem == null || curVal == undefined || curVal[this.fieldItem.fieldName] == undefined || curVal[this.fieldItem.fieldName].displayValue == null)){
          this.displayValue = '';
        }else{
          this.displayValue = curVal[this.fieldItem.fieldName].displayValue[this.fieldItem.entityFieldIndex];
        }
        this.fieldValue = (curVal == undefined) ? [] : curVal[this.fieldItem.fieldName];



        // this.displayValue =
        //   this.fieldItem == null ||
        //   curVal == undefined ||
        //   curVal[this.fieldItem.fieldName] == undefined ||
        //   curVal[this.fieldItem.fieldName].displayValue == null
        //     ? ''
        //     : curVal[this.fieldItem.fieldName].displayValue[
        //       this.fieldItem.entityFieldIndex
        //     ];
        // this.fieldValue =
        //   curVal == undefined ? [] : curVal[this.fieldItem.fieldName];
      },
    },
  },

  mounted: function () {},

  methods: {
    /**
     * 获取modelData中字段的显示值
     */
    getModelDataFieldDisplayValue : function(){
      if(this.modelData == null 
          || this.fieldItem == null 
          || this.modelData.data[this.fieldItem.fieldName] == null 
          || this.modelData.data[this.fieldItem.fieldName].displayValue == null){
        return null;
      }
      return this.modelData.data[this.fieldItem.fieldName].displayValue[this.fieldItem.entityFieldIndex];
    },


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

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

    textChanged: function (value) {
      var newFieldValue = {
        displayValue: [value],
        fieldType: 'String',
      };
      this.$emit('valueChanged', newFieldValue);
    },

    // 执行数据校验
    performValidate: function () {
      var _self = this;
      _self.validateMandatory = true;
      if (_self.fieldItem.mandatory == true) {
        if (
          fieldUtil.isSelectType(_self.fieldItem) ||
          fieldUtil.isSearchType(_self.fieldItem)
        ) {
          var idValue =
            _self.modelData.data == undefined ||
            _self.modelData.data[_self.fieldItem.fieldName] == undefined
              ? undefined
              : _self.modelData.data[_self.fieldItem.fieldName].id;
          if (idValue == undefined || idValue == '' || idValue < 1) {
            _self.validateMandatory = false;
          }
        } else if (fieldUtil.isCheckBoxType(_self.fieldItem)) {
          return true;
        } else if (fieldUtil.isRedGreenEditorType(_self.fieldItem)) {
          return true;
        } else {
          var stringValue =
            _self.modelData.data == undefined ||
            _self.modelData.data[_self.fieldItem.fieldName] == undefined
              ? ''
              : _self.modelData.data[_self.fieldItem.fieldName].displayValue[
                this.fieldItem.entityFieldIndex
              ];
          if (stringValue == undefined || stringValue === '') {
            _self.validateMandatory = false;
          }
        }
      }
      return _self.validateMandatory;
    },

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

    /**
     * 年月选择完毕
     */
    refresh: function () {
      var newFieldValue = {
        displayValue: [this.month],
        fieldType: 'String',
      };
      this.$emit('valueChanged', newFieldValue);
    },

    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();
      }
    },
  },
};
</script>
<style scoped>
.required-mark {
  color: red;
}
</style>

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