package cn.iocoder.yudao.module.system.service.yk.impl;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.system.controller.admin.yk.vo.YkDeliveryStatsDetailReqVO;
import cn.iocoder.yudao.module.system.controller.admin.yk.vo.deliveryPerson.DeliveryPersonInfoCreateReqVO;
import cn.iocoder.yudao.module.system.controller.admin.yk.vo.deliveryPerson.DeliveryPersonInfoPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.yk.vo.deliveryPerson.DeliveryPersonInfoUpdateReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.yk.YkDeliveryStaffInfoDO;
import cn.iocoder.yudao.module.system.dal.dataobject.yk.YkElderlyDeliveryDO;
import cn.iocoder.yudao.module.system.dal.dataobject.home.HomeElderlyInfoDO;
import cn.iocoder.yudao.module.system.dal.mysql.yk.YkDeliveryStaffInfoMapper;
import cn.iocoder.yudao.module.system.dal.mysql.yk.YkElderlyDeliveryMapper;
import cn.iocoder.yudao.module.system.dal.mysql.home.HomeElderlyInfoMapper;
import cn.iocoder.yudao.module.system.service.yk.DeliveryPersonInfoService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;

/**
 * 送餐员信息 Service 实现类
 *
 * @author 系统管理员
 */
@Service
@Validated
public class DeliveryPersonInfoServiceImpl implements DeliveryPersonInfoService {

    @Resource
    private YkDeliveryStaffInfoMapper deliveryPersonInfoMapper;
    @Resource
    private YkElderlyDeliveryMapper ykElderlyDeliveryMapper;
    @Resource
    private HomeElderlyInfoMapper homeElderlyInfoMapper;

    @Override
    public Long createDeliveryPersonInfo(DeliveryPersonInfoCreateReqVO createReqVO) {
        // 插入
        YkDeliveryStaffInfoDO deliveryPersonInfo = BeanUtils.toBean(createReqVO, YkDeliveryStaffInfoDO.class);
        deliveryPersonInfo.setTenantId(createReqVO.getTenantId() == null ? TenantContextHolder.getTenantId() : createReqVO.getTenantId());
        deliveryPersonInfo.setCreatedBy(SecurityFrameworkUtils.getLoginUserNickname());
        deliveryPersonInfo.setJoinDate(deliveryPersonInfo.getJoinDate() == null ? LocalDate.now() : deliveryPersonInfo.getJoinDate());
        deliveryPersonInfoMapper.insert(deliveryPersonInfo);
        // 返回
        return deliveryPersonInfo.getId();
    }

    @Override
    public void updateDeliveryPersonInfo(DeliveryPersonInfoUpdateReqVO updateReqVO) {
        // 校验存在
        validateDeliveryPersonInfoExists(updateReqVO.getId());
        // 更新
        YkDeliveryStaffInfoDO updateObj = BeanUtils.toBean(updateReqVO, YkDeliveryStaffInfoDO.class);
        deliveryPersonInfoMapper.updateById(updateObj);
    }

    @Override
    public void deleteDeliveryPersonInfo(Long id) {
        // 校验存在
        validateDeliveryPersonInfoExists(id);
        // 删除
        deliveryPersonInfoMapper.deleteById(id);
    }

    private void validateDeliveryPersonInfoExists(Long id) {
        if (deliveryPersonInfoMapper.selectById(id) == null) {
            throw new RuntimeException("送餐员信息不存在");
        }
    }

    @Override
    public YkDeliveryStaffInfoDO getDeliveryPersonInfo(Long id) {
        return deliveryPersonInfoMapper.selectById(id);
    }

    @Override
    public List<YkDeliveryStaffInfoDO> getDeliveryPersonInfoList(List<Long> ids) {
        return deliveryPersonInfoMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<YkDeliveryStaffInfoDO> getDeliveryPersonInfoPage(DeliveryPersonInfoPageReqVO pageReqVO) {
        return deliveryPersonInfoMapper.selectPage(pageReqVO, new LambdaQueryWrapperX<YkDeliveryStaffInfoDO>()
                .likeIfPresent(YkDeliveryStaffInfoDO::getName, pageReqVO.getName())
                .likeIfPresent(YkDeliveryStaffInfoDO::getPhone, pageReqVO.getPhone())
                .eqIfPresent(YkDeliveryStaffInfoDO::getStatus, pageReqVO.getStatus())
                .inIfPresent(YkDeliveryStaffInfoDO::getTenantId, pageReqVO.getTenantIds())
                .orderByDesc(YkDeliveryStaffInfoDO::getId));
    }


    @Override
    public Map<String, Object> getDeliveryStatsDetail(YkDeliveryStatsDetailReqVO reqVO) {
        Map<String, Object> result = new HashMap<>();

        // 查询总送餐员数
        Long totalStaff = deliveryPersonInfoMapper.selectCount(new LambdaQueryWrapperX<YkDeliveryStaffInfoDO>()
                .eq(YkDeliveryStaffInfoDO::getTenantId, reqVO.getTenantId()));
        result.put("totalStaff", totalStaff.intValue());

        // 查询在职送餐员数（这里假设在职状态为1）
        Long activeStaff = deliveryPersonInfoMapper.selectCount(new LambdaQueryWrapperX<YkDeliveryStaffInfoDO>()
                .eq(YkDeliveryStaffInfoDO::getStatus, 1));
        result.put("activeStaff", activeStaff.intValue());

        // 查询总送餐次数
        LambdaQueryWrapperX<YkElderlyDeliveryDO> deliveryWrapper = new LambdaQueryWrapperX<YkElderlyDeliveryDO>()
                .betweenIfPresent(YkElderlyDeliveryDO::getDeliveryDate, reqVO.getStartDate(), reqVO.getEndDate())
                .eqIfPresent(YkElderlyDeliveryDO::getDeliveryPersonId, reqVO.getStaffId());

        Long totalDeliveries = ykElderlyDeliveryMapper.selectCount(deliveryWrapper);
        result.put("totalDeliveries", totalDeliveries.intValue());

        // 查询各送餐员统计详情
        List<Map<String, Object>> staffStats = ykElderlyDeliveryMapper.selectDeliveryStatsByStaffMap(
                reqVO.getStartDate(), reqVO.getEndDate(), reqVO.getStaffId());
        result.put("staffStats", staffStats);

        return result;
    }

    @Override
    public Map<String, Object> getDeliveryStatsRangeDetail(String startDate, String endDate, Long tenantId) {
        Map<String, Object> result = new HashMap<>();

        LambdaQueryWrapperX<YkElderlyDeliveryDO> deliveryWrapper = new LambdaQueryWrapperX<YkElderlyDeliveryDO>()
                .betweenIfPresent(YkElderlyDeliveryDO::getDeliveryDate, startDate, endDate)
                .eqIfPresent(YkElderlyDeliveryDO::getTenantId, tenantId);


        Long totalMeals = ykElderlyDeliveryMapper.selectCount(deliveryWrapper);
        result.put("totalMeals", totalMeals.intValue());

        List<HomeElderlyInfoDO> elderlyInfoList = homeElderlyInfoMapper.selectList(new LambdaQueryWrapperX<HomeElderlyInfoDO>().eqIfPresent(HomeElderlyInfoDO::getTenantId, tenantId));

        // 计算elderlyInfoList里面每个长者的余额总和
        BigDecimal totalAmount = elderlyInfoList.stream()
                .map(HomeElderlyInfoDO::getBalance)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        result.put("totalAmount", totalAmount);
        return result;
    }

    @Override
    public Map<String, Object> getDeliveryStatsRangeDetail(String date, Long tenantId) {
        Map<String, Object> result = new HashMap<>();

        LambdaQueryWrapperX<YkElderlyDeliveryDO> deliveryWrapper = new LambdaQueryWrapperX<YkElderlyDeliveryDO>()
                .eqIfPresent(YkElderlyDeliveryDO::getDeliveryDate, date)
                .eqIfPresent(YkElderlyDeliveryDO::getTenantId, tenantId);

        Long confirmedMeals = ykElderlyDeliveryMapper.selectCount(deliveryWrapper);
        result.put("confirmedMeals", confirmedMeals.intValue());
        List<HomeElderlyInfoDO> elderlyInfoList = homeElderlyInfoMapper.selectList(new LambdaQueryWrapperX<HomeElderlyInfoDO>().eqIfPresent(HomeElderlyInfoDO::getTenantId, tenantId));

        // 计算elderlyInfoList里面每个长者的余额总和
        BigDecimal totalAmount = elderlyInfoList.stream()
                .map(HomeElderlyInfoDO::getBalance)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        result.put("totalAmount", totalAmount);
        return result;
    }

}