package com.fdkankan.platform.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fdkankan.common.constant.CameraConstant;
import com.fdkankan.common.constant.Constant;
import com.fdkankan.common.constant.ErrorCode;
import com.fdkankan.common.constant.ServerCode;
import com.fdkankan.common.constant.TbStatus;
import com.fdkankan.common.exception.BusinessException;
import com.fdkankan.common.user.SSOUser;
import com.fdkankan.common.util.NumberUtils;
import com.fdkankan.platform.agent.constant.AgentConstant;
import com.fdkankan.platform.agent.vo.AgentVo;
import com.fdkankan.platform.agent.vo.ResponseAgentCamera;
import com.fdkankan.platform.order.entity.VirtualOrder;
import com.fdkankan.platform.order.mapper.IVirtualOrderMapper;
import com.fdkankan.platform.order.service.IDownloadOrderService;
import com.fdkankan.platform.order.service.IExpansionOrderService;
import com.fdkankan.platform.order.service.IIncrementOrderService;
import com.fdkankan.platform.order.service.IVirtualOrderService;
import com.fdkankan.platform.order.vo.ResponseExpansionOrder;
import com.fdkankan.platform.user.request.*;
import com.fdkankan.platform.user.service.IUserService;
import com.fdkankan.platform.user.vo.ResponseDownloadOrder;
import com.fdkankan.platform.user.vo.ResponseIncrementOrder;
import com.fdkankan.platform.user.vo.ResponseVirtualOrder;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 充值订单表（双目相机点数充值、消费） 服务实现类
 * </p>
 *
 * @author
 * @since 2021-12-24
 */
@Service
public class VirtualOrderServiceImpl extends ServiceImpl<IVirtualOrderMapper, VirtualOrder> implements IVirtualOrderService {

    @Resource
    private IVirtualOrderMapper virtualOrderMapper;
    @Autowired
    private IUserService userService;
    @Autowired
    private IExpansionOrderService expansionOrderService;
    @Autowired
    private IIncrementOrderService incrementOrderService;
    @Autowired
    private IDownloadOrderService downloadOrderService;

    @Override
    public void saveVirtualOrderByAgent(Long cameraId) {
        VirtualOrder virtualOrderEntity = new VirtualOrder();
        virtualOrderEntity.setCameraId(cameraId);
        virtualOrderEntity.setOrderSn(NumberUtils.getOrderSn());
        virtualOrderEntity.setPayType(2);
        virtualOrderEntity.setPayStatus(1);
        virtualOrderEntity.setPoints(AgentConstant.INIT_POINTS);
        virtualOrderEntity.setStatus(0);
        virtualOrderEntity.setBody(AgentConstant.DEFAULT_BODY);
        virtualOrderEntity.setTradeTime(new Date());
        if(!this.save(virtualOrderEntity)){
            throw new BusinessException(ErrorCode.ERROR_MSG);
        }
    }

    @Override
    public void getByStatusAndCameraId(AgentVo agentVo, String startDate, String endDate) {
        QueryWrapper<VirtualOrder> queryWrapper= new QueryWrapper<>();
        queryWrapper.lambda().eq(VirtualOrder::getTbStatus, TbStatus.VALID.code());
        queryWrapper.lambda().eq(VirtualOrder::getPayStatus,1);
        queryWrapper.lambda().inSql(VirtualOrder::getCameraId,
                "select o.camera_id from t_camera_detail o where o.agency like '%"+agentVo.getAgentId()+"%' and o.rec_status = 'A'");
        if(StringUtils.isNotBlank(startDate)){
            queryWrapper.lambda().ge(VirtualOrder::getTradeTime,startDate);
        }
        if(StringUtils.isNotBlank(startDate)){
            queryWrapper.lambda().le(VirtualOrder::getTradeTime,startDate);
        }
        List<VirtualOrder> list = this.list(queryWrapper);
        // 累计消耗点数
        int subSubExpend = 0;
        // 提成金额
        int subSubExtract = 0;
        // 累计充值
        int subSubRecharge = 0;
        int subGift = 0;
        int subMoney = 0;
        int subStract = 0;
        for (VirtualOrder virtualOrder : list) {
            if (virtualOrder.getStatus() == 1) {
                subMoney += virtualOrder.getPoints();
            } else if (virtualOrder.getStatus() == -1) {
                subStract += virtualOrder.getPoints();
            } else if (virtualOrder.getStatus() == 0) {
                subGift += virtualOrder.getPoints();
            } else if (virtualOrder.getStatus() == -2) {
                subMoney -= virtualOrder.getPoints();
            }
        }
        if (subStract > subGift) {
            subSubExpend += subStract - subGift;
            subSubExtract += (subStract - subGift) * AgentConstant.EXTRACT;
        }
        subSubRecharge += subMoney;
        agentVo.setSubExpend(subSubExpend);
        agentVo.setSubExtract(subSubExtract);
        agentVo.setSubRecharge(subSubRecharge);
    }

    @Override
    public ResponseAgentCamera getPointsByCameraId(Long cameraId, String startDate, String endDate) {
        //期初点数
        int initPoint = 0;
        //赠送点数
        int giftPoint = 0;
        int preGiftPoint = 0;
        //之前消耗的点数
        int preLessPoint = 0;
        //已用点数
        int usedPoint = 0;
        //充值金额
        int charge = 0;
        //退充值
        int recharge = 0;
        //提成
        BigDecimal extract = new BigDecimal(0.0);
        if(StringUtils.isNotBlank(startDate)){
            QueryWrapper<VirtualOrder> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(VirtualOrder::getTbStatus,TbStatus.VALID.code());
            queryWrapper.lambda().eq(VirtualOrder::getPayStatus,1);
            queryWrapper.lambda().eq(VirtualOrder::getCameraId,cameraId);
            queryWrapper.lambda().orderByDesc(VirtualOrder::getTradeTime);
            queryWrapper.lambda().le(VirtualOrder::getTradeTime,startDate+" 00:00:00");
            List<VirtualOrder> list = this.list(queryWrapper);
            for (VirtualOrder entityV : list) {
                int status = entityV.getStatus();
                if (status == 0 || status == 1) {
                    initPoint += entityV.getPoints();
                    if (status == 0) {
                        preGiftPoint += entityV.getPoints();
                    }
                } else if (status == -1) {
                    initPoint -= entityV.getPoints();
                    preLessPoint += entityV.getPoints();
                } else if (status == -2) {
                    initPoint -= entityV.getPoints();
                }
            }
        }
        QueryWrapper<VirtualOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(VirtualOrder::getPayStatus,1);
        queryWrapper.lambda().eq(VirtualOrder::getCameraId,cameraId);
        queryWrapper.lambda().orderByDesc(VirtualOrder::getTradeTime);
        if(StringUtils.isNotBlank(startDate)){
            queryWrapper.lambda().ge(VirtualOrder::getTradeTime,startDate+" 00:00:00");
        }
        if(StringUtils.isNotBlank(startDate)){
            queryWrapper.lambda().le(VirtualOrder::getTradeTime,endDate+" 23:59:59");
        }
        List<VirtualOrder> list = this.list(queryWrapper);
        for (VirtualOrder entityV : list) {
            int status = entityV.getStatus();
            if (status == 0) {
                giftPoint += entityV.getPoints();
            } else if (status == -1) {
                usedPoint += entityV.getPoints();
            }
            if (status == 1) {
                charge += entityV.getPoints();
            } else if (status == -2) {
                recharge += entityV.getPoints();
            }
        }
        ResponseAgentCamera vo = new ResponseAgentCamera();
        vo.setInitPoint(initPoint);
        vo.setGiftPoint(giftPoint);
        //之前赠送的点数大于使用的点数
        if (preGiftPoint >= preLessPoint) {
            //赠送的点数一直大于使用的点数
            if (preGiftPoint - preLessPoint + giftPoint - usedPoint >= 0) {
                vo.setUsedPoint(-1 * usedPoint);
                vo.setLessPoint(0);
            } else {
                vo.setUsedPoint(-1 * (preGiftPoint - preLessPoint + giftPoint));
                vo.setLessPoint(usedPoint - (preGiftPoint - preLessPoint + giftPoint));
            }
        } else {
            //规定的时间段内赠送的点数大于使用的点数
            if (preGiftPoint - preLessPoint + giftPoint - usedPoint >= 0) {
                vo.setUsedPoint(-1 * usedPoint);
                vo.setLessPoint(0);
            } else {
                vo.setUsedPoint(-1 * giftPoint);
                vo.setLessPoint(usedPoint - giftPoint);
            }
        }
        vo.setSurPlusPoint( (initPoint + giftPoint > usedPoint) ? (initPoint + giftPoint - usedPoint) : 0);
        vo.setCharge(charge - recharge);
        vo.setExchangePoint(charge - recharge);
        if (usedPoint > giftPoint) {
            extract = new BigDecimal((usedPoint - giftPoint) * AgentConstant.EXTRACT).setScale(2, BigDecimal.ROUND_HALF_UP);
        }
        vo.setExtract(extract);
        return vo;
    }

    @Override
    public ResponseVirtualOrder saveByCamera(Long userId, RequestCamera camera) {
        VirtualOrder virtualOrderEntity = new VirtualOrder();
        virtualOrderEntity.setCameraId(camera.getCameraId());
        virtualOrderEntity.setPayType(camera.getPayType());
//        if (camera.getAbroad().intValue() == 1){
////            virtualOrderEntity.setAmount(new BigDecimal(camera.getPoints()).multiply(new BigDecimal(0.145)));
////        }else{
////            virtualOrderEntity.setAmount(new BigDecimal(camera.getPoints()));
////        }
        virtualOrderEntity.setAmount(new BigDecimal(camera.getPoints()));
        virtualOrderEntity.setPoints(camera.getPoints());
        virtualOrderEntity.setOrderSn(NumberUtils.getOrderSn());
        virtualOrderEntity.setUserId(userId);
        virtualOrderEntity.setStatus(1);
        virtualOrderEntity.setPayStatus(-1);
        virtualOrderEntity.setBody(Constant.PAY_SUBJECT);
        virtualOrderEntity.setAbroad(camera.getAbroad());
        virtualOrderEntity.setTradeTime(new Date());
        this.save(virtualOrderEntity);
        ResponseVirtualOrder responseVirtualOrder = new ResponseVirtualOrder();
        BeanUtils.copyProperties(virtualOrderEntity, responseVirtualOrder);
        return responseVirtualOrder;
    }

    @Override
    public Page<ResponseVirtualOrder> chargeList(RequestVirtualOrder param, String token) {
        if(token!=null){
            SSOUser ssouser = userService.getSSOUserByToken(token);
            param.setUserId(ssouser.getId());
        }
        Page<ResponseVirtualOrder> pageVo = new Page<>(param.getPageNum(), param.getPageSize());
        param.setOrderBy( "o.trade_time desc");
        return   virtualOrderMapper.getChargeListByParam(pageVo,param);
    }

    @Override
    public Page<ResponseExpansionOrder> expansionList(RequestCamera param, String token) {
        SSOUser ssouser = userService.getSSOUserByToken(token);
        param.setUserId(ssouser.getId());
        return expansionOrderService.getExpansionListByParam(param);
    }

    @Override
    public Page<ResponseIncrementOrder> incrementOrderList(RequestIncrementOrder param, String token) {
        SSOUser ssouser = userService.getSSOUserByToken(token);
        //查询该用户已支付的增值权益
        return incrementOrderService.getPageByParam(ssouser.getId(),param);

    }

    @Override
    public Page<ResponseDownloadOrder> downloadOrderList(RequestDownloadOrder param, String token) {
        SSOUser ssouser = userService.getSSOUserByToken(token);
        //查询该用户已支付的增值权益
        return  downloadOrderService.getPageByParam(ssouser.getId(),param);
    }

    @Override
    public VirtualOrder getByOrderSn(String orderSn) {
        QueryWrapper<VirtualOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(VirtualOrder::getTbStatus,TbStatus.VALID.code());
        queryWrapper.lambda().eq(VirtualOrder::getOrderSn,orderSn);
        List<VirtualOrder> list = this.list(queryWrapper);
        if(list == null || list.size()<=0){
            return null;
        }
        return list.get(0);
    }

    @Override
    public boolean paySuccessVirtualOrder(String orderSn, String tradeNo, int paymentTypeName) {
        LambdaUpdateWrapper<VirtualOrder> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(VirtualOrder::getPayType,paymentTypeName)
                .set(VirtualOrder::getNumber,tradeNo)
                .set(VirtualOrder::getPayStatus, 1)
                .set(VirtualOrder::getTradeTime, new Date())
                .eq(VirtualOrder::getOrderSn,orderSn)
                .eq(VirtualOrder::getTbStatus,TbStatus.VALID.code());
        return this.update(updateWrapper);
    }

    @Override
    public List<VirtualOrder> getAllByParam(RequestCamera param) {
        param.setOrderBy("trade_time desc");
        return  this.virtualOrderMapper.getAllByParam(param);
    }

    @Override
    public Page<ResponseVirtualOrder> getPageVoByParam(RequestCamera param) {
        LambdaQueryWrapper<VirtualOrder> query = new LambdaQueryWrapper<>();
        query.eq(VirtualOrder::getTbStatus,TbStatus.VALID.code());
        query.eq(VirtualOrder::getCameraId,param.getCameraId());
        if(param.getType() == 0 ){
            query.or().eq(VirtualOrder::getStatus,1).or().eq(VirtualOrder::getStatus,-2);
        }else {
            query.eq(VirtualOrder::getStatus,-1);
        }
        if (StringUtils.isNotEmpty(param.getStartDate())){
            query.ge(VirtualOrder::getTradeTime,param.getStartDate() +" 00:00:00");
        }
        if (StringUtils.isNotEmpty(param.getEndDate())){
            query.le(VirtualOrder::getTradeTime,param.getStartDate() +" 00:00:00");
        }
        query.orderByDesc(VirtualOrder::getTradeTime);
        Page<VirtualOrder> objectPage = new Page<>(param.getPageNum(), param.getPageSize());
        Page<VirtualOrder> page = this.page(objectPage, query);

        List<ResponseVirtualOrder> orderRsps = this.convert(page.getRecords());

        Page<ResponseVirtualOrder> vo = new Page<ResponseVirtualOrder>(param.getPageNum(), param.getPageSize());
        vo.setTotal(page.getTotal());
        vo.setRecords(orderRsps);
        return vo;
    }

    public List<ResponseVirtualOrder> convert(List<VirtualOrder> list) {
        List<ResponseVirtualOrder> orderRsps = new ArrayList<>();
        for (VirtualOrder order : list){
            ResponseVirtualOrder orderRsp = new ResponseVirtualOrder();
            BeanUtils.copyProperties(order, orderRsp);
            orderRsps.add(orderRsp);
        }
        return orderRsps;
    }

    @Override
    public boolean addVirtualOrder(RequestVirtualOrder vo) {
        //添加虚拟订单记录
        VirtualOrder order = new VirtualOrder();
        BeanUtils.copyProperties(vo, order);
        order.setStatus(Integer.valueOf(vo.getStatus()));
        return this.save(order);
    }

    @Override
    public String modifyPoints(RequestCamera param) {
        BigDecimal amount = new BigDecimal(0.00);
        String body = "";
        if (-2 == param.getBody()){
            int rechargeAmount = this.queryRechargeByCameraIdAndStatus(param.getCameraId(), 1);
            int backRechargeAmount = this.queryRechargeByCameraIdAndStatus(param.getCameraId(), -2);
            if (rechargeAmount - backRechargeAmount > param.getPoints()){
                amount = BigDecimal.valueOf(param.getPoints());
                body = "系统退充值";
            }else{
                throw new BusinessException(CameraConstant.FAILURE_6002);
            }
        }else if (0 == param.getBody()){
            body = "系统赠送";
        }
        VirtualOrder order = new VirtualOrder();
        order.setCameraId(param.getCameraId());
        order.setOrderSn(NumberUtils.getOrderSn());
        order.setPayType(2);
        order.setPayStatus(1);
        order.setPoints(param.getPoints());
        order.setStatus(param.getBody());
        order.setUserId(null);//空代表管理员添加
        order.setAmount(amount);
        order.setBody(body);
        order.setTradeTime(new Date());
        if(!this.save(order)){
            throw new BusinessException(ErrorCode.ERROR_MSG);
        }
        return ServerCode.SUCCESS.message();
    }

    @Override
    public int queryRechargeByCameraIdAndStatus(Long cameraId, int status) {
        return virtualOrderMapper.queryRechargeByCameraIdAndStatus(cameraId,status);
    }

    @Override
    public Integer queryOrderCountByToday() {
        return virtualOrderMapper.queryOrderCountByToday();
    }

    @Override
    public BigDecimal queryTurnoverByToday(int i) {
        return virtualOrderMapper.queryTurnoverByToday(i);
    }

    @Override
    public BigDecimal queryTurnoverByMonth() {
        return virtualOrderMapper.queryTurnoverByMonth();
    }

    @Override
    public BigDecimal queryTurnoverByLastMonth() {
        return virtualOrderMapper.queryTurnoverByLastMonth();
    }

    @Override
    public Integer queryAllCount() {
        return virtualOrderMapper.queryAllCount();
    }

    @Override
    public BigDecimal selectAllTurnover(int i) {
        return virtualOrderMapper.selectAllTurnover(i);
    }

    @Override
    public List<ResponseVirtualOrder> queryTrendRechargeOrder(int i) {
        return virtualOrderMapper.queryTrendRechargeOrder(i);
    }

    @Override
    public ResponseVirtualOrder getVoById(Long virtualOrderId) {
        VirtualOrder virtualOrderEntity = getById(virtualOrderId);
        ResponseVirtualOrder responseVirtualOrder = new ResponseVirtualOrder();
        if(virtualOrderEntity!=null){
            BeanUtils.copyProperties(virtualOrderEntity,responseVirtualOrder);
        }
        return responseVirtualOrder;
    }

    @Override
    public Page<ResponseVirtualOrder> getPageVoByParam(RequestTrade param) {
        Page<ResponseVirtualOrder> pageVo = new Page<>(param.getPageNum(), param.getPageSize());
        param.setOrderBy("trade_time desc");
        return virtualOrderMapper.getListByParam(pageVo,param);
    }

    @Override
    public void insertVirtualOrderBigScene(Long cameraId, String num, Long userId, Integer country) {
        VirtualOrder orderEntity = new VirtualOrder();
        orderEntity.setCameraId(cameraId);
        orderEntity.setOrderSn(NumberUtils.getOrderSn());
        orderEntity.setPayType(2);
        orderEntity.setPayStatus(1);
        orderEntity.setPoints(Constant.MONEY_SCENE);
        orderEntity.setStatus(-1);
        orderEntity.setSceneNum(num);
        orderEntity.setUserId(userId);
        orderEntity.setBody("生成大场景");
        orderEntity.setAbroad(country);
        orderEntity.setTradeTime(new Date());
        this.save(orderEntity);
    }
}
