package com.gx.obe.evaluation.step.thread;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.zip.ZipException;

import org.apache.log4j.Logger;

import com.gx.obe.WebserviceConstants;
import com.gx.obe.business.entity.BidPriceRound;
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.download.infer.FileDownloadListener.DOWN_STATUS;
import com.gx.obe.common.file.enumeration.FileConstants;
import com.gx.obe.common.file.http.HttpURLDownload;
import com.gx.obe.common.file.utils.ZipUtils;
import com.gx.obe.common.widget.thread.MyRunnable;
import com.gx.obe.components.core.I18NEnum;
import com.gx.obe.components.core.enumeration.BidPriceEnum;
import com.gx.obe.config.utils.PropertiesUtils;
import com.gx.obe.evaluation.step.listener.RemoteMultyRoundBidPriceListener;
import com.gx.obe.message.Messages;
import com.gx.obe.util.utils.ModelMapper;
import com.gx.obe.util.utils.StringUtils;
import com.gx.obe.util.utils.UuidUtils;
import com.gx.obe.web.entity.Supplier;
import com.gx.obe.web.entity.TransactionServer;
import com.gx.obe.web.entity.price.BidPrice;
import com.gx.obe.web.entity.price.BidPriceHisResult;
import com.gx.obe.web.entity.price.BidPriceResult;
import com.gx.obe.web.entity.tender.TenderProjectEntity;
import com.gx.obe.web.service.BidPriceHisResultService;
import com.gx.obe.web.service.BidPriceRoundStatusService;
import com.gx.obe.web.service.BidPriceService;
import com.gx.obe.web.service.ReBidPriceRoundService;
import com.gx.tools.utils.BidPriceUtils;
import com.gx.utils.ActionLogUtils;
import com.gx.utils.NowTimeUtils;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
 * @Description: 下载最新的再次报价
 * @author wangxaing
 */
public class RefreshRemoteSupplierMultyBidPriceResutlThread extends MyRunnable {

	private BidPriceHisResultService bidPriceHisResultService;
	private BidPriceService bidPriceService;
	private ReBidPriceRoundService reBidPriceRoundService;
//	private BidPriceResultService bidPriceResultService ;
	private Logger LOG = Logger.getLogger(RefreshRemoteSupplierMultyBidPriceResutlThread.class);
	private TenderProjectEntity tenderProjectEntity;
	private Map<String, BidPrice> bidPriceNameMap;
	private Map<String, BidPrice> bidPriceIdMap;
	private List<BidPrice> priceList;
	private String serverId;
	private List<Supplier> supplierList;
	private Map<String, Supplier> complateSupplierIdMap;
	private RemoteMultyRoundBidPriceListener istener;
	private List<BidPrice> bidPriceTable;
	private boolean download;
	private boolean loop;
	private BidPriceRoundStatusService bidPriceRoundStatusService;
	private  BidPriceRound bidPriceRound;

	public RefreshRemoteSupplierMultyBidPriceResutlThread(TenderProjectEntity tenderProjectEntity, List<Supplier> supplierList, boolean download, boolean loop, BidPriceRound bidPriceRound,RemoteMultyRoundBidPriceListener istener) {
		this.tenderProjectEntity = tenderProjectEntity;
		this.supplierList = supplierList;
		this.istener = istener;
		this.bidPriceRound = bidPriceRound;
		this.download = download;
		this.loop = loop;
	}

	public void run() {
		this.serverId = tenderProjectEntity.getTransactionServerId();
		bidPriceService = new BidPriceService();
		bidPriceHisResultService = new BidPriceHisResultService();
		bidPriceRoundStatusService = new BidPriceRoundStatusService();
		complateSupplierIdMap = new HashMap<String, Supplier>();
		String packCode = tenderProjectEntity.getTenderNo();
		String SUPPLIER_NAME = com.gx.obe.components.core.I18N.getString(I18NEnum.SUPPLIERNAME, tenderProjectEntity.getTenderType());
		TransactionServer transactionServer = HttpUtils.getTransactionServer(serverId);
		HttpUrl httpUrl = HttpUtils.getProjectHttpUrl(tenderProjectEntity, transactionServer, PropertiesUtils.getWebserviceProperty(WebserviceConstants.GETREBIDPRICE, "secondBidPriceHS.do?getLastSecondBidPriceList"));
		if(null != httpUrl){
			if(null == tenderProjectEntity.getParentId()){
				httpUrl.setAttribute("packCode", packCode);
			}
			httpUrl.setAttribute("accessToken", "");
		}
		istener.showMessage(MessageFormat.format(Messages.Tips_gettingRemoteBidPrice, SUPPLIER_NAME));
		String getWebserviceXml = "";
		long startTime = Calendar.getInstance().getTimeInMillis();
		int preComplateCount = 0;
		long useTime = -1;
		boolean finalStatues = false;
		while(null != thread){
			startTime = Calendar.getInstance().getTimeInMillis();
			final Map<String,String> resultMap = bidPriceRoundStatusService.getSupplierBidPriceRoundStatus(bidPriceRound.getId());
			complateSupplierIdMap.clear();
			int complateCount = 0;
			for(Supplier supplier : supplierList){
				if(resultMap.containsKey(supplier.getId())){
					if(null != resultMap.get(supplier.getId()) && BidPriceEnum.PRICE_STATUS_OK.equals(resultMap.get(supplier.getId()))){
						// 已完成报价的供应商记录
						complateCount ++;
						istener.refresh(supplier.getId(), true, complateCount);
					}else {
						complateSupplierIdMap.put(supplier.getOrgCode(), supplier);
						istener.refresh(supplier.getId(), false, complateCount);
					}
				}else {
					complateSupplierIdMap.put(supplier.getOrgCode(), supplier);
				}
			}
 			if(complateSupplierIdMap.isEmpty()){
				istener.showMessage(MessageFormat.format(Messages.Tips_allComplateQuotedBidPrice, SUPPLIER_NAME));
				stop();
				istener.complate();
				break;
			}
			if(preComplateCount != complateCount){
				preComplateCount = complateCount;
				istener.showMessage(MessageFormat.format(Messages.Tips_notComplateQuotedBidPrice, supplierList.size() - complateCount, SUPPLIER_NAME));
			}
			if(!download){
				stop();
				break;
			}
			if(null != httpUrl){
				httpUrl.setName("获取多轮报价");
				HttpResponse httpResponse = HttpUtils.doPost(httpUrl);
				finalStatues = !resolveXml(httpResponse);
			}else {
				LOG.error("该项目为本地项目");
//				stop();
//				break;
			}
			
			if(!loop){
				stop();
				break;
			}
			
			useTime = Calendar.getInstance().getTimeInMillis() - startTime;
			// 每隔10秒刷新
			if(useTime > 10000){
				// 此次刷新时间超过10秒
			}else if(useTime > 0) {
				try {
					Thread.sleep(10000 - useTime);
				} catch (InterruptedException e) {
				}
			}
		}
		
		if(finalStatues) {
			LOG.error("获得再次报价接口"+httpUrl.getUrl() +httpUrl.getAttributs()+"/t返回的xml结果为："+getWebserviceXml);
			ActionLogUtils.addServerLog(tenderProjectEntity.getId(), "获得多轮报价失败", httpUrl, false);
		}
	}

	private boolean resolveXml(HttpResponse httpResponse){
		if(!httpResponse.getStatus()){
			LOG.error("服务器无响应内容!");
			return false;
		}
		if (thread == null) {
			return false;
		}
		if(null == reBidPriceRoundService){
			reBidPriceRoundService = new ReBidPriceRoundService();
		}
		int maxRound = reBidPriceRoundService.getMaxRound(tenderProjectEntity.getId());
		if(maxRound <= 1){
			return false;
		}
		String reBidPriceRoundFolder = FileConstants.getReBidPriceFilePath(tenderProjectEntity.getId()).concat(maxRound+"").concat(File.separator);
		
		try {
			JSONArray reBidPriceObject = httpResponse.getDataJSONArray("secondBidPriceList");
			Object[] supplierJsonList = reBidPriceObject.toArray();
			int supplierNum = 0;
			int downSupplierNum = 0;
			if(null != supplierJsonList && supplierJsonList.length > 0){
				supplierNum = supplierJsonList.length;
				for(Object _object : supplierJsonList){
					if (thread == null) {
						continue;
					}
					JSONObject supplierJson = (JSONObject) _object;
					String orgCode =  (String) supplierJson.get("offerOrgCode");
					if(StringUtils.isEmpty(orgCode)){
						LOG.error("机构编码为空"+supplierJson.toString());
						continue;
					}
					Supplier supplier = null;
					if(complateSupplierIdMap.containsKey(orgCode)){
						supplier = complateSupplierIdMap.get(orgCode);
					}
					if(null == supplier){
						LOG.error("机构编码为"+orgCode +"的供应商已经完成报价或者不需要报价");
						continue;
					}
					List<BidPriceResult> bidPriceResultList = null;
					JSONArray fileList = (JSONArray) supplierJson.get("secondBidPriceAttFiles");
					Object[] fileJsonList = fileList.toArray();
					if(fileJsonList.length == 1){
						JSONObject fileJson = (JSONObject) fileJsonList[0];
						String downUrl =   (String)fileJson.get("downloadUrl");
						String fileName =  (String) fileJson.get("fileName");
						long bidFileSize = 0;
						if (null != fileJson.get("fileSize") && !"".equals(fileJson.get("fileSize"))) {
							try {
								bidFileSize = (Long) Long.parseLong((String) fileJson.get("fileSize"));
							} catch (Exception e) {
							}
						}
						File downFile = new File(reBidPriceRoundFolder.concat(orgCode).concat(File.separator).concat(fileName));
						if(downFile.exists()){
							downFile.delete();
						}
						if(downloadFile(downUrl, bidFileSize, downFile.getAbsolutePath())){
							istener.showMessage(MessageFormat.format(Messages.Tips_getSupplerBidPriceFileAndParsing, supplier.getSupplierName()));
							// 下载成功后解压文件
							boolean downFlag = unZipFile(downFile.getAbsolutePath(), downFile.getParent());
							//如果解压成功  解析
							if(downFlag){
								if(downFile.delete()){
									downFile.deleteOnExit();
								}
								String bidPriceXmlpath = reBidPriceRoundFolder.concat(orgCode).concat(File.separator).concat(FileConstants.BID_PRICE_XML);
								bidPriceResultList = BidPriceUtils.getSupplierBidPriceResultTable(tenderProjectEntity.getId(), supplier.getId(), bidPriceXmlpath);
								if(null == bidPriceResultList || bidPriceResultList.size() == 0){
									LOG.error(supplier.getSupplierName() + "解析供应商报价文件失败" + bidPriceXmlpath);
									istener.showMessage(MessageFormat.format(Messages.Tips_getSupplerBidPriceFailed, supplier.getSupplierName()));
									continue;
								}
								getBidPriceTable();
								
								int priceIndex = 0;
								for(int i = 0; i < bidPriceResultList.size(); i++){
									BidPriceResult bidPriceResult = bidPriceResultList.get(i);
									boolean isPriceItem = BidPriceEnum.IS_PRICE_ITEM.equals(bidPriceResult.getBidPriceType());
									
									BidPrice bidPrice = bidPriceIdMap.get(bidPriceResult.getBidPriceId());
									if(StringUtils.hasLength(bidPriceResult.getBidPriceName())){
										bidPrice = bidPriceNameMap.get(bidPriceResult.getBidPriceName().trim());
									}
									if(isPriceItem){
										// 如果根据报价的名称取不到开标一览表报价项，则直接按报价项的顺序获取
										if(null == bidPrice && priceList.size() > priceIndex){
											bidPrice = priceList.get(priceIndex);
											LOG.error(tenderProjectEntity.getTenderName() + "未按报价项名称获取到开标一览表结构:" + bidPrice.getBidPriceName() +"\t取第"+priceIndex+"个报价项");
											
										}
										priceIndex ++;
									}else {
										// 如果根据报价的名称取不到开标一览表非报价项，则直接按开标一览表的顺序获取
										if(null == bidPrice && null != bidPriceTable && bidPriceResultList.size() == bidPriceTable.size() && i < bidPriceTable.size()){
											bidPrice = bidPriceTable.get(i);
											LOG.error(tenderProjectEntity.getTenderName() + "未按非报价项名称获取到开标一览表结构:" + bidPrice.getBidPriceName() +"\t取第"+i+"个开标一览表项");
											if(BidPriceEnum.IS_PRICE_ITEM.equals(bidPrice.getBidPriceType())){
												// 如果非报价项根据顺序取到的正好是报价项，则不能使用
												bidPrice = null;
												LOG.error(tenderProjectEntity.getTenderName() + "开标一览表结构与投标人开标一览表结构不一致！");
												
											}
										}
									}
									if(null != bidPrice){
										bidPriceResult.setBidPriceId(bidPrice.getId());
										if(StringUtils.isEmpty(bidPriceResult.getJoinTotal())){
											bidPriceResult.setJoinTotal(bidPrice.getJoinTotal());
										}
										if(StringUtils.isEmpty(bidPriceResult.getBidPriceType())){
											bidPriceResult.setBidPriceType(bidPrice.getBidPriceType());
										}
										if(StringUtils.isEmpty(bidPriceResult.getBidPriceCode())){
											bidPriceResult.setBidPriceCode(bidPrice.getBidPriceCode());
										}
										if(StringUtils.isEmpty(bidPriceResult.getPriceType())){
											bidPriceResult.setPriceType(bidPrice.getPriceType());
										}
										bidPriceResult.setId(UuidUtils.getUUID());
									}else {
										LOG.error(supplier.getSupplierName() + bidPriceResult.getBidPriceName() + "不在报价结构范围内！" + downFile.getAbsolutePath());
									}
								}
							}else {
								LOG.error(supplier.getSupplierName() + "供应商报价文件下载后解析失败！" + downFile.getAbsolutePath());
							}
							downSupplierNum++;
						}else {
							LOG.error(supplier.getSupplierName() + "供应商报价文件下载失败！"+ downFile.getAbsolutePath());
						}
					
						if (null != thread) {
//							if(null != bidPriceResultList && bidPriceResultService.saveSupplierReBidPriceResult(tenderProjectEntity.getId(), supplier.getId(), bidPriceResultList,bidPriceRound.getId())){
							if(null != bidPriceResultList){	
								List<BidPriceHisResult> bidPriceHisResult = bidPriceResultList.stream().map(t -> ModelMapper.map(t, BidPriceHisResult.class, null)).collect(Collectors.toList());
								bidPriceHisResult.stream().forEach(item-> {
									item.setRoundName(bidPriceRound.getRoundName());
									item.setBidPriceRound(bidPriceRound.getRoundNo());
									item.setCreateTime(NowTimeUtils.getNowDate());
								});
								boolean isSvae = bidPriceHisResultService.saveSupplierReBidPriceHisResult(tenderProjectEntity.getId(), supplier.getId(), bidPriceHisResult,bidPriceRound.getId(), downUrl, fileName);
								if(!isSvae) {
									istener.showMessage(MessageFormat.format(Messages.Tips_getSupplerBidPriceFailed, supplier.getSupplierName()));
									LOG.error(supplier.getSupplierName() +"报价获取失败！");
								}
								LOG.debug(supplier.getSupplierName() +"已完成报价！");
								istener.showMessage(MessageFormat.format(Messages.Tips_getSupplerBidPriceSuccess, supplier.getSupplierName()));
							}else {
								istener.showMessage(MessageFormat.format(Messages.Tips_getSupplerBidPriceFailed, supplier.getSupplierName()));
								LOG.error(supplier.getSupplierName() +"报价获取失败！");
							}
						}
					}
				}
			}else {
				LOG.error("获取多轮报价列表为空：" + httpResponse.getContent());
			}
			
			if(supplierNum == downSupplierNum){
				return true;
			}else{
//				LOG.error("获得再次报价接口服务器返回内容："+xmlStr);
				return false;
			}
		} catch (Exception e) {
			LOG.error("获取多轮报价" + httpResponse.getContent(), e);
		}
		return false;
	}
	
	private void getBidPriceTable(){
		if(null != bidPriceNameMap)return;
		bidPriceTable = bidPriceService.getTenderBidPriceTableList(tenderProjectEntity.getId());
		bidPriceNameMap = new HashMap<String, BidPrice>();
		bidPriceIdMap = new HashMap<String, BidPrice>();
		priceList = new ArrayList<BidPrice>();
		if(null != bidPriceTable){
			for(BidPrice bidPrice : bidPriceTable){
				if(StringUtils.isNotEmpty(bidPrice.getBidPriceName())){
					if(bidPriceNameMap.containsKey(bidPrice.getBidPriceName().trim())){
						LOG.error(tenderProjectEntity.getTenderName() + "\t存在相同的开标一览表名称:" + bidPrice.getBidPriceName());
					}
					bidPriceNameMap.put(bidPrice.getBidPriceName().trim(), bidPrice);
					bidPriceIdMap.put(bidPrice.getId(), bidPrice);
				}
				if(BidPriceEnum.IS_PRICE_ITEM.equals(bidPrice.getBidPriceType())){
					priceList.add(bidPrice);
				}
			}
		}
	}
	/**
	 * @Description: 下载文件
	 * @author wangxiang
	 * @param urlPath
	 * @param downloadDir
	 * @return
	 */
	private boolean downloadFile(String urlPath, long fileSize, String saveFile) {
		HttpURLDownload download = new HttpURLDownload(urlPath, fileSize, saveFile, null) {
			public DOWN_STATUS downloadStatus() {
				return thread == null ? DOWN_STATUS.CANCEL : null;
			}
		};
		download.setMessageStartName(" - 再次报价文件");
		return download.downLoad();
	}
	
	/**
	 * @Description: 解压投标文件
	 * @author guoyr
	 * @param archive
	 * @param decompressDir
	 * @return
	 */
	private boolean unZipFile(String archive, String decompressDir){
		boolean unZipFlag = false;
		unZipFlag = ZipUtils.unZip(archive, decompressDir, true, true, true, null);
		return unZipFlag;
	}
}
