package cn.iocoder.yudao.module.member.service.statisticsspacecapsuleorder;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.*;
import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.member.controller.admin.orderspacecapsule.vo.OrderSpaceCapsuleSaveReqVO;
import cn.iocoder.yudao.module.member.controller.admin.orderspacecapsule.vo.OrderSpaceCapsuleStatisticsComVo;
import cn.iocoder.yudao.module.member.controller.admin.orderspacecapsule.vo.OrderSpaceCapsuleStatisticsVo;
import cn.iocoder.yudao.module.member.controller.admin.statisticsspacecapsuleorder.vo.SpaceCapsuleOrderNameRespVO;
import cn.iocoder.yudao.module.member.controller.admin.statisticsspacecapsuleorder.vo.SpaceCapsuleOrderReqVO;
import cn.iocoder.yudao.module.member.controller.admin.statisticsspacecapsuleorder.vo.StatisticsSpaceCapsuleOrderPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.statisticsspacecapsuleorder.vo.StatisticsSpaceCapsuleOrderSaveReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.orderspacecapsule.OrderSpaceCapsuleDO;
import cn.iocoder.yudao.module.member.dal.dataobject.spacecapsule.SpaceCapsuleDO;
import cn.iocoder.yudao.module.member.dal.dataobject.statisticsspacecapsuleorder.StatisticsSpaceCapsuleOrderDO;
import cn.iocoder.yudao.module.member.dal.mysql.orderspacecapsule.OrderSpaceCapsuleMapper;
import cn.iocoder.yudao.module.member.dal.mysql.spacecapsule.SpaceCapsuleMapper;
import cn.iocoder.yudao.module.member.dal.mysql.statisticsspacecapsuleorder.StatisticsSpaceCapsuleOrderMapper;
import cn.iocoder.yudao.module.member.enums.SpaceCapsuleOrderEnum;
import cn.iocoder.yudao.module.member.service.orderspacecapsule.OrderSpaceCapsuleServiceImpl;
import cn.iocoder.yudao.module.system.api.carteen.CarteenApi;
import cn.iocoder.yudao.module.system.api.carteen.dto.CarteenRespDto;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import java.math.BigDecimal;
import java.util.*;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.STORE_REFUND_NOT_STATISTICS_EXISTS;

/**
 * 太空舱订单营业额统计 Service 实现类
 *
 * @author 管理员
 */
@Service
@Validated
public class StatisticsSpaceCapsuleOrderServiceImpl implements StatisticsSpaceCapsuleOrderService {
    @Resource
    private CarteenApi carteenApi;
    @Resource
    private OrderSpaceCapsuleMapper orderSpaceCapsuleMapper;
    @Resource
    private SpaceCapsuleMapper spaceCapsuleMapper;
    @Resource
    private StatisticsSpaceCapsuleOrderMapper statisticsSpaceCapsuleOrderMapper;
    @Override
    public Long createStatisticsSpaceCapsuleOrder(StatisticsSpaceCapsuleOrderSaveReqVO createReqVO) {
        // 插入
        StatisticsSpaceCapsuleOrderDO statisticsSpaceCapsuleOrder = BeanUtils.toBean(createReqVO, StatisticsSpaceCapsuleOrderDO.class);
        statisticsSpaceCapsuleOrderMapper.insert(statisticsSpaceCapsuleOrder);
        // 返回
        return statisticsSpaceCapsuleOrder.getId();
    }

    @Override
    public void updateStatisticsSpaceCapsuleOrder(StatisticsSpaceCapsuleOrderSaveReqVO updateReqVO) {
        // 校验存在
        validateStatisticsSpaceCapsuleOrderExists(updateReqVO.getId());
        // 更新
        StatisticsSpaceCapsuleOrderDO updateObj = BeanUtils.toBean(updateReqVO, StatisticsSpaceCapsuleOrderDO.class);
        statisticsSpaceCapsuleOrderMapper.updateById(updateObj);
    }

    @Override
    public void deleteStatisticsSpaceCapsuleOrder(Long id) {
        // 校验存在
        validateStatisticsSpaceCapsuleOrderExists(id);
        // 删除
        statisticsSpaceCapsuleOrderMapper.deleteById(id);
    }

    private void validateStatisticsSpaceCapsuleOrderExists(Long id) {
        if (statisticsSpaceCapsuleOrderMapper.selectById(id) == null) {
            throw exception(STORE_REFUND_NOT_STATISTICS_EXISTS);
        }
    }

    @Override
    public StatisticsSpaceCapsuleOrderDO getStatisticsSpaceCapsuleOrder(Long id) {
        return statisticsSpaceCapsuleOrderMapper.selectById(id);
    }

    @Override
    public PageResult<StatisticsSpaceCapsuleOrderDO> getStatisticsSpaceCapsuleOrderPage(StatisticsSpaceCapsuleOrderPageReqVO pageReqVO) {
        return statisticsSpaceCapsuleOrderMapper.selectPage(pageReqVO);
    }
    public List<StatisticsSpaceCapsuleOrderDO> statistics(Date startTime,Date endTime){
        List<CarteenRespDto> carteenList = carteenApi.getCarteenList();
        List<StatisticsSpaceCapsuleOrderDO> list=new ArrayList<>();
        for (CarteenRespDto dto : carteenList) {
            Long id = dto.getId();
            OrderSpaceCapsuleStatisticsVo vo = orderSpaceCapsuleMapper.compDay(SpaceCapsuleOrderEnum.SPACE_CAPSULE_ORDER_ENUM_DONE.getCode(), startTime, endTime, id);
            vo.setRemark(DateUtil.format(startTime,DatePattern.NORM_DATE_PATTERN));
            StatisticsSpaceCapsuleOrderDO bean = BeanUtils.toBean(vo, StatisticsSpaceCapsuleOrderDO.class);
            list.add(bean);
        }
        return list;
    }

    @Override
    public OrderSpaceCapsuleStatisticsVo compDayMon(Long carteenId, String type, Date time) {
        if("0".equals(type)){
            return compDay(carteenId,time);
        }else if("2".equals(type)){
            return compMonth(carteenId,time);
        }
        return null;
    }

    @Override
    public List<SpaceCapsuleOrderNameRespVO> getStatisticsSpaceCapsuleOrder(SpaceCapsuleOrderReqVO vo) {
        List<SpaceCapsuleOrderNameRespVO> list=new ArrayList<>();
        if(vo.getId()==null){
            Long carteenId = vo.getCarteenId();
            Date endTime = vo.getEndTime();
            Date startTime = vo.getStartTime();
            List<SpaceCapsuleDO> spaceCapsuleDOS = spaceCapsuleMapper.selectList(new LambdaQueryWrapperX<SpaceCapsuleDO>().eq(SpaceCapsuleDO::getCarteenId, carteenId));
            for (SpaceCapsuleDO aDo : spaceCapsuleDOS) {
                SpaceCapsuleOrderNameRespVO vo1 = getStatisticsSpaceCapsuleOrder1(aDo.getId(), endTime, startTime);
                list.add(vo1);
            }
        }else{
            list.add(getStatisticsSpaceCapsuleOrder1(vo.getId(),vo.getStartTime(),vo.getEndTime()));
        }
        return list;
    }

    @Override
    public void updateStatistics(OrderSpaceCapsuleDO vo) {
        DateTime date = DateUtil.date();
        DateTime start = DateUtil.beginOfDay(date);
        DateTime end = DateUtil.endOfDay(date);
        StatisticsSpaceCapsuleOrderDO orderDO = statisticsSpaceCapsuleOrderMapper.selectOne(new LambdaQueryWrapperX<StatisticsSpaceCapsuleOrderDO>()
                .eq(StatisticsSpaceCapsuleOrderDO::getCarteenId, vo.getCarteenId())
                .between(StatisticsSpaceCapsuleOrderDO::getCreateTime, start, end)
                .last(" limit 1")
        );
        if(ObjUtil.isNotEmpty(orderDO)){
            OrderSpaceCapsuleDO orderSpaceCapsuleDO = orderSpaceCapsuleMapper.selectById(vo.getId());
            updateStatistics(orderDO,orderSpaceCapsuleDO);
            statisticsSpaceCapsuleOrderMapper.updateById(orderDO);
        }else{
            CarteenRespDto carteenById = carteenApi.getCarteenById(vo.getCarteenId());
            StatisticsSpaceCapsuleOrderDO statisticsSpaceCapsuleOrderDO = getStatisticsSpaceCapsuleOrderDO(carteenById);
            statisticsSpaceCapsuleOrderMapper.insert(statisticsSpaceCapsuleOrderDO);
            this.updateStatistics(vo);
        }
    }
    public void updateStatistics( StatisticsSpaceCapsuleOrderDO orderDO,OrderSpaceCapsuleDO vo) {
        //进行运算加
        if(SpaceCapsuleOrderEnum.SPACE_CAPSULE_ORDER_ENUM_REFUNDED.getCode().equals(vo.getStatus())){
            orderDO.setRefundMoney(orderDO.getRefundMoney().add(vo.getRefundMoney() == null ? BigDecimal.ZERO:vo.getRefundMoney()));
        }else{
            orderDO.setTotalMoney(orderDO.getTotalMoney().add(vo.getMoney()));
            orderDO.setTotalOrder(orderDO.getTotalOrder()+1);
            orderDO.setTotalMinute(orderDO.getTotalMinute().add(new BigDecimal(vo.getComboMinutes()*vo.getComboNum())));
            orderDO.setTotalPackageSum(orderDO.getTotalPackageSum()+vo.getComboNum());
            orderDO.setTotalCustomer(orderDO.getTotalCustomer()+1);
        }
    }
    @Override
    public void init() {
        List<StatisticsSpaceCapsuleOrderDO> list=new ArrayList<>();
        for (CarteenRespDto carteenRespDto : carteenApi.getCarteenList()) {
            StatisticsSpaceCapsuleOrderDO orderDO = getStatisticsSpaceCapsuleOrderDO(carteenRespDto);
            list.add(orderDO);
        }
        if(CollUtil.isNotEmpty(list)) {
            statisticsSpaceCapsuleOrderMapper.insertBatch(list);
        }
    }
    private static StatisticsSpaceCapsuleOrderDO getStatisticsSpaceCapsuleOrderDO(CarteenRespDto carteenRespDto) {
        DateTime date = DateUtil.date();
        StatisticsSpaceCapsuleOrderDO orderDO=new StatisticsSpaceCapsuleOrderDO();
        orderDO.setTotalMoney(BigDecimal.ZERO);
        orderDO.setTotalOrder(0);
        orderDO.setTotalMinute(BigDecimal.ZERO);
        orderDO.setCarteenId(carteenRespDto.getId());
        orderDO.setRefundMoney(BigDecimal.ZERO);
        orderDO.setTotalPackageSum(0);
        orderDO.setCarteenName(carteenRespDto.getStoresName());
        orderDO.setRemark(DateUtil.format(date, DatePattern.NORM_DATE_PATTERN));
        orderDO.setTotalCustomer(0);
        return orderDO;
    }
    public SpaceCapsuleOrderNameRespVO getStatisticsSpaceCapsuleOrder1(Long id,Date start,Date end){
        return orderSpaceCapsuleMapper.compDay1(SpaceCapsuleOrderEnum.SPACE_CAPSULE_ORDER_ENUM_DONE.getCode(),start,end,id);
    }
    /**
     * 日报
     * @param carteenId
     * @param end
     * @return
     */
    public OrderSpaceCapsuleStatisticsVo compDay(Long carteenId,Date end){
        DateTime start = DateUtil.beginOfDay(end);
        OrderSpaceCapsuleStatisticsVo orvo = orderSpaceCapsuleMapper.compDay(SpaceCapsuleOrderEnum.SPACE_CAPSULE_ORDER_ENUM_DONE.getCode(), start, end, carteenId);
        if(orvo==null){
            orvo=new OrderSpaceCapsuleStatisticsVo();
        }
        DateTime dateTime = DateUtil.offsetDay(start, -1);
        DateTime start2 = DateUtil.beginOfDay(dateTime);
        DateTime end2 = DateUtil.endOfDay(dateTime);
        comp(carteenId, orvo, start2, end2);
        DateTime dateTime1 = DateUtil.beginOfMonth(end2);
        DateTime dateTime2 = DateUtil.endOfMonth(dateTime1);
        DateRange range = DateUtil.range(dateTime1, dateTime2, DateField.DAY_OF_MONTH);
        List<OrderSpaceCapsuleStatisticsComVo> list=new ArrayList<>();
        for (DateTime time : range) {
            DateTime var1 = DateUtil.beginOfDay(time);
            DateTime var2 = DateUtil.endOfDay(time);
            OrderSpaceCapsuleStatisticsComVo vo = orderSpaceCapsuleMapper.compMoney(var1, var2);
            if(vo==null){
                OrderSpaceCapsuleStatisticsComVo vo1=new OrderSpaceCapsuleStatisticsComVo();
                vo1.setTotalMoney(new BigDecimal(0));
                vo=vo1;
            }
            if(DateUtil.isSameDay(end, var2)){
                vo.setTotalMoney(orvo.getTotalMoney());
            }
            vo.setDate(DateUtil.format(var2,"d"));
            list.add(vo) ;
        }
        orvo.setLists(list);
        return orvo;
    }
    /**
     * 月报
     * @param carteenId
     * @return
     */
    public OrderSpaceCapsuleStatisticsVo compMonth(Long carteenId,Date end1){
        DateTime end = DateUtil.endOfMonth(end1);
        DateTime start = DateUtil.beginOfMonth(end);
        OrderSpaceCapsuleStatisticsVo orvo = orderSpaceCapsuleMapper.compDay(SpaceCapsuleOrderEnum.SPACE_CAPSULE_ORDER_ENUM_DONE.getCode(), start, end, carteenId);
        if(orvo==null){
            orvo=new OrderSpaceCapsuleStatisticsVo();
        }
        DateTime dateTime = DateUtil.offsetMonth(start, -1);
        DateTime start2 = DateUtil.beginOfMonth(dateTime);
        DateTime end2 = DateUtil.endOfMonth(dateTime);
        comp(carteenId, orvo, start2, end2);
        DateTime var1 = DateUtil.beginOfYear(start2);
        DateTime var2 = DateUtil.endOfYear(start2);
        DateRange range = DateUtil.range(var1, var2, DateField.MONTH);
        List<OrderSpaceCapsuleStatisticsComVo> list=new ArrayList<>();
        for (DateTime time : range) {
            DateTime var3 = DateUtil.beginOfMonth(time);
            DateTime var4 = DateUtil.endOfMonth(time);
            OrderSpaceCapsuleStatisticsComVo vo = orderSpaceCapsuleMapper.compMoney(var3, var4);
            if(vo==null){
                OrderSpaceCapsuleStatisticsComVo vo1=new OrderSpaceCapsuleStatisticsComVo();
                vo1.setTotalMoney(new BigDecimal(0));
                vo=vo1;
            }
            if(DateUtil.isSameMonth(end, var3)){
                vo.setTotalMoney(orvo.getTotalMoney());
            }
            vo.setDate(DateUtil.format(var3,"M月"));
            list.add(vo) ;
        }
        orvo.setLists(list);
        return orvo;
    }

    private void comp(Long carteenId, OrderSpaceCapsuleStatisticsVo orvo, DateTime start2, DateTime end2) {
        OrderSpaceCapsuleStatisticsVo vo1 = orderSpaceCapsuleMapper.compDay(SpaceCapsuleOrderEnum.SPACE_CAPSULE_ORDER_ENUM_DONE.getCode(), start2, end2, carteenId);

        if (vo1 != null) {
            orvo.setCompMoney(Optional.ofNullable(orvo.getTotalMoney()).orElse(BigDecimal.ZERO)
                    .subtract(Optional.ofNullable(vo1.getTotalMoney()).orElse(BigDecimal.ZERO)));

            orvo.setCompOrder(Optional.ofNullable(orvo.getTotalOrder()).orElse(0)
                    - Optional.ofNullable(vo1.getTotalOrder()).orElse(0));

            orvo.setCompCustomer(Optional.ofNullable(orvo.getTotalCustomer()).orElse(0)
                    - Optional.ofNullable(vo1.getTotalCustomer()).orElse(0));

            orvo.setCompMinute(Optional.ofNullable(orvo.getTotalMinute()).orElse(BigDecimal.ZERO)
                    .subtract(Optional.ofNullable(vo1.getTotalMinute()).orElse(BigDecimal.ZERO)));

            orvo.setCompAvgOrderMoney(Optional.ofNullable(orvo.getAvgOrderMoney()).orElse(BigDecimal.ZERO)
                    .subtract(Optional.ofNullable(vo1.getAvgOrderMoney()).orElse(BigDecimal.ZERO)));

            orvo.setCompPackageSum(Optional.ofNullable(orvo.getTotalPackageSum()).orElse(0)
                    - Optional.ofNullable(vo1.getTotalPackageSum()).orElse(0));

            orvo.setCompRefundMoneyy(Optional.ofNullable(orvo.getRefundMoney()).orElse(BigDecimal.ZERO)
                    .subtract(Optional.ofNullable(vo1.getRefundMoney()).orElse(BigDecimal.ZERO)));
        } else {
            // 设置默认值为 Total 值，避免 null 值带来的 NPE
            orvo.setCompMoney(Optional.ofNullable(orvo.getTotalMoney()).orElse(BigDecimal.ZERO));
            orvo.setCompOrder(Optional.ofNullable(orvo.getTotalOrder()).orElse(0));
            orvo.setCompCustomer(Optional.ofNullable(orvo.getTotalCustomer()).orElse(0));
            orvo.setCompMinute(Optional.ofNullable(orvo.getTotalMinute()).orElse(BigDecimal.ZERO));
            orvo.setCompAvgOrderMoney(Optional.ofNullable(orvo.getAvgOrderMoney()).orElse(BigDecimal.ZERO));
            orvo.setCompPackageSum(Optional.ofNullable(orvo.getTotalPackageSum()).orElse(0));
            orvo.setCompRefundMoneyy(Optional.ofNullable(orvo.getRefundMoney()).orElse(BigDecimal.ZERO));
        }
    }

}