package org.dromara.work.service.impl;

import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.work.domain.TpOrder;
import org.dromara.work.domain.TpWechatNum;
import org.dromara.work.mapper.TpOrderMapper;
import org.springframework.stereotype.Service;
import org.dromara.work.domain.bo.TpCoursesBo;
import org.dromara.work.domain.vo.TpCoursesVo;
import org.dromara.work.domain.TpCourses;
import org.dromara.work.mapper.TpCoursesMapper;
import org.dromara.work.service.ITpCoursesService;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Collection;

/**
 * 课程Service业务层处理
 *
 * @author Maosw
 * @date 2025-04-19
 */
@RequiredArgsConstructor
@Service
public class TpCoursesServiceImpl implements ITpCoursesService {

    private final TpCoursesMapper baseMapper;

    private final TpOrderMapper orderMapper;

    /**
     * 查询课程
     *
     * @param id 主键
     * @return 课程
     */
    @Override
    public TpCoursesVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 分页查询课程列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 课程分页列表
     */
    @Override
    public TableDataInfo<TpCoursesVo> queryPageList(TpCoursesBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<TpCourses> lqw = buildQueryWrapper(bo);
        Page<TpCoursesVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);

        for (TpCoursesVo vo : result.getRecords()) {
            List<TpOrder> orderList = orderMapper.selectList(new LambdaQueryWrapper<TpOrder>().eq(TpOrder::getCourseId, vo.getId()).ne(TpOrder::getPayState, 1));
            vo.setBmNum(orderList.stream().mapToInt(TpOrder::getBmNum).sum());
            vo.setDcNum(orderList.stream().mapToInt(TpOrder::getDcNum).sum());

            BigDecimal total = orderList.stream().map(f -> new BigDecimal(String.valueOf(f.getPrice()))).reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal payPrice = orderList.stream().map(f -> new BigDecimal(String.valueOf(f.getPayPrice()))).reduce(BigDecimal.ZERO, BigDecimal::add);
            vo.setPrice(total);
            vo.setPayPrice(payPrice);
            if (payPrice.compareTo(BigDecimal.ZERO) == 0) {
                vo.setBili("0%");
            } else {
                BigDecimal bili = payPrice.divide(total, 2, BigDecimal.ROUND_HALF_UP);
                vo.setBili(bili.multiply(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_HALF_UP) + "%");
            }
        }
        return TableDataInfo.build(result);
    }

    /**
     * 查询课程数量
     *
     * @param bo 课程
     * @return 课程数量
     */
    @Override
    public Map<String, Object> queryCount(TpCoursesBo bo) {
        LambdaQueryWrapper<TpCourses> lqw = buildQueryWrapper(bo);
        List<TpCoursesVo> list = baseMapper.selectVoList(lqw);
        List<TpOrder> orderList = orderMapper.selectList(new LambdaQueryWrapper<TpOrder>().in(TpOrder::getCourseId, list.stream().map(TpCoursesVo::getId).toList()).ne(TpOrder::getPayState, 1));
        Map<String, Object> map = new HashMap<>();
        map.put("count", list.size());
        map.put("bmNum", orderList.stream().mapToInt(TpOrder::getBmNum).sum());
        map.put("dcNum", orderList.stream().mapToInt(TpOrder::getDcNum).sum());
        map.put("price", orderList.stream().map(f -> new BigDecimal(String.valueOf(f.getPrice()))).reduce(BigDecimal.ZERO, BigDecimal::add));
        map.put("payPrice", orderList.stream().map(f -> new BigDecimal(String.valueOf(f.getPayPrice()))).reduce(BigDecimal.ZERO, BigDecimal::add));
        return map;
    }

    /**
     * 查询符合条件的课程列表
     *
     * @param bo 查询条件
     * @return 课程列表
     */
    @Override
    public List<TpCoursesVo> queryList(TpCoursesBo bo) {
        LambdaQueryWrapper<TpCourses> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<TpCourses> buildQueryWrapper(TpCoursesBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<TpCourses> lqw = Wrappers.lambdaQuery();
        lqw.orderByDesc(TpCourses::getCreateTime);
        lqw.like(StringUtils.isNotBlank(bo.getName()), TpCourses::getName, bo.getName());
        lqw.eq(bo.getType() != null, TpCourses::getType, bo.getType());
        lqw.eq(bo.getUserId() != null, TpCourses::getUserId, bo.getUserId());
        lqw.like(StringUtils.isNotBlank(bo.getUserName()), TpCourses::getUserName, bo.getUserName());
        lqw.eq(bo.getStartTime() != null, TpCourses::getStartTime, bo.getStartTime());
        lqw.eq(bo.getEndTime() != null, TpCourses::getEndTime, bo.getEndTime());
        lqw.eq(StringUtils.isNotBlank(bo.getLocation()), TpCourses::getLocation, bo.getLocation());
        lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
            TpCourses::getCreateTime ,params.get("beginCreateTime"), params.get("endCreateTime"));
        lqw.between(params.get("beginStartTime") != null && params.get("endStartTime") != null,
            TpCourses::getStartTime ,params.get("beginStartTime"), params.get("endStartTime"));

        return lqw;
    }

    /**
     * 新增课程
     *
     * @param bo 课程
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(TpCoursesBo bo) {
        TpCourses add = MapstructUtils.convert(bo, TpCourses.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改课程
     *
     * @param bo 课程
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(TpCoursesBo bo) {
        TpCourses update = MapstructUtils.convert(bo, TpCourses.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(TpCourses entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除课程信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }
}
