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

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.prolog.common.RestMsgHelper;
import com.prolog.cs.basic.common.model.SysRegistry;
import com.prolog.cs.basic.common.model.print.PrintParam;
import com.prolog.cs.biz.inbound.dto.RelationCodeResult;
import com.prolog.cs.biz.inbound.dto.RelationCodeResultDTO;
import com.prolog.cs.biz.inbound.dto.ScanCodeResultDTO;
import com.prolog.cs.biz.inbound.vo.RelationCodeResultVO;
import com.prolog.cs.biz.outbound.dao.OmsDoBillDMapper;
import com.prolog.cs.biz.outbound.model.PickTaskD;
import com.prolog.cs.biz.outbound.model.SYZJPrintAgain;
import com.prolog.cs.biz.outbound.model.dto.OmsDoBillDDTO;
import com.prolog.cs.biz.outbound.model.entity.OmsDoBillDDO;
import com.prolog.cs.biz.outbound.resource.CommonClient;
import com.prolog.cs.biz.outbound.resource.InventoryResource;
import com.prolog.cs.biz.outbound.service.IOmsDoBillDService;
import com.prolog.cs.biz.outbound.service.PrintLogService;
import com.prolog.framework.authority.core.dto.UserDTO;
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.dao.util.PageUtils;
import com.prolog.framework.utils.MapUtils;
import com.prolog.framework.utils.StringUtils;
import com.prolog.upcloud.base.inventory.model.WmsInvBatchNumbers;
import com.taobao.api.ApiException;
import com.taobao.api.DefaultTaobaoClient;
import com.taobao.api.TaobaoClient;
import com.taobao.api.request.AlibabaAlihealthDrugCodeKytQuerycodeRequest;
import com.taobao.api.request.AlibabaAlihealthDrugKytSinglerelationRequest;
import com.taobao.api.response.AlibabaAlihealthDrugCodeKytQuerycodeResponse;
import com.taobao.api.response.AlibabaAlihealthDrugKytSinglerelationResponse;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 出库单行业务处理类
 *
 * @author lihao
 * @since 2021/12/18
 */
@Slf4j
@Service
public class OmsDoBillDServiceImpl implements IOmsDoBillDService {

    private static Logger logger = LoggerFactory.getLogger(OmsDoBillDServiceImpl.class);

    @Autowired
    private UserTemplate userTemplate;

    @Autowired
    private OmsDoBillDMapper omsDoBillDMapper;

    @Autowired
    private InventoryResource inventoryResource;

    @Autowired
    private CommonClient commonClient;
    @Autowired
    private PrintLogService printLogService;

    @Override
    public Page<OmsDoBillDDO> queryDoBillDList(OmsDoBillDDO omsDoBillDDO) {
        UserDTO userDTO = userTemplate.getUserDTO();
        PageHelper.startPage(omsDoBillDDO.getPageNum(), omsDoBillDDO.getPageSize());
        Criteria crt = Criteria.forClass(OmsDoBillDDO.class);
        Restriction r1 = StringUtils.isBlank(omsDoBillDDO.getBillno())? null : Restrictions.eq("billno", omsDoBillDDO.getBillno());
        Restriction r2 = StringUtils.isBlank(omsDoBillDDO.getLineid())? null : Restrictions.eq("lineid", omsDoBillDDO.getLineid());
        crt.setRestriction(Restrictions.and(r1,r2));
        List<OmsDoBillDDO> list = omsDoBillDMapper.findByCriteria(crt);
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        list.forEach(vo->{
            if (null != vo.getStockStatus()) {
                if (vo.getStockStatus().equals("1")) {
                    vo.setStockStatusName("合格");
                } else if (vo.getStockStatus().equals("2")) {
                    vo.setStockStatusName("不合格");
                } else if (vo.getStockStatus().equals("3")) {
                    vo.setStockStatusName("待检");
                } else if (vo.getStockStatus().equals("4")) {
                    vo.setStockStatusName("退货");
                }
            }
            try {
                if (!StringUtils.isBlank(vo.getPdateFrom())) {
                    vo.setDateFromStr(df.format(df.parse(vo.getPdateFrom())));
                }
                if (!StringUtils.isBlank(vo.getValidUntil())) {
                    vo.setValidUntilStr(df.format(df.parse(vo.getValidUntil())));
                }
            } catch (ParseException e) {
                logger.info(e.getMessage());
            }

            if (null != vo.getCreatedate()) {
                vo.setCreatedateStr(df.format(vo.getCreatedate()));
            }
            if (null != vo.getLastmodifydate()) {
                vo.setLastmodifydateStr(df.format(vo.getLastmodifydate()));
            }

        });
        return PageUtils.getPage(list);
    }

    @Override
    @Transactional
    public Boolean saveDoBillD(OmsDoBillDDTO omsDoBillDDTO) {
        Date now = new Date();
        UserDTO userDTO = userTemplate.getUserDTO();
        List<OmsDoBillDDO> updateItems = omsDoBillDDTO.getUpdateItems();
        if (CollectionUtil.isNotEmpty(updateItems)) {
            for (OmsDoBillDDO omsDoBillDDO:updateItems) {
                omsDoBillDDO.setLastmodifyby(userDTO.getUsername());
                omsDoBillDDO.setLastmodifydate(now);
                omsDoBillDMapper.update(omsDoBillDDO);
            }
        }
        return true;
    }

    @Override
    public void PrintAgainSY(List<SYZJPrintAgain> list) {
        List<PrintParam> printParamList = new ArrayList<>();
        for (SYZJPrintAgain syzjPrintAgain : list) {
            PrintParam printParam = new PrintParam();
            printParam.setPrintBillCode("imgManage-SYZL-pdf");
            printParam.setParams(MapUtils.put("itemId", syzjPrintAgain.getItemcode()).put("batchId",syzjPrintAgain.getBatchId()).put("barcode", syzjPrintAgain.getBillno()).getMap());
            printParamList.add(printParam);
        }
        log.info("补打首营资料入参：{}", JSON.toJSONString(printParamList));
        RestMessage<?> restMessage = commonClient.executePrint(printParamList);
        //保存打印记录
        for (SYZJPrintAgain syzjPrintAgain : list) {
            printLogService.save(syzjPrintAgain.getBillno(),"imgManage-SYZL-pdf",syzjPrintAgain.getItemcode(),syzjPrintAgain.getBatchId(),restMessage.isSuccess());
        }

        List<String> billdLineIds = list.stream().map(SYZJPrintAgain::getLineid).collect(Collectors.toList());
        //记录打印次数 attrstr3
        billdLineIds = new ArrayList<>(new HashSet<>(billdLineIds));
        omsDoBillDMapper.updateAttrstr3(billdLineIds);
        log.info("补打首营资料返回结果：{}", JSON.toJSONString(restMessage));
    }

    @Override
    public void PrintAgainZJ(List<SYZJPrintAgain> list) {
        List<PrintParam> printParamList = new ArrayList<>();
        for (SYZJPrintAgain syzjPrintAgain : list) {
            PrintParam printParam = new PrintParam();
            printParam.setPrintBillCode("imgManage-ZJBG-pdf");
            printParam.setParams(MapUtils.put("itemId", syzjPrintAgain.getItemid()).put("batchId",syzjPrintAgain.getBatchId()).put("barcode", syzjPrintAgain.getBillno()).getMap());
            printParamList.add(printParam);
        }
        log.info("补打质检报告单入参：{}",JSON.toJSONString(printParamList));
        RestMessage<?> restMessage = commonClient.executePrint(printParamList);
        //保存打印记录
        for (SYZJPrintAgain syzjPrintAgain : list) {
            printLogService.save(syzjPrintAgain.getBillno(),"imgManage-ZJBG-pdf",syzjPrintAgain.getItemcode(),syzjPrintAgain.getBatchId(),restMessage.isSuccess());
        }

        List<String> billdLineIds = list.stream().map(SYZJPrintAgain::getLineid).collect(Collectors.toList());
        //记录打印次数 attrstr4
        billdLineIds = new ArrayList<>(new HashSet<>(billdLineIds));
        omsDoBillDMapper.updateAttrstr4(billdLineIds);
        log.info("补打质检报告单返回结果：{}", JSON.toJSONString(restMessage));
    }

    @Override
    public ScanCodeResultDTO scanSupervisionCode(String supervisionCode) {
        UserDTO userDTO = userTemplate.getUserDTO();
        String enterpriseId = userDTO.getEnterpriseId();
        RestMessage<SysRegistry> restMessage1 = commonClient.getRegistryInfo("serverUrl",enterpriseId);
        if (!restMessage1.isSuccess()) {
            throw new RuntimeException("未查询到 serverUrl 的系统配置参数:" + restMessage1.getMessage());
        }
        SysRegistry data1 = restMessage1.getData();
        String serverUrl = data1.getRegValue();

        RestMessage<SysRegistry> restMessage2 = commonClient.getRegistryInfo("appKeyKyt",enterpriseId);
        if (!restMessage2.isSuccess()) {
            throw new RuntimeException("未查询到 appKeyKyt 的系统配置参数:" + restMessage2.getMessage());
        }
        SysRegistry data2 = restMessage2.getData();
        String appKey = data2.getRegValue();

        RestMessage<SysRegistry> restMessage3 = commonClient.getRegistryInfo("appSecretKyt",enterpriseId);
        if (!restMessage3.isSuccess()) {
            throw new RuntimeException("未查询到 appSecretKyt 的系统配置参数:" + restMessage3.getMessage());
        }
        SysRegistry data3 = restMessage3.getData();
        String appSecret = data3.getRegValue();

        RestMessage<SysRegistry> restMessage4 = commonClient.getRegistryInfo("refEntIdKyt",enterpriseId);
        if (!restMessage4.isSuccess()) {
            throw new RuntimeException("未查询到 refEntIdKyt 的系统配置参数:" + restMessage4.getMessage());
        }
        SysRegistry data4 = restMessage4.getData();
        String ref_ent_id = data4.getRegValue();

        logger.info("serverUrl = "+ serverUrl+",appKey = "+ appKey+",appSecret = "+ appSecret+",ref_ent_id = "+ ref_ent_id);
        ScanCodeResultDTO scanCodeResultDTO =new ScanCodeResultDTO();
        logger.info("supervisionCode="+ supervisionCode);
//        String serverUrl = "http://gw.api.taobao.com/router/rest";
//        String appKey = "31829450";
//        String appSecret = "ec698ea2ac4accd88006cd8a390b4567";
//        String ref_ent_id = "fa3dfe7f41ce42c1b6b6f9505e530e32";
        TaobaoClient client = new DefaultTaobaoClient(serverUrl,appKey, appSecret);
        AlibabaAlihealthDrugCodeKytQuerycodeRequest req = new AlibabaAlihealthDrugCodeKytQuerycodeRequest();
        req.setCodes(supervisionCode);
        req.setRefEntId(ref_ent_id);
        try {
            AlibabaAlihealthDrugCodeKytQuerycodeResponse rsp = client.execute(req);
            logger.info("码上平台返回参数rsp="+JSON.toJSONString(rsp));
            AlibabaAlihealthDrugCodeKytQuerycodeResponse.CodeFullInfoDto model = rsp.getResult().getModels().get(0);
            String codeStatus = model.getCodeStatusTypeDTO().getCodeStatus();
            if("E".equals(codeStatus)){
                throw new BizException("未查到该监管码"+ supervisionCode +"对应的码上平台药品信息");
            }else {
                String batchNo = model.getCodeProduceInfoDTO().getProduceInfoList().get(0).getBatchNo();
                String expireDate = model.getCodeProduceInfoDTO().getProduceInfoList().get(0).getExpireDate();
                String produceDate = model.getCodeProduceInfoDTO().getProduceInfoList().get(0).getProduceDateStr().replace("-","");
                String physicName = model.getDrugEntBaseDTO().getPhysicName();
                scanCodeResultDTO.setBatchNo(batchNo);
                scanCodeResultDTO.setExpireDate(expireDate);
                scanCodeResultDTO.setProduceDate(produceDate);
                scanCodeResultDTO.setPhysicName(physicName);
                logger.info("scanCodeResultDTO ="+ JSON.toJSONString(scanCodeResultDTO));
                return  scanCodeResultDTO;
            }
        } catch (ApiException e) {
            throw new BizException("调用码上放心平台异常，请联系管理员");
        }
    }

    @SneakyThrows
    @Override
    public List<RelationCodeResultDTO> relationSupervisionCode(List<RelationCodeResultVO> resultVOS) {
        String enterpriseId =  resultVOS.get(0).getEnterpriseId();

        RestMessage<SysRegistry> restMessage1 = commonClient.getRegistryInfo("serverUrl",enterpriseId);
        if (!restMessage1.isSuccess()) {
            throw new RuntimeException("未查询到 serverUrl 的系统配置参数:" + restMessage1.getMessage());
        }
        SysRegistry data1 = restMessage1.getData();
        String serverUrl = data1.getRegValue();

        RestMessage<SysRegistry> restMessage2 = commonClient.getRegistryInfo("appKeyKyt",enterpriseId);
        if (!restMessage2.isSuccess()) {
            throw new RuntimeException("未查询到 appKeyKyt 的系统配置参数:" + restMessage2.getMessage());
        }
        SysRegistry data2 = restMessage2.getData();
        String appKey = data2.getRegValue();

        RestMessage<SysRegistry> restMessage3 = commonClient.getRegistryInfo("appSecretKyt",enterpriseId);
        if (!restMessage3.isSuccess()) {
            throw new RuntimeException("未查询到 appSecretKyt 的系统配置参数:" + restMessage3.getMessage());
        }
        SysRegistry data3 = restMessage3.getData();
        String appSecret = data3.getRegValue();

        RestMessage<SysRegistry> restMessage4 = commonClient.getRegistryInfo("refEntIdKyt",enterpriseId);
        if (!restMessage4.isSuccess()) {
            throw new RuntimeException("未查询到 refEntIdKyt 的系统配置参数:" + restMessage4.getMessage());
        }
        SysRegistry data4 = restMessage4.getData();
        String ref_ent_id = data4.getRegValue();
        List<RelationCodeResultDTO> relationCodeResultDTOS = new ArrayList<>();

        for (RelationCodeResultVO resultVO : resultVOS) {
            RelationCodeResultDTO relationCodeResultDTO = new RelationCodeResultDTO();
            relationCodeResultDTO.setFlag(1);//默认保存成功
            String supervisionCode =resultVO.getSupervisionCode();
            Integer packLevel =resultVO.getPackLevel();
            logger.info("supervisionCode = "+ supervisionCode+",packLevel = "+ packLevel+",enterpriseId = "+ enterpriseId);
            List<RelationCodeResult> relationCodeResultS = new ArrayList<>();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            logger.info("serverUrl = "+ serverUrl+",appKey = "+ appKey+",appSecret = "+ appSecret+",ref_ent_id = "+ ref_ent_id);
            TaobaoClient client = new DefaultTaobaoClient(serverUrl,appKey, appSecret);
            AlibabaAlihealthDrugKytSinglerelationRequest req = new AlibabaAlihealthDrugKytSinglerelationRequest();
            req.setCode(supervisionCode);
            req.setRefEntId(ref_ent_id);
            req.setDesRefEntId(ref_ent_id);
            try {
                AlibabaAlihealthDrugKytSinglerelationResponse rsp = client.execute(req);
                logger.info("码上平台返回参数rsp="+JSON.toJSONString(rsp));
                if(!rsp.getResult().getResponseSuccess()){
                    String message  = "查询监管码平台返回失败:" +rsp.getResult().getMsgInfo();
                    logger.info(message);
                    relationCodeResultDTO.setFlag(2);
                    relationCodeResultDTO.setMessage(message);
                    relationCodeResultDTO.setSupervisionCode(supervisionCode);
                    relationCodeResultDTOS.add(relationCodeResultDTO);
                    continue;
//                    throw new RuntimeException("查询监管码平台返回失败:" +rsp.getResult().getMsgInfo());
                }

                AlibabaAlihealthDrugKytSinglerelationResponse.CodeRelationDto codeRelationDto = rsp.getResult().getModelList().get(0);
                String pkgRatio = codeRelationDto.getBaseInfosDTO().getBaseInfoList().get(0).getPkgRatio();
                logger.info("药品包装比例pkgRatio="+ pkgRatio);
                String[] split = pkgRatio.split(":");
                List<AlibabaAlihealthDrugKytSinglerelationResponse.CodeInfo> codeRelationList = codeRelationDto.getCodeRelationList();
                AlibabaAlihealthDrugKytSinglerelationResponse.ProduceInfoDto produceInfoDto = codeRelationDto.getProduceInfoList().get(0);

                List<String> targetSupervisionCodes = new ArrayList<>();
                if(packLevel == 1){//如果是中包装，只查询出监管码平台对应的中包装的所有小包装，即pkg_ratio 	药品包装比例 必须为三层结构1:1:1
                    if(split.length<3){
                        String message  = "扫描的是中包装，但在监管码平台中查询到的包装结构为" +pkgRatio;
                        logger.info(message);
                        relationCodeResultDTO.setFlag(2);
                        relationCodeResultDTO.setMessage(message);
                        relationCodeResultDTO.setSupervisionCode(supervisionCode);
                        relationCodeResultDTOS.add(relationCodeResultDTO);
                        continue;
//                        throw new RuntimeException("扫描的是中包装，但在监管码平台中查询到的包装结构为" +pkgRatio);
                    }
                    //只查询出parent_code =当前code的所有子码合集
                    targetSupervisionCodes = codeRelationList.stream().filter(item -> item.getParentCode().equals(supervisionCode)).map(AlibabaAlihealthDrugKytSinglerelationResponse.CodeInfo :: getCode).distinct().collect(Collectors.toList());
                }else if (packLevel == 0){//如果是大包装 ,则只保存所有的小包装,目前不保存中包装
                    if(split.length == 3){//如果是三层结构，则只保存所有的小包装,目前不保存中包装和大包装自己的监管码
                        targetSupervisionCodes = codeRelationList.stream().filter(e -> e.getCodeLevel().equals("3")).map(AlibabaAlihealthDrugKytSinglerelationResponse.CodeInfo :: getCode).distinct().collect(Collectors.toList());
                    }else {//如果是二层结构，则只保存所有的小包装,目前不保存大包装自己的监管码
                        targetSupervisionCodes = codeRelationList.stream().filter(e -> e.getCodeLevel().equals("2")).map(AlibabaAlihealthDrugKytSinglerelationResponse.CodeInfo :: getCode).distinct().collect(Collectors.toList());
                    }
                }else {
                    String message  = "packLevel=" +packLevel +" 对应的包装层级不对 ";
                    logger.info(message);
                    relationCodeResultDTO.setFlag(2);
                    relationCodeResultDTO.setMessage(message);
                    relationCodeResultDTO.setSupervisionCode(supervisionCode);
                    relationCodeResultDTOS.add(relationCodeResultDTO);
                    continue;
//                    throw new RuntimeException("packLevel=" +packLevel +" 对应的包装层级不对 ");
                }

                if(targetSupervisionCodes.size()>0){
                    for (String targetSupervisionCode : targetSupervisionCodes) {
                        RelationCodeResult relationCodeResult = new RelationCodeResult();
                        relationCodeResult.setBatchNo(produceInfoDto.getBatchNo());
                        relationCodeResult.setProduceDate(produceInfoDto.getProduceDate());
                        String expireDate = produceInfoDto.getExpireDate();
                        String DateExpireDate = expireDate.substring(0,4)+ "-" + expireDate.substring(4,6)+ "-" + expireDate.substring(6,8)+" 00:00:00";
                        relationCodeResult.setExpireDate(sdf.parse(DateExpireDate));
                        relationCodeResult.setCode(targetSupervisionCode);
                        relationCodeResult.setParentCode(supervisionCode);
                        relationCodeResultS.add(relationCodeResult);
                    }
                }
                relationCodeResultDTO.setSupervisionCode(supervisionCode);
                relationCodeResultDTO.setRelationCodeResults(relationCodeResultS);
                relationCodeResultDTOS.add(relationCodeResultDTO);
            } catch (ApiException e) {
                throw new BizException("调用码上放心平台异常，请联系管理员");
            }

        }

        return relationCodeResultDTOS;
    }


}
