package com.prolog.cs.biz.inbound.service.impl;

import com.prolog.cs.basic.chain.model.customer.vo.BaseCustomerMstRealatedVO;
import com.prolog.cs.basic.chain.service.supplier.vo.BaseSupplierMstRealatedVO;
import com.prolog.cs.biz.inbound.dao.SupervisionCodeMapper;
import com.prolog.cs.biz.inbound.model.SupervisionCode;
import com.prolog.cs.biz.inbound.remote.ChainRemoteCaller;
import com.prolog.cs.biz.inbound.xml.*;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.BizException;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.core.restriction.FieldSelector;
import com.prolog.framework.core.restriction.Restriction;
import com.prolog.framework.core.restriction.Restrictions;
import com.prolog.framework.utils.DateUtils;
import com.prolog.framework.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class SupervisionCodeXmlHandler {

	private static Logger log = LoggerFactory.getLogger(SupervisionCodeXmlHandler.class);

	@Resource
	private SupervisionCodeMapper mapper;

	@Resource
	private ChainRemoteCaller chainRemoteCaller;

	public String spellXml(Integer supervisionType, List<SupervisionCode> voList,Map<String, Map<String, String>> elecCodeMap) throws Exception {
		List<Data> dataList = new ArrayList();
		for (int i = 0; i < voList.size(); i++) {
			Data data = new Data();
			SupervisionCode supervisionCode = voList.get(i);
			data.setActor(supervisionCode.getScanName());
			data.setActDate(DateUtils.format(supervisionCode.getScanDate(), "yyyy-MM-dd HH:mm:ss"));
			if(dataList.stream().filter(t->t.getCode().equals(supervisionCode.getSupervisionCode())).count()>0L){
				continue;
			}
			data.setCode(supervisionCode.getSupervisionCode());
			data.setCorpOrderID(supervisionCode.getSrcCode());
			String shipperId = supervisionCode.getShipperId();
			/*if (!com.prolog.framework.utils.StringUtils.isBlank(shipperId)) {
				if (elecCodeMap.get(shipperId) != null && elecCodeMap.get(shipperId).get("elecCode") != null) {
					data.setToCorpID(elecCodeMap.get(shipperId).get("elecCode"));
				} else {
					data.setToCorpID(elecCodeMap.get(shipperId)==null?"":elecCodeMap.get(shipperId).get("code"));
				}
			}*/
			if (!com.prolog.framework.utils.StringUtils.isBlank(shipperId)) {
				if (elecCodeMap.get(shipperId) != null && elecCodeMap.get(shipperId).get("elecCode") != null) {
					data.setToCorpID(elecCodeMap.get(shipperId).get("elecCode"));
				} else {
					RestMessage<BaseCustomerMstRealatedVO> customerResult = chainRemoteCaller.findCustomerWithAttr(shipperId);
					if (customerResult.isSuccess() && customerResult.getData() != null) {
						BaseCustomerMstRealatedVO customerResultData = customerResult.getData();
						if (customerResultData != null && customerResultData.getHealth() != null &&
								!StringUtils.isEmpty(customerResultData.getHealth().getElecCode())) {
							data.setToCorpID(customerResultData.getHealth().getElecCode());
							Map<String, String> elecCode = new HashMap<>();
							elecCode.put("elecCode",customerResultData.getHealth().getElecCode());
							elecCodeMap.put(shipperId, elecCode);
						} else {
							data.setToCorpID(customerResultData.getMaster().getCustomerCode());
						}
					}
				}
			}
			String supplierId = supervisionCode.getSupplierId();
			/*if (!StringUtils.isBlank(supplierId)) {
				if (elecCodeMap.get(supplierId) != null && elecCodeMap.get(supplierId).get("elecCode") != null) {
					data.setToCorpID(elecCodeMap.get(supplierId).get("elecCode"));
				} else {
					data.setToCorpID(elecCodeMap.get(supplierId)==null?"":elecCodeMap.get(supplierId).get("code"));
				}
			}*/
			if (!com.prolog.framework.utils.StringUtils.isBlank(supplierId)) {
				if (elecCodeMap.get(supplierId) != null && elecCodeMap.get(supplierId).get("elecCode") != null) {
					data.setToCorpID(elecCodeMap.get(supplierId).get("elecCode"));
				} else {
					RestMessage<BaseSupplierMstRealatedVO> supplierResult = chainRemoteCaller.findSupplierWithAttr(supplierId);
					if (supplierResult.isSuccess() && supplierResult.getData() != null) {
						BaseSupplierMstRealatedVO supplierMstRealatedVO = supplierResult.getData();
						if (supplierMstRealatedVO != null && supplierMstRealatedVO.getHealth() != null &&
								!StringUtils.isEmpty(supplierMstRealatedVO.getHealth().getElecCode())) {
							data.setToCorpID(supplierMstRealatedVO.getHealth().getElecCode());
							Map<String, String> elecCode = new HashMap<>();
							elecCode.put("elecCode",supplierMstRealatedVO.getHealth().getElecCode());
							elecCodeMap.put(shipperId, elecCode);
						} else {
							data.setToCorpID(supplierMstRealatedVO.getMaster().getSupplierCode());
						}
					}
				}
			}
			//this.mapper.updateMapById(voList.get(i).getId(), MapUtils.put("status", 20).getMap(), SupervisionCode.class);
			dataList.add(data);
		}
		String beanToXml = beanToXml(spellDocument(supervisionType, dataList), Document.class);
		if (supervisionType == 0 || supervisionType == 1) {
			beanToXml = beanToXml.replaceAll("ToCorpID", "FromCorpID");
		}
		return beanToXml;
	}

	@Transactional
	public void batchUpdateBySrcCode(List<String> voList) {
		Criteria criteria = new Criteria(SupervisionCode.class);
		Restriction in = Restrictions.in("srcCode", voList.toArray(new String[voList.size()]));
		criteria.setRestriction(Restrictions.and(in));
		SupervisionCode supervisionCode=new SupervisionCode();
		supervisionCode.setStatus("20");
		this.mapper.updateFieldsByCriteria(supervisionCode, FieldSelector.newInstance().include("status"),criteria);
	}

	private Document spellDocument(Integer supervisionType,List<Data> dataList) {
		if(supervisionType==null){
			throw new BizException("监管码导出单据监管类型不能为空!");
		}
		DataField dataField=new DataField();
		dataField.setData(dataList);
		Event event=new Event();
		if(supervisionType==0 || supervisionType==1){//入库
			if(supervisionType==0){
				event.setName("PurchaseWareHouseIn");
			}else if(supervisionType==1){
				event.setName("ReturnWareHouseIn");
			}
			event.setMainAction("WareHouseIn");
		}else if(supervisionType==2 || supervisionType==3|| supervisionType==5|| supervisionType==6|| supervisionType==7|| supervisionType==8|| supervisionType==9){//出库
			if(supervisionType==2 || supervisionType==3|| supervisionType==5|| supervisionType==6){
				event.setName("SalesWareHouseOut");
			}else if(supervisionType==7|| supervisionType==8|| supervisionType==9){
				event.setName("ReturnWareHouseOut");
			}
			event.setMainAction("WareHouseOut");
		}
		event.setDataField(dataField);
		Events events=new Events();
		events.setEvent(event);
		Document document=new Document();
		document.setEvents(events);
		return document;
	}

	public static String beanToXml(Object obj, Class<?> load) throws JAXBException {
		JAXBContext context = JAXBContext.newInstance(load);
		Marshaller marshaller = context.createMarshaller();
		marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
		marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false);// 生成xml的默认报文头
//        marshaller.setProperty("com.sun.xml.bind.xmlHeaders", "<?xml version=\"1.0\" encoding=\"utf-8\"?>");
//      marshaller.setProperty(Marshaller.JAXB_ENCODING, "GBK");
		StringWriter writer = new StringWriter();
		marshaller.marshal(obj, writer);
		return writer.toString();
	}
}
