<template>
  <tr
    v-if="showTabGridTitleFields" class="sticky-row" height="40px" :style="{ 'background-color': warningColor }"
    :class="{ 'warning': isSelected }"
  >
    <td rowspan="2" class="text-center  sticky-col">{{ serialNumber }}</td>
    <td rowspan="2" class="text-center  sticky-col" style="left:50px">
      <input v-model="isSelected" autocomplete="off" type="checkbox" @click="clickModelData(modelData)" />
    </td>

    <td v-if="isShowEdit == undefined || isShowEdit" rowspan="2" class="sticky-col" style="left: 80px; z-index: 2">
      <template v-if="showEditButton">
        <span class="operation-delete" aria-hidden="true" @click="editRecord">
          <i class="fa" :class="{ 'fa-pencil': !modelData.editMode, 'fa-check': modelData.editMode }" />
        </span>
        <span class="operation-edit" aria-hidden="true" @click="deleteRecord">
          <i class="fa fa-remove" />
        </span>
      </template>
    </td>

    <td :colspan="tabGridFields.length + 1" style="text-align: left; padding-left: 2rem;">
      <a-space align="center">
        <div v-for="tabGridTitleField in tabGridTitleFields" :key="tabGridTitleField.fieldName" @click="clickRecord">
          <a-space align="center">
            <span style="font-weight: normal;">{{ Language.getDisplayNameTrl($i18n.locale, tabGridTitleField) }}</span>
            <CellTextItem
              v-if="!modelData.editMode" :grid-field-item="tabGridTitleField" :model-data="modelData"
              :class-name="className" style="display: inline-block; font-weight: normal; padding-top: 3px;"
              @execute-callout="executeCallout(tabGridTitleField)"
            />
            <CellItem
              v-else :ref="'cellItem' + index" :scroll-object="scrollObject" :field-item="tabGridTitleField"
              :model-data="modelData" :parent-model-data="parentModelData" :class-name="className" :window-no="windowNo"
              :tab-index="tabIndex" style="display: inline-block; min-width: 200px;"
              :class="{ 'table-cell-searchwidget': fieldUtil.isSearchType(tabGridTitleField) }"
              @value-changed="valueChanged($event, tabGridTitleField)"
              @execute-callout="executeCallout(tabGridTitleField)"
            />
          </a-space>
        </div>
      </a-space>
    </td>
  </tr>
  <tr :style="{ 'background-color': warningColor }" :class="{ 'warning': isSelected }" height="40px">
    <template v-if="!showTabGridTitleFields">
      <td class="text-center sticky-col" style="left: 0; z-index: 1">{{ serialNumber }}</td>
      <td class="text-center sticky-col" style="left: 50px; z-index: 1">
        <input v-model="isSelected" autocomplete="off" type="checkbox" @click="clickModelData(modelData)" />
      </td>

      <td v-if="isShowEdit == undefined || isShowEdit" class="sticky-col" style="left: 80px; z-index: 1">
        <template v-if="showEditButton">
          <span class="operation-delete" aria-hidden="true" @click="editRecord">
            <i class="fa" :class="{ 'fa-pencil': !modelData.editMode, 'fa-check': modelData.editMode }" />
          </span>
          <span class="operation-edit" aria-hidden="true" @click="deleteRecord">
            <i class="fa fa-remove" />
          </span>
        </template>
      </td>
    </template>


    <template
      v-for="(gridFieldItem, index) in tabGridFields"
      :key="'TabGridField_' + gridFieldItem.fieldName + '_' + index"
    >
      <template
        v-if="gridFieldItem.groupNames == null || gridFieldItem.groupNames.length == 0 || (nowTab != null && (gridFieldItem.groupNames.indexOf(nowTab) >= 0))"
      >
        <td
          v-if="!modelData.editMode" v-show="gridFieldItem.visible" :class="{
            'text-center sticky-col': gridFieldItem.fieldName === '-',
            'sticky-left': gridFieldItem.fieldName === '-' && index === 0,
            'sticky-right': gridFieldItem.fieldName === '-' && index === tabGridFields.length - 1
          }"
          @click="clickRecord"
        >
          <div>
            <CellTextItem
              ref="cellTextItem" :window="window" :grid-field-item="gridFieldItem" :model-data="modelData"
              :class-name="className" :simple-filter-params="simpleFilterParams"
              :complex-filter-params="complexFilterParams" :model-datas="modelDatas" :js-url="jsUrl" :index="index"
              @execute-callout="executeCallout(gridFieldItem)" @delete-record="deleteRecord"
              @refresh-datas="refreshDatas" @edit-record="editRecord" @read-record="readRecord"
            />
          </div>
        </td>
        <td
          v-else v-show="gridFieldItem.visible"
          :class="{ 'table-cell-searchwidget': fieldUtil.isSearchType(gridFieldItem) }" @click="clickRecord"
        >
          <CellItem
            :ref="'cellItem' + index" :scroll-object="scrollObject" :field-item="gridFieldItem"
            :model-data="modelData" :parent-model-data="parentModelData" :class-name="className" :window-no="windowNo"
            :tab-index="tabIndex" @value-changed="valueChanged($event, gridFieldItem)"
            @execute-callout="executeCallout(gridFieldItem)"
          />
        </td>
      </template>
    </template>
  </tr>
  <Modal v-model:show="modal" :full="true" @ok="modal = false">
    <ProcessReportResultPreview
      v-if="
        processReportResult != null &&
          (processReportResult.reportResults != null ||
            processReportResult.processResult != null)
      " :process-report-result="processReportResult" :pdf-only="false" :excel-only="false"
    />
    <template #header>
      {{ $t("lang.tabButton.executeResult") }}
    </template>
  </Modal>
  <Modal v-model:show="titleModal" :show-canel-button="false" :show-ok-button="false">
    <template #header>
      {{ tabButtonModel.tipsTitle }}
    </template>
    {{ tabButtonModel.tipsContent }}
    <template #footer>
      <button type="button" class="btn btn-default" @click="titleModalClose">
        {{ $t("lang.tabButton.cancel") }}
      </button>
      <button type="primary" class="btn btn-default" @click="executeProcess">
        确认
      </button>
    </template>
  </Modal>
</template>

<script>

import WindowClientUtil from '../../resource/dictionary/WindowClientUtil.js';
import FieldUtil from '../../resource/dictionary/FieldUtil.js';
import CellItem from './CellItem.vue';
import CellTextItem from './CellTextItem.vue';
import Common from '../../common/Common.js';
import Context from '../common/Context.js';
import JsUtil from '../../common/JsUtil.js';
import Language from '../../common/Language.js';
import { Notify } from 'pc-component-v3';

export default {

  components: {
    CellItem, CellTextItem,
  },


  props: {

    window: {
      type: Object,
      default: function () {
        return null;
      },
    },
    windowNo: {
      type: String,
      default: null,
    },
    tabIndex: {
      type: Number,
      default: null,
    },
    /** 表格标题字段 */
    tabGridTitleFields: {
      type: Array,
      default: function () {
        return null;
      },
    },
    /** 表格字段 */
    tabGridFields: {
      type: Array,
      default: function () {
        return null;
      },
    },
    modelData: {
      type: Object,
      default: function () {
        return null;
      },
    },
    parentModelData: {
      type: Object,
      default: function () {
        return null;
      },
    },
    className: {
      type: String,
      default: null,
    },
    isShowEdit: {
      type: Boolean,
      default: false,
    },
    scrollObject: {
      type: Object,
      default: null,
    },
    serialNumber: {
      type: Number,
      default: null,
    },
    jsUrl: {
      type: String,
      default: null,
    },
    simpleFilterParams: {
      type: String,
      default: null,
    },
    complexFilterParams: {
      type: Array,
      default: () => {
        return [];
      },
    },
    modelDatas: {
      type: Array,
      default: () => {
        return [];
      },
    },
    // 当前的页签
    nowTab: {
      type: String,
      default: '',
    },
  },
  emits: ['deleteRecord', 'editRecord', 'readRecord', 'clickModelData', 'executeCallout', 'valueChanged', 'refreshDatas'],


  data: function () {
    return {
      tabGridFields1: this.tabGridFields,
      lastClickTime: 0,
      fieldUtil: FieldUtil,
      Language: Language,
      processReportResult: {},
      modal: false,
      titleModal: false,
      tabButtonModel: {},
    };
  },
  computed: {
    modelDataCopy: function () {
      return JSON.parse(JSON.stringify(this.modelData));
    },

    isSelected: {
      get: function () {
        return this.modelData.select == true;
      },
      set: function () {

      },
    },
    /**
         * 获取报警颜色
         */
    warningColor: function () {
      if (this.modelData.data['warningColor'] != undefined && this.modelData.data['warningColor'].displayValue.length > 0) {
        return this.modelData.data['warningColor'].displayValue[0];
      } else {
        return 'none';
      }

    },

    /**
         * 是否显示编辑按钮
         */
    showEditButton: function () {
      if (this.isShowEdit == undefined || this.isShowEdit) {
        if (this.modelData != undefined
          && this.modelData.data != undefined
          && this.modelData.data['documentStatus'] != undefined
          && this.modelData.data['documentStatus'].displayValue != undefined
          && (this.modelData.data['documentStatus'].displayValue[0] == 'APPROVED'
            || this.modelData.data['documentStatus'].displayValue[0] == 'REJECTED'
            || this.modelData.data['documentStatus'].displayValue[0] == 'PROCESSING')) {
          return false;
        }
        return true;
      }
      return false;
    },

    /**
     * 是否显示标题行
     */
    showTabGridTitleFields: function () {
      if (this.tabGridTitleFields == null || this.tabGridTitleFields.length == 0) {
        return false;
      } else {
        return true;
      }
    },
  },
  watch: {
    'parentModelData': {
      deep: true,
      handler(curVal, oldVal) {
        var _self = this;
        for (let index = 0; index < _self.tabGridFields.length; index++) {
          const tabGridField = _self.tabGridFields[index];
          let oldTabGridFieldString = JSON.stringify(tabGridField);

          const columnShowLogical = tabGridField.columnShowLogical;
          if (columnShowLogical != null && columnShowLogical.length > 0) {
            let functionName = tabGridField.fieldName.replace('.', '_') + '_showLogical';

            let executeFunction = function () {
              let parentCtx = new _self.getContext(_self.parentModelData);
              try {
                tabGridField.visible = _self[functionName](null, parentCtx.modelData);
              } catch (e) {
                console.error('js代码 %s 执行异常 %o', columnShowLogical, e);
                tabGridField.visible = true;
              }
            };

            if (_self[functionName] == null) {
              // 执行服务端的脚本
              const jsUrl = _self.jsUrl;
              if (jsUrl == null || jsUrl == undefined) {
                Notify.error('数据字典定义异常', '【' + tabGridField.fieldName + '】列显示逻辑的JS文件不存在,请联系管理员检查数据字典是否JS文件。', false);
                return;
              }
              let promise = JsUtil.dynamicLoadJsFunction(jsUrl, columnShowLogical);
              promise.then(dynamicFunction => {
                let targetFunction = dynamicFunction;

                if (targetFunction == null) {
                  Notify.error('数据字典定义异常', '【' + tabGridField.fieldName + '】列显示逻辑定义异常,请联系管理员检查数据字典的定义。', false);
                  return;
                }

                _self[functionName] = targetFunction;

                executeFunction();
              }, errorData => {
                console.error(errorData);
              });
            } else {
              executeFunction();
            }
          } else {
            tabGridField.visible = true;
          }

          let newTabGridFieldString = JSON.stringify(tabGridField);

          // bug fixed by jack 2022-01-17
          // 只有当数据发生改变以后，才重新设置数据，解决当子表数据量很打的时候，输入卡顿的问题。
          if (oldTabGridFieldString != newTabGridFieldString) {
            _self.tabGridFields[index] = tabGridField;
          }
        }
        console.log(_self.tabGridFields);
      },
    },
  },


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

    deleteRecord: function () {
      this.$emit('deleteRecord');
    },
    refreshDatas: function () {
      this.$emit('refreshDatas');
    },

    buttonClick: function () {
      Notify.error('提示', '暂不支持该组件', false);
    },

    // 改变表格行元素的编辑状态
    editRecord: function (modelData, index) {
      const validateResults = this.performValidate();
      const allTrue = validateResults.every(item => item === true);
      if (allTrue) this.$emit('editRecord', modelData, index);
    },

    readRecord: function (isRead, modelData, index) {
      this.$emit('readRecord', isRead, modelData, index);
    },

    clickModelData: function () {
      this.$emit('clickModelData');
      this.$emit('readRecord', false);
    },

    // 值发生改变
    valueChanged: function (newFieldValue, gridFieldItem) {
      var valueObject = {
        newFieldValue: newFieldValue,
        gridFieldItem: gridFieldItem,
      };
      this.$emit('valueChanged', valueObject);

      this.refreshSelectField(this.modelData, gridFieldItem.fieldName);
    },

    // 刷新下拉选择框keyValues
    refreshSelectField: function (modelData, valueChangedFieldName) {
      var _self = this;
      if (_self.tabGridFields1) {
        _self.tabGridFields1.forEach(function (item) {
          if (item.displayType == 'ListBoxEditor') {
            var name1 = ':' + valueChangedFieldName;
            var showLogical = item.showLogical;
            if (showLogical != undefined && showLogical.indexOf(name1) >= 0) {
              refresh(item);
            }
          }
        });
      }

      function refresh(item) {
        var obj = {
          fieldId: item.id,
          modelData: modelData,
        };

        console.log('GridBody RefreshField');
        $.ajax({
          url: Common.getApiURL('FieldResource/refreshField'),
          async: false,
          dataType: 'json',
          type: 'post',
          data: JSON.stringify(obj),
          contentType: 'application/json',
          beforeSend: function (request) {
            Common.addTokenToRequest(request);
          },
          success: function (data) {
            if (data != undefined) {
              item.keyValues = data.keyValues;
            }
          },
          error: function (XMLHttpRequest, textStatus, errorThrown) {
            Common.processException(XMLHttpRequest, textStatus, errorThrown);
          },
        });
      }
    },

    performValidate: function () {
      var validateResults = [];
      for (var i = 0; i < this.tabGridFields1.length; i++) {
        let cellId = 'cellItem' + i;
        if (this.$refs[cellId] && this.$refs[cellId][0]) {
          var result = this.$refs[cellId][0].performValidate();
          validateResults.push(result);
        }
      }
      return validateResults;
    },
    clickRecord: function () {
      // 暂时取消双击打开
      var now = new Date().getTime();
      // if (now - this.lastClickTime < 500) {
      //   this.readRecord();
      // }
      // this.lastClickTime = now;
    },
    /**
     * 执行Callout
     */
    executeCallout: function (gridFieldItem, isBtn) {
      this.$emit('executeCallout', gridFieldItem, isBtn);
    },

    /**
     * 获取字符串的哈希值
     * @param input
     */
    getHash: function (input) {
      let hash = 0;
      if (input.length === 0) {
        return hash;
      }
      for (let i = 0; i < input.length; i++) {
        const char = input.charCodeAt(i);
        hash = (hash << 5) - hash + char;
        hash = hash & hash; // 确保返回值是一个32位有符号整数
      }
      return Math.abs(hash).toString();
    },

  },
};
</script>

<style scoped>
.table-cell-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: center;
}

/** 搜索框，自动提示表格， */
.table-cell-searchwidget {
  position: relative;
}

.text-center {
  text-align: center;
}

.operation-delete {
  margin-left: 10px;
  margin-right: 5px;
}

.operation-edit {
  margin-left: 5px;
  margin-right: 10px;
}

table {
  border-collapse: collapse;
  background: white;
}

table>th,
td {
  border: 1px solid #e8e8e8;
  padding: 8px;
}

table>tbody>tr:nth-of-type(odd) {
  background-color: #f9f9f9;
}

.sticky-col {
  position: sticky;
  background: #f7f7f7;
}


.warning {
  background-color: #fcf8e3 !important;
}

/* 选中行时固定列的背景色也要变化 */
.warning .sticky-col {
  background-color: #fcf8e3 !important;
}
.sticky-left {
  left: 80px;
}

.sticky-right{
  right: 0;
}

/* 鼠标悬浮行效果 */
tr:hover {
  background-color: #e6f4ff !important;
}

/* 鼠标悬浮时固定列的背景色也要变化 */
tr:hover .sticky-col {
  background-color: #e6f4ff !important;
}
</style>
