package cn.iocoder.yudao.module.member.job;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.member.dal.dataobject.orderdetail.OrderDetailDO;
import cn.iocoder.yudao.module.member.dal.mysql.orderdetail.OrderDetailMapper;
import cn.iocoder.yudao.module.member.enums.TimePeriodEnum;
import cn.iocoder.yudao.module.system.api.DeviceMoney.DeviceMoneyApi;
import cn.iocoder.yudao.module.system.api.DeviceMoney.dto.DeviceMoneyDto;
import cn.iocoder.yudao.module.system.api.carteen.CarteenApi;
import cn.iocoder.yudao.module.system.api.carteen.dto.CarteenRespDto;
import cn.iocoder.yudao.module.system.api.deviceInfo.DeviceInfoApi;
import cn.iocoder.yudao.module.system.api.deviceInfo.dto.DeviceInfoDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author:qjq 每日统计设备流水金额
 * @Date:2024/4/15 上午9:59
 */
@Slf4j
@Component
public class DeviceMoneyJob implements JobHandler {
    @Resource
    private CarteenApi carteenApi;
    @Resource
    private OrderDetailMapper orderDetailMapper;
    @Resource
    private DeviceInfoApi deviceInfoApi;
    @Resource
    private DeviceMoneyApi deviceMoneyApi;
    /**
     * 执行任务
     *
     * @param param 参数
     * @return 结果
     * @throws Exception 异常
     */
    @Override
    @TenantIgnore
    public String execute(String param) throws Exception {
        //获取昨天时间
        LocalDateTime offset = LocalDateTimeUtil.offset(LocalDateTime.now(), -1, ChronoUnit.DAYS);
        //获取昨天开始时间
        LocalDateTime startTime = LocalDateTimeUtil.beginOfDay(offset);
        LocalDateTime endTime = LocalDateTimeUtil.endOfDay(offset);
        //获取门店信息
        List<CarteenRespDto> car = carteenApi.getCarteenList();
        for (CarteenRespDto dto : car) {
            int i=0;
            //获取门店下的设备
            List<String> ips = deviceInfoApi.getDeviceInfoList(dto.getId()).stream()
                    .map(DeviceInfoDto::getDeviceIp)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
            if(ObjectUtil.isNotEmpty(ips)){
                //获取设备营业数据
                List<OrderDetailDO> dos = orderDetailMapper.selectList(new LambdaQueryWrapperX<OrderDetailDO>()
                        .in(OrderDetailDO::getSn, ips)
                        .betweenIfPresent(OrderDetailDO::getCreateTime, startTime, endTime));
                if(ObjectUtil.isNotEmpty(dos)){
                    //根据设备分组
                    Map<String, List<OrderDetailDO>> collect = dos.stream().collect(Collectors.groupingBy(OrderDetailDO::getSn));
                    for (Map.Entry<String, List<OrderDetailDO>> map : collect.entrySet()) {
                        DeviceMoneyDto bean = BeanUtil.toBean(dto, DeviceMoneyDto.class);
                        bean.setCarteenId(dto.getId());
                        List<OrderDetailDO> value = map.getValue();
                        //设置设备ip
                        bean.setDeviceIp(map.getKey());
                        bean.setDeviceName(deviceInfoApi.getDeviceInfoName(map.getKey()));
                        //根据时间进行时间段赋值
                        value.forEach(v -> v.setCreator(TimePeriodEnum.getTimeName(v.getCreateTime())));
                        //根据时间段分组
                        value.stream().collect(Collectors.groupingBy(OrderDetailDO::getCreator))
                                .forEach((k, v) -> {
                                    //根据时间段进行金额统计
                                    BigDecimal sum = v.stream()
                                            .map(OrderDetailDO::getPrice)
                                            .filter(ObjectUtil::isNotEmpty)
                                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                                    bean.setTimePeriod(k);
                                    bean.setMoney(sum);
                                });
                        i+= deviceMoneyApi.insertDeviceMoney(bean);
                    }
                }
            }
            log.info("[execute][定时插入门店设备流水数据成功 {} 条数据]",i);
        }
        return String.format("定时插入统计营业数据是否成功  %s ", true);
    }
}
