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

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bonus.canteen.core.basic.domain.*;
import com.bonus.canteen.core.basic.mapper.BasicStallMealtimeMapper;
import com.bonus.canteen.core.cook.domain.CookRecipe;
import com.bonus.canteen.core.cook.dto.*;
import com.bonus.canteen.core.cook.mapper.CookRecipeH5Mapper;
import com.bonus.canteen.core.cook.service.ICookRecipeH5Service;
import com.bonus.canteen.core.cook.vo.*;
import com.bonus.canteen.core.utils.BnsConstants;
import com.bonus.common.core.exception.ServiceException;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 菜品计划信息Service业务层处理
 * 
 * @author xsheng
 * @date 2025-05-25
 */
@Service
@Slf4j
public class CookRecipeServiceH5Impl implements ICookRecipeH5Service {
    @Autowired
    private CookRecipeH5Mapper cookRecipeH5Mapper;
    @Autowired
    private BasicStallMealtimeMapper basicStallMealtimeMapper;


    @Override
    public List<AppletReserveCanteenVO> getReserveMealCanteenList() {
        List<AppletReserveCanteenVO> resultList = this.cookRecipeH5Mapper.selectReserveMealCanteenList();
        if (ObjectUtil.isEmpty(resultList)) {
            return resultList;
        } else {
            //this.allocCanteenService.checkAndDelReserveCanteen(resultList);
            List<Long> stallIdList = (List)resultList.stream().flatMap((canteen) -> {
                return canteen.getStallList().stream().map(AppletReserveStallVO::getStallId);
            }).collect(Collectors.toList());
            if (ObjectUtil.isNotEmpty(stallIdList)) {
                List<CookStallSaleModel> stallMonthSalesList = this.cookRecipeH5Mapper.selectMonthSalesStall(stallIdList);
                Map<Long, Integer> stallSaleMap = (Map)stallMonthSalesList.stream().collect(Collectors.toMap(CookStallSaleModel::getStallId, CookStallSaleModel::getMonthlySales));
                resultList.forEach((canteen) -> {
                    List<AppletReserveStallVO> stallList = canteen.getStallList();
                    if (ObjectUtil.isNotEmpty(stallList)) {
                        stallList.forEach((stall) -> {
                            stall.setMonthlySales((Integer)stallSaleMap.get(stall.getStallId()));
                        });
                    }
                });
            }
            return resultList;
        }
    }

    @Override
    public List<LocalDate> listReserveDate(AllocMobileCanteenQueryDTO queryDTO) {
        return this.listMatchData(queryDTO.getReserveLimitDayNum(), queryDTO.getIfAllowReserveToday());
    }

    private List<LocalDate> listMatchData(Integer reserveLimitDayNum, String ifAllowReserveToday) {
        log.info(String.format("查询日期,天数:%d", reserveLimitDayNum));
        List<LocalDate> reserveDateList = new ArrayList();
        LocalDate startDate;
        if (BnsConstants.COMMON_YES.equals(ifAllowReserveToday)) {
            log.info("允许预定当天");
            startDate = LocalDate.now();
        } else {
            log.info("不允许预定当天");
            startDate = LocalDate.now().plusDays(1L);
        }

        for(int i = 0; i < reserveLimitDayNum; ++i) {
            reserveDateList.add(startDate.plusDays((long)i));
        }

        return reserveDateList;
    }

    @Override
    public List<AppletReserveRecipeVO> getReserveRecipeDetailList(AppletReserveRecipeDTO content) {
        List<AppletReserveRecipeVO> resultList = cookRecipeH5Mapper.selectReserveRecipe(content.getApplyDate(), content.getRecipeId());
        if (ObjectUtil.isEmpty(resultList)) {
            return resultList;
        } else {
            resultList.sort(Collections.reverseOrder((s1, s2) -> {
                return s2.getMealtimeType() - s1.getMealtimeType();
            }));
            Long stallId = cookRecipeH5Mapper.selectStallIdByRecipeId(content.getRecipeId());
            List<BasicStallMealtime> allocStallMealtimes = basicStallMealtimeMapper.selectBasicStallMealtimeByStallId(stallId);
            List<BasicStallMealtime> mealTimeList = allocStallMealtimes;
            log.info("配置api查询的档口餐次,档口id: {}, 配置: {}", stallId, JSON.toJSONString(mealTimeList));
            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<BasicStallMealtime> finalMealTimeList = mealTimeList;
                    resultList = resultList.stream().filter((time) -> {
                        return finalMealTimeList.stream().map(BasicStallMealtime::getMealtimeType).collect(Collectors.toList()).contains(time.getMealtimeType());
                    }).collect(Collectors.toList());
                    return resultList;
                }
            }
        }
    }

    @Override
    public List<AppletWeekCanteenVO> selectWeekCanteenList(AppletWeekCanteenDTO content) {
        return this.cookRecipeH5Mapper.selectWeekCanteenList();
    }

    @Override
    public List<AppletWeekRecipeVO> getWeekRecipeDetailList(AppletWeekRecipeDTO content) {
        List<Long> recipeIdList = Lists.newArrayList();
        if (ObjectUtil.isNull(content.getRecipeId())) {
            recipeIdList = this.cookRecipeH5Mapper.selectWeekRecipeId(content.getRecipeId());
            if (ObjectUtil.isEmpty(recipeIdList)) {
                return Lists.newArrayList();
            }
        } else {
            LocalDate applyDate = content.getApplyDate(); // LocalDate.parse(content.getDate());
            LocalDate now = LocalDate.now();

            if (applyDate.isBefore(now)) {
                System.out.println("applyDate 早于当前日期");
                //获取当前菜谱绑定的日期
                String bindTime = this.cookRecipeH5Mapper.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.cookRecipeH5Mapper.selectWeekRecipeId(content.getRecipeId());
                    }else{
                        System.out.println("绑定日期迟于查询历史信息日期");
                        List<Long> repeIdList = this.cookRecipeH5Mapper.getRecipeIdListByRecipeId(content.getRecipeId());
                        recipeIdList = this.cookRecipeH5Mapper.selectWeekRecipeIdHistory(repeIdList, null,applyDate);
                        if(recipeIdList == null || recipeIdList.size() == 0){
                            ((List) recipeIdList).add(content.getRecipeId());
                        }
                    }
                }
            } else if (applyDate.isAfter(now)) {
                System.out.println("applyDate 晚于当前日期");
                recipeIdList = this.cookRecipeH5Mapper.selectWeekRecipeId(content.getRecipeId());
            } else {
                System.out.println("applyDate 等于当前日期");
                recipeIdList = this.cookRecipeH5Mapper.selectWeekRecipeId(content.getRecipeId());
            }
            if(recipeIdList == null || recipeIdList.size() == 0){
                log.error("本档口没有更早的历史菜谱记录");
                return new ArrayList<>();
            }
        }

        //this.generateRecipe((List) recipeIdList, content.getApplyDate());
        List<AppletWeekRecipeVO> resultList = cookRecipeH5Mapper.selectWeekRecipe(content.getApplyDate(), content.getRecipeId(), (List) recipeIdList);
        resultList.sort(Collections.reverseOrder((s1, s2) -> {
            return s2.getMealtimeType() - s1.getMealtimeType();
        }));
        return resultList;
    }
}
