package org.dromara.web.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.system.domain.SysUser;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.web.domain.DailyMealPlan;
import org.dromara.web.domain.DailyMealRecipe;
import org.dromara.web.domain.HospitalMealRecipe;
import org.dromara.web.domain.bo.DailyMealPlanBo;
import org.dromara.web.domain.vo.DailyMealPlanVo;
import org.dromara.web.domain.vo.DailyMealRecipeVo;
import org.dromara.web.domain.vo.HospitalMealPlanVo;
import org.dromara.web.domain.vo.HospitalMealRecipeVo;
import org.dromara.web.mapper.DailyMealPlanMapper;
import org.dromara.web.mapper.DailyMealRecipeMapper;
import org.dromara.web.service.IDailyMealPlanService;
import org.springframework.stereotype.Service;

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

/**
 * 日常膳食主Service业务层处理
 *
 * @author Lion Li
 * @date 2025-07-25
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class DailyMealPlanServiceImpl implements IDailyMealPlanService {

    private final DailyMealPlanMapper baseMapper;

    private final SysUserMapper userMapper;

    private final DailyMealRecipeMapper mealRecipeMapper;

    /**
     * 查询日常膳食主
     *
     * @param id 主键
     * @return 院内膳食主
     */
    @Override
    public DailyMealPlanVo queryById(Long id) {
        DailyMealPlanVo dailyMealPlanVo = baseMapper.selectVoById(id);
        if (ObjUtil.isNotNull(dailyMealPlanVo)) {
            List<DailyMealRecipeVo> voList = mealRecipeMapper.selectVoList(Wrappers.lambdaQuery(DailyMealRecipe.class).eq(DailyMealRecipe::getPlanId, dailyMealPlanVo.getId()));
            dailyMealPlanVo.setMealRecipeList(voList);
        }
        return dailyMealPlanVo;
    }

    /**
     * 分页查询日常膳食主列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 日常膳食主分页列表
     */
    @Override
    public TableDataInfo<DailyMealPlanVo> queryPageList(DailyMealPlanBo bo, PageQuery pageQuery) {

        LambdaQueryWrapper<DailyMealPlan> lqw = buildQueryWrapper(bo);
        Page<DailyMealPlanVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        List<DailyMealPlanVo> records = result.getRecords();
        if (CollUtil.isNotEmpty(records)) {
            Set<Long> userList = CollUtil.newHashSet();
            records.forEach(v -> {
                userList.add(v.getCreateBy());
            });
            Map<Long, String> userMap = userMapper.selectList(Wrappers.lambdaQuery(SysUser.class)
                .select(SysUser::getUserId, SysUser::getUserName)
                .in(SysUser::getUserId, userList)).stream().collect(Collectors.toMap(k1 -> k1.getUserId(), k2 -> k2.getUserName(), (k1, k2) -> k1));
            records.forEach(v -> {
                v.setCreateByUser(userMap.get(v.getCreateBy()));
            });
        }
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的日常膳食主列表
     *
     * @param bo 查询条件
     * @return 日常膳食主列表
     */
    @Override
    public List<DailyMealPlanVo> queryList(DailyMealPlanBo bo) {
        LambdaQueryWrapper<DailyMealPlan> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<DailyMealPlan> buildQueryWrapper(DailyMealPlanBo bo) {
        List<Date> dateRange = bo.getDateRange();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        List<SysUser> userList = userMapper.selectList(Wrappers.lambdaQuery(SysUser.class).select(SysUser::getUserId, SysUser::getUserName));
        Map<String, Long> userMap = userList.stream().collect(Collectors.toMap(k1 -> String.valueOf(k1.getUserName()), k2 -> k2.getUserId(), (k1, k2) -> k1));
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<DailyMealPlan> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(DailyMealPlan::getId);
        lqw.eq(StringUtils.isNotBlank(bo.getType()), DailyMealPlan::getType, bo.getType());
        lqw.eq(bo.getPatientId() != null, DailyMealPlan::getPatientId, bo.getPatientId());
        if (StringUtils.isNotBlank(bo.getSearchValue())) {
            lqw.and(wrapper -> wrapper.like(DailyMealPlan::getCreateBy, userMap.get(bo.getSearchValue())).or().like(DailyMealPlan::getOutpatientNo, bo.getSearchValue()));
        }
        if (dateRange != null && dateRange.size() == 2) {
            String startTime = sdf.format(dateRange.get(0)) + " 00:00:00";  // 开始时间
            String endTime = sdf.format(dateRange.get(1)) + " 23:59:59";    // 结束时间
            if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
                lqw.between(DailyMealPlan::getCreateTime, startTime, endTime);

            }
        }
        return lqw;
    }

    /**
     * 新增日常膳食主
     *
     * @param bo 日常膳食主
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(DailyMealPlanBo bo) {
        DailyMealPlan add = MapstructUtils.convert(bo, DailyMealPlan.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            List<DailyMealRecipe> hList = bo.getMealRecipeList().stream().map(mealRecipe -> {
                DailyMealRecipe dailyMealRecipe = MapstructUtils.convert(mealRecipe, DailyMealRecipe.class);
                dailyMealRecipe.setPlanId(add.getId());
                return dailyMealRecipe;
            }).collect(Collectors.toList());
            mealRecipeMapper.insertBatch(hList);
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改日常膳食主
     *
     * @param bo 日常膳食主
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(DailyMealPlanBo bo) {
        DailyMealPlan update = MapstructUtils.convert(bo, DailyMealPlan.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

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

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