package com.gx.obe.management.webservice;

import java.io.File;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.eclipse.swt.core.CallBack;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gx.obe.WebserviceConstants;
import com.gx.obe.business.http.HttpResponse;
import com.gx.obe.business.http.HttpUrl;
import com.gx.obe.business.http.HttpUtils;
import com.gx.obe.common.file.enumeration.FileConstants;
import com.gx.obe.common.widget.thread.MyRunnable;
import com.gx.obe.config.utils.PropertiesUtils;
import com.gx.obe.util.utils.ObjectUtils;
import com.gx.obe.util.utils.StringUtils;
import com.gx.obe.util.utils.UuidUtils;
import com.gx.obe.web.entity.Chain;
import com.gx.obe.web.entity.Supplier;
import com.gx.obe.web.entity.SupplierEvaluationResult;
import com.gx.obe.web.entity.SupplierOpeningResult;
import com.gx.obe.web.entity.auth.AuthUser;
import com.gx.obe.web.entity.expert.Expert;
import com.gx.obe.web.entity.tender.TenderProjectEntity;
import com.gx.obe.web.entity.tender.TenderProjectRuleEntity;
import com.gx.obe.web.service.ChainService;
import com.gx.obe.web.service.ProjectRuleService;
import com.gx.obe.web.service.SupplierEvaluationResultService;
import com.gx.obe.web.service.SupplierOpeningResultService;
import com.gx.obe.web.service.SupplierService;
import com.gx.obe.web.service.TenderProjectService;
import com.gx.obe.web.service.UserService;
import com.gx.obe.web.service.expert.ExpertService;
import com.gx.utils.ActionLogUtils;

import hyperledger.FosunBlockChain;

/**
 * @Description: 评标结果登记
 * @author wangxaing
 */
public class RegisterEvaluationResultThread extends MyRunnable {
	
	private CallBack callBack;
	private ExpertService expertService;
	private SupplierService supplierService = new SupplierService();
	private TenderProjectService tenderProjectService ;
	private Logger LOG = Logger.getLogger(RegisterEvaluationResultThread.class);
	private TenderProjectEntity tenderProjectEntity;
	private TenderProjectEntity parentProject;
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
	private String blockChainUrl;
	private ProjectRuleService projectRuleService;
	private UserService userService;
	private TenderProjectRuleEntity projectRule;
	private SupplierOpeningResultService supplierOpeningResultService;
	private List<File> reportFileList;
	private Map<String, String> fileUrlMap;
	private Map<String, SupplierEvaluationResult> supplierEvaluationResultMap;
	private SupplierEvaluationResultService supplierEvaluationResultService;
	private ChainService chainService;
	
	public RegisterEvaluationResultThread(TenderProjectEntity tenderProject, List<File> reportFileList, Map<String, String> fileUrlMap, CallBack callBack) {
		this.fileUrlMap = fileUrlMap;
		this.callBack = callBack;
		this.reportFileList = reportFileList;
		this.tenderProjectEntity = tenderProject;
		this.callBack = callBack;
		expertService = new ExpertService();
		tenderProjectService = new TenderProjectService();
		projectRuleService = new ProjectRuleService();
		userService = new UserService();
		supplierOpeningResultService = new SupplierOpeningResultService();
		supplierEvaluationResultService = new SupplierEvaluationResultService();
		chainService = new ChainService();
	}
	
	public void run() {
		blockChainUrl = PropertiesUtils.getWebserviceProperty(WebserviceConstants.BLOCK_CHAIN_URL, "");
		boolean upLoadFlag = uploadGx();
		if (null != callBack && upLoadFlag) {
			callBack.callBack(true, "");
		} else {
			callBack.callBack(false, "上传失败！");
		}
	}
	
	private boolean uploadGx() {
		if(blockChainUrl.length() == 0){
			LOG.error("未获取到区块链地址！");
			return false;
		}
		
		String params = getParams().toJSONString();
		HttpUrl httpUrl = new HttpUrl(blockChainUrl);
		httpUrl.setRequestProperty("Content-Type" , "application/json");
		httpUrl.setRequestProperty("connection" , "keep-alive");
		HttpResponse httpResponse = HttpUtils.doPost(httpUrl, params);
		boolean uploadFlag = resolveXml(tenderProjectEntity, httpResponse);
		ActionLogUtils.addServerLog(tenderProjectEntity.getId(),"上传区块链" + uploadFlag, blockChainUrl);
		if(!uploadFlag){
			LOG.error("上传区块链失败，：" + httpUrl.getUrl() + "\r\n参数：" + params + "\r\n返回："+httpResponse.getContent());
		}
		return uploadFlag;
	}
	
	/**
	 * @param b 
	 * @Description: 评标结果登记Json字符串
	 * @return
	 */
	private String getJsonObject() {
		projectRule = projectRuleService.getProjectRule(tenderProjectEntity.getId());
		JSONObject jsonMap = new JSONObject();
		jsonMap.put("funcName", "FB805");
		jsonMap.put("platCode", "platCode");//平台ID
		jsonMap.put("toolCode", "toolCode");//工具ID
		if (StringUtils.isNotEmpty(tenderProjectEntity.getParentId())) {
			parentProject = (TenderProjectEntity) tenderProjectService.getById(tenderProjectEntity.getParentId());
			jsonMap.put("tenderProjectCode", parentProject.getTenderNo());
			jsonMap.put("tenderProjectName", parentProject.getTenderName());
			jsonMap.put("bidSectionCode", tenderProjectEntity.getTenderNo());
			jsonMap.put("bidSectionName", tenderProjectEntity.getTenderName());
		} else {
			jsonMap.put("tenderProjectCode", tenderProjectEntity.getTenderNo());
			jsonMap.put("tenderProjectName", tenderProjectEntity.getTenderName());
			jsonMap.put("bidSectionCode", tenderProjectEntity.getTenderNo());
			jsonMap.put("bidSectionName", tenderProjectEntity.getTenderNo());
		}
		jsonMap.put("tenderCode", "tenderCode");
		jsonMap.put("projectType", tenderProjectEntity.getTenderType());
		jsonMap.put("qualType", projectRule.getEvalMethodType());
		jsonMap.put("tenderCodeType", "tenderCodeType");//机构ID
		jsonMap.put("tendererCode", "tendererCode");
		jsonMap.put("tenderMode", "tenderMode");
		jsonMap.put("tendererName", (null != tenderProjectEntity.getPurchaserName()&&!("".equals(tenderProjectEntity.getPurchaserName().trim()))) ? tenderProjectEntity.getPurchaserName() :"tendererName");
		jsonMap.put("tenderAgencyCodeType", "tenderAgencyCodeType");
		jsonMap.put("tenderAgencyCode", "tenderAgencyCode");
		jsonMap.put("tendererAgencyName", (null != tenderProjectEntity.getAgentName()&&!("".equals(tenderProjectEntity.getAgentName().trim())) )? tenderProjectEntity.getAgentName() : "tendererAgencyName");
		jsonMap.put("projectLeaderName", tenderProjectEntity.getManagerName());
		String userId = tenderProjectEntity.getUserId();
		AuthUser user = userService.findById(userId);
		jsonMap.put("projectLeaderCode", null != user.getUserIdcard() ? user.getUserIdcard() : "projectLeaderCode");
		jsonMap.put("bidOpeningTime", projectRule.getBidOpeningStartTime()+"");
		jsonMap.put("bidEvaluationTime", null != projectRule.getBidEvaluationStartTime() ? projectRule.getBidEvaluationStartTime() : "bidEvaluationTime");
		jsonMap.put("upperChainTime",  sdf.format(new Date()));
		
		JSONArray bidderInfo = setBidderInfoList();
		jsonMap.put("bidderInfoData", bidderInfo);
		
		JSONArray expertInfo = setExpertInfoList();
		jsonMap.put("expertInfoData", expertInfo);
		
		JSONArray attachmentInfo = setAttachmentInfoList();
		jsonMap.put("attachmentInfoData", attachmentInfo);
		
		
		return jsonMap.toJSONString();
	}
	
	/**
	 * @Description: 拼接供应商数据
	 * @param bidderInfoList
	 */
	private JSONArray setBidderInfoList() {
		List<Supplier> supplierList = supplierService.getAllSupplierList(tenderProjectEntity.getId());
		JSONArray bidderInfoDataArray = new JSONArray();
		if (null != supplierList && supplierList.size() > 0) {
			for (Supplier supplier : supplierList) {
				JSONObject bidderInfoMap = new JSONObject();
				bidderInfoMap.put("bidCodeType", "bidCodeType1");
				bidderInfoMap.put("bidCode", null != supplier.getOrgCode() ? supplier.getOrgCode() : "");
				bidderInfoMap.put("bidName", null != supplier.getSupplierName() ? supplier.getSupplierName() : "");
				SupplierOpeningResult supplierOpeningResult = supplierOpeningResultService.getSupplierOpeningResult(tenderProjectEntity.getId(), supplier.getId());
				bidderInfoMap.put("bidQuote",null != supplierOpeningResult ?  supplierOpeningResult.getBidPrice()+"" : "");
				bidderInfoMap.put("decryptionTime", null != supplierOpeningResult ?  supplierOpeningResult.getBidOpeningTime() +"": "");
//				bidderInfoMap.put("bidQuote", "");
//				bidderInfoMap.put("decryptionTime", "");
//				bidderInfoMap.put("bidFinalRanking",  "");
				SupplierEvaluationResult supplierEvalResult = getSupplierEvaluationResult(supplier.getId());
				bidderInfoMap.put("bidFinalScore", null != supplierEvalResult && null != supplierEvalResult.getEvaluationFinalScore() ? supplierEvalResult.getEvaluationFinalScore() : "");
				bidderInfoMap.put("bidFinalRanking", null != supplierEvalResult ? supplierEvalResult.getSortNo()+"" : "");
				bidderInfoMap.put("winCandidate", null != supplierEvalResult && null != supplierEvalResult.getRecommend() ? supplierEvalResult.getRecommend(): "");
				bidderInfoDataArray.add(bidderInfoMap);
			}
		}
		return bidderInfoDataArray;
	}
	
	/**
	 * @Description: 拼接专家数据
	 * @param bidderInfoList
	 */
	private JSONArray setExpertInfoList() {
		List<Expert> expertList = expertService.getExpertList(tenderProjectEntity.getId(), null);
		JSONArray expertInfoDataArray = new JSONArray();
		if (null != expertList && expertList.size() > 0) {
			for (Expert expert : expertList) {
				JSONObject expertInfoMap = new JSONObject();
				expertInfoMap.put("expertName", expert.getUser().getUserName());
				expertInfoMap.put("expertCode", expert.getUser().getUserIdcard());
				expertInfoMap.put("expertSignTime", sdf.format(null != expert.getSignTime()? expert.getSignTime() : new Date()));
				expertInfoDataArray.add(expertInfoMap);
			}
		}
		return expertInfoDataArray;
	}
	
	/**
	 * @Description:附件信息数组
	 * @param attachmentInfoList
	 */
	private JSONArray setAttachmentInfoList() {
		File zipFolder = new File(FileConstants.TEMP_PATH+tenderProjectEntity.getId());
		String uploadFilePath =zipFolder.getAbsolutePath()+File.separator + "upload" + File.separator;
		
		List<File> fileList = new ArrayList<File>();
		fileList.addAll(reportFileList);
		getFiles(uploadFilePath,fileList);
		
		JSONArray attachmentInfoDataArray = new JSONArray();
		if (fileList.size() > 0) {
			for (File file : fileList) {
				JSONObject attachmentInfoMap = new JSONObject();
				String fileId =  UuidUtils.getUUID();
				attachmentInfoMap.put("attachmentCode", fileId);
				attachmentInfoMap.put("fileList", "fileList");
//				attachmentInfoMap.put("attachmentFileName", fileId + "***" +file.getName());
				attachmentInfoMap.put("attachmentFileName", file.getName());
				attachmentInfoMap.put("fileType", "fileType");
				attachmentInfoMap.put("dataTimestamp", sdf.format(new Date()));
				String urlPath = fileUrlMap.get(file.getName());
				attachmentInfoMap.put("urlPath", urlPath);
				
				String Md5 = null;
				try {
					Md5 = FosunBlockChain.FB902(file,blockChainUrl);
					
					JSONObject root = JSONObject.parseObject(Md5);
					String msg = (String)root.get("msg");	
					JSONObject msgRoot = JSONObject.parseObject(msg);
					Md5 = (String)msgRoot.get("md5");
					
//					String fb902Str = new String("FB902 : ");
//					int md5Start = Md5.indexOf(fb902Str);
//					Md5 = Md5.substring(md5Start + fb902Str.length());
				} catch (NoSuchAlgorithmException e) {
				} catch (IOException e) {
				} catch (CloneNotSupportedException e) {
				} catch (Exception e) {
				}
				attachmentInfoMap.put("md5", Md5);
				attachmentInfoDataArray.add(attachmentInfoMap);
			}
		}
		return attachmentInfoDataArray;
	}
	
	/**
	 * @param sign 
	 * @Description: 评标结果登记Json字符串
	 * @return
	 */
	private JSONObject getParams() {
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("code", "F103");
		String jsonStr = getJsonObject();
		jsonObject.put("param", jsonStr);
		String sign = null;
		try {
			sign = FosunBlockChain.FB901(jsonObject.get("code").toString(), jsonStr);
			LOG.error("生成的签名为"+ sign);
		} catch (NoSuchAlgorithmException e) {
			LOG.error("结构化数据签名错误"+ jsonStr , e);
		} catch (IOException e) {
			e.printStackTrace();
		} 
		jsonObject.put("sign", sign);
		
		return jsonObject;
	}
	
	/**
	 * @Description 获得供应商评标结果
	 * @param directoryPath
	 * @return
	 */
	private void getFiles(String directoryPath, List<File> fileList) {
		File file = new File(directoryPath);
		if (file.isDirectory()) {
			File[] files = file.listFiles();
			for (File fileIndex : files) {
				//如果这个文件是目录，则进行递归搜索
				if (fileIndex.isDirectory()) {
//					getFiles(fileIndex.getPath(), fileList);
				} else {
					//如果文件是普通文件，则将文件句柄放入集合中
					fileList.add(fileIndex);
				}
			}
		}
	}
	
	/**
	 * @Description 获得供应商评标结果
	 * @param supplierId
	 * @return
	 */
	public SupplierEvaluationResult getSupplierEvaluationResult(String supplierId){
		if(null == supplierEvaluationResultMap){
			List<SupplierEvaluationResult> supplierEvaluationResultList = supplierEvaluationResultService.getSupplierEvaluationResultListByTenderId(tenderProjectEntity.getId());
			if(null != supplierEvaluationResultList && supplierEvaluationResultList.size() > 0){
				supplierEvaluationResultMap = new HashMap<String, SupplierEvaluationResult>();
				for(SupplierEvaluationResult supplierEvaluationResult : supplierEvaluationResultList){
					supplierEvaluationResultMap.put(supplierEvaluationResult.getSupplierId(), supplierEvaluationResult);
				}
			}else {
				supplierEvaluationResultMap = null;
			}
			
		}
		if(null != supplierEvaluationResultMap){
			return supplierEvaluationResultMap.get(supplierId);
		}
		return null;
	}
	
	
	/**
	 * @Description: 是否成功判断
	 * @param tenderProject2
	 * @param sendPost
	 * @return
	 */
	private boolean resolveXml(TenderProjectEntity tenderProject2, HttpResponse httpResponse) {
		if(!httpResponse.getStatus()){
			return false;
		}
		//
		
		/**
		 * {"result":true,"msg":"{\"TxHash\":\"0x9a707ececbbac4c462787821a77a7e0b732bbf22d4e784e1660640ae8942f0e6\",\"bidEvaluationId\":\"257729A72EE3E60DE5F71F9E7F4A40A3\",\"returnCode\":\"S0000\",\"returnMessage\":\"S0000, FB805 is Success!\"}"}
		 * TxHash:区块中的一笔交易hash
		 * **/
		try {
			boolean resultObject = ObjectUtils.getObjBoolean(httpResponse.getParam("result"));
			if(resultObject){
				String msg = (String)httpResponse.getParam("msg");
				JSONObject msgRoot = JSONObject.parseObject(msg);
				String txHash = (String)msgRoot.get("TxHash");
				tenderProjectEntity.setEvaluationResultBlockchainAddress(txHash);
				
				Chain chain = chainService.getChainByTenderIdAndType(tenderProjectEntity.getId(),"evaluationResultRegister");
				if(null == chain){
					chain =  new Chain();
					chain.setId(UuidUtils.getUUID());
					chain.setTenderId(tenderProjectEntity.getId());
					chain.setTxHashAddress(txHash);
					chain.setChainType("evaluationResultRegister");
					chainService.insert(chain);
				}else{
					chain.setTxHashAddress(txHash);
					chain.setChainType("evaluationResultRegister");
					chainService.updateAssignProperty(chain, new String[]{"txHashAddress","fileUrlMap"});
				}
				tenderProjectEntity.setEvaluationParam("fileUrlMap", fileUrlMap);
				
//				JSONArray bidEvaluationIdArray = msgRoot.getJSONArray("bidEvaluationId");
//				for(int i = 0; i < bidEvaluationIdArray.size(); i++){
//					JSONObject jo = bidEvaluationIdArray.getJSONObject(i);
//					Map<String, Object> bidEvaluationIdMap = jo.getInnerMap();
//					tenderProject.setEvaluationParam("bidEvaluationIdMap", bidEvaluationIdMap);
//				}
				
				return resultObject;
			}else{
				LOG.error("上传公信链失败："+httpResponse.getContent());
				return false;
			}
		} catch (Exception e) {
		}
		return false;
	}
}
