package com.github.wxiaoqi.security.admin.biz;


import cn.hutool.json.JSONObject;
import com.github.wxiaoqi.security.admin.constant.enumerate.CompanyWalletITypeEnum;
import com.github.wxiaoqi.security.admin.constant.enumerate.CompanyWalletSourceEnum;
import com.github.wxiaoqi.security.admin.dto.BaseOrderAcceptDetailedDTO;
import com.github.wxiaoqi.security.admin.dto.OrderWaterDTO;
import com.github.wxiaoqi.security.admin.dto.WalletDetailDTO;
import com.github.wxiaoqi.security.admin.entity.BaseOrderRevenue;
import com.github.wxiaoqi.security.admin.entity.CompanyWalletDetail;
import com.github.wxiaoqi.security.admin.mapper.CompanyWalletDetailMapper;
import com.github.wxiaoqi.security.admin.vo.BaseOrderAcceptDetailedVO;
import com.github.wxiaoqi.security.admin.vo.CompanyWalletDetailVo;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.github.wxiaoqi.security.common.util.CollectorsUtil;
import com.github.wxiaoqi.security.common.util.process.ResultCode;
import com.github.wxiaoqi.security.common.vo.PageDataVO;
import com.github.wxiaoqi.security.admin.entity.CompanyWallet;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
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;


@Service
@Slf4j
public class CompanyWalletDetailBiz extends BaseBiz<CompanyWalletDetailMapper, CompanyWalletDetail> {


    @Autowired
    BaseOrderAcceptDetailedBiz  acceptDetailedBiz;

    @Autowired
    CompanyWalletBiz  companyWalletBiz;

    @Autowired
    BaseOrderRevenueBiz revenueBiz;






    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void addOrUpd(OrderWaterDTO orderWaterDTO){
        if (StringUtils.isBlank(orderWaterDTO.getOrderNo())){
            throw  new BaseException("订单号不存在",ResultCode.FAILED_CODE);
        }
        List<Integer> divisionTypes=new ArrayList<>();
        divisionTypes.add(3);
        divisionTypes.add(5);
        divisionTypes.add(6);
        divisionTypes.add(7);
        divisionTypes.add(8);
        BaseOrderAcceptDetailedDTO  acceptDetailedDTO =  BaseOrderAcceptDetailedDTO
                .builder()
                .orderNo(orderWaterDTO.getOrderNo())
                .divisionTypes(divisionTypes)
                .iType(CompanyWalletITypeEnum.COMPANY.getCode())
                .build();
        updByIdOrOrderNo(acceptDetailedDTO);
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void saveById(Integer acceptId){
        if (acceptId == null || acceptId == 0){
            throw  new BaseException("分账信息不存在",ResultCode.FAILED_CODE);
        }
        BaseOrderAcceptDetailedDTO  acceptDetailedDTO =  BaseOrderAcceptDetailedDTO
                .builder()
                .acceptId(acceptId)
                .iType(CompanyWalletITypeEnum.REGULATION.getCode())
                .build();
        updByIdOrOrderNo(acceptDetailedDTO);
    }

    public  void  updByIdOrOrderNo(BaseOrderAcceptDetailedDTO acceptDetailedDTO){
        List<BaseOrderAcceptDetailedVO> list = acceptDetailedBiz.getList(acceptDetailedDTO);
        List<CompanyWalletDetail> walletDetails = new ArrayList<>();
        List<BaseOrderRevenue> revenues = new ArrayList<>();
        String orderNo = "";
        if (list.size() > 0){
            for (BaseOrderAcceptDetailedVO acceptDetailedVO : list){
                BigDecimal divisionAmount = acceptDetailedVO.getDivisionAmount() == null ? BigDecimal.ZERO : acceptDetailedVO.getDivisionAmount();
                Integer source = setItype(acceptDetailedVO.getDivisionType());
                orderNo=acceptDetailedVO.getOrderNo();
                BaseOrderRevenue baseOrderRevenue = new BaseOrderRevenue();
                baseOrderRevenue.setCompanyId(acceptDetailedVO.getMchId());
                baseOrderRevenue.setAmount(divisionAmount);
                revenues.add(baseOrderRevenue);
                if (divisionAmount .compareTo(BigDecimal.ZERO) > 0 ){
                    Integer entryType = acceptDetailedVO.getEntryType() == null ? 0 : acceptDetailedVO.getEntryType();
                    if (entryType != 1){
                        log.info("----线下分账不入店铺明细----orderNo==="+acceptDetailedVO.getOrderNo()+"-----店铺id==="+acceptDetailedVO.getMchId());
                        continue;
                    }
                    CompanyWallet companyWallet=companyWalletBiz.selectById(acceptDetailedVO.getMchId());
                    BigDecimal companyAmount=BigDecimal.ZERO;
                    if (companyWallet != null){
                        companyAmount=companyWallet.getBalance();
                    }
                    CompanyWalletDetail companyWalletDetail = new CompanyWalletDetail();
                    companyWalletDetail.setCono(acceptDetailedVO.getOrderNo());
                    companyWalletDetail.setAmount(divisionAmount);
                    companyWalletDetail.setCompanyId(acceptDetailedVO.getMchId());
                    companyWalletDetail.setSAmount(companyAmount);
                    companyWalletDetail.setSource(source);
                    companyWalletDetail.setItype(acceptDetailedDTO.getIType());
                    insertSelective(companyWalletDetail);
                    walletDetails.add(companyWalletDetail);
                }
            }
        }
        Map<Integer, BigDecimal> amountSum = walletDetails.stream().filter(t -> t.getAmount() != null)
                .collect(Collectors.groupingBy(CompanyWalletDetail::getCompanyId, CollectorsUtil.summingBigDecimal(CompanyWalletDetail::getAmount)));
        amountSum.forEach((k,v) -> updCompanyWallet(k,v));

        //营收明细
        if (revenues.size() > 0){
            Map<Integer, BigDecimal> amounts = revenues.stream().filter(t -> t.getAmount() != null)
                    .collect(Collectors.groupingBy(BaseOrderRevenue::getCompanyId, CollectorsUtil.summingBigDecimal(BaseOrderRevenue::getAmount)));
            for(Map.Entry<Integer, BigDecimal> entry : amounts.entrySet()){
                Integer companyId = entry.getKey();
                BigDecimal amount = entry.getValue();
                BaseOrderRevenue  baseOrderRevenue = new BaseOrderRevenue();
                baseOrderRevenue.setAmount(amount);
                baseOrderRevenue.setCompanyId(companyId);
                baseOrderRevenue.setOrderNo(orderNo);
                baseOrderRevenue.setStatus(1);
                revenueBiz.addOrUpd(baseOrderRevenue);
            }
        }
    }


    public PageDataVO<CompanyWalletDetailVo> selectList(WalletDetailDTO walletDetailDTO) {
        return PageDataVO.pageInfo(walletDetailDTO.getPage(), walletDetailDTO.getLimit(), () -> getList(walletDetailDTO));
    }

    public List<CompanyWalletDetailVo> getList(WalletDetailDTO walletDetailDTO){
        return  mapper.selectList(walletDetailDTO);
    }


    public PageDataVO<CompanyWalletDetailVo> selectListByCompanyId(WalletDetailDTO walletDetailDTO) {
        return PageDataVO.pageInfo(walletDetailDTO.getPage(), walletDetailDTO.getLimit(), () -> walletDetail(walletDetailDTO));
    }

    public List<CompanyWalletDetailVo> walletDetail(WalletDetailDTO walletDetailDTO){
        return  mapper.walletDetail(walletDetailDTO);
    }

    public JSONObject  getSumAmount(WalletDetailDTO walletDetailDTO){
        List<Integer> itypes=new ArrayList<>();
        itypes.add(1);
        walletDetailDTO.setItypes(itypes);
        BigDecimal amount = mapper.sumAmount(walletDetailDTO);
        JSONObject jsonObject=new JSONObject();
        jsonObject.put("orderAmount",amount);
        itypes=new ArrayList<>();
        itypes.add(2);
        itypes.add(3);
        itypes.add(4);
        walletDetailDTO.setItypes(itypes);
        amount = mapper.sumAmount(walletDetailDTO);
        jsonObject.put("otherAmount",amount);
        CompanyWallet companyWallet=companyWalletBiz.sumAmount(walletDetailDTO);
        if (companyWallet != null ){
            jsonObject.put("balance",companyWallet.getBalance());
            jsonObject.put("withdrawals",companyWallet.getWithdrawals());
        }

        return jsonObject;
    }
    //更新钱包
    public void  updCompanyWallet(Integer companyId,BigDecimal amount){
        CompanyWallet companyWallet = companyWalletBiz.selectById(companyId);
        Long time=System.currentTimeMillis();
        if (companyWallet == null ){
            companyWallet=new CompanyWallet();
            companyWallet.setCompanyId(companyId);
            companyWallet.setBalance(amount);
            companyWallet.setLastIntime(time);
            companyWallet.setTotalAmount(amount);
            companyWalletBiz.insertSelective(companyWallet);
        }else {
            companyWallet.setTotalAmount(companyWallet.getTotalAmount().add(amount));
            companyWallet.setBalance(companyWallet.getBalance().add(amount));
            companyWallet.setLastIntime(time);
            companyWalletBiz.updCompanyWallet(companyWallet);
        }
    }


    public  Integer setItype(Integer divisionType){
        Integer source = 0;
        switch (divisionType){
            case 3 :
                source = CompanyWalletSourceEnum.WATER.getCode();
                break;
            case 5 :
                source = CompanyWalletSourceEnum.VEHICLE.getCode();
                break;
            case 6 :
                source = CompanyWalletSourceEnum.LOSS.getCode();
                break;
            case 7 :
                source = CompanyWalletSourceEnum.REGULATION.getCode();
                break;
            case 8 :
                source = CompanyWalletSourceEnum.VIOLATE.getCode();
                break;
        }

        return source;
    }




}
