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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bonus.canteen.core.android.vo.UserInfoVo;
import com.bonus.canteen.core.menu.domain.MapBean;
import com.bonus.canteen.core.menu.domain.MenuRecipe;
import com.bonus.canteen.core.menu.domain.MenuRecipeDetail;
import com.bonus.canteen.core.menu.domain.MenuRecipeDishes;
import com.bonus.canteen.core.menu.dto.AppletDishesDetailDTO;
import com.bonus.canteen.core.menu.dto.AppletWeekCanteenDTO;
import com.bonus.canteen.core.menu.dto.AppletWeekRecipeDTO;
import com.bonus.canteen.core.menu.enums.MktEffTypeEnum;
import com.bonus.canteen.core.menu.enums.MktUserTypeEnum;
import com.bonus.canteen.core.menu.mapper.AppletRecipeH5Mapper;
import com.bonus.canteen.core.menu.mapper.MenuDishesMapper;
import com.bonus.canteen.core.menu.mapper.MenuRecipeMapper;
import com.bonus.canteen.core.menu.service.AppletRecipeH5Service;
import com.bonus.canteen.core.menu.service.IMenuRecipeDetailService;
import com.bonus.canteen.core.menu.service.IMenuRecipeDishesService;
import com.bonus.canteen.core.menu.vo.*;
import com.bonus.canteen.core.nutrition.common.enums.YesOrNoEnum;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.houqin.constant.DelFlagEnum;
import com.bonus.common.houqin.i18n.I18n;
import com.bonus.common.houqin.utils.id.Id;
import com.bonus.common.security.utils.SecurityUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.hibernate.validator.internal.util.StringHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * @author xliu
 * @date 2025/4/15 16:38
 */
@Service
public class AppletRecipeH5ServiceImpl extends ServiceImpl<MenuRecipeMapper, MenuRecipe> implements AppletRecipeH5Service {

    @Resource
    private AppletRecipeH5Mapper appletRecipeH5Mapper;

    @Resource
    private IMenuRecipeDetailService menuRecipeDetailService;

    @Resource
    private IMenuRecipeDishesService menuRecipeDishesService;

    @Resource
    private  MenuRecipeMapper menuRecipeMapper;

    @Resource
    private MenuDishesMapper menuDishesMapper;

    @Override
    public List<AppletWeekCanteenVO> getWeekMealList(AppletWeekCanteenDTO content) {
        //人员范围  暂时不用
//        Set<Long> effIdSet = this.getShopstallIdListByCustId(content.getUserId(), false);
//        if (ObjectUtil.isEmpty(effIdSet)) {
//            effIdSet = Sets.newTreeSet();
//            effIdSet.add(-1L);
//        }

        return this.appletRecipeH5Mapper.selectWeekCanteenList();
    }

    @Override
    public Set<Long> getShopstallIdListByCustId(Long custId, boolean checkCustInfo) {
        Set<Long> effIdSet = Sets.newTreeSet();
//        UserInfoVo userInfoVo = new UserInfoVo();
//        userInfoVo.setUserId(String.valueOf(custId));
//        userInfoVo.setAccStatus("1");
//        UserInfoVo custInfo = menuAppRecipeMapper.selectMessageByUserId(userInfoVo);
//        if (ObjectUtil.isNull(custInfo)) {
//            if (checkCustInfo) {
//                throw new ServiceException("菜单绑定错误");
//            } else {
//                throw new ServiceException("***[获取全档口菜谱信息]_未查询到人员信息,直接返回********************");
//                return effIdSet;
//            }
//        } else {
//            List<MktEffectiveUserVO> effectiveUserVOList = menuRecipeMapper.selectAllUserEff(MktEffTypeEnum.USER_SORT.key(), DelFlagEnum.DEL_FALSE.key());
//            Long orgId = custInfo.getOrgId();
//            Integer psnType = custInfo.getPsnType();
//            if (ObjectUtil.isNotEmpty(effectiveUserVOList)) {
//                List<MktEffectiveUserVO> collect = effectiveUserVOList.stream().filter((u) -> {
//                    boolean containsOrg = ObjectUtil.isNotEmpty(u.getOrgIdList()) && u.getOrgIdList().contains(orgId);
//                    boolean containsPsn = ObjectUtil.isNotEmpty(u.getPsnTypeList()) && u.getPsnTypeList().contains(psnType);
//                    return MktUserTypeEnum.INTERSECTION.key().equals(u.getUserType()) && containsOrg && containsPsn || MktUserTypeEnum.UNION_SET.key().equals(u.getUserType()) && (containsOrg || containsPsn);
//                }).collect(Collectors.toList());
//                if (ObjectUtil.isNotEmpty(collect)) {
//                    effIdSet = collect.stream().map(MktEffectiveUserVO::getEffId).collect(Collectors.toSet());
//                    effIdSet.add(-1L);
//                }
//            }
//
//            log.info("***[获取指定人员折扣比例]_指定人员的生效范围effIdSet: {}", effIdSet);
//            return effIdSet;
//        }
        return effIdSet;
    }

    @Override
    public AppletDishesDetailVO getDishesDetailByDishesId(AppletDishesDetailDTO dishesDetailDTO) {
        dishesDetailDTO.setDelFlag(DelFlagEnum.DEL_FALSE.key());
        Long baseDishesId = dishesDetailDTO.getBaseDishesId();
        Long custId = dishesDetailDTO.getCustId();
        //人员收藏信息暂时不管
//        if (!ObjectUtil.isNull(custId) && custId != -1L) {
            AppletDishesDetailVO appletDishesDetailVO = appletRecipeH5Mapper.selectDishesDetailByDishesId(dishesDetailDTO);
//            Long countDishes = this.appletRecipeH5Mapper.selectCount(Wrappers.lambdaQuery(MenuCollectionDishes.class)
//                    .eq(MenuCollectionDishes::getCustId, custId).eq(MenuCollectionDishes::getDishesId, baseDishesId));
//            if (ObjectUtil.isNotNull(countDishes) && countDishes > 0L) {
//                appletDishesDetailVO.setIsFavorites(1);
//            } else {
//                appletDishesDetailVO.setIsFavorites(2);
//            }
          if(appletDishesDetailVO != null && appletDishesDetailVO.getDishesDetailList() !=null && appletDishesDetailVO.getDishesDetailList().size()>0){
                String tasteIds = appletDishesDetailVO.getDishesDetailList().get(0).getTasteIds();
                if(!StringHelper.isNullOrEmptyString(tasteIds)){
                    List<String> list = Arrays.asList(tasteIds.split(","));
                    List<MapBean> mapBean = menuDishesMapper.getDishesTypeByList("dishes_taste",list);
                    System.err.println("mapBean="+mapBean);
                    String result = mapBean.stream()
                            .map(MapBean::getKey)  // 提取每个 MapBean 的 key
                            .collect(Collectors.joining(","));  // 用逗号连
                    appletDishesDetailVO.getDishesDetailList().get(0).setTasteIds(result);
                }
                //     return menuDishesMapper.getDishesType(mapBean);
          }
            Long dishesId = ((AppletDishesSizeV2VO) appletDishesDetailVO.getDishesDetailList().get(0)).getDishesId();
            List materialList;
            if (appletDishesDetailVO.getMealType() == 1) {
                materialList = this.appletRecipeH5Mapper.getMenuMaterialById(dishesId);
                appletDishesDetailVO.setMaterialList(materialList);
            } else {
                //套餐信息  暂时删除不要
//                materialList = this.appletRecipeH5Mapper.selectDishesName(dishesId);
//                appletDishesDetailVO.setPackageDishesList(materialList);
            }

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

            return appletDishesDetailVO;
//        } else {
//            throw new ServiceException(I18n.getMessage("menu_no_cust_info", new Object[0]));
//        }
    }

    @Override
    public List<AppletWeekRecipeVO> getWeekRecipeDetailList(AppletWeekRecipeDTO content) {
        try{
        List<Long> recipeIdList = Lists.newArrayList();
        Set<Long> effIdSet = this.getShopstallIdListByCustId(content.getCustId(), false);
        if (ObjectUtil.isNull(content.getRecipeId())) {
            if (ObjectUtil.isEmpty(effIdSet)) {
                effIdSet = Sets.newTreeSet();
                effIdSet.add(-1L);
            }
            recipeIdList = this.appletRecipeH5Mapper.selectWeekRecipeId(content.getRecipeId(), (Set) effIdSet);

            if (ObjectUtil.isEmpty(recipeIdList)) {
                return Lists.newArrayList();
            }
        } else {
            LocalDate applyDate = content.getApplyDate();
            LocalDate now = LocalDate.now();
            if (applyDate.isBefore(now)) {
                System.out.println("applyDate 早于当前日期");
                //获取当前菜谱绑定的日期
                String bindTime = this.appletRecipeH5Mapper.getBingTimeByRecipeId(content.getRecipeId());
                if(bindTime !=null){
                    bindTime =  bindTime.substring(0,10);
                    LocalDate bindDate = LocalDate.parse(bindTime);
                    System.out.println("Parsed date and time: " + bindDate);
                    if(bindDate.isBefore(applyDate)){
                        System.out.println("绑定日期早于查询历史信息日期");
                        recipeIdList = this.appletRecipeH5Mapper.selectWeekRecipeId(content.getRecipeId(), effIdSet);
                    }else{
                        System.out.println("绑定日期迟于查询历史信息日期");

                        List<Long> repeIdList = this.appletRecipeH5Mapper.getRecipeIdListByRecipeId(content.getRecipeId());

                        recipeIdList = this.appletRecipeH5Mapper.selectWeekRecipeIdHistory(repeIdList, null,applyDate);
                        if(recipeIdList == null || recipeIdList.size() == 0){
                            recipeIdList.add(content.getRecipeId());
                        }
                    }
                }else{
                    throw new ServiceException("菜谱档口绑定日期为空");
                }
            } else if (applyDate.isAfter(now)) {
                System.out.println("applyDate 晚于当前日期");
                recipeIdList = this.appletRecipeH5Mapper.selectWeekRecipeId(content.getRecipeId(), null);
            } else {
                System.out.println("applyDate 等于当前日期");
                recipeIdList = this.appletRecipeH5Mapper.selectWeekRecipeId(content.getRecipeId(), null);
            }
            if(recipeIdList == null || recipeIdList.size() == 0){
                throw new ServiceException("本档口没有更早的历史菜谱记录");
                // recipeIdList.add(content.getRecipeId());
            }
        }

        this.generateRecipe(recipeIdList, content.getApplyDate());
        List<AppletWeekRecipeVO> resultList = appletRecipeH5Mapper.selectWeekRecipe(content.getApplyDate(), content.getRecipeId(), (List) recipeIdList);
        resultList.sort(Collections.reverseOrder((s1, s2) -> {
            return s2.getMealtimeType() - s1.getMealtimeType();
        }));
        return resultList;
        }catch (Exception e){
            throw new ServiceException(e.toString());
        }

    }

    @Transactional(rollbackFor = {Exception.class})
    public synchronized void generateRecipe(List<Long> recipeIdList, LocalDate applyDate) {
        if (!ObjectUtil.isEmpty(recipeIdList) && !ObjectUtil.isEmpty(applyDate)) {
            recipeIdList = new ArrayList(recipeIdList);
            Map<Long, Long> recipeDetailContMap = (Map) this.menuRecipeDetailService.list((Wrapper<MenuRecipeDetail>) ((LambdaQueryWrapper<MenuRecipeDetail>) Wrappers.lambdaQuery(MenuRecipeDetail.class).select(MenuRecipeDetail::getRecipeId).eq(MenuRecipeDetail::getApplyDate, applyDate)).in(MenuRecipeDetail::getRecipeId, recipeIdList)).stream().collect(Collectors.groupingBy(MenuRecipeDetail::getRecipeId, Collectors.counting()));
            recipeIdList.removeAll(recipeDetailContMap.keySet());
            if (!ObjectUtil.isEmpty(recipeIdList)) {
                List<MenuRecipe> menuRecipes = this.list((Wrapper) ((LambdaQueryWrapper) Wrappers.lambdaQuery(MenuRecipe.class).in(MenuRecipe::getRecipeType, new Object[]{2, 3})).apply(CollUtil.isNotEmpty(recipeIdList), "recipe_id IN (" + recipeIdList.stream().map(String::valueOf).collect(Collectors.joining(", ")) + ")"));
                if (!ObjectUtil.isEmpty(menuRecipes)) {
                    Map<Long, MenuRecipe> recipeMap = (Map) menuRecipes.stream().collect(Collectors.toMap(MenuRecipe::getRecipeId, Function.identity()));
                    List<MenuRecipeDetail> menuRecipeDetails = this.menuRecipeDetailService.list((Wrapper) ((LambdaQueryWrapper) Wrappers.lambdaQuery(MenuRecipeDetail.class).eq(MenuRecipeDetail::getDetailType, 1)).apply(CollUtil.isNotEmpty(recipeIdList), "recipe_id IN (" + recipeIdList.stream().map(String::valueOf).collect(Collectors.joining(", ")) + ")"));
                    Map<Long, Integer> recipeTypeMap = (Map) menuRecipes.stream().collect(Collectors.toMap(MenuRecipe::getRecipeId, MenuRecipe::getRecipeType));
                    menuRecipeDetails = this.filterMenuRecipeDetails(recipeTypeMap, menuRecipeDetails, applyDate);
                    if (!ObjectUtil.isEmpty(menuRecipeDetails)) {
                        Map<Long, List<MenuRecipeDetail>> detailMap = (Map) menuRecipeDetails.stream().collect(Collectors.groupingBy(MenuRecipeDetail::getRecipeId));
                        List<Long> detailIds = (List) menuRecipeDetails.stream().map(MenuRecipeDetail::getDetailId).collect(Collectors.toList());
                        Map<Long, List<MenuRecipeDishes>> recipeDishes = (Map) this.menuRecipeDishesService.list((Wrapper) Wrappers.lambdaQuery(MenuRecipeDishes.class).in(MenuRecipeDishes::getDetailId, detailIds)).stream().collect(Collectors.groupingBy(MenuRecipeDishes::getDetailId));
                        List<MenuRecipeDetail> recipeDetailV2List = Lists.newArrayList();
                        List<MenuRecipeDishes> recipeDishesV2List = Lists.newArrayList();
                        Iterator var13 = recipeMap.keySet().iterator();

                        label59:
                        while (true) {
                            Long recipeId;
                            Integer type;
                            List menuRecipeDetail;
                            do {
                                if (!var13.hasNext()) {
                                    this.menuRecipeDetailService.saveBatch(recipeDetailV2List);
                                    if (ObjectUtil.isNotEmpty(recipeDishesV2List)) {
                                        this.menuRecipeDishesService.saveBatch(recipeDishesV2List);
                                    }
                                    return;
                                }
                                recipeId = (Long) var13.next();
                                type = (Integer) recipeTypeMap.get(recipeId);
                                menuRecipeDetail = (List) detailMap.get(recipeId);
                            } while (!ObjectUtil.isNotEmpty(menuRecipeDetail));
                            Iterator var17 = menuRecipeDetail.iterator();
                            while (true) {
                                Long detailId;
                                List dishes;
                                do {
                                    if (!var17.hasNext()) {
                                        continue label59;
                                    }
                                    MenuRecipeDetail recipeDetail = (MenuRecipeDetail) var17.next();
                                    MenuRecipeDetail detailItem = new MenuRecipeDetail();
                                    detailId = Id.next();
                                    detailItem.setDetailId(detailId);
                                    detailItem.setRecipeId(recipeId);
                                    if (ObjectUtil.equal(type, 3)) {
                                        detailItem.setApplyWeek(applyDate.getDayOfWeek().getValue());
                                    }
                                    detailItem.setApplyDate(applyDate);
                                    detailItem.setMealtimeType(recipeDetail.getMealtimeType());
                                    detailItem.setDetailType(2);
                                    recipeDetailV2List.add(detailItem);
                                    dishes = (List) recipeDishes.get(recipeDetail.getDetailId());
                                } while (!ObjectUtil.isNotEmpty(dishes));
                                Iterator var22 = dishes.iterator();
                                while (var22.hasNext()) {
                                    MenuRecipeDishes dish = (MenuRecipeDishes) var22.next();
                                    MenuRecipeDishes dishesItem = (MenuRecipeDishes) BeanUtil.copyProperties(dish, MenuRecipeDishes.class, new String[0]);
                                    dishesItem.setDetailId(detailId);
                                    dishesItem.setId((Long) null);
                                    recipeDishesV2List.add(dishesItem);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    public List<MenuRecipeDetail> filterMenuRecipeDetails(Map<Long, Integer> recipeTypeMap, List<MenuRecipeDetail> menuRecipeDetails, LocalDate applyDate) {
        return menuRecipeDetails.stream().filter((item) -> {
            Long recipeId = item.getRecipeId();
            Integer type = (Integer) recipeTypeMap.get(recipeId);
            if (type == 3) {
                return ObjectUtil.equal(item.getApplyWeek(), applyDate.getDayOfWeek().getValue());
            } else {
                return type == 2;
            }
        }).collect(Collectors.toList());
    }

}
