package com.huigou.uasp.data.controller;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.util.*;

import com.huigou.context.Operator;
import com.huigou.context.OrgUnit;
import com.huigou.exception.ApplicationException;
import com.huigou.uasp.bmp.common.BizBillStatus;
import com.huigou.util.ApplicationContextWrapper;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import com.alibaba.fastjson.JSON;
import com.google.common.base.CaseFormat;
import com.huigou.uasp.annotation.ControllerMapping;
import com.huigou.uasp.builder.vo.ParamFormVO;
import com.huigou.uasp.builder.vo.PubDataRecord;
import com.huigou.uasp.builder.vo.SeleListCustomVO;
import com.huigou.uasp.client.CommonController;
import com.huigou.uasp.form.application.CommonUtilApplication;
import com.huigou.uasp.form.application.SafFormslistApplication;
import com.huigou.uasp.form.domain.model.FormAttribute;
import com.huigou.uasp.form.domain.model.FormSearchSql;
import com.huigou.uasp.form.domain.model.FormTables;
import com.huigou.uasp.form.domain.model.SafFormslist;
import com.huigou.uasp.form.domain.query.SafFormsQueryRequest;
import com.huigou.uasp.form.repository.FormAttributeRepository;
import com.huigou.uasp.form.repository.FormSearchSqlRepository;
import com.huigou.uasp.form.repository.FormTablesRepository;
import com.huigou.uasp.form.repository.SafFormslistRepository;
import com.huigou.uasp.model.domain.query.DbTablesQueryRequest;
import com.huigou.uasp.util.Constant;
import com.huigou.uasp.util.ReflectionUtil;
import com.huigou.uasp.util.Utils;
import com.huigou.uasp.data.application.DataRecordApplication;
import com.huigou.uasp.data.domain.query.DataRecordQueryRequest;
import com.huigou.util.SDO;
import com.huigou.util.StringUtil;
import org.springframework.util.Assert;

@Controller
@ControllerMapping("dataManage")
public class DataManageController extends CommonController {

    @Autowired
    private SafFormslistRepository safFormslistRepository;
    @Autowired
    private FormTablesRepository formTablesRepository;

    @Autowired
    private FormSearchSqlRepository formSearchSqlRepository;

    @Autowired
    private FormAttributeRepository formAttributeRepository;

    @Autowired
    private DataRecordApplication dataRecordApplication;


    @Autowired
    private CommonUtilApplication commonUtilApplication;

    @Override
    protected String getPagePath() {
        return "/customform/";
    }


    /**
     * 查询数据列表
     *
     * @return
     */
    public String slicedQueryFormData() {
        SDO sdo = this.getSDO();
        DataRecordQueryRequest queryRequest = sdo.toQueryRequest(DataRecordQueryRequest.class);
        // queryRequest.setDisplayListing(1); //只查询显示的字段
        List<SafFormslist> list = safFormslistRepository.findByFormNo(sdo.getString("formNo"));
        SafFormslist safFormslist = list.get(0);

        String tableName = commonUtilApplication.getTablesByFormId(safFormslist.getId(), 1);
        tableName = tableName.split(",")[0];  //取第一个主表

        queryRequest.setMaiTab(tableName);
        queryRequest.setSubTab(tableName);
        queryRequest.setFormId(safFormslist.getId());
        //处理查询字段
        List<FormAttribute> searchList = formAttributeRepository.findByFormId(safFormslist.getId());
        FormAttribute formAttribute = null;
        Map<String, Object> map = new HashMap<String, Object>();
        for (int u = 0; u < searchList.size(); u++) {
            formAttribute = searchList.get(u);
            if (formAttribute.getSearchField() != null && formAttribute.getSearchField() == 1) {
                map.put("field" + u, sdo.getString("field" + u));
            }
        }
        queryRequest.setSearchContent(map);

        Map<String, Object> data = this.dataRecordApplication.queryDataRecord(queryRequest);
        //Map<String, Object> data = null;
        return toResult(data);
    }


    /**
     * 添加/修改数据
     * return
     */
    @SuppressWarnings("unchecked")
    public String addDataRecord() {
        SDO sdo = this.getSDO();
        // 优先取id作为业务主键
        String id = sdo.getString("id");
        if (StringUtils.isBlank(id)) {
            // 否则取bizId作为业务主键
            id = sdo.getBizId();
            sdo.putProperty("id", id);
        }
        if  (StringUtils.isNotBlank(sdo.getString("procId"))){
            this.putAttribute("procId",sdo.getString("procId"));
        }
        String formNo = sdo.getString("formNo");
        DataRecordQueryRequest queryRequest =sdo.toQueryRequest(DataRecordQueryRequest.class);

        List<SafFormslist> list = safFormslistRepository.findByFormNo(formNo);
        SafFormslist safFormslist = list.get(0);

        String tableName = commonUtilApplication.getTablesByFormId(safFormslist.getId(), 1);
        tableName = tableName.split(",")[0];  //取第一个主表

        String pageName = formNo + "/" + CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, tableName);

        queryRequest.setMaiTab(tableName);
        queryRequest.setFormId(safFormslist.getId());
        // mdmDataRecordApplication.needGenerateFile(queryRequest);
        List<FormAttribute> attrList = this.formAttributeRepository.findByFormIdAndTable(safFormslist.getId(), tableName.toUpperCase());
        //JSONObject backData = new JSONObject();
        //增加 对于radio 、checkbox 、select 等存在自定义数据来源值的情况 需要
        Map<String, Object> mapData = new HashMap<String, Object>();
        int u = 0;
        for (FormAttribute formAttribute : attrList) {   //是否存在查询顺序与显示顺序不一致的情况？？？
            if (formAttribute.getDataSourceType() != null && Constant.DATASOURCETYPE_FIX.equals(formAttribute.getDataSourceType())) { // 自定义数据来源的
                mapData = new HashMap<String, Object>();
                if (formAttribute.getDataSource() != null) {
                    mapData = (Map<String, Object>) JSON.parse(formAttribute.getDataSource());
                    this.putAttribute("field" + u + "_" + formAttribute.getFieldTag(), mapData);
                }
            }
            u++;
        }

        PubDataRecord entity = null;
        if (StringUtils.isEmpty(id)) { //新增
            entity = new PubDataRecord();
            entity.setFormId(safFormslist.getId());
            //是否存在字段与编码规则，生成新编码
            entity = this.dataRecordApplication.loadDataRecordByAdded(queryRequest);
            //获取流程定义的key
            this.putAttribute("processDefinitionKey", commonUtilApplication.getProcDefinitionByFormNo(formNo));
            this.putAttribute("procUnitId", "Apply");
            entity.setStatusId(BizBillStatus.APPLYING.getId());
        } else {   //编辑
            entity = this.dataRecordApplication.loadDataRecord(queryRequest);
        }
        entity.setFormId(safFormslist.getId());
        // this.putAttribute("formId", safFormslist.getId());
        Map<String, Object> map = entity.getHiddField();
        //  System.out.println("通过Map.entrySet遍历key和value");
        if (map != null) {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                //  System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
                this.putAttribute(entry.getKey(), entry.getValue());
            }
        }


        /**
         * 设置jsp页面初始化填充数据，如果不设置， 那么在jsp页面上填写完表单之后立即提交申请TaskDescription获取不到时间和相关人员信息
         */
        Operator operator = getOperator();
        //entity.setDefaultValues(new OrgUnit(operator.getFullId(), operator.getFullName()),formNo );
        internalSetDefaultValues(entity, new OrgUnit(operator.getFullId(), operator.getFullName()), formNo);

        return forward(pageName, entity);
    }

    //初始化流程页面的默认参数
    private void internalSetDefaultValues(PubDataRecord entity, OrgUnit orgUnit, String formNo) {
        Assert.notNull(orgUnit, "参数orgUnit不能为空。");
        String codeRuleId = formNo;//this.getCodeRuleId();
        Assert.hasText(codeRuleId, "没有设置单据编码规则。");
        Object codeGenerator = ApplicationContextWrapper.getBean("codeGenerator");

        try {
            Method method = codeGenerator.getClass().getMethod("getNextCode", String.class);
            String code = (String) method.invoke(codeGenerator, codeRuleId);
            entity.setBillCode(code);
        } catch (SecurityException | NoSuchMethodException var6) {
            throw new ApplicationException(var6.getMessage());
        } catch (IllegalAccessException var7) {
            throw new ApplicationException(var7.getMessage());
        } catch (IllegalArgumentException var8) {
            throw new ApplicationException(var8.getMessage());
        } catch (InvocationTargetException var9) {
            throw new ApplicationException(var9.getTargetException().getMessage());
        }

        entity.setFullId(orgUnit.getFullId());
        entity.setOrganId(orgUnit.getOrgId());
        entity.setOrganName(orgUnit.getOrgName());
        entity.setDeptId(orgUnit.getDeptId());
        entity.setDeptName(orgUnit.getDeptName());
        entity.setPositionId(orgUnit.getPositionId());
        entity.setPositionName(orgUnit.getPositionName());
        entity.setPersonMemberId(orgUnit.getPersonMemberId());
        entity.setPersonMemberName(orgUnit.getPersonMemberName());
        entity.setFillinDate(new Timestamp((new Date()).getTime()));

    }

    /**
     * 保存数据方法
     *
     * @return
     */
    public String saveDataRecord() {
        SDO sdo = getSDO();
        PubDataRecord entity = (PubDataRecord) sdo.toObject(PubDataRecord.class);
        DataRecordQueryRequest queryRequest = getSDO().toQueryRequest(DataRecordQueryRequest.class);
        //获取表单信息
        SafFormslist form = safFormslistRepository.findOne(sdo.getString("formId"));
        List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>();

        SafFormsQueryRequest safFormsQueryRequest = new SafFormsQueryRequest();
        safFormsQueryRequest.setId(form.getId());
        String tableName = commonUtilApplication.getTablesByFormId(form.getId(), 1);
        tableName = tableName.split(",")[0];  //取第一个主表

        queryRequest.setMaiTab(tableName);
        queryRequest.setFormId(form.getId());
        queryRequest.setFormNo(form.getFormNo());
        queryRequest.setSaveMode(form.getSaveMode());

        List<Map<String, Object>> fieldList = this.commonUtilApplication.queryDataRecordSingleFields(safFormsQueryRequest.getId(), tableName.toUpperCase());
        Map<String, Object> map = Utils.dataValueTransfer(fieldList, entity);

        //查找存在的隐藏字段
        List<String> hiddenFields = new ArrayList<String>();
	 	/* List <FormSearchSql>customlists=formSearchSqlRepository.searchSqlByFormNo(form.getFormNo());
	     	SeleListCustomVO customVO=null;
	   	    List <String>hiddenFields=new ArrayList<String>();
	 	 for (int i=0;i<customlists.size();i++){
	    	   customVO=new SeleListCustomVO();
	    	   Utils.CopyBean(customlists.get(i),customVO);
	    	   hiddenFields.addAll(Utils.getHiddenFields(customVO));
	 	 }*/


        DbTablesQueryRequest dbqueryRequest = new DbTablesQueryRequest();
        dbqueryRequest.setTableName(tableName.toUpperCase());
        hiddenFields = commonUtilApplication.queryTableHiddenFields(dbqueryRequest, 0);
        queryRequest.setHiddenField(hiddenFields);

        String vals = "", tempHiddenStr = "";
        for (String hiddenStr : hiddenFields) {
            tempHiddenStr = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, hiddenStr); //转成驼峰法
            if (StringUtils.isNotBlank(sdo.getString(tempHiddenStr))) {
                vals = sdo.getString(tempHiddenStr);
                //hiddenStr=CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE,hiddenStr);//转成下划线  存入数据库
                map.put(hiddenStr, vals);
            }
        }


        //问题 是当隐藏字段不存在时 如何效验？？ 否则保存出错 ？？？？
        if (entity.getId() != null)
            map.put("id", entity.getId());

        //  dataList.add(map);
        String sid = this.dataRecordApplication.saveDataRecord(queryRequest, map);
        // entity=list.get(list.size()-1);
        String methods = "";
        //是否存在子表
	  /*    List <Map<String, Object>>multsFieldAttrCodes=this.mdmDataRecordApplication.queryDataRecordMultsFieldsAttrCode(queryRequest);
	  	if (multsFieldAttrCodes!=null&&multsFieldAttrCodes.size()>0) {
	         // String tableName=commonDataService.getTableName(queryRequest.getModelId());
	    	  tableName=CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL,tableName);
	    	  tableName=Utils.toUpperCaseFirstOne(tableName);
	  		  String attrCode="";
	  		for (int i=0;i<multsFieldAttrCodes.size();i++) {
	  			map=multsFieldAttrCodes.get(i);
	  			attrCode=CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL,map.get("attrCode").toString());
	  			attrCode=Utils.toUpperCaseFirstOne(attrCode);
	  			methods+="saveRow"+tableName+attrCode;
	  			if (i<multsFieldAttrCodes.size()-1){
	  				methods+=",";
	  			}
	  		}
	  	 }*/
        if (!"".equals(methods)) {
            return success(sid + ";" + methods);
        } else {
            return success(sid);
        }

    }

    /*
     * 删除数据列表
     *
     */
    public String deleteDataRecord() {
        SDO sdo = this.getSDO();
        DataRecordQueryRequest queryRequest = sdo.toQueryRequest(DataRecordQueryRequest.class);
        List<SafFormslist> list = safFormslistRepository.findByFormNo(sdo.getString("formNo"));
        SafFormslist safFormslist = list.get(0);

        String tableName = commonUtilApplication.getTablesByFormId(safFormslist.getId(), 1);
        tableName = tableName.split(",")[0];  //取第一个主表

        String subTableName = commonUtilApplication.getTablesByFormId(safFormslist.getId(), 2);

        queryRequest.setMaiTab(tableName);
        queryRequest.setSubTab(subTableName);

        queryRequest.setFormId(safFormslist.getId());

        Map<String, Object> data = new HashMap<String, Object>();
        //List<MdmDataRecord> detailData = sdo.getList("detailData", MdmDataRecord.class);
        this.dataRecordApplication.deleteDataRecord(queryRequest, getSDO().getIds());
        return toResult(data);
    }

    /*
     * 删除数据明细列表
     *
     */
    public String deleteDataRecordDetail() {
        SDO sdo = this.getSDO();
        DataRecordQueryRequest queryRequest = sdo.toQueryRequest(DataRecordQueryRequest.class);
        this.dataRecordApplication.deleteDataRecordDetail(queryRequest, sdo.getString("ids"));
        Map<String, Object> data = new HashMap<String, Object>();
        return toResult(data);
    }


    /*
     * 查询数据明细列表
     *
     */
    public String slicedQueryDataRecordDetail() {
        SDO sdo = this.getSDO();
        DataRecordQueryRequest queryRequest = sdo.toQueryRequest(DataRecordQueryRequest.class);
        //queryRequest.setModelId("1"); //测试使用
        Map<String, Object> data = new HashMap<String, Object>();
        SafFormslist safFormslist = this.safFormslistRepository.findOne(queryRequest.getFormId());
        queryRequest.setFormNo(safFormslist.getFormNo());
        //查询存在检索SQL 返回的隐藏字段
        List<String> hiddenFieldList = getDetailHiddenFields(queryRequest);
        queryRequest.setHiddenField(hiddenFieldList);

        if (!StringUtils.isEmpty(sdo.getString("id"))) {
            if (this.dataRecordApplication.queryIsExistTable(queryRequest) == 0) {
                data.put("error", queryRequest.getSubTab() + Constant.NOT_DATA_DETAIL_TABLE);
            } else {
                data = this.dataRecordApplication.queryDataRecordDetail(queryRequest);
            }
        }
        return toResult(data);
    }


    /*
     * 保存明细数据列表
     * 参数：formId,主表Id,当前明细表名,明细数据
     */
    public String saveRowDataRecordDetail() {
        SDO sdo = this.getSDO();
        DataRecordQueryRequest queryRequest = sdo.toQueryRequest(DataRecordQueryRequest.class);

        List<PubDataRecord> detailData = sdo.getList("detailData", PubDataRecord.class);
        queryRequest.setId(sdo.getString("mid").toString());//主表ID

        Map<String, Object> data =this.dataRecordApplication.saveRowDataRecordDetail(queryRequest.getFormId(),sdo.getString("mid"),
                queryRequest.getSubTab(),detailData);

        return toResult(data);
    }


    //获取信息明细表中检索SQL的隐藏字段
    public List<String> getDetailHiddenFields(DataRecordQueryRequest queryRequest) {
        //存在检索SQL 需要获得返回的隐藏字段的值
        // String detailTable=sdo.getString("subTab");

        List<Map<String, Object>> hiddenList = this.dataRecordApplication.queryHiddenFieldBySearchSQL(queryRequest);

        List<String> hiddenFieldList = new ArrayList<String>();
        if (hiddenList.size() > 0) {
            SeleListCustomVO customVO = null;
            for (Map<String, Object> map : hiddenList) {
                customVO = new SeleListCustomVO();
                customVO.setBackFields(map.get("backFields").toString());
                customVO.setFieldTypes(map.get("fieldTypes").toString());
                hiddenFieldList.addAll(Utils.getHiddenFields(customVO));
            }
        }
        return hiddenFieldList;
    }

    //修改状态
    public String changeDataRecordStatus() {
        SDO sdo = this.getSDO();
        DataRecordQueryRequest queryRequest = sdo.toQueryRequest(DataRecordQueryRequest.class);
        // 	SafFormslist form=safFormslistRepository.findOne(sdo.getString("id"));
        //	SafFormslist safFormslist=list.get(0);

        String tableName = commonUtilApplication.getTablesByFormId(sdo.getString("id"), 1);
        tableName = tableName.split(",")[0];  //取第一个主表
        queryRequest.setMaiTab(tableName);
        this.dataRecordApplication.changeDataRecordStatus(queryRequest);
	     /*  MdmCodeRule entity=this.mdmCodeRuleApplication.loadMdmCodeRule(sdo.getString("id"));
	      if(entity!=null){
			entity.setStatus(sdo.getInteger("status"));
		  }
	      this.mdmCodeRuleRepository.save(entity);*/
        return success();
    }

    //修改明细表的状态
    public String changeDataRecordDetailStatus() {
        SDO sdo = this.getSDO();
        DataRecordQueryRequest queryRequest = sdo.toQueryRequest(DataRecordQueryRequest.class);
        this.dataRecordApplication.changeDataRecordDetailStatus(queryRequest);
        return success();
    }


    /**
     * 字段效验调用方法
     *
     * @return flag=0 表示未通过  flag=1表示通过  result表示返回结果
     * 函数定义时：注意参数中默认第一个是id,第二个是当前字段的值，后面是其它参数的值
     * 函数成功返回success  如果返回有值 则 success:值
     */
    public String checkFieldFunction() {
        SDO sdo = this.getSDO();
        String id = sdo.getString("id");
        String currVal = sdo.getString("currVal");
        String funcname = sdo.getString("funcname");
        String paramfields = sdo.getString("paramfield");
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("funcname", funcname);
        map.put("paramfields", paramfields);
        map.put("currVal", currVal);
        map.put("id", id);
        if (!"".equals(paramfields)) {
            map.put("paramfields", paramfields);
            String[] paramfield = paramfields.split(",");
            for (String pafield : paramfield) {
                map.put(pafield, sdo.getString(pafield));
            }
        }
        String backStr = this.dataRecordApplication.checkFieldFunction(map);
        Map<String, Object> backmap = new HashMap<String, Object>();
        backmap.put("flag", "0");   //表示没有通过验证
        if (backStr.startsWith("success")) { //函数返回成功  默认为success
            backStr = backStr.replace("success:", "");
            backmap.put("flag", "1");
        }
        backmap.put("result", backStr);
        return toResult(backmap);
    }

}
