package com.prolog.cs.biz.outbound.controller;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.prolog.cs.biz.inbound.dto.RelationCodeResultDTO;
import com.prolog.cs.biz.inbound.dto.ScanCodeResultDTO;
import com.prolog.cs.biz.inbound.dto.SuperviseResultDTO;
import com.prolog.cs.biz.inbound.model.SupervisionCode;
import com.prolog.cs.biz.inbound.vo.RelationCodeResultVO;
import com.prolog.cs.biz.outbound.dao.*;
import com.prolog.cs.biz.outbound.model.OmsDoBillHDO;
import com.prolog.cs.biz.outbound.model.PickTaskD;
import com.prolog.cs.biz.outbound.model.SaleRedRecord;
import com.prolog.cs.biz.outbound.model.entity.BarCodeDDO;
import com.prolog.cs.biz.outbound.model.entity.OmsDoBillDDO;
import com.prolog.cs.biz.outbound.model.entity.WaveBillDO;
import com.prolog.cs.biz.outbound.model.entity.WaveStorageDO;
import com.prolog.cs.biz.outbound.resource.InBoundClient;
import com.prolog.cs.biz.outbound.service.IOmsDoBillDService;
import com.prolog.cs.biz.outbound.service.RedService;
import com.prolog.framework.authority.user.UserTemplate;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.BizException;
import com.prolog.framework.core.pojo.Page;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.core.restriction.Restriction;
import com.prolog.framework.core.restriction.Restrictions;
import com.prolog.framework.log.aop.annotation.UserLog;
import com.prolog.framework.utils.ArrayUtils;
import com.prolog.framework.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description 
 * 田海龙
 * @Date 2021-06-03 
 */

@Api(tags = "监管码")
@RestController
@RequestMapping("/supervisionCode")
public class SupervisionCodeController {

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

	@Autowired
	private UserTemplate userTemplate;

	@Autowired
	InBoundClient inBoundClient;

	@Autowired
	private BarcodeHMapper barcodeHMapper;
	
	@Autowired
	private WaveBillMapper billMapper;

	@Autowired
	private OmsDoBillHMapper OmsDoBillHMapper;
	
	@Autowired
	private OmsDoBillDMapper OmsDoBillDMapper;

	@Autowired
	private BarcodeDMapper barcodeDMapper;

	@Autowired
	private PickTaskDMapper pickTaskDMapper;

	@Autowired
	private WaveStorageMapper waveStorageMapper;

	@Autowired
	private RedService redService;

	@Autowired
	private IOmsDoBillDService iOmsDoBillDService;

	/**
	 * // 扫描监管码
	 */
	@ApiOperation("扫描监管码")
	@PostMapping("/addSupervisionCode")
	public RestMessage<SuperviseResultDTO> addSupervisionCode(@RequestBody SupervisionCode dto){
		dto.setSource("out");
		if (dto.getUnlock()!=null && dto.getUnlock()==1) {
			// 解锁
			dto.setUploadFlag("0");
			dto.setDownFlag(0);
			dto.setSaveType(2);
			return inBoundClient.addSupervisionCode(dto);
		}
		if (StringUtils.isEmpty(dto.getCargoOwnerId()) && !StringUtils.isEmpty(dto.getConsignorId())) {
			dto.setCargoOwnerId(dto.getConsignorId());
		}
		Criteria cr = Criteria.forClass(OmsDoBillHDO.class);
		String srcCode = dto.getSrcCode();
		Integer stage = dto.getStage();
		if (stage !=null) {
			if (stage ==2) {
				srcCode=dto.getRefBillId();
			} else if (stage==3 && !StringUtils.isBlank(dto.getRefBillLineId())) {
				BarCodeDDO barCodeDDO=barcodeDMapper.findById(dto.getRefBillLineId(), BarCodeDDO.class);
				if(barCodeDDO!=null && !StringUtils.isBlank(barCodeDDO.getWmsPickTaskDId())){
					PickTaskD pickTaskD = pickTaskDMapper.findById(barCodeDDO.getWmsPickTaskDId(),PickTaskD.class);
					if(pickTaskD!=null && !StringUtils.isBlank(pickTaskD.getWaveStorageId())){
						WaveStorageDO waveStorageDO = waveStorageMapper.findById(pickTaskD.getWaveStorageId(), WaveStorageDO.class);
						if(waveStorageDO!=null && !StringUtils.isBlank(waveStorageDO.getBillId())){
							WaveBillDO waveBillDO = billMapper.findById(waveStorageDO.getBillId(), WaveBillDO.class);
							if(waveBillDO!=null){
								srcCode=waveBillDO.getSrcCode();
							}
						}
					}
				}
			}
		}

		Restriction restriction = Restrictions.eq("billid", srcCode);
		cr.setRestriction(restriction);
		List<OmsDoBillHDO> billHList = OmsDoBillHMapper.findByCriteria(cr);
		if(billHList!=null && billHList.size()>0){
			OmsDoBillHDO omsDoBillHDO = billHList.get(0);
			if(StringUtils.isBlank(dto.getConsignorId())){
				dto.setConsignorId(omsDoBillHDO.getConsignorid());
			}
			if ("1".equals(omsDoBillHDO.getBilltype())) {
				dto.setSupplierId(omsDoBillHDO.getShipperid());
				dto.setSupervisionType(1);
			} else {
				dto.setShipperId(omsDoBillHDO.getShipperid());
				dto.setSupervisionType(4);
			}
			if(StringUtils.isBlank(dto.getManufacturerLotNum())){
				Criteria crD = Criteria.forClass(OmsDoBillDDO.class);
				Restriction billIdD = Restrictions.eq("billno", srcCode);
				Restriction itemIdD = Restrictions.eq("itemid", dto.getItemId());
				crD.setRestriction(Restrictions.and(billIdD,itemIdD));
				List<OmsDoBillDDO> billDList = OmsDoBillDMapper.findByCriteria(crD);
				if(billDList!=null && billDList.size()>0){
					String lotNo = billDList.get(0).getLotNo();
					if(StringUtils.isBlank(lotNo)){
						dto.setManufacturerLotNum("N/A");
					}else{
						dto.setManufacturerLotNum(lotNo);
					}
				}
			}
			dto.setWarehouseId(omsDoBillHDO.getBranchid());
			dto.setWarehouseCode(omsDoBillHDO.getBranchcode());
			dto.setBillType(omsDoBillHDO.getBilltype());
			dto.setSrcCode(omsDoBillHDO.getBillno());
			dto.setUploadFlag("0");
			dto.setDownFlag(0);
			dto.setSaveType(2);
			log.info("dto属性信息:{}", JSONUtil.toJsonStr(dto));
			return inBoundClient.addSupervisionCode(dto);
		}
		return RestMessage.error("OMS单数据异常，请联系系统管理员");
	}

	/**
	 * // 扫描监管码
	 */
	@ApiOperation("批量扫描监管码")
	@PostMapping("/addSupervisionCodeList")
	public RestMessage<SuperviseResultDTO> addSupervisionCodeList(@RequestBody SupervisionCode dto){
		if(StringUtils.isEmpty(dto.getSupervisionCode())){
			throw new BizException("监管码数据不能为空");
		}
		List<SupervisionCode> resultList = new ArrayList<>();
        List<String> supervisionCodes = ArrayUtils.toList(dto.getSupervisionCode().split(","));
		//去除重复监管码
        List<String> supervisionCodeList = supervisionCodes.stream().distinct().collect(Collectors.toList());
        for (String supervisionCode : supervisionCodeList) {
            if (dto.getUnlock()!=null && dto.getUnlock()==1) {
                // 解锁
				dto.setUploadFlag("0");
				dto.setDownFlag(0);
				dto.setSaveType(2);
                return inBoundClient.addSupervisionCode(dto);
            }
            if (StringUtils.isEmpty(dto.getCargoOwnerId()) && !StringUtils.isEmpty(dto.getConsignorId())) {
                dto.setCargoOwnerId(dto.getConsignorId());
            }
            Criteria cr = Criteria.forClass(OmsDoBillHDO.class);
            String srcCode = dto.getSrcCode();
            Integer stage = dto.getStage();
            if (stage != null) {
                if (stage ==2) {
                    srcCode=dto.getRefBillId();
                } else if (stage==3 && !StringUtils.isBlank(dto.getRefBillLineId())) {
                    BarCodeDDO barCodeDDO=barcodeDMapper.findById(dto.getRefBillLineId(), BarCodeDDO.class);
                    if (barCodeDDO!=null && !StringUtils.isBlank(barCodeDDO.getWmsPickTaskDId())){
                        PickTaskD pickTaskD = pickTaskDMapper.findById(barCodeDDO.getWmsPickTaskDId(),PickTaskD.class);
                        if (pickTaskD!=null && !StringUtils.isBlank(pickTaskD.getWaveStorageId())){
                            WaveStorageDO waveStorageDO = waveStorageMapper.findById(pickTaskD.getWaveStorageId(), WaveStorageDO.class);
                            if (waveStorageDO!=null && !StringUtils.isBlank(waveStorageDO.getBillId())) {
                                WaveBillDO waveBillDO = billMapper.findById(waveStorageDO.getBillId(), WaveBillDO.class);
                                if (waveBillDO != null) {
                                    srcCode = waveBillDO.getSrcId();
                                }
                            }
                        }
                    }
                }
            }

            Restriction restriction = Restrictions.eq("billid", srcCode);
            cr.setRestriction(restriction);
            List<OmsDoBillHDO> billHList = OmsDoBillHMapper.findByCriteria(cr);
            if (billHList!=null && billHList.size()>0) {
                OmsDoBillHDO omsDoBillHDO = billHList.get(0);
                if (StringUtils.isBlank(dto.getConsignorId())) {
                    dto.setConsignorId(omsDoBillHDO.getConsignorid());
                }
                if ("1".equals(omsDoBillHDO.getBilltype())) {
                    dto.setSupplierId(omsDoBillHDO.getShipperid());
                    dto.setSupervisionType(1);
                } else {
                    dto.setShipperId(omsDoBillHDO.getShipperid());
                    dto.setSupervisionType(4);
                }
                if (StringUtils.isBlank(dto.getManufacturerLotNum())) {
                    Criteria crD = Criteria.forClass(OmsDoBillDDO.class);
                    Restriction billIdD = Restrictions.eq("billid", srcCode);
                    Restriction itemIdD = Restrictions.eq("itemid", dto.getItemId());
                    crD.setRestriction(Restrictions.and(billIdD, itemIdD));
                    List<OmsDoBillDDO> billDList = OmsDoBillDMapper.findByCriteria(crD);
                    if (billDList != null && billDList.size() > 0) {
                        String lotNo = billDList.get(0).getLotNo();
                        if (StringUtils.isBlank(lotNo)) {
                            dto.setManufacturerLotNum("N/A");
                        } else {
                            dto.setManufacturerLotNum(lotNo);
                        }
                    }
                }
                dto.setWarehouseId(omsDoBillHDO.getBranchid());
                dto.setWarehouseCode(omsDoBillHDO.getBranchcode());
                dto.setBillType(omsDoBillHDO.getBilltype());
                dto.setSrcCode(omsDoBillHDO.getBillno());
                log.info("dto属性信息:{}", JSONUtil.toJsonStr(dto));
				SupervisionCode code = new SupervisionCode();
				BeanUtils.copyProperties(dto,code);
				code.setSupervisionCode(supervisionCode);
                resultList.add(code);
            }
        }
		if(resultList.size()>0){
			return inBoundClient.addSupervisionCodeList(resultList);
		}
		return RestMessage.error("OMS单数据异常，请联系系统管理员");
	}

	/**
	 * 异常行详情
	 */
	@UserLog("获取已扫码监管码列表")
	@ApiOperation("获取已扫码监管码列表")
	@GetMapping("/findCodesByBill")
	public RestMessage<SuperviseResultDTO> findCodesByBill(@RequestParam(required = true) String refBillId,
                                                     @RequestParam(required = true) String refBillLineId) {
		return inBoundClient.findCodesByBill(refBillId,refBillLineId);
	}


	/**
	 * 是否完成扫描监管码
	 */
	@UserLog("是否完成扫描监管码")
	@ApiOperation("是否完成扫描监管码")
	@PostMapping("/isSupervised")
	public RestMessage<Boolean> isSupervised(@RequestBody List<SupervisionCode> list) {
		// 增加单据冲红判断逻辑,判断此条数据是否冲红
		return isSupervisedOut(list);
	}

	public RestMessage<Boolean> isSupervisedOut(List<SupervisionCode> list) {
		List<SupervisionCode> rsList = new ArrayList<>();
		for (int i = 0; i < list.size(); i++) {
			SupervisionCode supervisionCode= list.get(i);
			RestMessage<List<SaleRedRecord>> restMessage = null;
			List<SaleRedRecord> saleRedRecordList = new ArrayList<>();
			OmsDoBillDDO omsDoBillDDO = new OmsDoBillDDO();
			Page<OmsDoBillDDO> pageOmsDList = new Page<>();
			if (!StringUtils.isBlank(supervisionCode.getSrcId()) && !StringUtils.isBlank(supervisionCode.getSrcLineId())) {
				omsDoBillDDO.setLineid(supervisionCode.getSrcLineId());
				omsDoBillDDO.setPageSize(20);
				omsDoBillDDO.setPageNum(1);
				restMessage = redService.omsRedRecordQuery(supervisionCode.getSrcId(),supervisionCode.getSrcLineId());
			}
			if (null != restMessage && restMessage.isSuccess()) {
				saleRedRecordList = restMessage.getData();
				pageOmsDList = iOmsDoBillDService.queryDoBillDList(omsDoBillDDO);
			}
			if (saleRedRecordList.size()==0) {
				rsList.add(supervisionCode);
			} else {
				if (null == pageOmsDList || pageOmsDList.getList().size()==0) {
					continue;
				}
				if (saleRedRecordList.size() != pageOmsDList.getList().get(0).getItemQty().intValue()) {
					// 商品数量不等于冲红数量
					rsList.add(supervisionCode);
				}
			}
		}
		if (rsList.size()>0) {
			log.info("rsList: {}", JSON.toJSONString(rsList));
			return inBoundClient.isSupervised(rsList);
		} else {
			return RestMessage.newInstance(true, "success", true);
		}
	}

    @ApiOperation("扫描监管码获取 商品批号效期等信息")
    @GetMapping("/scanSupervisionCode")
    public RestMessage<ScanCodeResultDTO> scanSupervisionCode(@RequestParam(value = "supervisionCode") String supervisionCode) {
        ScanCodeResultDTO scanCodeResultDTO = iOmsDoBillDService.scanSupervisionCode(supervisionCode);
        return RestMessage.newInstance(true, "查询成功", scanCodeResultDTO);
    }

	@ApiOperation("单码关联关系查询，通过一个码查询这个码下的所有子码")
	@PostMapping("/relationSupervisionCode")
	public RestMessage<List<RelationCodeResultDTO>> relationSupervisionCode(@RequestBody List<RelationCodeResultVO> resultVOS) {
		List<RelationCodeResultDTO> relationCodeResultDTOs = iOmsDoBillDService.relationSupervisionCode(resultVOS);
		return RestMessage.newInstance(true, "查询成功", relationCodeResultDTOs);
	}
}
