package com.bonus.canteen.core.cook.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bonus.canteen.core.common.enums.YesOrNoEnum;
import com.bonus.canteen.core.cook.domain.CookRecipe;
import com.bonus.canteen.core.cook.domain.CookRecipeDetail;
import com.bonus.canteen.core.cook.domain.CookRecipeDishes;
import com.bonus.canteen.core.cook.dto.AppletDishesDetailDTO;
import com.bonus.canteen.core.cook.dto.CookH5ReserveRecipeDTO;
import com.bonus.canteen.core.cook.dto.CookH5WeekDetailsDTO;
import com.bonus.canteen.core.cook.dto.UserInfoDTO;
import com.bonus.canteen.core.cook.mapper.CookH5Mapper;
import com.bonus.canteen.core.cook.mapper.CookRecipeDetailMapper;
import com.bonus.canteen.core.cook.mapper.CookRecipeDishesMapper;
import com.bonus.canteen.core.cook.mapper.CookRecipeMapper;
import com.bonus.canteen.core.cook.service.ICookH5Service;
import com.bonus.canteen.core.cook.service.ICookRecipeService;
import com.bonus.canteen.core.cook.vo.*;
import com.bonus.common.houqin.constant.DelFlagEnum;
import com.bonus.common.security.utils.SecurityUtils;
import com.google.common.collect.Lists;
import org.hibernate.validator.internal.util.StringHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author xliu
 * @date 2025/5/28 9:22
 */
@Service
public class CookH5ServiceImpl implements ICookH5Service {

    private static final Logger log = LoggerFactory.getLogger(CookH5ServiceImpl.class);

    @Resource
    private CookH5Mapper cookH5Mapper;
    @Resource
    private CookRecipeDetailMapper cookRecipeDetailMapper;
    @Resource
    private CookRecipeDishesMapper cookRecipeDishesMapper;

    @Resource
    private CookRecipeMapper cookRecipeMapper;

    @Override
    public List<CookH5WeekCanteenListVO> getWeekCanteenList(UserInfoDTO userInfoDTO) {
        return cookH5Mapper.getWeekCanteenList(userInfoDTO);
    }

    @Override
    public List<CookH5WeekDetailsVO> getWeekRecipeDetail(CookH5WeekDetailsDTO dto) {
        List<CookH5WeekDetailsVO> resutlList = cookH5Mapper.getWeekRecipeDetail(dto);
        resutlList.sort(Comparator.comparingInt(CookH5WeekDetailsVO::getMealtimeType).reversed());
        return resutlList;
    }

    @Override
    public List<CookH5ReserveCanteenListVO> getReserveCanteenList(UserInfoDTO dto) {
        List<CookH5ReserveCanteenListVO> resultList = this.cookH5Mapper.selectReserveMealCanteenList(dto);
        if (ObjectUtil.isEmpty(resultList)) {
            return resultList;
        }else{
            //获取集合中档口id
            List<Long> stallIdList = resultList.stream().flatMap((canteen) -> {
                return canteen.getStallList().stream().map(CookH5ReserveStallVO::getStallId);
            }).collect(Collectors.toList());
            if (ObjectUtil.isNotEmpty(stallIdList)) {
                //获取每个档口月销量
                List<StallMonthSalesVO> stallMonthSalesList = this.cookH5Mapper.selectMonthSalesStall(stallIdList);
                //将档口月销量转换为Map
                Map<Integer, Integer> stallSaleMap = stallMonthSalesList.stream().collect(Collectors.toMap(StallMonthSalesVO::getStallId, StallMonthSalesVO::getMonthlySales));
               // 遍历食堂列表，将每个档口的月销量设置到对应的档口中
                resultList.forEach((canteen) -> {
                    List<CookH5ReserveStallVO> stallList = canteen.getStallList();
                    if (ObjectUtil.isNotEmpty(stallList)) {
                        stallList.forEach((stall) -> {
                            stall.setMonthlySales((stallSaleMap.get(stall.getStallId()) == null) ? 0 : stallSaleMap.get(stall.getStallId()));
                        });
                    }

                });
                //获取每个档口推荐菜品
                resultList.forEach((c) -> {
                    List<CookH5ReserveStallVO> stallList = c.getStallList();
                    if (ObjectUtil.isNotEmpty(stallList)) {
                        stallList.forEach((s) -> {
                            List<Long> topDishesIdList = this.cookH5Mapper.selectTopDishesIdList(Collections.singletonList(s.getStallId()));
                            List<CookH5ReserveDishesVO> recommendList = Lists.newArrayList();
                            List<CookH5ReserveDishesVO> allRecipeDishesList = cookH5Mapper.selectAllRecipeDishesList(s.getRecipeId());
                            if (ObjectUtil.isNotEmpty(allRecipeDishesList) && ObjectUtil.isNotEmpty(topDishesIdList)) {
                                Iterator var5 = topDishesIdList.iterator();

                                while(var5.hasNext()) {
                                    Long dishesId = (Long)var5.next();
                                    if (allRecipeDishesList.stream().map(CookH5ReserveDishesVO::getDishesId).collect(Collectors.toList()).contains(dishesId)) {
                                        CookH5ReserveDishesVO recommendDishes = (CookH5ReserveDishesVO)allRecipeDishesList.stream().filter((a) -> {
                                            return a.getDishesId().equals(dishesId);
                                        }).collect(Collectors.toList()).get(0);
                                        if (!recommendList.contains(recommendDishes)) {
                                            recommendList.add(recommendDishes);
                                        }

                                        if (recommendList.size() >= 3) {
                                            s.setRecommendList(recommendList);
                                            return;
                                        }
                                    }
                                }
                            }
                            s.setRecommendList(recommendList);
                        });
                    }
                });
            }

        }
        return resultList;
    }


    @Override
    public List<CookH5ReserveRecipeDetailsVO> getReserveRecipeDetailList(CookH5ReserveRecipeDTO content) {
        List<CookH5ReserveRecipeDetailsVO> resultList = cookH5Mapper.selectReserveRecipe(content.getApplyDate(), content.getRecipeId());
        if (ObjectUtil.isEmpty(resultList)) {
            return resultList;
        } else {
            Set<Long> stallSet = new HashSet<>();
            resultList.forEach((typeList)-> {
                if (ObjectUtil.isNotEmpty(typeList.getTypeList())) {
                    typeList.getTypeList().forEach((type) -> {
                        if(ObjectUtil.isNotEmpty(type)){
                            type.getDishesList().forEach((dishes) -> {
                                stallSet.add(dishes.getStallId());
                            });
                        }
                    });
                }
            });
            resultList.sort(Comparator.comparingInt(CookH5ReserveRecipeDetailsVO::getMealtimeType).reversed());
            //设置默认配送方式
            List<CookH5AllocDeliveryCostVO> deliveryCostList = new ArrayList<>();
            CookH5AllocDeliveryCostVO deliveryCost = new CookH5AllocDeliveryCostVO();
            deliveryCost.setDeliveryType(1);
            deliveryCost.setDeliveryName("自取");
            deliveryCost.setDeliveryAmount(BigDecimal.valueOf(0));
            deliveryCost.setPackingFee(BigDecimal.valueOf(0));
            deliveryCostList.add(deliveryCost);

            List<CookH5ReserveMealtimeStateVO> mealTimeList = cookH5Mapper.getCookMealtimeListByStallId(stallSet);
            if (ObjectUtil.isEmpty(mealTimeList)) {
                log.info("未获取到开启餐次");
                return Lists.newArrayList();
            } else {
                if (LocalDate.now().isEqual(content.getApplyDate())) {
                    mealTimeList = mealTimeList.stream().filter((time) -> {
                        return LocalTime.now().isBefore(time.getStartTime());
                    }).collect(Collectors.toList());
                }
                if (ObjectUtil.isEmpty(mealTimeList)) {
                    log.info("未获取到餐次信息");
                    return Lists.newArrayList();
                }else{
                    List<CookH5ReserveMealtimeStateVO> finalMealTimeList = mealTimeList;
                    resultList = resultList.stream().filter((time) -> {
                        return finalMealTimeList.stream().map(CookH5ReserveMealtimeStateVO::getMealtimeType).collect(Collectors.toList()).contains(time.getMealtimeType());
                    }).collect(Collectors.toList());
                    resultList.forEach((time) -> {
                        List<CookH5ReserveRecipeTypeVO> typeList = time.getTypeList();
                        if (ObjectUtil.isNotEmpty(typeList)) {
                            typeList.forEach((type) -> {
                                List<CookH5ReserveRecipeDishesVO> dishesList = type.getDishesList();
                                if (ObjectUtil.isNotEmpty(dishesList)) {
                                    dishesList.forEach((dishes) -> {
                                        //添加配送方式 默认全是自取
                                        dishes.setCostModelList(deliveryCostList);
                                    });
                                }

                            });
                        }
                    });
                    // 计算菜品分值  暂未开发

                }
            }

        }
        return resultList;
    }


    @Override
    public void scheduledTask() {
        List<Long> recipeIdList = cookH5Mapper.selectRecipeIdList();
        //查询所有每周菜谱、指定日期菜谱id
        for(int i = 0; i < 7; ++i) {
            this.scheduledTaskRun(recipeIdList, LocalDate.now().plusDays(i));
        }
    }

    public void scheduledTaskRun(List<Long> recipeIdList, LocalDate applyDate) {
        if (ObjectUtil.isEmpty(recipeIdList) && recipeIdList.size()==0) {
            log.info("未获取到菜谱id");
        }else{
            List<Long> recipeIdMap = cookH5Mapper.recipeIdMap(recipeIdList,applyDate);
            //去除当日已有菜品的菜谱id
            recipeIdList = new ArrayList<>(recipeIdList);
            recipeIdList.removeAll(recipeIdMap);
            if(recipeIdList.isEmpty()){
                log.info("当日无需要生成菜品");
                return;
            }
            List<CookRecipe> cookRecipeList = cookRecipeMapper.getCookRecipeByRecipeIds(recipeIdList);
            if(!cookRecipeList.isEmpty()){
               // Map<Long, CookRecipe> recipeMap = cookRecipeList.stream().collect(Collectors.toMap(CookRecipe::getRecipeId, Function.identity()));
                //获取菜谱id对应detailsId信息
                recipeIdList.forEach( recipeId -> {
                    //获取具体的餐次信息
                    List<CookRecipeDetail> cookRecipeDetailList = cookRecipeDetailMapper.getCookRecipeDetailLTemplate(recipeId, "1");
                    if(!cookRecipeDetailList.isEmpty()){
                        cookRecipeDetailList.forEach(detail -> {
                            //设置菜谱id
                            //detail.setRecipeId(recipeId);
                            detail.setApplyDate(applyDate);
                            detail.setDetailType(2L);
                            detail.setApplyWeek(Long.valueOf(applyDate.getDayOfWeek().getValue()));
                            List<CookRecipeDishes> cookRecipeDishesList = cookRecipeDishesMapper.getCookRecipeDishesByDetailId(detail.getRecipeDetailId());
                            cookRecipeDetailMapper.insertCookRecipeDetail(detail);
                            if(!cookRecipeDishesList.isEmpty()){
                                cookRecipeDishesList.forEach(dishes -> {
                                    //设置菜品id
                                    dishes.setRecipeDetailId(detail.getRecipeDetailId());
                                    cookRecipeDishesMapper.insertCookRecipeDishes(dishes);
                                });
                            }
                        });
                    }
                    //获取details对应的菜品信息
                });

            }else{
                log.info("未获取到菜谱信息");
            }
        }
    }


    @Override
    public AppletDishesDetailVO getDishesDetailByDishesId(AppletDishesDetailDTO dto) {
        dto.setDelFlag(DelFlagEnum.DEL_FALSE.key());
        AppletDishesDetailVO appletDishesDetailVO = cookH5Mapper.selectDishesDetailByDishesId(dto);
        Long dishesId = ((AppletDishesSizeV2VO) appletDishesDetailVO.getDishesDetailList().get(0)).getDishesId();
        List materialList;
        if (appletDishesDetailVO.getMealType() == 1) {
            materialList = this.cookH5Mapper.getMenuMaterialById(dishesId);
            appletDishesDetailVO.setMaterialList(materialList);
        }

//        int countDishes = this.cookH5Mapper.getCollectionCountByUserIdAndDishesId(SecurityUtils.getUserId(), dishesId);
//        if (countDishes > 0) {
//            appletDishesDetailVO.setIsFavorites(YesOrNoEnum.YES.key());
//        } else {
//            appletDishesDetailVO.setIsFavorites(YesOrNoEnum.NO.key());
//        }

        return appletDishesDetailVO;
    }
}
