package cn.iocoder.yudao.module.rescue.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.iocoder.yudao.module.rescue.domain.RescueCarSpend;
import cn.iocoder.yudao.module.rescue.domain.RescueInfo;
import cn.iocoder.yudao.module.rescue.domain.RescueOrderInfo;
import cn.iocoder.yudao.module.rescue.domain.RescueRefuelRecord;
import cn.iocoder.yudao.module.rescue.mapper.RescueCarSpendMapper;
import cn.iocoder.yudao.module.rescue.service.IRescueRefuelRecordService;
import cn.iocoder.yudao.module.rescue.utils.DateUtils;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.iocoder.yudao.module.rescue.mapper.RescueRefuelRecordMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 加油记录Service业务层处理
 *
 * @author zcy
 * @date 2023-09-26
 */
@Service
public class RescueRefuelRecordServiceImpl extends ServiceImpl<RescueRefuelRecordMapper, RescueRefuelRecord> implements IRescueRefuelRecordService {

    @Autowired
    private RescueCarSpendMapper rescueCarSpendMapper;
    /**
     * 查询加油记录
     *
     * @param id 加油记录主键
     * @return 加油记录
     */
    @Override
    public RescueRefuelRecord selectRescueRefuelRecordById(Long id) {
        return baseMapper.selectRescueRefuelRecordById(id);
    }

    /**
     * 查询加油记录列表
     *
     * @param rescueRefuelRecord 加油记录
     * @return 加油记录
     */
    @Override
    public IPage<RescueRefuelRecord> selectRescueRefuelRecordList(RescueRefuelRecord rescueRefuelRecord, Page<RescueRefuelRecord> page) {
        return baseMapper.selectRescueRefuelRecordList(rescueRefuelRecord, page);
    }

    /**
     * 新增加油记录
     *
     * @param rescueRefuelRecord 加油记录
     * @return 结果
     */
    @Override
    public int insertRescueRefuelRecord(RescueRefuelRecord rescueRefuelRecord) {
        return baseMapper.insert(rescueRefuelRecord);
    }

    /**
     * 修改加油记录
     *
     * @param rescueRefuelRecord 加油记录
     * @return 结果
     */
    @Override
    public int updateRescueRefuelRecord(RescueRefuelRecord rescueRefuelRecord) {
        return baseMapper.updateById(rescueRefuelRecord);
    }

    /**
     * 批量删除加油记录
     *
     * @param ids 需要删除的加油记录主键
     * @return 结果
     */
    @Override
    public int deleteRescueRefuelRecordByIds(Long[] ids) {
        return baseMapper.deleteByIds(Arrays.asList(ids));
    }

    /**
     * 删除加油记录信息
     *
     * @param id 加油记录主键
     * @return 结果
     */
    @Override
    public int deleteRescueRefuelRecordById(Long id) {
        return baseMapper.deleteRescueRefuelRecordById(id);
    }


    //通过司机主键和时间计算该月的加油总数和行驶总公里数
    @Override
    public JSONObject getMonthRescueRefuelRecord(Long driverId, String time, Long carId) {
        return baseMapper.getMonthRescueRefuelRecord(driverId, time, carId);

    }

    @Override
    public JSONObject listData(RescueInfo rescueInfo) {
        return baseMapper.listData(rescueInfo);
    }

    /**
     * 救援大屏日常费用统计
     *
     * @param timeType day 日  week 周  month 月
     * @return
     */
    @Override
    public Map<String, Object> getRescueExpenseCount(String timeType) {
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> resp = DateUtils.getDateTimeList(timeType);
        List<DateTime> dateList = (List<DateTime>) resp.get("dateList");
        DateTime startTime = (DateTime) resp.get("startTime");
        DateTime endTime = (DateTime) resp.get("endTime");
        //根据开始时间与结束时间查询救援车加油记录表
        List<RescueRefuelRecord> rescueRefuelRecords = baseMapper.selectList(new LambdaQueryWrapper<RescueRefuelRecord>()
                .between(RescueRefuelRecord::getRecordTime, startTime, endTime));
        //根据开始时间与结束时间查询救援测保养费用
        List<RescueCarSpend> rescueCarSpends = rescueCarSpendMapper.selectList(new LambdaQueryWrapper<RescueCarSpend>()
                .between(RescueCarSpend::getMaintenanceTime, startTime, endTime));
        //燃油费统计
        double reefuleSum = rescueRefuelRecords.stream()
                .filter(Objects::nonNull) // 过滤掉 null 对象
                .filter(refule -> Objects.nonNull(refule.getRefuelMoney())) // 过滤掉 payMoney 为 null 的对象
                .mapToDouble(RescueRefuelRecord::getRefuelMoney) // 获取支付金额
                .sum();// 计算总和
        map.put("totalRefuelMoney", reefuleSum);

        //保养费统计
        double maintenanceSum = rescueCarSpends.stream()
                .filter(Objects::nonNull) // 过滤掉 null 对象
                .filter(maintenance -> Objects.nonNull(maintenance.getMaintenanceMoney())) // 过滤掉 payMoney 为 null 的对象
                .mapToDouble(RescueCarSpend::getMaintenanceMoney) // 获取支付金额
                .sum();// 计算总和
        map.put("totalMaintenanceMoney", maintenanceSum);

        //echarts 数据
        List<List<Object>> dataList = new ArrayList<>();
        List<Object> titleList = new ArrayList<>();
        titleList.add("product");
        titleList.add("油费");
        titleList.add("保养");
        dataList.add(titleList);
        for (DateTime dateTime : dateList) {
            List<Object> list = new ArrayList<>();
            String dateName = DateUtils.getDateName(timeType, dateTime);
            list.add(dateName);
            endTime = DateUtils.getEndTime(timeType, dateTime);
            Map<String, Double> maps = getTotalRefuelAndMaintenanceData(rescueRefuelRecords, rescueCarSpends, dateTime, endTime);
            list.add(maps.get("totalRefuelMoney"));
            list.add(maps.get("totalMaintenanceMoney"));
            dataList.add(list);
        }
        map.put("source", dataList);
        return map;
    }

    /**
     * 根据救援加油记录与救援保养记录计算总加油费用与总保养费用（通过时间筛选）
     * @param refuelRecords
     * @param carSpends
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return
     */
    public Map<String, Double> getTotalRefuelAndMaintenanceData(
            List<RescueRefuelRecord> refuelRecords,
            List<RescueCarSpend> carSpends,
            Date startTime,
            Date endTime) {

        double totalRefuelMoney = refuelRecords.stream()
                .filter(record -> record.getRecordTime().after(startTime) && record.getRecordTime().before(endTime))
                .mapToDouble(RescueRefuelRecord::getRefuelMoney)
                .sum();

        double totalMaintenanceMoney = carSpends.stream()
                .filter(spend -> spend.getMaintenanceTime().after(startTime) && spend.getMaintenanceTime().before(endTime))
                .mapToDouble(RescueCarSpend::getMaintenanceMoney)
                .sum();

        Map<String, Double> result = new HashMap<>();
        result.put("totalRefuelMoney", totalRefuelMoney);
        result.put("totalMaintenanceMoney", totalMaintenanceMoney);

        return result;
    }
}
