<template>
  <a-page-header
    :title="Language.getNameTrl($i18n.locale, tab)"
    style="border-bottom: 1px solid rgb(235, 237, 240); padding: 0px;"
  />

  <div class="m-row clearfix">
    <div>
      <div 
        v-if="tabFormFields && mModelData"
        :class="{
          'form-inline': tab.tabFormView.multipleColumn,
          'form-horizontal': !tab.tabFormView.multipleColumn,
        }"
      >
        <template
          v-for="fieldItem in tabFormFields" :key="
            'FieldEditView_' +
              windowNo +
              '_' +
              tab.tabIndex +
              '_' +
              fieldItem.fieldName +
              '_' +
              fieldItem.entityFieldIndex
          "
        >
          <FieldEditView
            ref="fieldItem1" 
            :class-name="tab.tabDataSource.className" 
            :field="fieldItem"
            :model-data="mModelData" 
            :window-no="windowNo" 
            :tab-index="tab.tabIndex" 
            :js-url="jsUrl"
            :is-chinese-english="curdWindow.isChineseEnglish" 
            :multiple-column="tab.tabFormView.multipleColumn"
            @value-changed="valueChanged($event, fieldItem)" 
            @execute-callout="executeCallout(fieldItem)"
          />
        </template>
      </div>
    </div>
  </div>
</template>

<script setup>
import Common from '../../common/Common';
import { Notify } from 'pc-component-v3';
import FieldEditView from './TabFormFieldEdit.vue';
import WindowClientUtil from '../../resource/dictionary/WindowClientUtil.js';
import WindowServerUtil from '../../resource/dictionary/WindowServerUtil.js';
import { ref, defineExpose, defineEmits, defineProps, watch } from 'vue';
import { debounce } from 'lodash';
import ProcessReportResource from '../../api/dic/ProcessReportResource.js';
import FieldUtil from '../../resource/dictionary/FieldUtil.js';

import Context from '../common/Context.js';
import { getCurrentInstance } from 'vue';
import JsUtil from '../../common/JsUtil.js';

import Language from '../../common/Language.js';


// proxy 就是当前组件实例，可以理解为组件级别的 this，没有全局的、路由、状态管理之类的
const { proxy, appContext } = getCurrentInstance();

// 接受父组件传递的数据
const props = defineProps({
  tab: {
    type: Object,
    default: () => {
      return {};
    },
  },
  parentModelData: {
    type: Object,
    default: () => {
      return {};
    },
  },
  curdWindow: {
    type: Object,
    default: () => {
      return {};
    },
  },

  windowNo: {
    type: String,
    default: null,
  },

  type: {
    type: String,
    default: null,
  },
  jsUrl: {
    type: String,
    default: null,
  },

  isChineseEnglish: {
    type: Boolean,
    default: false,
  },
});

const mModelData = ref({});
const tabFormFields = ref([]);
const fieldGroup = ref([]);
const oldCommand = ref(null);

const emits = defineEmits(['executeCallout', 'valueChanged']);

const getContext = Context;

/**
 * 查询一对一页签数据
 */
const getOneToOneTabData = function () {
  const params = {
    windowNo: props.windowNo,
    tabIndex: props.tab.tabIndex,
    parentId: props.parentModelData == undefined ? undefined : props.parentModelData.id,
  };
  $.ajax({
    url: Common.getApiURL('CurdWindowResource/oneToOneTabData'),
    async: false,
    dataType: 'json',
    type: 'post',
    data: JSON.stringify(params),
    contentType: 'application/json',
    beforeSend: function (request) {
      Common.addTokenToRequest(request);
    },
    success: function (data) {
      mModelData.value = data;
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) {
      Common.processException(XMLHttpRequest, textStatus, errorThrown);
    },
  });
};


/**
 * 获取一对一页签modelData(新建)
 * @param tabIndex 
 */
const createOneToOneModelData = function () {
  WindowServerUtil.newModelData(
    props.windowNo,
    props.tab.tabIndex,
    null,
    function (response) {
      if (response.errorCode != 0) {
        Notify.error('数据新建异常', response.errorMessage, false);
        return;
      }
      let newModelData = response.data;
      newModelData.editMode = true;
      mModelData.value = newModelData;
    },
  );
};

/**
 * 执行Callout
 */
const executeCallout = function (fieldItem) {
  if (fieldItem.calloutProcessReportNo != null) {
    callout(fieldItem.calloutProcessReportNo);
  }
};



/**
 * callout
 * @param  {[type]} calloutProcessReportNo [description]
 * @return {[type]}                  [description]
 */
const callout = function (calloutProcessReportNo) {

  // add by jack 20180529
  var subTabChangedData = getSubTabChangedData();
  if (subTabChangedData.length > 0) {
    mModelData.value.vaue.saveDatas = subTabChangedData;
  } else {
    mModelData.value.vaue.saveDatas = null;
  }

  // 查询流程和报表的定义
  ProcessReportResource.uniqueByNo(calloutProcessReportNo).then(
    successData => {
      if (successData == null) {
        return;
      }
      // 执行服务端的脚本
      ProcessReportResource.runCallout(
        calloutProcessReportNo,
        mModelData.value.vaue,
      ).then(
        successData => {
          if (successData && successData.modelData) {
            mModelData.value.vaue = successData.modelData;
          }
          // add by jack 20180529
          // add by jack 20220601
          mModelData.value.vaue.saveDatas = undefined;
        },
        errorData => {
          Common.processException(errorData);
        },
      );
    },
    errorData => {
      Common.processException(errorData);
    },
  );
};


// 获取子页签发生改变的数据
const getSubTabChangedData = function () {
  var subTabChangedRecords = [];
  if (props.tab.subTabs != undefined) {
    for (var index = 0; index < props.tab.subTabs.length; index++) {
      var subTabId = 'subTab' + props.tab.subTabs[index].tabIndex;
      // TODO
      // var modelDatas = $refs[subTabId][0].getChangedModelData();
      // if (modelDatas != undefined && modelDatas.length > 0) {
      //   modelDatas.forEach(function (modelData) {
      //     subTabChangedRecords.push(modelData);
      //   });
      // }
    }
  }
  console.log(subTabChangedRecords);
  return subTabChangedRecords;
};



/**
 * 延迟获取页面的数据
 */
const debounceNewAction = debounce(() => {
  if (props.type === 'create') {
    createOneToOneModelData();
  } else {
    getOneToOneTabData();
  }
}, 1000);


watch(
  () => [props.windowNo, props.tab, props.parentModelData, props.type],
  (newValue, oldValue) => {
    let newCommand = newValue[0] 
      + (newValue[1] != null ? (newValue[1].name + newValue[1].tabIndex) : '-')
      + (newValue[2] != null ? newValue[2].id : '-')
      + newValue[3];
    if(newCommand != oldCommand.value){
      debounceNewAction();
    }
    oldCommand.value = newCommand;
  },
  { immediate: true },
);

watch(
  () => props.tab,
  (newValue, oldValue) => {
    tabFormFields.value = WindowClientUtil.getDetailField(newValue);
    console.log(tabFormFields.value);
  },
  { immediate: true },
);



// 值改变事件
const valueChanged = function (newFieldValue, fieldItem) {
  console.log(fieldItem.fieldName + ' ValueChanged.');
  console.log(newFieldValue);
  var oldFieldValue = mModelData.value.data[fieldItem.fieldName];
  if (FieldUtil.isFieldValueEqual(newFieldValue, oldFieldValue) == false) {
    mModelData.value.data[fieldItem.fieldName] = newFieldValue;
    if (
      fieldItem.calloutProcessReportNo != undefined &&
      fieldItem.calloutProcessReportNo != null
    ) {
      callout(fieldItem.calloutProcessReportNo);
    }

    if (
      fieldItem.calloutLogical != undefined &&
      fieldItem.calloutLogical != null
    ) {
      executeCalloutJs(fieldItem, fieldItem.calloutLogical);
    }

    if (
      mModelData.value.changed &&
      fieldItem.displayType == 'ListBoxEditor'
    ) {
      // 值改变时，刷新所有下拉框的keyValues
      refreshSelectField(fieldItem.fieldName);
    }

    // add by jack 20170808
    mModelData.value.changed = true;

    let clearDynamicValidField = function (item) {
      var fieldName1 = item.fieldName;
      var dynamicValidFields = item.dynamicValidFields;
      if (
        fieldName0 != fieldName1 &&
        dynamicValidFields != undefined &&
        dynamicValidFields.indexOf(fieldName0) >= 0
      ) {
        var fieldValue0 = mModelData.value.data[fieldName1];
        fieldValue0.id = undefined;
        if (fieldValue0.displayValue != undefined) {
          fieldValue0.displayValue.splice(
            0,
            fieldValue0.displayValue.length,
          );
        } else {
          fieldValue0.displayValue = [];
        }
        mModelData.value.data[fieldName1] = fieldValue0;
      }
    };

    // 遍历所有的字段，判断是否有动态约束
    // 如果有关联的动态约束，则清空字段
    var fieldName0 = fieldItem.fieldName;
    tabFormFields.value.forEach(function (item) {
      clearDynamicValidField(item);
    });

    let fieldGroups = props.tab.tabFormView.fieldGroups;
    if (fieldGroups != null && fieldGroups.length > 0) {
      fieldGroups.forEach(fieldGroup => {
        if (fieldGroup.fields != null && fieldGroup.fields != null) {
          fieldGroup.fields.forEach(field => {
            clearDynamicValidField(field);
          });
        }
      });
    }
  }
};


// 刷新下拉选择框keyValues
const refreshSelectField = function (valueChangedFieldName) {

  if (tabFormFields.value) {
    tabFormFields.value.forEach(function (item) {
      if (item.displayType == 'ListBoxEditor') {
        var name1 = ':' + valueChangedFieldName;
        //var name2 = ":Parent_" + valueChangedFieldName;
        var showLogical = item.showLogical;
        if (showLogical != undefined && showLogical.indexOf(name1) >= 0) {
          refresh(item);
        }
      }
    });
  }

  if (fieldGroup.value) {
    fieldGroup.value.fields.forEach(function (item) {
      if (item.displayType == 'ListBoxEditor') {
        var name1 = ':' + valueChangedFieldName;
        //var name2 = ":Parent_" + valueChangedFieldName;
        var showLogical = item.showLogical;
        if (showLogical != undefined && showLogical.indexOf(name1) >= 0) {
          refresh(item);
        }
      }
    });
  }

  function refresh(item) {
    var obj = {
      windowNo: props.windowNo,
      tabIndex: props.tab.tabIndex,
      fieldName: item.fieldName,
      modelData: mModelData.value,
    };

    console.log('WindowEdit 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);
      },
    });
  }
};



/**
 * 执行JS Callout
 */
const executeCalloutJs = function (fieldItem, scriptText) {

  // add by jack 20180529
  var subTabChangedData = getSubTabChangedData();
  if (subTabChangedData.length > 0) {
    mModelData.value.saveDatas = subTabChangedData;
  } else {
    mModelData.value.saveDatas = null;
  }

  let functionName = fieldItem.fieldName.replace('.', '_') + '_calloutjs';

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

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

      proxy[functionName] = targetFunction;
      executeFunction();

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



/**
 * 获取子页签的集合
  */
const getSubTabs = function () {
  let subTabsRef = [];
  for (var tabIndex = 0; tabIndex < props.tab.subTabs.length; tabIndex++) {
    var subTabId = 'subTab' + props.tab.subTabs[tabIndex].tabIndex;
    // TODO
    // subTabsRef.push($refs[subTabId][0]);
  }
  return subTabsRef;
};


const fieldItem1 = ref();
const fieldItem2 = ref();

/**
 * 执行验证
 * @returns 验证错误的数量
 */
const performValide = function(){
  let error = 0;

  if (fieldItem1.value != undefined) {
    fieldItem1.value.forEach(function (w) {
      var validateResult = w.performValide();
      if (!validateResult) {
        error++;
      }
    });
  }

  if (fieldItem2.value != undefined) {
    fieldItem2.value.forEach(function (w) {
      var validateResult = w.performValide();
      if (!validateResult) {
        error++;
      }
    });
  }

  return error;
};


const getModelData = function(){
  return mModelData.value;
};

defineExpose({
  performValide,
  getModelData,
});

</script>

<style scoped></style>