package com.prolog.rdc.tms.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.google.common.collect.Lists;
import com.prolog.common.util.ToolKits;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.ParameterException;
import com.prolog.rdc.tms.constant.InterfaceConstant;
import com.prolog.rdc.tms.dao.mapper.ErrorLogMapper;
import com.prolog.rdc.tms.dao.mapper.ShipbillDetailHtyMapper;
import com.prolog.rdc.tms.dao.mapper.ShipbillDetailMapper;
import com.prolog.rdc.tms.dao.mapper.ShipbillHeaderHtyMapper;
import com.prolog.rdc.tms.dao.mapper.ShipbillHeaderMapper;
import com.prolog.rdc.tms.model.dto.IntfErrorLogDTO;
import com.prolog.rdc.tms.model.entity.ErrorLogModel;
import com.prolog.rdc.tms.model.entity.ShipbillDetailHtyModel;
import com.prolog.rdc.tms.model.entity.ShipbillDetailModel;
import com.prolog.rdc.tms.model.entity.ShipbillHeaderHtyModel;
import com.prolog.rdc.tms.model.entity.ShipbillHeaderModel;
import com.prolog.rdc.tms.model.vo.BillDownloadVO;
import com.prolog.rdc.tms.model.vo.IntfShipbillDetailVO;
import com.prolog.rdc.tms.model.vo.IntfShipbillHeaderVO;
import com.prolog.rdc.tms.rmi.feign.BusinessComingRecordFeign;
import com.prolog.rdc.tms.service.ShipbillService;
import com.prolog.rdc.tms.util.HttpUtils;

import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 
 *
 * 运单接口实现层
 *
 * @className :ShipbillServiceImpl
 * @author :fanzw
 * @creationTime :2022/11/07
 * @description :
 *
 * @modifier :fanzw
 * @modifyTime :2022/11/07
 * @reviseRemarks:
 *
 * @version :1.0.0
 *
 */
@Slf4j
@Service
public class ShipbillServiceImpl implements ShipbillService {

	@Autowired
	private BusinessComingRecordFeign businessComingRecordFeign;

	@Autowired
	private ShipbillHeaderMapper shipbillHeaderMapper;

	@Autowired
	private ShipbillHeaderHtyMapper shipbillHeaderHtyMapper;

	@Autowired
	private ShipbillDetailMapper shipbillDetailMapper;

	@Autowired
	private ShipbillDetailHtyMapper shipbillDetailHtyMapper;

	@Autowired
	private ErrorLogMapper errorLogMapper;

	// 同步BMS运单接口URL
	private static String shipbillBmsUrl;

	@Value("${prolog.interface.shipbillBmsUrl}")
	private void setShipbillBmsUrl(String shipbillBmsUrl) {
		ShipbillServiceImpl.shipbillBmsUrl = shipbillBmsUrl;
	}

	/**
	 * 运单接口保存
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public String saveShipbillData(IntfShipbillHeaderVO intfShipbillHeaderVO) {
		ToolKits.isParamNull(intfShipbillHeaderVO, "请求参数不为空");

		Date date = DateUtil.date();

		// 校验非空项
		ToolKits.isParamNull(intfShipbillHeaderVO.getOrderId(), "订单ID不为空");
		ToolKits.isParamNull(intfShipbillHeaderVO.getOrderNo(), "订单编号不为空");
		ToolKits.isParamNull(intfShipbillHeaderVO.getOrderDate(), "订单日期不为空");
		ToolKits.isParamNull(intfShipbillHeaderVO.getCargoOwnerCode(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】货主编码不为空");
		ToolKits.isParamNull(intfShipbillHeaderVO.getCargoOwnerName(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】货主名称不为空");
		ToolKits.isParamNull(intfShipbillHeaderVO.getBranchCode(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】仓库编码不为空");
		ToolKits.isParamNull(intfShipbillHeaderVO.getBranchName(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】仓库名称不为空");
		ToolKits.isParamNull(intfShipbillHeaderVO.getCarriersCode(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】承运商编码不为空");
		ToolKits.isParamNull(intfShipbillHeaderVO.getCarriersName(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】承运商名称不为空");
		ToolKits.isParamNull(intfShipbillHeaderVO.getOrderType(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】订单类型不为空");
		ToolKits.isParamNull(intfShipbillHeaderVO.getOrderBusinessType(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】订业务单类型不为空");
		ToolKits.isParamNull(intfShipbillHeaderVO.getDeliveryMethodType(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】配送方式不为空");
		ToolKits.isParamNull(intfShipbillHeaderVO.getTransportType(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】运输类型不为空");

		ToolKits.isParamNull(intfShipbillHeaderVO.getShipperType(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】发货方类型不为空");
		ToolKits.isParamNull(intfShipbillHeaderVO.getShipperUnitCode(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】发货方单位编码不为空");
		ToolKits.isParamNull(intfShipbillHeaderVO.getShipperUnitName(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】发货方单位名称不为空");
		if (intfShipbillHeaderVO.getShipperType().intValue() != InterfaceConstant.SHIPPER_TYPE_KH.intValue() && intfShipbillHeaderVO.getShipperType().intValue() != InterfaceConstant.SHIPPER_TYPE_CK.intValue() && intfShipbillHeaderVO.getShipperType().intValue() != InterfaceConstant.SHIPPER_TYPE_GYS.intValue()) {
			throw new ParameterException("发货方类型错误(1客户 2仓库 3供应商)");
		}

		if (intfShipbillHeaderVO.getShipperType().intValue() != InterfaceConstant.SHIPPER_TYPE_CK.intValue()) {
			ToolKits.isParamNull(intfShipbillHeaderVO.getShipperCode(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】发货方编码不为空");
			ToolKits.isParamNull(intfShipbillHeaderVO.getShipperName(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】发货方名称不为空");
		}

		ToolKits.isParamNull(intfShipbillHeaderVO.getConsigneeType(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】收货方类型不为空");
		ToolKits.isParamNull(intfShipbillHeaderVO.getConsigneeUnitCode(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】收货方单位编码不为空");
		ToolKits.isParamNull(intfShipbillHeaderVO.getConsigneeUnitName(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】收货方单位名称不为空");
		if (intfShipbillHeaderVO.getConsigneeType().intValue() != InterfaceConstant.CONSIGNEE_TYPE_KH.intValue() && intfShipbillHeaderVO.getConsigneeType().intValue() != InterfaceConstant.CONSIGNEE_TYPE_CK.intValue() && intfShipbillHeaderVO.getConsigneeType().intValue() != InterfaceConstant.CONSIGNEE_TYPE_GYS.intValue()) {
			throw new ParameterException("收货方类型错误(1客户 2仓库 3供应商)");
		}

		if (intfShipbillHeaderVO.getConsigneeType().intValue() != InterfaceConstant.CONSIGNEE_TYPE_CK.intValue()) {
			ToolKits.isParamNull(intfShipbillHeaderVO.getConsigneeCode(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】收货方编码不为空");
			ToolKits.isParamNull(intfShipbillHeaderVO.getConsigneeName(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】收货方名称不为空");
		}

		ToolKits.isParamNull(intfShipbillHeaderVO.getDepartmentId(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】部门ID不为空");
		ToolKits.isParamNull(intfShipbillHeaderVO.getDepartmentCode(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】部门编码不为空");
		ToolKits.isParamNull(intfShipbillHeaderVO.getDepartmentName(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】部门名称不为空");
		ToolKits.isParamNull(intfShipbillHeaderVO.getEnterpriseId(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】企业ID不为空");
		ToolKits.isParamNull(intfShipbillHeaderVO.getEnterpriseName(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】企业名称不为空");

		ShipbillHeaderModel shipbillHeaderModel = new ShipbillHeaderModel();
		BeanUtils.copyProperties(intfShipbillHeaderVO, shipbillHeaderModel);
		shipbillHeaderModel.setShipbillId(ToolKits.getUUID());
		shipbillHeaderModel.setShipbillNo(shipbillHeaderModel.getShipbillId());
		shipbillHeaderModel.setTotalPcs(ToolKits.isEmpty(intfShipbillHeaderVO.getTotalPcs()) ? BigDecimal.ZERO : intfShipbillHeaderVO.getTotalPcs());
		shipbillHeaderModel.setTotalVolume(ToolKits.isEmpty(intfShipbillHeaderVO.getTotalVolume()) ? BigDecimal.ZERO : intfShipbillHeaderVO.getTotalVolume());
		shipbillHeaderModel.setTotalWeight(ToolKits.isEmpty(intfShipbillHeaderVO.getTotalWeight()) ? BigDecimal.ZERO : intfShipbillHeaderVO.getTotalWeight());
		shipbillHeaderModel.setSource(InterfaceConstant.SOURCE_INTERFACE);
		shipbillHeaderModel.setCreatetime(date);
		shipbillHeaderModel.setUpdatetime(date);

		int count = 1;
		List<IntfShipbillDetailVO> details = new ArrayList<IntfShipbillDetailVO>();
		List<ShipbillDetailModel> shipbillDetailModels = Lists.newArrayList();
		// 运单明细接口对象集合
		List<IntfShipbillDetailVO> intfShipbillDetailVOs = intfShipbillHeaderVO.getDetails();
		for (IntfShipbillDetailVO intfShipbillDetailVO : intfShipbillDetailVOs) {
			ToolKits.isParamNull(intfShipbillDetailVO.getItemCode(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】商品编码不为空");
			ToolKits.isParamNull(intfShipbillDetailVO.getPackType(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】商品【" + intfShipbillDetailVO.getItemCode() + "】包装类型不为空");
			ToolKits.isParamNull(intfShipbillDetailVO.getPcs(), "订单【" + intfShipbillHeaderVO.getOrderNo() + "】商品【" + intfShipbillDetailVO.getItemCode() + "】件数不为空");

			ShipbillDetailModel shipbillDetailModel = new ShipbillDetailModel();
			BeanUtils.copyProperties(intfShipbillDetailVO, shipbillDetailModel);
			shipbillDetailModel.setId(ToolKits.getUUID());
			shipbillDetailModel.setShipbillId(shipbillHeaderModel.getShipbillId());
			shipbillDetailModel.setShipbillNo(shipbillHeaderModel.getShipbillNo());
			shipbillDetailModel.setCargoOwnerCode(intfShipbillHeaderVO.getCargoOwnerCode());
			shipbillDetailModel.setCargoOwnerName(intfShipbillHeaderVO.getCargoOwnerName());
			shipbillDetailModel.setSeqno(count++);
			shipbillDetailModel.setWeight(ToolKits.isEmpty(intfShipbillDetailVO.getWeight()) ? BigDecimal.ZERO : intfShipbillDetailVO.getWeight());
			shipbillDetailModel.setVolume(ToolKits.isEmpty(intfShipbillDetailVO.getVolume()) ? BigDecimal.ZERO : intfShipbillDetailVO.getVolume());
			shipbillDetailModel.setEnterpriseId(intfShipbillHeaderVO.getEnterpriseId());
			shipbillDetailModel.setEnterpriseName(intfShipbillHeaderVO.getEnterpriseName());
			shipbillDetailModel.setIntfStatus(InterfaceConstant.INTERFACE_DATA_N);
			shipbillDetailModel.setCreateperson(shipbillHeaderModel.getCreateperson());
			shipbillDetailModel.setCreatetime(date);
			shipbillDetailModel.setUpdateperson(shipbillHeaderModel.getUpdateperson());
			shipbillDetailModel.setUpdatetime(date);

			shipbillDetailModels.add(shipbillDetailModel);

			// 接口转业务明细数据
			IntfShipbillDetailVO shipbillDetailVO = new IntfShipbillDetailVO();
			BeanUtils.copyProperties(shipbillDetailModel, shipbillDetailVO);
			details.add(shipbillDetailVO);
		}

		// 转业务请求集合
		List<IntfShipbillHeaderVO> shipbillHeaderVOs = Lists.newArrayList();
		IntfShipbillHeaderVO shipbillHeaderVO = new IntfShipbillHeaderVO();
		BeanUtils.copyProperties(shipbillHeaderModel, shipbillHeaderVO);
		shipbillHeaderVO.setDetails(details);
		shipbillHeaderVOs.add(shipbillHeaderVO);

		// 接口用户登录
		HttpUtils.HttpRestClient();

		log.info("运单信息接口转业务请求报文:{}", JSONObject.toJSONString(shipbillHeaderVOs));

		RestMessage<List<IntfErrorLogDTO>> restMessage = businessComingRecordFeign.saveShipbillInterfaceExecute(shipbillHeaderVOs);
		if (restMessage.isSuccess()) {
			List<IntfErrorLogDTO> intfErrorLogs = restMessage.getData();
			Assert.isTrue(ToolKits.isNotEmpty(intfErrorLogs), "处理结果异常：响应为空");

			IntfErrorLogDTO intfErrorLog = intfErrorLogs.get(0);
			if (intfErrorLog.isStatus()) {
				// 运单接口转历史
				ShipbillHeaderHtyModel shipbillHeaderHtyModel = new ShipbillHeaderHtyModel();
				BeanUtils.copyProperties(shipbillHeaderModel, shipbillHeaderHtyModel);
				shipbillHeaderHtyModel.setShipbillId(ToolKits.getUUID());
				shipbillHeaderHtyModel.setIntfStatus(InterfaceConstant.INTERFACE_DATA_Y);
				shipbillHeaderHtyModel.setUpdatetime(DateUtil.date());
				shipbillHeaderHtyMapper.save(shipbillHeaderHtyModel);

				for (ShipbillDetailModel shipbillDetailModel : shipbillDetailModels) {
					// 运单明细历史对象
					ShipbillDetailHtyModel shipbillDetailHtyModel = new ShipbillDetailHtyModel();
					BeanUtils.copyProperties(shipbillDetailModel, shipbillDetailHtyModel);
					shipbillDetailHtyModel.setShipbillId(shipbillHeaderHtyModel.getShipbillId());
					shipbillDetailHtyModel.setIntfStatus(InterfaceConstant.INTERFACE_DATA_Y);
					shipbillDetailHtyModel.setUpdatetime(DateUtil.date());
					shipbillDetailHtyMapper.save(shipbillDetailHtyModel);
				}

				return null;
			} else {
				// 状态修改为E
				shipbillHeaderModel.setIntfStatus(InterfaceConstant.INTERFACE_DATA_E);
				shipbillHeaderModel.setUpdatetime(DateUtil.date());
				shipbillHeaderMapper.save(shipbillHeaderModel);

				// 明细不为空保存明细数据
				if (shipbillDetailModels.size() > 0) {
					// 保存明细数据
					shipbillDetailMapper.saveBatch(shipbillDetailModels);
				}

				ErrorLogModel errorLogModel = new ErrorLogModel();
				errorLogModel.setId(ToolKits.getUUID());
				errorLogModel.setIntfName("运单接口");
				errorLogModel.setErrorInfo(intfErrorLog.getErrorInfo());
				errorLogModel.setTableName("intf_shipbill_header");
				errorLogModel.setDataId(intfErrorLog.getDataId());
				errorLogModel.setCreatetime(date);
				errorLogMapper.save(errorLogModel);

				return intfErrorLog.getErrorInfo();
			}
		} else {
			throw new ParameterException(restMessage.getMessage());
		}
	}

	/**
	 * TMS运单同步BMS接口
	 */
	@Override
	public void saveShipbillBmsData(List<BillDownloadVO> billDownloadVO) {
		log.info("TMS同步BMS接口报文：{}", JSONObject.toJSONString(billDownloadVO, SerializerFeature.WriteDateUseDateFormat));

		// 发送请求
		JSONObject response = HttpUtils.postJsonRequest(shipbillBmsUrl, JSONObject.toJSONString(billDownloadVO, SerializerFeature.WriteDateUseDateFormat));
		log.info("TMS同步BMS接口响应：{}", response.toJSONString());

		if (!response.getBoolean("success")) {
			throw new ParameterException(response.getString("message"));
		}
	}

}
