package com.kingdee.eas.custom.erp.util;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Iterator;
import com.alibaba.fastjson.JSON;
import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.util.StringUtils;
import com.kingdee.eas.util.app.DbUtil;
import com.kingdee.jdbc.rowset.IRowSet;

public class SynSalaryFromErpUtils {
	
	private static Logger log = LoggerFactory.getLogger(SynSalaryFromErpUtils.class);
	/*
	 *erp地址接口
	 */
	private static String ierp = "https://sites.gtiit.edu.cn/kderpdev/ierp";
	
	private static String appId = "gtiit_sq";
	
	private static String appSecret = "Kingdee@2024Kingdee@2024";
	
	private static String tenantid = "ierp-client";
	
	private static String accountId = "1917417602120941568";
	
	
	private static String user = "jiekouyonghu";
	
	private static String usertype = "UserName";
	
	
	private static final List<String> sList = new ArrayList<String>() {{
        add("Value1");
        add("Value2");
        add("Value3");
    }};
	
	
	
	/**
	 * 获取appTokenUrl的请求
	 * @param request
	 * @param code
	 * @return
	 */
	 public static String getAllAppTokenUrl() {
	    	
	    	/*Properties config = SSOUtil.getConfig(request);
	    	appId = config.getProperty("ssoUrl");
	    	appSecret = config.getProperty("clientId2");
	    	tenantid = config.getProperty("redirectUri");
	    	accountId = config.getProperty("clientSecret2");*/
		 
		 Properties config = SynPublicUtils.getConfig();
		  ierp = (String)config.get("ierp");
	      return new StringBuffer().append(ierp).append("/api/getAppToken.do").toString();
	       
	    }
	 
	 
	 
	 /**
		 * 薪酬明细保存接口地址
		 * @param request
		 * @param code
		 * @return
	  */
		 public static String getAllGt15_save_paydetailUrl() {
			 Properties config = SynPublicUtils.getConfig();
			  ierp = (String)config.get("ierp");
		        return new StringBuffer().append(ierp).append("/kapi/v2/gt15/em/gt15_paydetail/gt15_save_paydetail").toString();
		       
		    }
	
		 /**
			 * 获取accessTokenUrl的请求
			 * @param request
			 * @param code
			 * @return
		  */
			 public static String getAllAccessTokenUrl(String apptoken) {
				 Properties config = SynPublicUtils.getConfig();
				  ierp = (String)config.get("ierp");
			        return new StringBuffer().append(ierp).append("/api/login.do").toString();
			       
			    }
	
	/**
	 * 获取app_token接口
	 * @param ctx
	 * @throws Exception 
	 * 
	 */
	 public static String getAppToken(Context ctx ) throws Exception {
		 
		//1.获取app_token接口
		 String appToken = "";
		 String allAppTokenUrl = getAllAppTokenUrl();
		 log.info("getAppToken.allAppTokenUrl :"+allAppTokenUrl);
		 		 
		 Properties config = SynPublicUtils.getConfig();
		 appId = (String)config.get("appId");
		 appSecret = (String)config.get("appSecret");
		 tenantid = (String)config.get("tenantid");
		 accountId = (String)config.get("accountId");
		 
		 JSONObject jo = new JSONObject();
         jo.put("appId",appId);
         jo.put("appSecret",appSecret);
         jo.put("tenantid",tenantid);
         jo.put("accountId",accountId);
         String param = jo.toString();
         log.info("getAppToken.param :"+param);
		 String appTokenResult = HttpsReqUtil.postByHttps(allAppTokenUrl, param);
		 log.info("getAppToken.appTokenResult :"+appTokenResult);
		 
		 if(StringUtils.isEmpty(appTokenResult)){
			 log.info("获取appTokenResult异常："+appTokenResult);
			 return appToken;
		 }
		 
		 JSONObject json = JSON.parseObject(appTokenResult);
		 String state = json.getString("state");
		 boolean status = json.getBoolean("status");
		 
		 if(!"success".equals(state)){
			 log.info("获取appTokenResult.state状态为："+state);
			 return appToken;
		 }
		 if(!status){
			 log.info("获取appTokenResult.status状态为："+status);
			 return appToken;
		 }
		  
		 JSONObject dataObjec = json.getJSONObject("data");
		 
		 if(dataObjec == null){
			 log.info("获取appTokenResult.dataObjec为："+dataObjec);
			 return appToken;
		 }
		 appToken = dataObjec.getString("app_token");
		
		 return appToken;
	 }
	 
	 
	 /**
	  * 获取access_token接口
	  * @param appToken
	  * @return
	 * @throws Exception 
	  */
	 public static String getAccessToken(String appToken) throws Exception{ 
		 String allAccessTokenUrl =  getAllAccessTokenUrl(appToken);
		 log.info("getAccessToken.allAccessTokenUrl :"+allAccessTokenUrl);
		 String accessToken = "";
		 
		 String param = "";
		 Properties config = SynPublicUtils.getConfig();
		 tenantid = (String)config.get("tenantid");
		 accountId = (String)config.get("accountId");
		 user = (String)config.get("user");
		 usertype = (String)config.get("usertype");
		 
		 
		 
		 JSONObject jo = new JSONObject();
         jo.put("user",user);
         jo.put("apptoken",appToken);
         jo.put("tenantid",tenantid);
         jo.put("accountId",accountId);
         jo.put("usertype",usertype);
          param = jo.toString();
		 
          
          log.info("getAccessToken.param :"+param);
		 String accessTokenResult = HttpsReqUtil.postByHttps(allAccessTokenUrl, param);
		 log.info("getAccessToken.accessTokenResult :"+accessTokenResult);
		 
		 if(StringUtils.isEmpty(accessTokenResult)){
			 log.info("accessTokenResult："+accessTokenResult);
			 return accessToken;
		 }
		 
		 JSONObject json = JSON.parseObject(accessTokenResult);
		 String state = json.getString("state");
		 boolean status = json.getBoolean("status");
		 
		 if(!"success".equals(state)){
			 log.info("获取getAccessToken.state状态为："+state);
			 return accessToken;
		 }
		 if(!status){
			 log.info("获取getAccessToken.status状态为："+status);
			 return accessToken;
		 }
		  
		 JSONObject dataObjec = json.getJSONObject("data");
		 
		 if(dataObjec == null){
			 log.info("获取getAccessToken.dataObjec为："+dataObjec);
			 return accessToken;
		 }
		 accessToken = dataObjec.getString("access_token");
		
		 return accessToken;
		 
	 }
	 
	 /**
	  * 薪酬明细保存接口
	  * @param accessToken
	  * @return
	 * @throws Exception 
	  */
	 public static String  savePaydetail2(String accessToken) throws Exception{
		 
		 String paydetailUrl = getAllGt15_save_paydetailUrl(); 
         //数据保存接口
         JSONObject entryEntityJO = new JSONObject();
         entryEntityJO.put("staffNo","ID-000043");
         entryEntityJO.put("currencyNumber","CNY");
         entryEntityJO.put("orgNumber","D0001");
         entryEntityJO.put("idNo","410323");
         entryEntityJO.put("positionName","开发");
         entryEntityJO.put("userTypeNumber","PT01");
         entryEntityJO.put("wokerTypeNumber","001");
         entryEntityJO.put("positionNumber","IT-2016008");
         entryEntityJO.put("projectNumber","A01");
         entryEntityJO.put("rate","1.80");
         entryEntityJO.put("originalAmount","104.04");
         entryEntityJO.put("remark","备注");

         JSONArray entryentitys = new JSONArray();
         entryentitys.add(entryEntityJO);


         JSONObject data = new JSONObject();
         data.put("period","2024-04");
         data.put("fullOrPart","FULL");
         data.put("entryentity",entryentitys);

         JSONArray datas = new JSONArray();
         datas.add(data);

         JSONObject paramJO = new JSONObject();
         paramJO.put("data",datas);

         log.info("savePaydetail.paramJOStr:"+paramJO.toString());
         log.info("savePaydetail.paydetailUrl:"+paydetailUrl);
         log.info("savePaydetail.accessToken:"+accessToken);
         String paramJOStr = paramJO.toString();
                  
         //数据保存接口
         String responseMsg = HttpsReqUtil.postByHttps(paydetailUrl, paramJOStr, accessToken);
		 
		 return responseMsg;
		 
	 }
	 
	 
	 /**
	  * 薪酬明细保存接口
	  * @param accessToken
	  * @return
	 * @throws Exception 
	  */
	 public static String  savePaydetail(Context ctx , String accessToken,String yearMonth) throws Exception{
		 int year = 0;
			 int month = 0;
		 if(StringUtils.isEmpty(yearMonth)){
			 Calendar calendar = Calendar.getInstance();
			 year = calendar.get(Calendar.YEAR);
			 month = calendar.get(Calendar.MONTH) + 1;
		 }else{
			 String[] ym = yearMonth.split("-");
			 String yearStr = ym[0];
			 String monthStr = ym[1];
			 year = Integer.parseInt(yearStr);
			 month = Integer.parseInt(monthStr);
		 }
		
		 log.info("savePaydetail.year:"+year+",month:"+month);
		 //全职的核算的id
		
		String paydetailUrl = getAllGt15_save_paydetailUrl(); 
		String responseMsg = "";
		
		//全职构建参数
		String paramJOStrFull = getFixDetailEntry(ctx,year,month,"FULL","pgQuAkV5SAislUptF1qRWv/N8rE=");
		log.info("savePaydetail.full.paramJOStrFull:"+paramJOStrFull);
		
		if(!StringUtils.isEmpty(paramJOStrFull)){
			//数据保存接口
		    responseMsg = HttpsReqUtil.postByHttps(paydetailUrl, paramJOStrFull, accessToken);
		}	
		
		//兼职的核算的id
		//全职构建参数
		String paramJOStrPart = getFixDetailEntry(ctx,year,month,"PART","lKaL/CRQTwahZivNPmnhRP/N8rE=");
		log.info("savePaydetail.part.paramJOStrPart:"+paramJOStrPart);
		
		if(!StringUtils.isEmpty(paramJOStrPart)){
			//数据保存接口
		    responseMsg = HttpsReqUtil.postByHttps(paydetailUrl, paramJOStrPart, accessToken);
		}
		 return responseMsg;
	 }
	 
	 
	 
	 
	 /**
	  * 通过周期,与已审核的状态来获取核算的Fid集合,全职
	  * @return
	 * @throws BOSException 
	 * @throws SQLException 
	  */
	 private static List<String> getSCmpCalTableFidFullList(Context ctx ,int periodyear,int periodmonth) throws BOSException, SQLException{
		String sql = "select fid as id from T_HR_SCmpCalTable where fcalschemeid = 'pgQuAkV5SAislUptF1qRWv/N8rE=' and fcalstate = 12 and fperiodyear = "+periodyear+" and fperiodmonth =" + periodmonth;
		IRowSet executeQuery = DbUtil.executeQuery(ctx, sql);
		List<String> SCmpCalTableFullFids = new ArrayList<String>();
		if(executeQuery.size()>0){
			while(executeQuery.next()){
				String id = executeQuery.getString("id");
				SCmpCalTableFullFids.add(id);	
			}
		}
		 log.info("getSCmpCalTableFidFullList.SCmpCalTableFids.size:"+SCmpCalTableFullFids.size());
		 return SCmpCalTableFullFids;
		  
	 }
	 
	 
	 /**
	  * 通过周期,与已审核的状态来获取核算的Fid集合,兼职
	  * @return
	 * @throws BOSException 
	 * @throws SQLException 
	  */
	 private static List<String> getSCmpCalTableFidPartList(Context ctx ,int periodyear,int periodmonth) throws BOSException, SQLException{
		String sql = "select fid as id from T_HR_SCmpCalTable where fcalschemeid = 'lKaL/CRQTwahZivNPmnhRP/N8rE=' and fcalstate = 12 and fperiodyear = "+periodyear+" and fperiodmonth =" + periodmonth;
		IRowSet executeQuery = DbUtil.executeQuery(ctx, sql);
		List<String> SCmpCalTablePartFids = new ArrayList<String>();
		if(executeQuery.size()>0){
			while(executeQuery.next()){
				String id = executeQuery.getString("id");
				SCmpCalTablePartFids.add(id);	
			}
		}
		 log.info("getSCmpCalTableFidPartList.SCmpCalTableFids.size:"+SCmpCalTablePartFids.size());
		 return SCmpCalTablePartFids;
		  
	 }
	 
	 
	 
	 
	 /**
	  * 通过id查询出所有的人员对应的项目分录，以分录为准
	  * @param ctx
	  * @param SCmpCalTableFid
	  * @param periodyear
	  * @param periodmonth
	  * @param fullOrPart
	  * @return
	  * @throws SQLException
	  * @throws BOSException
	  */
	 private static String getFixDetailEntry(Context ctx ,int periodyear,int periodmonth,String fullOrPart,String calschemeId) throws SQLException, BOSException{		 
		 String staffNo ="";
		 String staffName = "";
		 String currencyNumber = "";
		 String orgNumber = "";
		 String idNo = "";
		 String positionName = "";
		 String userTypeNumber = "";
		 String wokerTypeNumber = "";
		 String positionNumber ="";
		 Object  rate = null;
		 String remark = ""; 
		 String  paramJOStr = "";
		
		 Map<String,List<String>> keyFieldSnListNumberMap  =  getFieldsnList(ctx);
		 
		 //获取配置的项目fieldSn的集合
		 List<String> fieldSnList =keyFieldSnListNumberMap.get("fieldsnList");
		 
		 //获取配置的项目的number集合
		 List<String> numberList =keyFieldSnListNumberMap.get("numberList");
		 
		 
		 
		 log.info("getFixDetailEntry.fieldSnList.size:"+fieldSnList.size());
		 log.info("getFixDetailEntry.numberList.size:"+numberList.size());
		 
		 
		 //获取配置的项目的fieldSn
		 String fieldSnStr = getFildSnListStr(fieldSnList);
		 
		 
		 Map<String,Object> snValue = new HashMap<String,Object>();
		 String sql = " select scct.S272 as staffNo ,person2.fname_l2 as staffName ,scct.S62 as currencyNumber,baseUnit.fnumber as orgNumber,scct.S277 as idNo ,position.fnumber as positionName ,employeeClassify.fnumber as userTypeNumber, workerCategory.fnumber as wokerTypeNumber, t1.positionNumber as positionNumber," +
				 //TODO:先去掉原有写死的：" scct.S259 as remark,S230,S61,S72,S66,S74,S65,S68,S70,S64,S76,S105,S143,S107, S113,S121,S127,S152,S238,S258,S240,S242,S145,S147,S149,S244,S246,S252,S259,S313,S84,S119,S133,S172,S164,S168,S299,S202,S208,S214,S236,S228,S230,S248,S250,S147,S256,S160,S254,S210,S145,S154,S216,S129,S115,S109,S204 " +
				 " scct.S259 as remark,scct.S63 as rate, " +fieldSnStr +

				 " from T_HR_SCmpCalTable scct " +
				 " left join T_ORG_Position position on position.fid = scct.fpositionid " +
				 " left join t_bd_Person person2 on person2.fid = scct.fpersonid " +
				// " left join T_HR_BDEmployeeType et on et.fid = scct.femployeetypeid " +
				 " left join  (select op.fnumber as positionNumber ,pp.fpersonId as ppPersonId from T_HR_PersonPosition  pp\n" +
				 " left join T_ORG_Position  op on op.fid = pp.fprimarypositionid " +
				 " ) t1 on t1.ppPersonId = scct.fpersonId  " +
				 " LEFT JOIN T_BD_Currency currency on currency.fid = scct.fcurrencyid " +
				 " left join T_ORG_BaseUnit baseUnit on baseUnit.fid =  scct.fadminorgunitid " +
				 " LEFT JOIN  T_BD_Person person on person.fid = scct.fpersonId  " +
				 " left join  T_HR_EmployeeClassify employeeClassify on employeeClassify.fid = person.CFPersontypeID " +
				 " left join   T_HR_EmpOrgRelation a  on a.fid=person.fid  AND TO_CHAR(a.FLEFFDT,'YYYY-MM-DD')='2199-12-31' AND a.FASSIGNTYPE=1 " +
				 " left join ( " +
				 " select x.fid as personId,c.fnumber as dpt_number,c.fname_l1 as dpt_name,b.fnumber as post_number,b.fname_l1 as  " +
				 " post_name,b.fisrespposition as isincharge,d.fnumber as ispartjob,e.fnumber as superior_number,e.fname_l1 as superior_name, " +
				 " f.fnumber as  position_number,f.fname_l1 as position_l1,f.fname_l2 as position_l2,f.fname_l3 as  " +
				 " position_l3,a.CFWorkercategoryID as workercategoryId from t_BD_person x  " +
				 " left join   T_HR_EmpOrgRelation a  on x.fid=a.fpersonid  AND TO_CHAR(a.FLEFFDT,'YYYY-MM-DD')='2199-12-31' AND a.FASSIGNTYPE=1  " +
				 " left join t_org_position b on a.fpositionid=b.fid " +
				 " left join t_org_baseunit c on b.fadminorgunitid=c.fid " +
				 " left join CT_MP_Fullorpart d on d.fid = a.CFFtorptID " +
				 "  left join  T_BD_Person e on e.fid = a.CFLineManagerNameI " +
				 "  left join T_ORG_Job f on f.fid = b.FJobID " +
				 "  ) temp on temp.personId = person.fid  " +
				 " left join  CT_MP_WorkerCategory workerCategory on workerCategory.fid = temp.workercategoryId  " +
				 " where scct.fperiodyear="+periodyear+" and  scct.fperiodmonth = "+periodmonth+" and  scct.fcalschemeid = '"+calschemeId+"' and fcalstate = 12";
		 log.info("getFixDetailEntry.sql:"+sql);
		 IRowSet executeQuery = DbUtil.executeQuery(ctx, sql);
		 JSONArray entryentitys = new JSONArray();
		 if(executeQuery.size()>0){
				while(executeQuery.next()){
					 staffNo = executeQuery.getString("staffNo");
					 staffName = executeQuery.getString("staffName");
					 currencyNumber = executeQuery.getString("currencyNumber");
					 orgNumber = executeQuery.getString("orgNumber");
					 idNo = executeQuery.getString("idNo");
					 positionName = executeQuery.getString("positionName");
					 userTypeNumber = executeQuery.getString("userTypeNumber");
					 wokerTypeNumber = executeQuery.getString("wokerTypeNumber");
					 positionNumber = executeQuery.getString("positionNumber");
					
					 remark = executeQuery.getString("remark");
					 rate = executeQuery.getObject("rate");
					 for(int i = 0;i<fieldSnList.size();i++){
						 String fieldSn = fieldSnList.get(i);
						 BigDecimal fieldSnB = executeQuery.getBigDecimal(fieldSn);
						 String number =  numberList.get(i);
						 snValue.put(number,  fieldSnB = (fieldSnB == null)?BigDecimal.ZERO: fieldSnB);
					 }				
				
				Iterator<Map.Entry<String, Object>> iterator = snValue.entrySet().iterator();
				while (iterator.hasNext()) {
				    Map.Entry<String, Object> entry = iterator.next();
				    log.info("Key = " + entry.getKey() + ", Value = " + entry.getValue());
				    String projectNumber = entry.getKey();
				    Object originalAmount = entry.getValue();
				    JSONObject entryEntityJO = new JSONObject();
			         entryEntityJO.put("staffNo",staffNo);
			         entryEntityJO.put("staffName",staffName);
			         if("RMB".equals(currencyNumber)){
			        	//为人民币时,换为CNY
			        	 currencyNumber = "CNY"; 
			         }
			         entryEntityJO.put("currencyNumber",currencyNumber);
			         entryEntityJO.put("orgNumber",orgNumber);
			         entryEntityJO.put("idNo",idNo);
			         entryEntityJO.put("positionName",positionNumber);
			         entryEntityJO.put("userTypeNumber",userTypeNumber);
			         entryEntityJO.put("wokerTypeNumber",wokerTypeNumber);
			         entryEntityJO.put("positionNumber",positionNumber);
			         entryEntityJO.put("projectNumber",projectNumber);
			       /*  if("CNY".equals(currencyNumber)){
			        	 //为人民币时，设置为：1
			        	 rate = 1;
			         }*/
			         entryEntityJO.put("rate",rate);
			         if(originalAmount.equals(BigDecimal.ZERO)){
			        	 continue;
			         }
			         entryEntityJO.put("originalAmount",originalAmount);
			         entryEntityJO.put("remark",remark);
			         entryentitys.add(entryEntityJO);	    
				}
				}
				JSONObject data = new JSONObject();
				
				if(periodmonth>9){
					data.put("period",periodyear+"-"+periodmonth);
				}else{
					data.put("period",periodyear+"-0"+periodmonth);
				}
		         data.put("fullOrPart",fullOrPart);
		         data.put("entryentity",entryentitys);

		         JSONArray datas = new JSONArray();
		         datas.add(data);

		         JSONObject paramJO = new JSONObject();
		         paramJO.put("data",datas);
		         paramJOStr = paramJO.toString();
			} 
		  
		return paramJOStr; 
	 }
	 
	 
	 
	 /**
	  * 获取配置的项目的Map{fieldsnList:  s+Fieldsn,numberList: numberList  }
	  * @param ctx
	  * @return
	 * @throws BOSException 
	 * @throws SQLException 
	  */
	 private static  Map<String,List<String>> getFieldsnList (Context ctx) throws BOSException, SQLException{
		 String sql = "select item.fieldsn as fieldsn ,item.fnumber as number from  CT_COM_SynSalarySchemeEntry entry" +
		 		" left join T_HR_SCmpItem item on item.fid = entry.cfcmpitemid";
		 log.info("getFieldsnList.sql:"+sql);
		 IRowSet executeQuery = DbUtil.executeQuery(ctx, sql);
		 String fieldsn = "";
		 String number = "";
		 List<String> fieldsnList = new ArrayList<String>();
		 List<String> numberList = new ArrayList<String>();
		 if(executeQuery.size()>0){
				while(executeQuery.next()){
					fieldsn = executeQuery.getString("fieldsn");
					fieldsnList.add("S"+fieldsn);
					
					number = executeQuery.getString("number");
					numberList.add(number);
				}
		 }	 
		 
		 Map<String,List<String>> keyFieldSnListNumberMap  = new HashMap<String,List<String>>();
		 keyFieldSnListNumberMap.put("fieldsnList", fieldsnList);
		 keyFieldSnListNumberMap.put("numberList", numberList);
		 
		 return keyFieldSnListNumberMap;
	 }
	 
	 
	 /**
	  * 通过项目Fieldsn  获取字符串
	  * @param fieldsnList
	  * @return
	  */
	 private static String getFildSnListStr(List<String> fieldsnList){
		 String fildSnListStr = "";
		 for (int i = 0; i < fieldsnList.size(); ++i) {
				if (i != 0) {
					fildSnListStr = fildSnListStr + ",";
				}
				fildSnListStr = fildSnListStr  + fieldsnList.get(i);
			}
		 return fildSnListStr;
	 }
	 
	 
	 
	 
	 
	 
	/**
	 * 推送数据到ERP功能
	 * @return
	 * @throws Exception 
	 */
	 public static String synSalaryToErp(Context ctx, String yearMonth ) throws Exception{
		 
		 //获取appToken
		 String appToken = getAppToken(ctx);
		 log.info("获取synSalaryToErp.appToken："+appToken);
		 //获取accessToken
		 String accessToken = getAccessToken(appToken);
		 log.info("获取synSalaryToErp.accessToken状态为："+accessToken);
		 //薪酬明细保存接口
		 String responseMsg =  savePaydetail(ctx,accessToken,yearMonth);
		 log.info("获取synSalaryToErp.responseMsg："+accessToken);
		 return null;
	 }
	 
	 
	 
	 
}
