package thyyxxk.webserver.service.medicine;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.taobao.api.response.AlibabaAlihealthDrugtraceTopYljgQueryCodedetailResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import thyyxxk.webserver.config.envionment.MedinsurConfig;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.dao.his.medicine.YpTracCodgDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.datamodify.YpInDetl;
import thyyxxk.webserver.entity.datamodify.YpOutDetl;
import thyyxxk.webserver.entity.medicalinsurance.manage.inventory.InvinfoDelete;
import thyyxxk.webserver.entity.medicalinsurance.manage.inventory.InvinfoModify;
import thyyxxk.webserver.entity.medicalinsurance.manage.inventory.PurcinfoBought;
import thyyxxk.webserver.entity.medicalinsurance.manage.inventory.SelinfoReturn;
import thyyxxk.webserver.entity.medicalinsurance.manage.inventory.SelinfoSold;
import thyyxxk.webserver.entity.medicine.DrugTracCodg;
import thyyxxk.webserver.entity.medicine.InvChgType;
import thyyxxk.webserver.entity.medicine.YpCodgDownload;
import thyyxxk.webserver.entity.medicine.YpCodgLine;
import thyyxxk.webserver.entity.medicine.YpCodgUpload;
import thyyxxk.webserver.entity.medicine.YpDictConstant;
import thyyxxk.webserver.entity.medicine.YpInvinfoModify;
import thyyxxk.webserver.entity.medicine.YpPurcinfoBought;
import thyyxxk.webserver.entity.medicine.YpSelinfoSold;
import thyyxxk.webserver.entity.medicine.YpTracCodg;
import thyyxxk.webserver.entity.medicine.YpTracType;
import thyyxxk.webserver.entity.medicine.vo.YpDetlVo;
import thyyxxk.webserver.service.medicalinsurance.SiInventoryService;
import thyyxxk.webserver.utils.DateUtil;
import thyyxxk.webserver.utils.ResultVoUtil;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName YpTracCodgService
 * @Author hsh
 * @Date 2025/4/21 0021 10:58
 * @Version 1.0
 * @Description 药品追溯码上传相关
 **/
@Service
@Slf4j
public class YpTracCodgService {
    private final YpTracCodgDao dao;
    private final SiInventoryService sv;
    private final YpPurcinfoBoughtService boughtService;
    private final YpTaoBaoService tbService;
    private final YpSelinfoSoldService soldService;
    private final YpInvinfoService invinfoService;
    private final MedinsurConfig cfg;
    private final YpCodgLineService lineService;

    @Autowired
    public YpTracCodgService(YpTracCodgDao dao,
                             SiInventoryService sv,
                             YpPurcinfoBoughtService boughtService,
                             YpTaoBaoService tbService,
                             YpSelinfoSoldService soldService,
                             YpInvinfoService invinfoService,
                             MedinsurConfig cfg,
                             YpCodgLineService lineService) {
        this.dao = dao;
        this.sv = sv;
        this.boughtService = boughtService;
        this.tbService = tbService;
        this.soldService = soldService;
        this.invinfoService = invinfoService;
        this.cfg = cfg;
        this.lineService = lineService;
    }

    public ResultVo<Map<String, Object>> selectGroupNoInfo(){
        Map<String, Object> resultMap = new HashMap<>();
        List<Map<String, String>> yfList = dao.selectGroupNoInfoYf();
        List<Map<String, String>> ykList = dao.selectGroupNoInfoYk();
        List<Map<String, String>> kcList = new ArrayList<>();
        for (InvChgType type : InvChgType.values()) {
            Map<String, String> map = new HashMap<>();
            map.put("value", type.code);
            map.put("label", type.name);
            kcList.add(map);
        }
        resultMap.put("yfList", yfList);
        resultMap.put("ykList", ykList);
        resultMap.put("kcList", kcList);
        return ResultVoUtil.success(resultMap);
    }

    public ResultVo<Map<String, Object>> selectSupplyType(){
        Map<String, Object> resultMap = new HashMap<>();
        List<Map<String, String>> supplyList = dao.selectSupplyType();
        resultMap.put("supplyList", supplyList);
        return ResultVoUtil.success(resultMap);
    }

    public ResultVo<Map<String, Object>> uploadYpSaleGoodsData(YpTracCodg dto){
        if(StringUtils.isBlank(dto.getInDocuNo())){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "退库单号为空，请检查！");
        }
        if(!dto.getInDocuNo().startsWith("T")){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, dto.getInDocuNo() + "为入库单号，请检查！");
        }
        Map<String, Object> resultMap = new HashMap<>();
        List<SelinfoSold> selinfo = dao.selectYpSaleGoodsData(dto.getInDocuNo(), cfg.getHospId(), cfg.getHospName());
        ResultVo<JSONObject> str = sv.saleGoods(selinfo);
        if(YpDictConstant.ERROR_STATUS == str.getCode()) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, str.getMessage());
        }
        resultMap.put("sucMsg", str.getMessage());
        resultMap.put("msg", "上传药品退库信息成功！");
        resultMap.put("selinfo", selinfo);
        return ResultVoUtil.success(resultMap);
    }

    /**
     * @Description 对应商品信息删除
     * @Author hsh
     * @param dto（1-盘存信息；2-库存变更信息；3-采购信息；4-销售信息）
     * @return map
     * @Date 2025/5/19 0019 10:04
     */
    public ResultVo<Map<String, Object>> deleteYpGoodsData(InvinfoDelete dto) {
        if(StringUtils.isBlank(dto.getFixmedinsBchno())){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "定点医药机构批次流水号为空，请检查！");
        }
        if(StringUtils.isBlank(dto.getInvDataType())){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "进销存数据类型为空，请检查！");
        }
        Map<String, Object> resultMap = new HashMap<>();
        List<InvinfoDelete> invinfoList = new ArrayList<>();
        invinfoList.add(dto);
        ResultVo<JSONObject> str = sv.deleteGoods(invinfoList);
        if(YpDictConstant.ERROR_STATUS == str.getCode()) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, str.getMessage());
        }
        resultMap.put("sucMsg", str.getMessage());
        resultMap.put("msg", "删除药品"  + YpTracType.findName(dto.getInvDataType()) + "成功！");
        resultMap.put("invinfoList", invinfoList);
        return ResultVoUtil.success(resultMap);
    }

    public ResultVo<Map<String, Object>> selectYpSalesGoods(YpTracCodg dto) {
        dto.setFixmedinsCode(cfg.getHospId());
        Map<String, Object> resultMap = new HashMap<>();
        ResultVo<JSONObject> str = sv.selectSalesGoods(dto);
        if(YpDictConstant.ERROR_STATUS == str.getCode()) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, str.getMessage());
        }
        resultMap.put("sucMsg", str.getMessage());
        resultMap.put("msg", "根据批次流水号【"  + dto.getFixmedinsBchno() + "】查询药品销售信息成功！");
        resultMap.put("invinfoList", str.getData());
        return ResultVoUtil.success(resultMap);
    }

    public ResultVo<Map<String, Object>> selectDownloadCodgBchno(YpCodgDownload dto) {
        dto.setFixmedinsCode(cfg.getHospId());
        dto.setFixmedinsName(cfg.getHospName());
        dto.setUpldStas("1");
        if(StringUtils.isBlank(dto.getDelventpUscc()) || StringUtils.isBlank(dto.getDelventpName())){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "配送企业信用代码或者配送企业单位名称为空，请检查！");
        }
        // 如果下载的追溯码有已经销售记录的不允许重新下载
        YpDetlVo vo = new YpDetlVo();
        vo.setUploadFlag("1");
        vo.setReptNo(dto.getDelvBchno());
        vo.setSupplyId(dto.getDelventpUscc());
        ResultVo<List<YpCodgLine>> resultVo = lineService.selectYpCodgLineData(vo);
        List<YpCodgLine> lines = resultVo.getData();
        if(!lines.isEmpty()){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "已有销售数据不能重新下载追溯信息，请检查！");
        }
        Map<String, Object> resultMap = new HashMap<>();
        ResultVo<JSONObject> str = sv.selectDownloadCodgBchno(dto);
        if(YpDictConstant.ERROR_STATUS == str.getCode()) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, str.getMessage());
        }
        JSONObject obj = str.getData();
        List<YpCodgLine> list = new ArrayList<>();
        if("0".equals(obj.getString("infcode"))){
            JSONArray jsonArray = obj.getJSONObject("output").getJSONArray("data");
            if(jsonArray.isEmpty()){
                return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR,
                        "根据配送企业【"  + dto.getDelventpName() + "】的批次【" + dto.getDelvBchno() + "】查询企业追溯码下载信息为空，请检查！");
            }
            list = jsonArray.toJavaList(YpCodgLine.class);
            // 保存企业追溯下载信息
            lineService.updateYpCodgLineBatch(list);
        }
        resultMap.put("sucMsg", str.getMessage());
        resultMap.put("msg", "根据配送企业【"  + dto.getDelventpName() + "】的批次【" + dto.getDelvBchno() + "】查询企业追溯码下载信息成功！总共：" + list.size() + "条。");
        resultMap.put("codgList", list);
        return ResultVoUtil.success(resultMap);
    }

    /**
     * @Description 根据入/出库单号或者药品编码询商品采购信息
     * @Author hsh
     * @param dto 入/出库单号或者药品编码(type: 1 入库， 2 退库)
     * @return list 商品采购信息
     * @Date 2025/5/26 0026 16:42
     */
    public ResultVo<List<YpPurcinfoBought>> selectYpPurchaseDetail(YpCodgUpload dto) {
        if(StringUtils.isBlank(dto.getGroupNo())){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "查询药品入库/退货信息， 请选择药库！");
        }
        List<YpPurcinfoBought> purcinfoList = new ArrayList<>();
        if("1".equals(dto.getType())){
            purcinfoList = dao.selectYpPurchaseGoodsDetail(dto);
        } else if("2".equals(dto.getType())){
            purcinfoList = dao.selectYpPurchaseGoodsTkDetail(dto);
        }
        return ResultVoUtil.success(purcinfoList);
    }

    /**
     * @Description 批量上传药品入库记录 3503A 接口
     * @Author hsh
     * @param list 药品入库记录
     * @return map
     * @Date 2025/5/27 0027 15:01
     */
    public ResultVo<Map<String, Object>> uploadYpPurchaseBatch(List<YpPurcinfoBought> list) {
        Map<String, Object> resultMap = new HashMap<>();
        if(null == list || list.isEmpty()){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有入库数量，请检查！");
        }
        List<PurcinfoBought> boughtS = new ArrayList<>();
        for(YpPurcinfoBought yp : list){
            PurcinfoBought pb = new PurcinfoBought();
            BeanUtils.copyProperties(yp, pb);
            boughtS.add(pb);
        }
        ResultVo<String> str = sv.purchaseGoods(boughtS);
        if(YpDictConstant.ERROR_STATUS == str.getCode()) {
            callSaveYpPurcinfoBoughtData(list, str.getMessage(), YpDictConstant.UPLOAD_ERROR);
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, str.getMessage());
        }
        callSaveYpPurcinfoBoughtData(list, str.getMessage(), YpDictConstant.UPLOAD_SUCCESS);
        resultMap.put("sucMsg", str.getMessage());
        resultMap.put("msg", "上传药品入库信息成功！");
        resultMap.put("purcinfoList", boughtS);
        return ResultVoUtil.success(resultMap);
    }

    /**
     * @Description 上传结果信息处理
     * @Author hsh
     * @param list 上传结果数据
     * @param message 上传结果信息
     * @param uploadFlag 上传结果信息类型标志
     * @Date 2025/5/29 0029 9:24
     */
    private void callSaveYpPurcinfoBoughtData(@NotNull List<YpPurcinfoBought> list, String message, String uploadFlag) {
        for(YpPurcinfoBought b : list){
            b.setCreateTime(DateUtil.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
            b.setMsgErr(message);
            b.setUploadFlag(uploadFlag);
        }
        boughtService.updateYpPurcinfoBoughtBatch(list);
    }

    /**
     * @Description 批量上传药品退货记录 3504A接口
     * @Author hsh
     * @param list 药品退货记录
     * @return map
     * @Date 2025/5/27 0027 15:06
     */
    public ResultVo<Map<String, Object>> uploadYpPurchaseReturnBatch(List<YpPurcinfoBought> list) {
        Map<String, Object> resultMap = new HashMap<>();
        if(null == list || list.isEmpty()){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有退货数量，请检查！");
        }
        List<PurcinfoBought> boughtS = new ArrayList<>();
        for(YpPurcinfoBought yp : list){
            PurcinfoBought pb = new PurcinfoBought();
            BeanUtils.copyProperties(yp, pb);
            boughtS.add(pb);
        }
        ResultVo<String> str = sv.returnGoods(boughtS);
        if(YpDictConstant.ERROR_STATUS == str.getCode()) {
            callSaveYpPurcinfoBoughtData(list, str.getMessage(), YpDictConstant.UPLOAD_ERROR);
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, str.getMessage());
        }
        callSaveYpPurcinfoBoughtData(list, str.getMessage(), YpDictConstant.UPLOAD_SUCCESS);
        resultMap.put("sucMsg", str.getMessage());
        resultMap.put("msg", "上传药品退货信息成功！");
        return ResultVoUtil.success(resultMap);
    }

    /**
     * @Description 根据id，type等删除上传信息 3507A接口
     * @Author hsh
     * @param list 上传信息（1-盘存信息；2-库存变更信息；3-采购信息；4-销售信息）
     * @return map
     * @Date 2025/5/27 0027 20:19
     */
    public ResultVo<Map<String, Object>> deleteYpUploadBatch(List<YpCodgUpload> list) {
        Map<String, Object> resultMap = new HashMap<>();
        if(null == list || list.isEmpty()){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有可删除的数据，请检查！");
        }

        /*
         * type: 1,2是商品采购与退货上传（目前是废弃状态） 3,4是商品销售与退货 0是商品库存变化 其他没有
         */
        String type = list.get(0).getType();
        if(StringUtils.isBlank(type)){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "进销存数据类型【 " + type +  " 】为空，请检查！");
        }
        List<InvinfoDelete> invinfoList = new ArrayList<>();
        String invDataType = "";
        switch (type) {
            case "1":
            case "2":
                invDataType = YpTracType.THREE.getCode();
                break;
            case "3":
            case "4":
                invDataType = YpTracType.FOUR.getCode();
                break;
            case "0":
                invDataType = YpTracType.TWO.getCode();
                break;
        }
        if(StringUtils.isBlank(invDataType)){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "对应的进销存数据类型【 " + invDataType +  " 】为不匹配，请检查！");
        }
        for(YpCodgUpload up : list){
            InvinfoDelete dl = new InvinfoDelete();
            dl.setInvDataType(invDataType);
            dl.setFixmedinsBchno(up.getFixmedinsBchno());
            invinfoList.add(dl);
        }
        ResultVo<JSONObject> str = sv.deleteGoods(invinfoList);
        if(YpDictConstant.ERROR_STATUS == str.getCode()) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, str.getMessage());
        }
        JSONObject result = str.getData();
        JSONObject output = result.getJSONObject("output");
        JSONArray errDetail = output.getJSONArray("selinfoErrDetail");
        if(null != errDetail){
            List<Map> errList = errDetail.toJavaList(Map.class);
            String msg = String.valueOf(errList.get(0).get("msgRslt"));
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "批量删除药品" + YpTracType.findName(invDataType) + "失败： " + msg);
        }
        switch (type) {
            case "1":
            case "2":
                break;
            case "3":
            case "4":
                soldService.updateYpSelinfoSoldBatchByCode(list);
                break;
            case "0":
                invinfoService.updateYpInvinfoBatchByCode(list);
                break;
        }

        resultMap.put("sucMsg", str.getMessage());
        resultMap.put("msg", "批量删除药品"  + YpTracType.findName(invDataType) + "成功！");
        return ResultVoUtil.success(resultMap);
    }

    /**
     * @Description 更新药品退库发票号
     * @Author hsh
     * @param bought 药品退库发票号信息
     * @return map
     * @Date 2025/5/27 0027 22:41
     */
    public ResultVo<Map<String, Object>> saveYpInvoice(YpPurcinfoBought bought) {
        Map<String, Object> resultMap = new HashMap<>();
        if (null == bought || StringUtils.isBlank(bought.getInDocuNo()) || StringUtils.isBlank(bought.getInSeri())) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有找到退库单号信息，请检查！");
        }
        if (StringUtils.isBlank(bought.getMedListCodg()) || StringUtils.isBlank(bought.getSerial())) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有找到药品编码或者包装信息，请检查！");
        }
        int c = dao.selectYpInvoiceData(bought.getInDocuNo(), bought.getInSeri(), bought.getMedListCodg(), bought.getSerial());
        if(c != 1){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有找到药品【" + bought.getMedListCodg() + "】退库单号信息，请检查！");
        }
        int sd = dao.updateYpInvoice(bought.getInDocuNo(), bought.getInSeri(),
                bought.getMedListCodg(), bought.getSerial(), bought.getPurcInvoNo());
        if(sd == 0){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "根据【" + bought.getInDocuNo() + "】退库单号更新发票号失败，请检查！");
        }
        resultMap.put("msg", "更新发票号成功！");
        return ResultVoUtil.success(resultMap);
    }

    /**
     * @Description 根据病人信息查询商品销售/销售退货信息
     * @Author hsh
     * @param dto 病人信息
     * @return list
     * @Date 2025/5/29 0029 11:14
     */
    public ResultVo<List<YpSelinfoSold>> selectYpSelinfoDetail(YpCodgUpload dto){
        if(StringUtils.isBlank(dto.getGroupNo())){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "查询商品销售/销售退货信息， 请选择药房！");
        }
        List<YpSelinfoSold> selinfoList = new ArrayList<>();
        if(YpDictConstant.MZ_XYF_NO.equals(dto.getGroupNo())){
            if("3".equals(dto.getType())){
                // 销售待上传数据
                selinfoList = dao.selectYpSelinfoSoldDetailByXyf(dto);
            } else if("4".equals(dto.getType())){
                // 销售退货待上传数据
                selinfoList = dao.selectYpSelinfoSoldThDetailByXyf(dto);
            }
        }
        return ResultVoUtil.success(selinfoList);
    }

    /**
     * @Description 批量上传药品销售信息
     * @Author hsh
     * @param list 药品销售信息
     * @return map
     * @Date 2025/5/30 0030 9:16
     */
    public ResultVo<Map<String, Object>> uploadYpSelinfoBatch(List<YpSelinfoSold> list) {
        Map<String, Object> resultMap = new HashMap<>();
        if(null == list || list.isEmpty()){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有销售数量，请检查！");
        }
        List<SelinfoSold> selinfoS = new ArrayList<>();
        int fail = 0;
        for(YpSelinfoSold yp : list){
            SelinfoSold pb = new SelinfoSold();
            yp.setIsTy("0");
            String msg = callYpCodgInfo(yp, "0");
            if(StringUtils.isNotBlank(msg)){
                yp.setMsgErr(msg);
                yp.setUploadFlag("0");
                fail++;
                continue;
            }
            BeanUtils.copyProperties(yp, pb);
            selinfoS.add(pb);
        }
        if(selinfoS.isEmpty()){
            soldService.updateYpSelinfoSoldBatch(list);
            resultMap.put("msg", "批量上传药品销售信息结果： 成功【" + (list.size() - fail) + "】条，失败【" + fail + "】条。");
            return ResultVoUtil.success(resultMap);
        }
        ResultVo<JSONObject> str = sv.saleGoods(selinfoS);
        if(YpDictConstant.ERROR_STATUS == str.getCode()){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "批量上传药品销售信息失败：" + str.getMessage());
        }
        JSONObject result = str.getData();
        JSONObject output = result.getJSONObject("output");
        JSONArray s = output.getJSONArray("selinfoDetail");
        List<Map> sd = s.toJavaList(Map.class);
        for(Map m : sd){
            String retRslt = String.valueOf(m.get("retRslt"));
            String fixmedinsBchno = String.valueOf(m.get("fixmedins_bchno"));
            if(YpDictConstant.UPLOAD_ERROR.equals(retRslt)){
                fail++;
            }
            for(YpSelinfoSold in : list){
                if(in.getFixmedinsBchno().equals(fixmedinsBchno)){
                    in.setUploadFlag(retRslt);
                    in.setMsgErr(m.get("msgRslt") == null ? "" : String.valueOf(m.get("msgRslt")));
                    in.setCreateTime(DateUtil.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
                }
            }
        }
        soldService.updateYpSelinfoSoldBatch(list);
        resultMap.put("msg", "批量上传药品销售信息结果： 成功【" + (list.size() - fail) + "】条，失败【" + fail + "】条。");
        return ResultVoUtil.success(resultMap);
    }

    /**
     * @Description 查询药品追溯码信息并找到追溯码的药品信息
     * @Author hsh
     * @param yp 上传药品信息
     * @param isTy 0: 销售药品； 1：销售退药
     * @Date 2025/5/30 0030 10:49
     */
    private String callYpCodgInfo(YpSelinfoSold yp, String isTy) {
        String tableName = "0".equals(isTy) ? "mz_drug_trac_codg" : "mz_drug_trac_codg_ty";
        List<Map<String, String>> zsmList = dao.selectCodgInfoById(
                tableName, yp.getPatNo(), yp.getTimes(), yp.getChargeCode(), yp.getSerial());
        if(null != zsmList && !zsmList.isEmpty()){
            List<DrugTracCodg> list = new ArrayList<>();
            String ypCodg = "";
            String errCodg = "";
            String confirmTime = "";
            for(Map<String, String> map : zsmList){
                String c = map.get("ypCodg");
                if(null != c && c.length() != 20){
                    errCodg = c;
                    continue;
                }
                if(StringUtils.isBlank(ypCodg)){
                    ypCodg = c;
                    confirmTime = map.get("confirmTime");
                }
                DrugTracCodg codg = new DrugTracCodg();
                codg.setDrugTracCodg(c);
                list.add(codg);
            }
            if(StringUtils.isBlank(ypCodg)){
                return "门诊号【" + yp.getPatNo() + "】找到的销售药品追溯码【"+ errCodg + "】不正确，请检查！";
            }
            yp.setDrugtracinfo(list);
            if(zsmList.size() > 1){
                StringBuilder strCodg = new StringBuilder();
                List<List<Map<String, String>>> split = CollUtil.split(zsmList, 10);
                for(int i = 0; i < split.size(); ++i){
                    List<Map<String, String>> cl = split.get(i);
                    StringBuilder s = new StringBuilder();
                    for(int j = 0; i < cl.size(); ++i){
                        String codg = cl.get(i).get("ypCodg");
                        if(cl.size() - 1  == i){
                            s.append(codg);
                        } else {
                            s.append(codg).append(",");
                        }
                    }
                    if(split.size() > 1){
                        strCodg.append(s);
                    } else {
                        if(split.size() - 1  == i){
                            strCodg.append(s);
                        } else {
                            strCodg.append(s).append(",");
                        }
                    }
                }
                yp.setDrugTracCodg(String.valueOf(strCodg));
            }
            ResultVo<Map<String, Object>> resultVo = tbService.queryCodeDetail(ypCodg);
            Map<String, Object> map = resultVo.getData();
            if(null == map){
                return resultVo.getMessage();
            }
            List<AlibabaAlihealthDrugtraceTopYljgQueryCodedetailResponse.CodeFullInfoDto> ss = (List<AlibabaAlihealthDrugtraceTopYljgQueryCodedetailResponse.CodeFullInfoDto>) map.get("data");
            yp.setManuDate(ss.get(0).getCodeProduceInfoDTO().getProduceInfoList().get(0).getProduceDateStr());
            yp.setManuLotnum(ss.get(0).getCodeProduceInfoDTO().getProduceInfoList().get(0).getBatchNo());
            yp.setExpyEnd(ss.get(0).getCodeProduceInfoDTO().getProduceInfoList().get(0).getExpireDate());
            YpInDetl inDetl = dao.selectCodgInfoProdTime(yp.getChargeCode(), yp.getSerial(), yp.getManuLotnum(), confirmTime);

            if(null == inDetl){
                if(YpDictConstant.SERIAL_01.equals(yp.getSerial())){
                    YpInDetl deal = dao.selectCodgInfoProdTime(yp.getChargeCode(), YpDictConstant.SERIAL_99, yp.getManuLotnum(), confirmTime);
                    if(null == deal){
                        return "批量上传药品销售失败，根据追溯码【" + ypCodg +
                                "】查出药品【" + ss.get(0).getDrugEntBaseDTO().getPhysicName() + "】品名，生产批号【"
                                + ss.get(0).getCodeProduceInfoDTO().getProduceInfoList().get(0).getBatchNo()
                                + "】与销售药品【" + yp.getChargeName() + "】品名不符合或者生产批号不存在，请核对！" ;
                    } else {
                        yp.setTrdnFlag("1");
                        yp.setFixmedinsBchno(StringUtils.trim(deal.getInDocuNo()) + "_" + deal.getInSeri());
                    }
                } else {
                    return "批量上传药品销售失败，根据追溯码【" + ypCodg +
                            "】查出药品【" + ss.get(0).getDrugEntBaseDTO().getPhysicName() + "】品名，生产批号【"
                            + ss.get(0).getCodeProduceInfoDTO().getProduceInfoList().get(0).getBatchNo()
                            + "】与销售药品【" + yp.getChargeName() + "】品名不符合或者生产批号不存在，请核对！" ;
                }
            } else {
                yp.setTrdnFlag("0");
                yp.setFixmedinsBchno(StringUtils.trim(inDetl.getInDocuNo()) + "_" + inDetl.getInSeri());
            }
            yp.setDrugTracCodg(ypCodg);
        } else {
            YpOutDetl outDetl = dao.selectCodgInfoManu(yp.getChargeCode(), yp.getGroupNo());
            if(null != outDetl){
                YpInDetl inDetl = dao.selectCodgInfoProdTime(outDetl.getChargeCode(), outDetl.getSerial(), outDetl.getManuNo(), DateUtil.formatDate(outDetl.getConfirmDate(), "yyyy-MM-dd HH:mm:ss"));
                if(null != inDetl){
                    yp.setManuLotnum(StringUtils.trim(inDetl.getManuNo()));
                    yp.setManuDate(DateUtil.formatDate(inDetl.getProducingDate(), "yyyy-MM-dd"));
                    yp.setFixmedinsBchno(StringUtils.trim(inDetl.getInDocuNo()) + "_" + inDetl.getInSeri());
                    if(outDetl.getSerial().equals(yp.getSerial())){
                        yp.setTrdnFlag("0");
                    } else {
                        yp.setTrdnFlag("1");
                    }
                }
            }
        }
        return "";
    }

    /**
     * @Description 批量上传药品销售退货信息
     * @Author hsh
     * @param list 药品销售退货信息
     * @return map
     * @Date 2025/5/30 0030 9:23
     */
    public ResultVo<Map<String, Object>> uploadYpSelinfoReturnBatch(List<YpSelinfoSold> list) {
        Map<String, Object> resultMap = new HashMap<>();
        if(null == list || list.isEmpty()){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有销售退货数量，请检查！");
        }
        String type = list.get(0).getType();
        List<SelinfoReturn> selinfoS = new ArrayList<>();
        for(YpSelinfoSold yp : list){
            SelinfoReturn pb = new SelinfoReturn();
            yp.setIsTy("1");
            callYpCodgInfo(yp, type);
            BeanUtils.copyProperties(yp, pb);
            selinfoS.add(pb);
        }
        ResultVo<JSONObject> str = sv.returnSales(selinfoS);
        if(YpDictConstant.ERROR_STATUS == str.getCode()){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "批量上传药品销售退货信息失败：" + str.getMessage());
        }
        JSONObject result = str.getData();
        JSONObject output = result.getJSONObject("output");
        JSONArray errDetail = output.getJSONArray("selinfoErrDetail");
        if(null != errDetail){
            List<Map> errList = errDetail.toJavaList(Map.class);
            String msg = String.valueOf(errList.get(0).get("msgRslt"));
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "批量上传药品销售退货信息失败：" + msg);
        }
        JSONArray s = output.getJSONArray("selinfoDetail");
        List<Map> sd = s.toJavaList(Map.class);
        boolean status = false;
        for(Map m : sd){
            String retRslt = String.valueOf(m.get("retRslt"));
            String fixmedinsBchno = String.valueOf(m.get("fixmedins_bchno"));
            if(YpDictConstant.UPLOAD_ERROR.equals(retRslt)){
                status = true;
            }
            for(YpSelinfoSold in : list){
                if(in.getFixmedinsBchno().equals(fixmedinsBchno)){
                    in.setUploadFlag("-2");
                    in.setMsgErr(m.get("msgRslt") == null ? "" : String.valueOf(m.get("msgRslt")));
                    in.setCreateTime(DateUtil.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
                }
            }
        }
        soldService.updateYpSelinfoSoldBatch(list);
        if(status){
            resultMap.put("msg", "批量上传药品销售退货信息存在失败情况，请检查！");
        } else {
            resultMap.put("msg", "批量上传药品销售退货信息全部成功！");
        }
        return ResultVoUtil.success(resultMap);
    }

    /**
     * @Description ai 查询库存变更记录
     * @Author hsh
     * @param dto 参数
     * @return list
     * @Date 2025/6/4 0004 16:02
     */
    public ResultVo<List<YpInvinfoModify>> selectYpInvinfoDetail(YpCodgUpload dto){
        if(StringUtils.isBlank(dto.getGroupNo())){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "查询药品库存变更信息， 请选择药库！");
        }
        if(StringUtils.isBlank(dto.getInvChgType())){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "查询药品库存变更信息， 请选择库存变更类型！");
        }
        List<YpInvinfoModify> invinfoList = new ArrayList<>();
        if(StringUtils.isNotEmpty(dto.getDocuNo())){
            dto.setStartTime(null);
            dto.setEndTime(null);
        }
        List<YpInvinfoModify> invinfoRk = dao.selectYpInvinfoModifyDetailRk(dto);
        if(null != invinfoRk && !invinfoRk.isEmpty()){
            for (YpInvinfoModify mo : invinfoRk){
                String type = mo.getType();
                if("0".equals(type)){
                    // 入库(药品入库视为采购入库)
                    mo.setInvChgType(InvChgType.SP_RK.code);
                    mo.setInvChgTypeName(InvChgType.SP_RK.name);
                } else if("1".equals(type)){
                    // 退货(药品退货视为其他出库)
                    mo.setInvChgType(InvChgType.SP_CK.code);
                    mo.setInvChgTypeName(InvChgType.SP_CK.name);
                } else {
                    mo.setInvChgType(InvChgType.QT_RK.code);
                    mo.setInvChgTypeName(InvChgType.QT_RK.name);
                }
            }
            invinfoList.addAll(invinfoRk.stream().filter(item ->
                    dto.getInvChgType().equals(item.getInvChgType())).collect(Collectors.toList()));
        }
//        List<YpInvinfoModify> invinfoCk = dao.selectYpInvinfoModifyDetailCk(dto);
//        if(null != invinfoCk && !invinfoCk.isEmpty()){
//            for (YpInvinfoModify mo : invinfoCk){
//                String type = mo.getType();
//                if("0".equals(type)){
//                    // 出库(药品出库视为调拨出库)
//                    mo.setInvChgType(InvChgType.TB_CK.code);
//                    mo.setInvChgTypeName(InvChgType.TB_CK.name);
//                } else if("2".equals(type)){
//                    // 退库(药房退回药库，视为调拨入库)
//                    mo.setInvChgType(InvChgType.TB_RK.code);
//                    mo.setInvChgTypeName(InvChgType.TB_RK.name);
//                } if("8".equals(type)){
//                    // 盘点(盘点盈亏都算作盘盈，只不过盘亏数量是负的)
//                    mo.setInvChgType(InvChgType.PY.code);
//                    mo.setInvChgTypeName(InvChgType.PY.name);
//                } if("1".equals(type)){
//                    // 报损(视为销毁)
//                    mo.setInvChgType(InvChgType.XH.code);
//                    mo.setInvChgTypeName(InvChgType.XH.name);
//                } else {
//                    mo.setInvChgType(InvChgType.QT_RK.code);
//                    mo.setInvChgTypeName(InvChgType.QT_RK.name);
//                }
//            }
//            invinfoList.addAll(invinfoCk);
//        }
        return ResultVoUtil.success(invinfoList);
    }

    /**
     * @Description 批量上传药品库存变更信息
     * @Author hsh
     * @param list 药品库存变更信息
     * @return map
     * @Date 2025/6/4 0004 16:55
     */
    public ResultVo<Map<String, Object>> uploadYpInvinfoBatch(List<YpInvinfoModify> list){
        Map<String, Object> resultMap = new HashMap<>();
        if(null == list || list.isEmpty()){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有库存变更数量，请检查！");
        }
        List<InvinfoModify> invinfoS = new ArrayList<>();
        for(YpInvinfoModify yp : list){
            InvinfoModify pb = new InvinfoModify();
            BeanUtils.copyProperties(yp, pb);
            invinfoS.add(pb);
        }
        ResultVo<JSONObject> str = sv.modifyInvinfo(invinfoS);
        if(YpDictConstant.ERROR_STATUS == str.getCode()){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "批量上传药品库存变更信息失败：" + str.getMessage());
        }
        JSONObject result = str.getData();
        JSONObject output = result.getJSONObject("output");
        JSONArray s = output.getJSONArray("invinfoErrDetail");
        List<Map> sf = s.toJavaList(Map.class);
        boolean status = false;
        for(Map m : sf){
            String retRslt = String.valueOf(m.get("retRslt"));
            String fixmedinsBchno = String.valueOf(m.get("fixmedins_bchno"));
            if(YpDictConstant.UPLOAD_ERROR.equals(retRslt)){
                status = true;
            }
            for(YpInvinfoModify in : list){
                if(in.getFixmedinsBchno().equals(fixmedinsBchno)){
                    in.setUploadFlag(retRslt);
                    in.setMsgErr(m.get("msgRslt") == null ? "" : String.valueOf(m.get("msgRslt")));
                    in.setCreateTime(DateUtil.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
                }
            }
        }

        invinfoService.updateYpInvinfoBatch(list);
        resultMap.put("sucMsg", str.getMessage());
        if(status){
            resultMap.put("msg", "批量上传药品库存变更信息存在失败情况，请检查！");
        } else {
            resultMap.put("msg", "批量上传药品库存变更信息全部成功！");
        }
        return ResultVoUtil.success(resultMap);
    }

}
