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

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.prolog.cs.basic.chain.model.cargo.BaseCargoOwnerMst;
import com.prolog.cs.biz.inbound.dao.SupervisionCodeMapper;
import com.prolog.cs.biz.inbound.dto.IsSuperviseDTO;
import com.prolog.cs.biz.inbound.dto.Supervise4CargoChange;
import com.prolog.cs.biz.inbound.dto.Supervise4CargoChangeDetail;
import com.prolog.cs.biz.inbound.dto.SuperviseResultDTO;
import com.prolog.cs.biz.inbound.dto.rqc.WmsInRqcStRuleDTO;
import com.prolog.cs.biz.inbound.model.SupervisionCode;
import com.prolog.cs.biz.inbound.service.SupervisionCodeService;
import com.prolog.cs.biz.inbound.vo.SupervisionCodeVO;
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.AssertUtils;
import com.taobao.api.DefaultTaobaoClient;
import com.taobao.api.TaobaoClient;
import com.taobao.api.TaobaoResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @Description // TODO 
 * @Date 2021-06-03 
 */

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

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

	@Resource
	private SupervisionCodeService supervisionCodeService;

	@Resource
	private SupervisionCodeMapper mapper;

	@Resource
	private UserTemplate userTemplate;

	@Value("${prolog.taobao.serverUrl}")
	private String serverUrl;

	@Value("${prolog.taobao.appKey}")
	private String appKey;

	@Value("${prolog.taobao.appSecret}")
	private String appSecret;

	@Value("${prolog.taobao.refEntId}")
	private String refEntId;
	
	/**
	 * // 扫描监管码
	 */
	@ApiOperation("扫描监管码")
	@PostMapping("/addSupervisionCode")
	public RestMessage<SuperviseResultDTO> addSupervisionCode(@RequestBody SupervisionCode dto){
		if(StringUtils.isBlank(dto.getSource())){
			dto.setRefBillLineId(dto.getAsnLineId());
		}
		if(dto.getUnlock()!=null && dto.getUnlock()==1){

		}else{
			BigDecimal subtract1 = new BigDecimal(dto.getPieceQty()).subtract(new BigDecimal(dto.getPackSize()));
			if(subtract1.compareTo(BigDecimal.ZERO)<0){
				throw new BizException("当前包装数量大于剩余数量");
			}
			if(StringUtils.isNotBlank(dto.getSource()) && "out".equals(dto.getSource())){
				//管码需要有商品+批号+监管码的校验
				supervisionCodeService.checkSupervisionCode(dto);
			}
			SuperviseResultDTO superviseResultDTO = supervisionCodeService.itemsByBill1(dto.getRefBillId(), dto.getRefBillLineId());
			if(superviseResultDTO!=null){
				List<SupervisionCode> superviseCodesModal = superviseResultDTO.getSuperviseCodesModal();
				if(superviseCodesModal!=null&&superviseCodesModal.size()>0){
					BigDecimal reduce = superviseCodesModal.stream().map(x -> new BigDecimal(x.getPackSize())).reduce(BigDecimal.ZERO, BigDecimal::add);
					//剩余数量
					BigDecimal sub = new BigDecimal(dto.getPieceQty()).subtract(reduce);
					BigDecimal subtract = sub.subtract(new BigDecimal(dto.getPackSize()));
					if(subtract.compareTo(BigDecimal.ZERO)<0){
						throw new BizException("当前包装数量大于剩余数量");
					}
				}
			}
		}
		return RestMessage.newInstance(true, "success", supervisionCodeService.addSupervisionCode(dto));
	}

	/**
	 * // 扫描监管码
	 */
	@ApiOperation("批量监管码")
	@PostMapping("/addSupervisionCodes")
	public RestMessage<SuperviseResultDTO> addSupervisionCodes(@RequestBody List<SupervisionCode> dtos){
		if(dtos==null||dtos.size()==0){
			throw new BizException("扫描监管码不能为空");
		}
		//扫描数量
		BigDecimal reduce = dtos.stream().map(x -> new BigDecimal(x.getPackSize())).reduce(BigDecimal.ZERO, BigDecimal::add);

		BigDecimal subtract1 = new BigDecimal(dtos.get(0).getPieceQty()).subtract(reduce);
		if(subtract1.compareTo(BigDecimal.ZERO)<0){
			throw new BizException("当前扫描数量大于剩余数量");
		}
		SuperviseResultDTO superviseResultDTO = supervisionCodeService.itemsByBill1(dtos.get(0).getRefBillId(), dtos.get(0).getRefBillLineId());
		if(superviseResultDTO!=null){
			List<SupervisionCode> superviseCodesModal = superviseResultDTO.getSuperviseCodesModal();
			if(superviseCodesModal!=null&&superviseCodesModal.size()>0){
				BigDecimal reduce1 = superviseCodesModal.stream().map(x -> new BigDecimal(x.getPackSize())).reduce(BigDecimal.ZERO, BigDecimal::add);
				//剩余数量
				BigDecimal sub = new BigDecimal(dtos.get(0).getPieceQty()).subtract(reduce1);
				BigDecimal subtract = sub.subtract(reduce);
				if(subtract.compareTo(BigDecimal.ZERO)<0){
					throw new BizException("当前扫描数量大于剩余数量");
				}
			}
		}
		return RestMessage.newInstance(true, "success",supervisionCodeService.addSupervisionCodes(dtos));
	}

	/**
	 * // 扫描监管码
	 */
	@ApiOperation("批量监管码")
	@PostMapping("/addSupervisionCodeList")
	public RestMessage<SuperviseResultDTO> addSupervisionCodeList(@RequestBody List<SupervisionCode> codes){
		if(codes==null||codes.size()==0){
			throw new BizException("扫描监管码不能为空");
		}
		List<SupervisionCode> dtos = new ArrayList<>();
		//排除重复的
		List<SupervisionCode> collect = codes.stream().distinct().collect(Collectors.toList());
		//排除已在库的
		for (SupervisionCode dto : collect) {
			String supervisionCode = dto.getSupervisionCode();
			if(StringUtils.isEmpty(supervisionCode) || !Pattern.compile("^[0-9]{20}$").matcher(supervisionCode).matches()){
				continue;
			}
			String srcCode = dto.getSrcCode();
			String warehouseId = dto.getWarehouseId();
			Restriction r1 = Restrictions.eq("warehouseId", warehouseId);
			Restriction r2 = Restrictions.eq("srcCode", srcCode);
			Restriction r3 = Restrictions.eq("supervisionCode", dto.getSupervisionCode());
			Restriction r4 = Restrictions.and(r1,r2,r3);
			Criteria criteria11 = Criteria.forClass(SupervisionCode.class);
			criteria11.setRestriction(r4);
			if(mapper.findCountByCriteria(criteria11) > 0L){
				continue;
			}
			dtos.add(dto);
		}
		if(dtos.size()==0){
            return RestMessage.newInstance(true, "success",null);
        }
		//扫描数量
		BigDecimal reduce = dtos.stream().map(x -> new BigDecimal(x.getPackSize())).reduce(BigDecimal.ZERO, BigDecimal::add);

		BigDecimal subtract1 = new BigDecimal(dtos.get(0).getPieceQty()).subtract(reduce);
		if(subtract1.compareTo(BigDecimal.ZERO)<0){
			throw new BizException("当前扫描数量大于剩余数量");
		}
		SuperviseResultDTO superviseResultDTO = supervisionCodeService.itemsByBill1(dtos.get(0).getRefBillId(), dtos.get(0).getRefBillLineId());
		if(superviseResultDTO!=null){
			List<SupervisionCode> superviseCodesModal = superviseResultDTO.getSuperviseCodesModal();
			if(superviseCodesModal!=null&&superviseCodesModal.size()>0){
				BigDecimal reduce1 = superviseCodesModal.stream().map(x -> new BigDecimal(x.getPackSize())).reduce(BigDecimal.ZERO, BigDecimal::add);
				//剩余数量
				BigDecimal sub = new BigDecimal(dtos.get(0).getPieceQty()).subtract(reduce1);
				BigDecimal subtract = sub.subtract(reduce);
				if(subtract.compareTo(BigDecimal.ZERO)<0){
					throw new BizException("当前扫描数量大于剩余数量");
				}
			}
		}
		return RestMessage.newInstance(true, "success",supervisionCodeService.addSupervisionCodeList(dtos));
	}

	/**
	 * // 删除监管码
	 */
	@ApiOperation("删除监管码")
	@PostMapping("/delSupervisionCode")
	public RestMessage<Object> delSupervisionCode(@RequestBody List<SupervisionCode> list){
		supervisionCodeService.delSupervisionCode(list);
		return RestMessage.newInstance(true, "success");
	}

	@ApiOperation("删除监管码-单行")
	@GetMapping("/deleteSupervisionCode")
	public RestMessage<Object> delSupervisionCode(@RequestParam(value = "Id") String Id){
		supervisionCodeService.deleteSupervisionCode(Id);
		return RestMessage.newInstance(true, "success");
	}
	
	/**
	 * // 扫描监管码
	 */
	@Deprecated
	@ApiOperation("补录监管码")
	@PostMapping("/addSupervisionCodeAppend")
	public RestMessage<Object> addSupervisionCodeAppend(@RequestBody List<SupervisionCode> dtoList){
		for (int i = 0; i < dtoList.size(); i++) {
			SupervisionCode dto=dtoList.get(i);
			AssertUtils.notNull(dto, "入参不能为空");
			AssertUtils.notNull(dto.getRefBillId(), "单据Id不能为空");
		}
		supervisionCodeService.addSupervisionCodeAppendList(dtoList);
		return RestMessage.newInstance(true, "findCodesByBill", null);
	}

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

	/**
	 * 获取已扫码监管码列表（校验所有选中数据是否都扫描完成）
	 */
	@UserLog("获取已扫码监管码列表（校验所有选中数据是否都扫描完成）")
	@ApiOperation("获取已扫码监管码列表（校验所有选中数据是否都扫描完成）")
	@PostMapping("/findCodesByAllRefBillLineId")
	public RestMessage<SuperviseResultDTO> findCodesByAllRefBillLineId(@RequestBody SupervisionCodeVO codeVO) {
		SuperviseResultDTO dto = supervisionCodeService.findCodesByAllRefBillLineId(codeVO);
		if(dto==null){
			dto=new SuperviseResultDTO();
			dto.setSuperviseCodes(new ArrayList<String>());
		}
		return RestMessage.newInstance(true, "findCodesByBill", dto);
	}


	/**
	 * 删除(主键id集合)
	 */
	@UserLog("删除(主键id集合)")
	@ApiOperation("删除(主键id集合)")
	@PostMapping("/delIds")
	public RestMessage<SuperviseResultDTO> delIds(@RequestBody List<String> pkIdList) {
		AssertUtils.notNull(pkIdList, "入参不能为空");
		supervisionCodeService.delIds(pkIdList);
		return RestMessage.newInstance(true, "delIds", null);
	}

	/**
	 * 获取已扫码监管码列表
	 */
	@UserLog("获取已扫码监管码列表")
	@ApiOperation("获取已扫码监管码列表")
	@GetMapping("/findCodesByBill1")
	public RestMessage<SuperviseResultDTO> findCodesByBill1(@RequestParam(required = true) String refBillId,
															@RequestParam(required = true) String refBillLineId) {
		return RestMessage.newInstance(true, "findCodesByBill", supervisionCodeService.itemsByBill1(refBillId,refBillLineId));
	}

	/**
	 * 删除已扫码监管码列表
	 */
	@UserLog("删除已扫码监管码列表")
	@ApiOperation("删除已扫码监管码列表")
	@PostMapping("/deleteCodesByBill")
	public RestMessage deleteCodesByBill(@RequestBody List<String> refBillLineIds) {
		supervisionCodeService.deleteCodesByBill(refBillLineIds);
		return RestMessage.newInstance(true, "deleteCodesByBill", null);
	}

	/**
	 * 获取已扫码监管码列表
	 */
	@UserLog("获取已扫码监管码列表")
	@ApiOperation("获取已扫码监管码列表")
	@GetMapping("/findCodesByBill-yj")
	public RestMessage<SuperviseResultDTO> findCodesByBillYj(@RequestParam(required = true) String refBillId,
															@RequestParam(required = true) String refBillLineId) {
		return RestMessage.newInstance(true, "findCodesByBill", supervisionCodeService.itemsByBillYj(refBillId,refBillLineId));
	}

	/**
	 * 是否完成扫描监管码
	 */
	@UserLog("是否完成扫描监管码")
	@ApiOperation("是否完成扫描监管码")
	@PostMapping("/isSupervised")
	public RestMessage<Boolean> isSupervised(@RequestBody List<SupervisionCode> list) {
		log.info("isSupervised,list：{}", JSON.toJSONString(list));
		if(list==null || list.size()==0){
			return RestMessage.newInstance(true, "success", true);
		}
		return RestMessage.newInstance(true, "success", supervisionCodeService.isSupervised(list));
	}

    /**
     * 是否完成扫描监管码（拒收判断）
     */
    @UserLog("是否完成扫描监管码（拒收判断）")
    @ApiOperation("是否完成扫描监管码（拒收判断）")
    @PostMapping("/isSupervised-reject")
    public RestMessage<Boolean> isSupervisedReject(@RequestBody List<SupervisionCode> list) {
        log.info("isSupervised,list：{}", JSON.toJSONString(list));
        if(list==null || list.size()==0){
            return RestMessage.newInstance(true, "success", true);
        }
        return RestMessage.newInstance(true, "success", supervisionCodeService.isSupervisedReject(list));
    }

	/**
	 * 校验是否扫描监管码
	 */
	@UserLog("校验是否扫描监管码")
	@ApiOperation("校验是否扫描监管码")
	@PostMapping("/isSupervise")
	public RestMessage<List<? extends IsSuperviseDTO>> isSupervise(@RequestBody List<? extends IsSuperviseDTO> list,@RequestParam("stage") Integer stage){
		log.info("isSupervise,list：{},stage：{}", JSON.toJSONString(list),stage);
		if(list==null || list.size()==0){
			return RestMessage.newInstance(true, "success", list);
		}
		return RestMessage.newInstance(true, "success", supervisionCodeService.isSupervise(list,stage));
	}

	/**
	 * 条件分页
	 */
	@ApiOperation("条件分页")
	@GetMapping("/page")
	public RestMessage<Page<SupervisionCode>> page(SupervisionCode dto, Integer pageSize, Integer pageNum) throws Exception {
		return RestMessage.newInstance(true, "pageSuccess", supervisionCodeService.page(dto, pageSize ,pageNum));
	}

	/**
	 * 异常行详情
	 */
//	@UserLog("测试监管码")
//	@GetMapping("/testTaoBaoSupervisionCode")
//	public RestMessage<String> testTaoBaoSupervisionCode(@RequestParam(required = true) String supervisionCode) {
//		TaobaoClient client = new DefaultTaobaoClient(serverUrl, appKey, appSecret);
//		AlibabaAlihealthDrugCodeKytQuerycodeRequest req = new AlibabaAlihealthDrugCodeKytQuerycodeRequest();
//		AlibabaAlihealthDrugCodeMscQuerycodeRequest req = new AlibabaAlihealthDrugCodeKytQuerycodeRequest();
//		req.setCodes(supervisionCode);//999枇杷膏
//		req.setRefEntId(refEntId);//企业唯一标识
//		try {
//			TaobaoResponse rsp = client.execute(req);
//			String rspBody = rsp.getBody();
//			System.out.println(rspBody);
//			return RestMessage.newInstance(true, "findCodesByBill", rspBody);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//		return RestMessage.newInstance(false, "findCodesByBill", "");
//	}

	/**
	 * 货主转换
	 */
	@ApiOperation("查询货主转换列表")
	@GetMapping("/findCargoChangeList")
	public RestMessage<List<Supervise4CargoChange>> findCargoChangeList(String cargoChangeBillNo) throws Exception {
		return RestMessage.newInstance(true, "success", supervisionCodeService.findCargoChangeList(cargoChangeBillNo));
	}


	/**
	 * 货主转换
	 */
	@ApiOperation("查询货主转换明细")
	@GetMapping("/findCargoChangeDetail")
	public RestMessage<Supervise4CargoChangeDetail> findCargoChangeDetail(String resultId) throws Exception {
		return RestMessage.newInstance(true, "success", supervisionCodeService.findCargoChangeDetail(resultId));
	}

	/**
	 * 货转转换扫描监管码
	 */
	@Deprecated
	@ApiOperation("货转转换扫描监管码")
	@PostMapping("/addSupervisionCodeCargoChange")
	public RestMessage<Object> addSupervisionCodeCargoChange(@RequestBody Supervise4CargoChangeDetail dto){
		supervisionCodeService.addSupervisionCodeCargoChange(dto);
		return RestMessage.newInstance(true, "success", null);
	}

	/**
	 * 根据已选择的任务重新提取质检池中的任务
	 */
	@ApiOperation("查询已扫数量及包装单位")
	@PostMapping("/querySupervisionCodedList")
	public RestMessage<Page<SupervisionCode>> querySupervisionCodedList(@RequestBody List<SupervisionCode> supervisionCodeList) {
		List<SupervisionCode> collect = supervisionCodeList.stream().filter(x -> new BigDecimal(x.getPieceQty()).compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList());
		if(CollectionUtil.isEmpty(collect)){
			return RestMessage.newInstance(false, "querySupervisionCodedList input params is null");
		}
		return RestMessage.newInstance(true, "querySupervisionCodedList", supervisionCodeService.querySupervisionCodedList(collect));
	}

	/**
	 * 批量新增监管码
	 */
	@ApiOperation("批量新增")
	@PostMapping("/batchAdd")
	public RestMessage<Object> batchAddSupCode(@RequestBody  List<SupervisionCode> supervisionCodes) {
		return RestMessage.newInstance(true, "batchAddSuccess", supervisionCodeService.batchAdd(supervisionCodes));
	}
}
