package com.ruoyi.ccb.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.ruoyi.ccb.domain.*;
import com.ruoyi.ccb.domain.basic.CargoDetail;
import com.ruoyi.ccb.domain.basic.CargoLockInfo;
import com.ruoyi.ccb.domain.basic.Page;
import com.ruoyi.ccb.domain.basic.SyncedOrg;
import com.ruoyi.ccb.service.CcbHttpService;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.warehouseBusiness.domain.TWarehousebillsitems;
import com.ruoyi.warehouseBusiness.service.IWarehouseBillsCcbService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * CCB-HTTP接口实现
 *
 * @author s
 */
@Service
@AllArgsConstructor
public class CcbHttpServiceImpl implements CcbHttpService {

    private final IWarehouseBillsCcbService ccbService;

    @Override
    public VoucherR takeVoucherIsExist(Voucher voucher) {
        // 库存帐查询
        List<Map<String, Object>> stockList = ccbService.getStockList(voucher.getTakeVoucher(), voucher.getUserName());

        VoucherR voucherR = new VoucherR();
        if (stockList.size() > 0) {
            voucherR.setIsExist("Y");
        } else {
            voucherR.setIsExist("N");
        }
        voucherR.setBeLongUser(voucher.getUserName());
        voucherR.setUscc(voucher.getUscc());
        return voucherR;
    }

    @Override
    public VoucherDetailR takeVoucherDetail(Voucher voucher) {
        // 库存帐查询
        List<CargoDetail> cargos = new ArrayList<>();
        List<Map<String, Object>> stockList = ccbService.getStockList(voucher.getTakeVoucher(), voucher.getUserName());
        stockList.forEach(map -> {
            String temp = JSON.toJSONString(map);

            CargoDetail detail = JSON.parseObject(temp, CargoDetail.class);
            detail.setNumberUnit("件");
            detail.setWeightUnit("千克");
            detail.setCargoBelong(voucher.getUserName());
            detail.setInStorageNumber(detail.getTakeVoucher());
            detail.setRemainNumber(detail.getNumberLeft());
            detail.setRemainWeight(detail.getWeightLeft());
            detail.setElectronicTags(ccbService.getLabel(detail.getTakeVoucher()));

            JSONObject object = JSON.parseObject(temp);
            if (!"0".equals(object.getString("lockStatus"))) {
                CargoLockInfo lockInfo = new CargoLockInfo();
                lockInfo.setCargoNo(detail.getCargoNo());
                lockInfo.setBlNumber(detail.getBlNumber());
                lockInfo.setCargoBelong(detail.getCargoBelong());
                lockInfo.setTakeVoucher(detail.getTakeVoucher());
                lockInfo.setNumber(detail.getNumberLeft());
                lockInfo.setNumberUnit(detail.getNumberUnit());
                lockInfo.setWeight(detail.getWeightLeft());
                lockInfo.setWeightUnit(detail.getWeightUnit());
                lockInfo.setSpeci(detail.getSpeci());
                lockInfo.setReasonCode("PLGL");
                lockInfo.setLockTime(object.getDate("lockTime"));
                lockInfo.setWrNumber(detail.getWrNumber());
                lockInfo.setElectronicTags(detail.getElectronicTags());
                detail.setLockInfo(lockInfo);
            }
            cargos.add(detail);
        });

        VoucherDetailR detailR = new VoucherDetailR();
        detailR.setTakeVoucher(voucher.getTakeVoucher());
        detailR.setStorageEnterpriseName(voucher.getUserName());
        detailR.setBondedStatus(0);
        detailR.setUserName(voucher.getUserName());
        detailR.setUscc(voucher.getUscc());
        detailR.setCargos(cargos);
        return detailR;
    }

    @Override
    public PledgeR cargoPledge(Pledge pledge) {
        List<String> billNoList = pledge.getCargos()
                .stream()
                .map(CargoDetail::getTakeVoucher)
                .collect(Collectors.toList());

        // 出质处理
        AjaxResult result = ccbService.lockStock(pledge.getNewUserName(), billNoList, false);

        PledgeR pledgeR = new PledgeR();
        pledgeR.setUserName(pledge.getUserName());
        pledgeR.setUscc(pledge.getUscc());
        pledgeR.setNewUserName(pledge.getNewUserName());
        pledgeR.setNewUserNameUscc(pledge.getNewUserNameUscc());
        pledgeR.setCargos(pledge.getCargos());
        if ((int) result.get("code") != 200) {
            pledgeR.setResult("N");
            pledgeR.setReason((String) result.get("msg"));
        } else {
            pledgeR.setResult("Y");
        }
        return pledgeR;
    }

    @Override
    public PledgeR cargoPledgeOut(Pledge pledge) {
        List<String> billNoList = pledge.getCargos()
                .stream()
                .map(CargoDetail::getTakeVoucher)
                .collect(Collectors.toList());

        // 解质处理
        AjaxResult result = ccbService.unlockStock(billNoList, false);

        PledgeR pledgeR = new PledgeR();
        pledgeR.setUserName(pledge.getNewUserName());
        pledgeR.setUscc(pledge.getNewUserNameUscc());
        pledgeR.setCargos(pledge.getCargos());
        if ((int) result.get("code") != 200) {
            pledgeR.setResult("N");
            pledgeR.setReason((String) result.get("msg"));
        } else {
            pledgeR.setResult("Y");
        }
        return pledgeR;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public InOutCargoR inCargoReq(InOutCargo inOutCargo) {
        List<TWarehousebillsitems> items = convert(inOutCargo.getCargos());
        AjaxResult result = ccbService.inAndOutStock("SJRK", items);

        InOutCargoR inOutCargoR = new InOutCargoR();
        inOutCargoR.setUserName(inOutCargo.getUserName());
        inOutCargoR.setUscc(inOutCargo.getUscc());
        inOutCargoR.setReqUser(inOutCargo.getReqUser());
        if ((int) result.get("code") != 200) {
            inOutCargoR.setResult("N");
            inOutCargoR.setReason((String) result.get("msg"));
        } else {
            inOutCargoR.setResult("Y");
        }
        return inOutCargoR;
    }

    @Override
    public InOutCargoR outCargoReq(InOutCargo inOutCargo) {
        List<TWarehousebillsitems> items = convert(inOutCargo.getCargos());
        AjaxResult result = ccbService.inAndOutStock("SJCK", items);

        InOutCargoR inOutCargoR = new InOutCargoR();
        inOutCargoR.setUserName(inOutCargo.getUserName());
        inOutCargoR.setUscc(inOutCargo.getUscc());
        inOutCargoR.setReqUser(inOutCargo.getReqUser());
        if ((int) result.get("code") != 200) {
            inOutCargoR.setResult("N");
            inOutCargoR.setReason((String) result.get("msg"));
        } else {
            inOutCargoR.setResult("Y");
            inOutCargoR.setReason("");
        }
        return inOutCargoR;
    }

    @Override
    public Page syncOrg(SyncOrg syncOrg) {
        Page page = syncOrg.getPage();
        if (ObjectUtil.isNull(page)) {
            page = new Page();
            page.setPageNo(1);
            page.setPageSize(10);
        }

        List<Map<String, Object>> orgList = ccbService.getSyncOrg(page.getPageNo(), page.getPageSize(), syncOrg.getRegisterAfter());
        page.setTotalRecords(new PageInfo<>(orgList).getTotal());

        List<SyncedOrg> orgListR = orgList.stream()
                .map(e -> JSON.parseObject(JSON.toJSONString(e), SyncedOrg.class))
                .collect(Collectors.toList());
        page.setContent(orgListR);
        return page;
    }

    @Override
    public PledgeR generateWrNumber(Pledge pledge) {
        List<CargoDetail> cargos = pledge.getCargos();
        List<String> billNoList = cargos.stream()
                .map(CargoDetail::getTakeVoucher)
                .collect(Collectors.toList());

        AjaxResult result = ccbService.unlockStock(billNoList, true);

        PledgeR pledgeR = new PledgeR();
        pledgeR.setUserName(pledge.getUserName());
        pledgeR.setUscc(pledge.getUscc());
        pledgeR.setNewUserName(pledge.getNewUserName());
        pledgeR.setNewUserNameUscc(pledge.getNewUserNameUscc());
        if ((int) result.get("code") != 200) {
            pledgeR.setResult("N");
            pledgeR.setReason((String) result.get("msg"));
        } else {
            pledgeR.setResult("Y");
            cargos.forEach(cargo -> cargo.setWrNumber(cargo.getTakeVoucher()));
        }
        pledgeR.setCargos(cargos);
        return pledgeR;
    }

    @Override
    public PledgeR cancelWrNumber(Pledge pledge) {
        List<String> billNoList = pledge.getCargos()
                .stream()
                .map(CargoDetail::getTakeVoucher)
                .collect(Collectors.toList());

        // 解质处理
        AjaxResult result = ccbService.unlockStock(billNoList, true);

        PledgeR pledgeR = new PledgeR();
        pledgeR.setUserName(pledge.getUserName());
        pledgeR.setUscc(pledge.getUscc());
        pledgeR.setNewUserName(pledge.getNewUserName());
        pledgeR.setNewUserNameUscc(pledge.getNewUserNameUscc());
        if ((int) result.get("code") != 200) {
            pledgeR.setResult("N");
            pledgeR.setReason((String) result.get("msg"));
        } else {
            pledgeR.setResult("Y");
        }
        pledgeR.setCargos(pledge.getCargos());
        return pledgeR;
    }

    /**
     * 查询提单号
     *
     * @param mblno 报文
     * @return 结果
     */
    @Override
    public MblnoR blNumberIsExist(Mblno mblno) {
        // 库存帐查询
        List<Map<String, Object>> stockList = ccbService.selectBlNumber(mblno.getBlNumber(), mblno.getUserName());
        //提单号返回信息
        MblnoR voucherR = new MblnoR();
        //判断该提单号是否存在
        if (stockList.size() > 0) {
            voucherR.setIsExist("Y");
        } else {
            voucherR.setIsExist("N");
        }
        voucherR.setBeLongUser(mblno.getUserName());
        voucherR.setUscc(mblno.getUscc());
        return voucherR;
    }


    /**
     * 提单号详情
     * @param mblno
     * @return
     */
    @Override
    public MblnoDetailR blNumberDetail(Mblno mblno) {
        // 货物信息集合
        List<CargoDetail> cargos = new ArrayList<>();
        //获取库存信息
        List<Map<String, Object>> stockList = ccbService.getStockList(mblno.getBlNumber(), mblno.getUserName());
        //遍历库存信息，将拿到的货物信息存入集合中
        stockList.forEach(map -> {
            String temp = JSON.toJSONString(map);

            //货物信息
            CargoDetail detail = JSON.parseObject(temp, CargoDetail.class);
            detail.setNumberUnit("件");
            detail.setWeightUnit("千克");
            detail.setCargoBelong(mblno.getUserName());
            detail.setInStorageNumber(detail.getTakeVoucher());
            detail.setRemainNumber(detail.getNumberLeft());
            detail.setRemainWeight(detail.getWeightLeft());
            detail.setElectronicTags(ccbService.getLabel(detail.getTakeVoucher()));
            detail.setBlNumber(mblno.getBlNumber());

            JSONObject object = JSON.parseObject(temp);
            //判断货物是否为锁定状态
            if (!"0".equals(object.getString("lockStatus"))) {
                //货物锁定信息
                CargoLockInfo lockInfo = new CargoLockInfo();
                lockInfo.setCargoNo(detail.getCargoNo());
                lockInfo.setBlNumber(detail.getBlNumber());
                lockInfo.setCargoBelong(detail.getCargoBelong());
                lockInfo.setTakeVoucher(detail.getTakeVoucher());
                lockInfo.setNumber(detail.getNumberLeft());
                lockInfo.setNumberUnit(detail.getNumberUnit());
                lockInfo.setWeight(detail.getWeightLeft());
                lockInfo.setWeightUnit(detail.getWeightUnit());
                lockInfo.setSpeci(detail.getSpeci());
                lockInfo.setReasonCode("PLGL");
                lockInfo.setLockTime(object.getDate("lockTime"));
                lockInfo.setWrNumber(detail.getWrNumber());
                lockInfo.setElectronicTags(detail.getElectronicTags());
                detail.setLockInfo(lockInfo);
            }
            cargos.add(detail);
        });

        //提单号返回信息
        MblnoDetailR detailR = new MblnoDetailR();
        detailR.setBlNumber(mblno.getBlNumber());
        detailR.setStorageEnterpriseName(mblno.getUserName());
        detailR.setBondedStatus(0);
        detailR.setUserName(mblno.getUserName());
        detailR.setUscc(mblno.getUscc());
        detailR.setCargos(cargos);
        return detailR;
    }

    /**
     * 数据转换
     *
     * @param cargos 出入库数据
     * @return 结果
     */
    private List<TWarehousebillsitems> convert(List<CargoDetail> cargos) {
        List<TWarehousebillsitems> items = new ArrayList<>();
        for (CargoDetail cargo : cargos) {
            TWarehousebillsitems item = new TWarehousebillsitems();
            item.setCargoNo(cargo.getCargoNo());
            item.setCargoBelong(cargo.getCargoBelong());
            item.setfMblno(cargo.getBlNumber());
            item.setfPackagespecs(cargo.getSpeci());
            item.setfOriginalbillno(cargo.getBlNumber());
            item.setfBillingway(3L);
            item.setfCntqty(1L);
            item.setWarehouseNo(cargo.getWarehouseNo());
            item.setShelvesNo(cargo.getShelvesName());

            if (ObjectUtil.isNotNull(cargo.getNumber())) {
                item.setfPlanqty(cargo.getNumber());
                item.setfQty(cargo.getNumber());
            } else {
                String[] s = String.valueOf(cargo.getWeight()).split("\\.");
                item.setfPlanqty(Long.parseLong(s[0]));
                item.setfQty(Long.parseLong(s[0]));
            }
            if (ObjectUtil.isNotNull(cargo.getWeight())) {
                item.setfPlangrossweight(BigDecimal.valueOf(cargo.getWeight()));
                item.setfPlannetweight(BigDecimal.valueOf(cargo.getWeight()));
                item.setfGrossweight(BigDecimal.valueOf(cargo.getWeight()));
                item.setfNetweight(BigDecimal.valueOf(cargo.getWeight()));
            } else {
                item.setfPlangrossweight(BigDecimal.valueOf(cargo.getNumber()));
                item.setfPlannetweight(BigDecimal.valueOf(cargo.getNumber()));
                item.setfGrossweight(BigDecimal.valueOf(cargo.getNumber()));
                item.setfNetweight(BigDecimal.valueOf(cargo.getNumber()));
            }

            // fSealno代替保税字段
            item.setfSealno(cargo.getBondedStatus());
            item.setfPlanvolumn(BigDecimal.ZERO);
            item.setfVolumn(BigDecimal.ZERO);
            item.setfBillstatus(10L);
            item.setElectronicTags(cargo.getElectronicTags());
            items.add(item);
        }
        return items;
    }

}
