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


import com.github.wxiaoqi.security.admin.dto.*;
import com.github.wxiaoqi.security.admin.entity.*;
import com.github.wxiaoqi.security.admin.mapper.BaseOrderAcceptDetailedMapper;
import com.github.wxiaoqi.security.admin.vo.BaseOrderAcceptDetailedVO;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.util.process.ResultCode;
import com.xxfc.platform.order.entity.OrderRentVehicleDetail;
import com.xxfc.platform.order.entity.inter.OrderDetail;
import com.xxfc.platform.order.feign.OrderFeign;
import com.xxfc.platform.order.pojo.dto.OrderDetailDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
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 tk.mybatis.mapper.entity.Example;
import java.math.BigDecimal;
import java.util.*;

/**
 * 订单分账表
 *
 * @author zjw
 * @email 18178966185@163.com
 * @date 2019-07-11 14:14:54
 */
@Service
@Slf4j
public class BaseOrderAcceptDetailedBiz extends BaseBiz<BaseOrderAcceptDetailedMapper, BaseOrderAcceptDetailed> {


    @Autowired
    AppUserRelationBiz relationBiz;

    @Autowired
    BaseGoodCommissionBiz commissionBiz;

    @Autowired
    AppUserPositionBiz positionBiz;

    @Autowired
    AppUserDetailBiz detailBiz;

    @Autowired
    MyWaterBiz myWaterBiz;

    @Autowired
    BaseCommissionRatioBiz commissionRatioBiz;

    @Autowired
    BranchCompanyBiz companyBiz;

    @Autowired
    AppUserSellingWaterBiz sellingWaterBiz;

    @Autowired
    OrderFeign orderFeign;

    @Autowired
    CompanyWalletDetailBiz companyWalletDetailBiz;

    @Autowired
    BaseOrderRevenueBiz revenueBiz;


    //计算用户拥金
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void orderWater(OrderWaterDTO orderWaterDTO) {
        //订单状态
        log.info("进入分账----orderWater------status===" + orderWaterDTO.getStatus()+"---orderNo==="+orderWaterDTO.getOrderNo());
        Integer status = orderWaterDTO.getStatus();
        if (status == null || status == 0) {
            log.info("分账----orderWater----参数不能为空----status===" + status);
            return;
        }
        ObjectRestResponse<OrderDetailDTO> restResponse = orderFeign.getOrderDetail(orderWaterDTO.getOrderNo(), status);
        if (restResponse.getData() == null ){
            log.info("分账----订单信息不存在----参数不能为空---" );
            return;
        }
        OrderDetailDTO orderDetailDTO = restResponse.getData();
        if (status == 1) {
            payOrderAccept(orderWaterDTO,orderDetailDTO);
            revenueBiz.saveRevenue(orderWaterDTO);
        } else if (status == 2) {
            BigDecimal acceptAmount = orderDetailDTO.getAcceptAmount();
            log.info("分账----acceptAmount===="+acceptAmount );
            orderWaterDTO.setOrderAmount(acceptAmount);
            finishOrderAccept(orderWaterDTO,orderDetailDTO);
            sellingWaterBiz.updWalletByOrderId(orderWaterDTO);
            companyWalletDetailBiz.addOrUpd(orderWaterDTO);
        }else if (status == 3){
            Integer acceptId = othderAccept(orderDetailDTO);
            if (acceptId != null && acceptId > 0){
                companyWalletDetailBiz.saveById(acceptId);
            }
        }else if (status == 4){
            refundOrderAccept(orderWaterDTO);
            sellingWaterBiz.updWalletByOrderId(orderWaterDTO);
            companyWalletDetailBiz.addOrUpd(orderWaterDTO);
        }
    }

    //下单分账
    public void payOrderAccept(OrderWaterDTO orderWaterDTO,OrderDetailDTO orderDetailDTO) {
        //订单id
        Integer orderId = orderDetailDTO.getOrderId() == null ? 0 : orderDetailDTO.getOrderId();
        //订单号
        String orderNo = orderDetailDTO.getOrderNo();
        //用户id
        Integer userId = orderDetailDTO.getUserId()  == null ? 0 : orderDetailDTO.getUserId();

        OrderRentVehicleDetail rentVehicleDetail = orderDetailDTO.getRentVehicleDetail();


        Integer companyId = rentVehicleDetail.getVehicleManageCompanyId() == null ? 0 : rentVehicleDetail.getVehicleManageCompanyId();

        log.info("分账----payOrderAccept----userId====" + userId + "---orderId===" + orderId + "---orderNo===" + orderNo+"----companyId==="+companyId);


        if (orderId == 0  || userId == 0 || companyId == 0 ) {
            throw  new BaseException("分账----payOrderAccept----参数不能为空----orderId===" + orderId,ResultCode.FAILED_CODE);
        }

        BigDecimal orderAmount = orderDetailDTO.getAcceptAmount();

        log.info("分账----payOrderAccept--------userId===" + userId + "---orderAmount===="+orderAmount);

        List<BaseCommissionRatio> baseCommissionRatios = commissionRatioBiz.getList();
        BigDecimal amount=BigDecimal.ZERO;
        BigDecimal companyDivisionAmount=orderAmount;
        BigDecimal extrac = new BigDecimal(100);
        BigDecimal  companyExtrac=new BigDecimal(100);
        if (baseCommissionRatios.size() > 0){
            //先计算分给店铺
            extrac = baseCommissionRatios.stream().map(BaseCommissionRatio::getExtract).reduce(BigDecimal.ZERO,BigDecimal::add);
            companyExtrac = new BigDecimal(100).subtract(extrac);
            //店铺金额
            companyDivisionAmount=orderAmount.multiply(companyExtrac).divide(new BigDecimal(100)).setScale(2,   BigDecimal.ROUND_HALF_UP);
            //其他金额
            BigDecimal  otherDivisionAmount=orderAmount.subtract(companyDivisionAmount);

            Integer num = 0;
            for (BaseCommissionRatio commissionRatio:baseCommissionRatios){
                num++;
                Integer type = commissionRatio.getType() == null ? 0 : commissionRatio.getType();
                Integer mchId=0;
                Integer divisionType=0;
                if (type == 1 ){
                    BranchCompany branchCompany = companyBiz.selectById(companyId);
                    if (branchCompany != null ){
                        mchId=branchCompany.getInviterAccount() == null ? 0 : branchCompany.getInviterAccount();
                    }
                    divisionType=4;
                }else if (type == 2){
                    AppUserRelation relation = relationBiz.getRelationByIdUserIdAndTime(userId);
                    if (relation == null ) {
                        log.info("分账----payOrderAccept--------userId===" + userId + "---无有效上线");
                        continue;
                    }
                    mchId = relation.getParentId() == null ? 0 : relation.getParentId();
                    divisionType = mchId > 0 ? 2: 3;
                    mchId = mchId == 0 ? relation.getCompanyId() : mchId;
                }else if (type == 3){
                    divisionType=1;
                }
                log.info("分账----payOrderAccept----mchId===="+mchId+"----divisionType==="+divisionType);
                if (type != 3 && mchId  == 0){
                    continue;
                }
                BigDecimal divisionAmount ;
                BigDecimal extract1=commissionRatio.getExtract();
                if (num.equals(baseCommissionRatios.size())){
                    divisionAmount=otherDivisionAmount.subtract(amount);
                    extract1=extrac;
                }else {
                    divisionAmount=orderAmount.multiply(extract1).divide(new BigDecimal(100)).setScale(2,   BigDecimal.ROUND_HALF_UP);
                }
                BaseOrderAcceptDetailed acceptDetailed=new BaseOrderAcceptDetailed();
                BeanUtils.copyProperties(orderWaterDTO,acceptDetailed);
                acceptDetailed.setMchId(mchId);
                acceptDetailed.setOrderAmount(orderAmount);
                acceptDetailed.setDivisionAmount(divisionAmount);
                acceptDetailed.setExtract(extract1);
                acceptDetailed.setDivisionType(divisionType);
                acceptDetailed.setAddTime(System.currentTimeMillis());
                acceptDetailed.setStatus(0);
                insertSelective(acceptDetailed);
                amount=amount.add(divisionAmount);
                extrac=extrac.subtract(extract1);
                orderWaterDTO.setAcceptId(acceptDetailed.getId());
                sellingWaterBiz.payOrderWater(orderWaterDTO);
            }
        }

        //店铺分账
        BaseOrderAcceptDetailed acceptDetailed=new BaseOrderAcceptDetailed();
        BeanUtils.copyProperties(orderWaterDTO,acceptDetailed);
        acceptDetailed.setMchId(companyId);
        acceptDetailed.setExtract(companyExtrac);
        acceptDetailed.setOrderAmount(orderAmount);
        acceptDetailed.setDivisionAmount(companyDivisionAmount);
        acceptDetailed.setDivisionType(5);
        acceptDetailed.setAddTime(System.currentTimeMillis());
        acceptDetailed.setStatus(0);
        insertSelective(acceptDetailed);

        //添加保险
        addInsure(orderDetailDTO,0);


    }


    public  void  addInsure(OrderDetailDTO orderDetailDTO,Integer status){
        BigDecimal insureAmount = orderDetailDTO.getInsureAmount() == null ? BigDecimal.ZERO : orderDetailDTO.getInsureAmount();
        log.info("-----保险分账---insureAmount===="+insureAmount);
        if (insureAmount.compareTo(BigDecimal.ZERO) > 0){
            Long time = System.currentTimeMillis();
            Integer type = status == 1 ? 2 : 1;
            BaseOrderAcceptDetailed acceptDetailed=new BaseOrderAcceptDetailed();
            acceptDetailed.setMchId(0);
            acceptDetailed.setUserId(orderDetailDTO.getUserId());
            acceptDetailed.setOrderNo(orderDetailDTO.getOrderNo());
            acceptDetailed.setOrderId(orderDetailDTO.getOrderId());
            acceptDetailed.setOrderAmount(orderDetailDTO.getOrderAmount());
            acceptDetailed.setDivisionAmount(insureAmount);
            acceptDetailed.setDivisionType(9);
            acceptDetailed.setAddTime(time);
            if (status == 1)
                acceptDetailed.setStatusTime(time);
            acceptDetailed.setStatus(status);
            acceptDetailed.setType(type);
            insertSelective(acceptDetailed);
        }
    }

    public void payOrderFAccept(OrderWaterDTO orderWaterDTO,OrderDetailDTO orderDetailDTO) {
        Integer orderId = orderWaterDTO.getOrderId() == null ? 0 : orderWaterDTO.getOrderId();
        if (orderDetailDTO != null ){
            Example example = new Example(BaseOrderAcceptDetailed.class);
            example.createCriteria().andEqualTo("orderId",orderId).andEqualTo("type",1);
            example.setOrderByClause("division_type desc ");
            List<BaseOrderAcceptDetailed> acceptDetaileds = selectByExample(example);
            if (acceptDetaileds.size() > 0){
                BigDecimal orderAmount = orderDetailDTO.getAcceptAmount();
                if (orderAmount.compareTo(BigDecimal.ZERO) > 0){
                    BigDecimal amount=orderAmount;
                    //先计算分给店铺
                    BigDecimal  companyExtrac = acceptDetaileds.stream().filter(x->x.getDivisionType() == 5).map(BaseOrderAcceptDetailed::getExtract).reduce(BigDecimal.ZERO, (x, y) -> x.add(y));
                    //店铺金额
                    BigDecimal companyDivisionAmount=orderAmount.multiply(companyExtrac).divide(new BigDecimal(100)).setScale(2,   BigDecimal.ROUND_HALF_UP);
                    //其他金额
                    BigDecimal  otherDivisionAmount=orderAmount.subtract(companyDivisionAmount);
                    Integer num=0;
                    for (BaseOrderAcceptDetailed acceptDetailed1:acceptDetaileds){
                        num++;
                        Integer zAcceptId = acceptDetailed1.getId();
                        acceptDetailed1.setType(2);
                        acceptDetailed1.setId(null);
                        acceptDetailed1.setOrderAmount(orderAmount);
                        BigDecimal dAmount = BigDecimal.ZERO;
                        if (num.equals(acceptDetaileds.size())){
                            acceptDetailed1.setDivisionAmount(amount);
                            insertSelective(acceptDetailed1);
                        }else {
                            if (acceptDetailed1.getDivisionType() == 5) {
                                acceptDetailed1.setDivisionAmount(companyDivisionAmount);
                                insertSelective(acceptDetailed1);
                                dAmount = acceptDetailed1.getDivisionAmount();
                            } else if (acceptDetailed1.getDivisionType() == 2 || acceptDetailed1.getDivisionType() == 3 || acceptDetailed1.getDivisionType() == 4) {
                                if (otherDivisionAmount.compareTo(BigDecimal.ZERO) > 0) {
                                    if (!orderDetailDTO.getOrderStatus().equals(OrderDetailDTO.CANEL)) {
                                        BigDecimal divisionAmount = orderAmount.multiply(acceptDetailed1.getExtract()).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
                                        acceptDetailed1.setDivisionAmount(divisionAmount);
                                    }
                                    insertSelective(acceptDetailed1);
                                    dAmount = acceptDetailed1.getDivisionAmount();
                                    orderWaterDTO.setAcceptId(acceptDetailed1.getId());
                                    orderWaterDTO.setZAcceptId(zAcceptId);
                                    orderWaterDTO.setOrderAmount(orderAmount);
                                    sellingWaterBiz.finishOrderFWater(orderWaterDTO);
                                }
                            }
                        }
                        amount=amount.subtract(dAmount);
                    }
                }
            }
        }
    }

    //订单完成计算用户拥金
    public void finishOrderAccept(OrderWaterDTO orderWaterDTO,OrderDetailDTO orderDetailDTO) {
        //订单id
        Integer orderId = orderWaterDTO.getOrderId() == null ? 0 : orderWaterDTO.getOrderId();

        BigDecimal acceptAmount = orderDetailDTO.getAcceptAmount() == null ? BigDecimal.ZERO : orderDetailDTO.getAcceptAmount();
        log.info("订单完成分账----finishOrderWater----orderId====" + orderId);
        if (orderId == 0) {
            return;
        }
        List<BaseOrderAcceptDetailed> list = getAcceptList(orderId);
        BigDecimal amount =BigDecimal.ZERO;
        if (list.size() > 0) {
            for (BaseOrderAcceptDetailed acceptDetailed : list) {
                Integer id = acceptDetailed.getId();
                Integer  divisionType = acceptDetailed.getDivisionType();
                acceptDetailed.setStatus(1);
                acceptDetailed.setStatusTime(System.currentTimeMillis());
                updateSelectiveById(acceptDetailed);
                orderWaterDTO.setAcceptId(id);
                BigDecimal commison=sellingWaterBiz.finishOrderWater(orderWaterDTO);
                log.info("订单完成分账----finishOrderAccept----id====" + id + "---commison==" + commison + "----divisionType===" + divisionType);
                amount = amount.add(commison);
            }
            Integer orderType = orderDetailDTO.getOrderType() == null ? 0 : orderDetailDTO.getOrderType();
            BigDecimal unbooked = amount;
            log.info("订单完成分账----finishOrderWater----orderId====" + orderId + "---amount==" + amount + "---unbooked==" + unbooked);
            if (acceptAmount.compareTo(BigDecimal.ZERO) > 0){
                payOrderFAccept(orderWaterDTO,orderDetailDTO);
            }
            othderAccept(orderDetailDTO);
            //保险
            addInsure(orderDetailDTO,1);
            log.info("订单完成分账----finishOrderWater--------orderId===" + orderId + "----amount====" + amount + "--orderType===" + orderType);
        }


    }

    //订单退款
    public void refundOrderAccept(OrderWaterDTO orderWaterDTO) {
        Integer orderId = orderWaterDTO.getOrderId() == null ? 0 :orderWaterDTO.getOrderId();
        log.info("分账----refundOrderAccept----orderId====" + orderId);
        if (orderId == 0) {
            return;
        }
        List<BaseOrderAcceptDetailed> list = getAcceptList(orderId);
        if (list.size() > 0) {
            for (BaseOrderAcceptDetailed acceptDetailed : list) {
                acceptDetailed.setStatus(1);
                acceptDetailed.setStatusTime(System.currentTimeMillis());
                updateSelectiveById(acceptDetailed);
                acceptDetailed.setId(null);
                acceptDetailed.setType(2);
                insertSelective(acceptDetailed);
            }
            sellingWaterBiz.refundOrderWater(orderWaterDTO);
        }
    }



    //获取拥金列表
    public List<BaseOrderAcceptDetailed> getAcceptList(Integer orderId) {
        Example example = new Example(BaseOrderAcceptDetailed.class);
        example.createCriteria().andEqualTo("orderId", orderId).andEqualTo("type", 1).andEqualTo("status", 0);
        return mapper.selectByExample(example);

    }

    public  Integer  othderAccept(OrderDetailDTO orderDetailDTO){
        OrderRentVehicleDetail rentVehicleDetail = orderDetailDTO.getRentVehicleDetail();
        BaseOrderAcceptDetailed acceptDetailed=new BaseOrderAcceptDetailed();
        BeanUtils.copyProperties(orderDetailDTO,acceptDetailed);
        acceptDetailed.setMchId(rentVehicleDetail.getVehicleManageCompanyId());
        acceptDetailed.setOrderAmount(orderDetailDTO.getAcceptAmount());
        acceptDetailed.setAddTime(System.currentTimeMillis());
        acceptDetailed.setStatusTime(System.currentTimeMillis());
        acceptDetailed.setStatus(1);
        BigDecimal violateAmount = orderDetailDTO.getViolateAmount() == null ? BigDecimal.ZERO :orderDetailDTO.getViolateAmount() ; //违约金
        if (violateAmount.compareTo(BigDecimal.ZERO) > 0 && orderDetailDTO.getOrderStatus().equals(OrderDetailDTO.DELAY)){
            acceptDetailed.setDivisionAmount(orderDetailDTO.getViolateAmount());
            acceptDetailed.setDivisionType(8);
            acceptDetailed.setEntryType(orderDetailDTO.getGoodsDepositType());
            insertSelective(acceptDetailed);
        }
        BigDecimal lossSpecifiedAmount = orderDetailDTO.getLossSpecifiedAmount() == null ? BigDecimal.ZERO :orderDetailDTO.getLossSpecifiedAmount() ; //定损
        if (lossSpecifiedAmount.compareTo(BigDecimal.ZERO) > 0 ){
            acceptDetailed.setDivisionAmount(lossSpecifiedAmount);
            acceptDetailed.setDivisionType(6);
            acceptDetailed.setEntryType(orderDetailDTO.getGoodsDepositType());
            insertSelective(acceptDetailed);
        }
        BigDecimal breakRulesRegulation = orderDetailDTO.getBreakRulesRegulation() == null ? BigDecimal.ZERO :orderDetailDTO.getBreakRulesRegulation() ; //违章
        if (breakRulesRegulation.compareTo(BigDecimal.ZERO) > 0 ){
            acceptDetailed.setDivisionAmount(breakRulesRegulation);
            acceptDetailed.setDivisionType(7);
            insertSelective(acceptDetailed);
        }
        return  acceptDetailed.getId();
    }


    public  List<BaseOrderAcceptDetailedVO> getList(BaseOrderAcceptDetailedDTO acceptDetailedDTO){
        return  mapper.selectList(acceptDetailedDTO);
    }


    public  List<BaseOrderRevenue> getListByRevenue(OrderWaterDTO orderWaterDTO){
        return  mapper.getListByOrderNo(orderWaterDTO);
    }

}