package shop.alien.store.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import shop.alien.entity.store.EssentialHolidayComparison;
import shop.alien.entity.store.StoreBookingBusinessHours;
import shop.alien.entity.store.StoreBookingCategory;
import shop.alien.entity.store.StoreBookingSettings;
import shop.alien.entity.store.StoreBusinessInfo;
import shop.alien.entity.store.dto.StoreBookingBusinessHoursDTO;
import shop.alien.entity.store.dto.StoreBookingSettingsDTO;
import shop.alien.mapper.EssentialHolidayComparisonMapper;
import shop.alien.mapper.StoreBookingSettingsMapper;
import shop.alien.mapper.StoreBusinessInfoMapper;
import shop.alien.store.service.StoreBookingBusinessHoursService;
import shop.alien.store.service.StoreBookingCategoryService;
import shop.alien.store.service.StoreBookingSettingsService;
import shop.alien.util.common.JwtUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.regex.Pattern;

/**
 * 预订服务信息设置表 服务实现类
 *
 * @author system
 * @since 2025-01-XX
 */
@Slf4j
@Service
@Transactional
public class StoreBookingSettingsServiceImpl extends ServiceImpl<StoreBookingSettingsMapper, StoreBookingSettings> implements StoreBookingSettingsService {

    private final StoreBookingBusinessHoursService storeBookingBusinessHoursService;
    private final EssentialHolidayComparisonMapper essentialHolidayComparisonMapper;
    private final StoreBusinessInfoMapper storeBusinessInfoMapper;
    private final StoreBookingCategoryService storeBookingCategoryService;

    public StoreBookingSettingsServiceImpl(
            StoreBookingBusinessHoursService storeBookingBusinessHoursService,
            EssentialHolidayComparisonMapper essentialHolidayComparisonMapper,
            StoreBusinessInfoMapper storeBusinessInfoMapper,
            @Lazy StoreBookingCategoryService storeBookingCategoryService) {
        this.storeBookingBusinessHoursService = storeBookingBusinessHoursService;
        this.essentialHolidayComparisonMapper = essentialHolidayComparisonMapper;
        this.storeBusinessInfoMapper = storeBusinessInfoMapper;
        this.storeBookingCategoryService = storeBookingCategoryService;
    }

    // 时间格式正则：HH:mm
    private static final Pattern TIME_PATTERN = Pattern.compile("^([0-1][0-9]|2[0-3]):[0-5][0-9]$");

    @Override
    public StoreBookingSettings getByStoreId(Integer storeId) {
        log.info("StoreBookingSettingsServiceImpl.getByStoreId?storeId={}", storeId);
        
        if (storeId == null) {
            log.warn("查询预订服务信息设置失败：门店ID不能为空");
            return null;
        }
        
        LambdaQueryWrapper<StoreBookingSettings> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StoreBookingSettings::getStoreId, storeId);
        // @TableLogic 会自动过滤已删除的记录（delete_flag=0）
        
        return this.getOne(wrapper);
    }

    @Override
    public boolean saveOrUpdateSettings(StoreBookingSettings settings) {
        log.info("StoreBookingSettingsServiceImpl.saveOrUpdateSettings?settings={}", settings);
        
        // 从JWT获取当前登录用户ID
        Integer userId = getCurrentUserId();
        
        // 参数验证
        if (settings.getStoreId() == null) {
            log.warn("保存预订服务信息设置失败：门店ID不能为空");
            throw new RuntimeException("门店ID不能为空");
        }
        if (settings.getRetainPositionFlag() == null) {
            log.warn("保存预订服务信息设置失败：未按时到店是否保留位置不能为空");
            throw new RuntimeException("未按时到店是否保留位置不能为空");
        }

        if (settings.getBookingDateDisplayDays() == null || settings.getBookingDateDisplayDays() <= 0) {
            log.warn("保存预订服务信息设置失败：预订日期显示天数必须大于0");
            throw new RuntimeException("预订日期显示天数必须大于0");
        }
//        if (settings.getBookingTimeType() == null) {
//            log.warn("保存预订服务信息设置失败：预订时间类型不能为空");
//            throw new RuntimeException("预订时间类型不能为空");
//        }
        if (settings.getMaxCapacityPerSlot() == null || settings.getMaxCapacityPerSlot() <= 0) {
            log.warn("保存预订服务信息设置失败：单时段最大容纳人数必须大于0");
            throw new RuntimeException("单时段最大容纳人数必须大于0");
        }
        
        // 验证预订相关字段
        // 如果选择付费（reservation=1），必须填写预订金额
        if (StringUtils.hasText(settings.getReservation()) && "1".equals(settings.getReservation())) {
            if (settings.getReservationMoney() == null || settings.getReservationMoney() < 0) {
                log.warn("保存预订服务信息设置失败：选择付费时必须填写预订金额，且金额不能小于0");
                throw new RuntimeException("选择付费时必须填写预订金额，且金额不能小于0");
            }
        } else if (StringUtils.hasText(settings.getReservation()) && "0".equals(settings.getReservation())) {
            // 如果选择免费，清空预订金额
            settings.setReservationMoney(null);
        }
        
        // 验证取消预订退费时长设置
        if (settings.getOffUnsubscribeHours() == null || settings.getOffUnsubscribeHours() < 0) {
            log.warn("保存预订服务信息设置失败：取消预订退费时长设置必须大于等于0");
            throw new RuntimeException("取消预订退费时长设置必须大于等于0");
        }
        
        // 验证营业时间结束前不可预订时间
        if (settings.getBookingNotAvailableTime() == null || settings.getBookingNotAvailableTime() < 0) {
            log.warn("保存预订服务信息设置失败：营业时间结束前不可预订时间必须大于等于0");
            throw new RuntimeException("营业时间结束前不可预订时间必须大于等于0");
        }
        
        // 如果选择非全天，必须填写开始时间和结束时间
//        if (settings.getBookingTimeType() != null && settings.getBookingTimeType() == 0) {
//            if (!StringUtils.hasText(settings.getBookingStartTime())) {
//                log.warn("保存预订服务信息设置失败：非全天时必须填写开始时间");
//                throw new RuntimeException("非全天时必须填写开始时间");
//            }
//            if (!StringUtils.hasText(settings.getBookingEndTime())) {
//                log.warn("保存预订服务信息设置失败：非全天时必须填写结束时间");
//                throw new RuntimeException("非全天时必须填写结束时间");
//            }
//            // 验证时间格式
//            if (!TIME_PATTERN.matcher(settings.getBookingStartTime()).matches()) {
//                log.warn("保存预订服务信息设置失败：开始时间格式不正确，应为HH:mm格式");
//                throw new RuntimeException("开始时间格式不正确，应为HH:mm格式");
//            }
//            if (!TIME_PATTERN.matcher(settings.getBookingEndTime()).matches()) {
//                log.warn("保存预订服务信息设置失败：结束时间格式不正确，应为HH:mm格式");
//                throw new RuntimeException("结束时间格式不正确，应为HH:mm格式");
//            }
//            // 验证开始时间必须小于结束时间
//            if (settings.getBookingStartTime().compareTo(settings.getBookingEndTime()) >= 0) {
//                log.warn("保存预订服务信息设置失败：开始时间必须小于结束时间");
//                throw new RuntimeException("开始时间必须小于结束时间");
//            }
//        } else {
//            // 如果是全天，清空开始时间和结束时间
//            settings.setBookingStartTime(null);
//            settings.setBookingEndTime(null);
//        }
        
        // 查询是否已存在该门店的设置
        StoreBookingSettings existingSettings = getByStoreId(settings.getStoreId());
        
        if (existingSettings != null) {
            // 更新
            settings.setId(existingSettings.getId());
            LambdaUpdateWrapper<StoreBookingSettings> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(StoreBookingSettings::getId, existingSettings.getId());
            
            updateWrapper.set(StoreBookingSettings::getRetainPositionFlag, settings.getRetainPositionFlag());
            updateWrapper.set(StoreBookingSettings::getRetentionDuration, settings.getRetentionDuration());
            updateWrapper.set(StoreBookingSettings::getBookingDateDisplayDays, settings.getBookingDateDisplayDays());
            updateWrapper.set(StoreBookingSettings::getBookingTimeType, settings.getBookingTimeType());
            updateWrapper.set(StoreBookingSettings::getBookingStartTime, settings.getBookingStartTime());
            updateWrapper.set(StoreBookingSettings::getBookingEndTime, settings.getBookingEndTime());
            updateWrapper.set(StoreBookingSettings::getMaxCapacityPerSlot, settings.getMaxCapacityPerSlot());
            updateWrapper.set(StoreBookingSettings::getReservation, settings.getReservation());
            updateWrapper.set(StoreBookingSettings::getReservationMoney, settings.getReservationMoney());
            updateWrapper.set(StoreBookingSettings::getOffUnsubscribeHours, settings.getOffUnsubscribeHours());
            updateWrapper.set(StoreBookingSettings::getBookingNotAvailableTime, settings.getBookingNotAvailableTime());
            updateWrapper.set(StoreBookingSettings::getImgUrl, settings.getImgUrl());
            
            if (userId != null) {
                updateWrapper.set(StoreBookingSettings::getUpdatedUserId, userId);
            }
            
            return this.update(updateWrapper);
        } else {
            // 新增
            settings.setCreatedUserId(userId);
            return this.save(settings);
        }
    }

    @Override
    public boolean saveSettingsWithBusinessHours(StoreBookingSettingsDTO dto) {
        log.info("StoreBookingSettingsServiceImpl.saveSettingsWithBusinessHours?dto={}", dto);
        
        // 校验：如果有保留时长（retain_position_flag = 1），保留时长不能超过分类中的最短最长预订时间
        // 如果当前门店没有分类，那保留时长可随意设置
        if (dto.getRetainPositionFlag() != null && dto.getRetainPositionFlag() == 1) {
            if (dto.getRetentionDuration() != null && dto.getRetentionDuration() > 0) {
                // 查询该门店下所有分类的最短最长预订时间（最小值）
                List<StoreBookingCategory> categories = storeBookingCategoryService.getCategoryList(dto.getStoreId());
                // 如果门店有分类，才进行校验
                if (categories != null && !categories.isEmpty()) {
                    Integer minMaxBookingTime = categories.stream()
                            .filter(c -> c.getMaxBookingTime() != null && c.getMaxBookingTime() > 0)
                            .map(StoreBookingCategory::getMaxBookingTime)
                            .min(Integer::compareTo)
                            .orElse(null);
                    
                    if (minMaxBookingTime != null && dto.getRetentionDuration() > minMaxBookingTime) {
                        log.warn("保留时长不能超过最长预订时长，retentionDuration={}, minMaxBookingTime={}", 
                                dto.getRetentionDuration(), minMaxBookingTime);
                        throw new RuntimeException("保留时长不能超过最长预订时长");
                    }
                }
                // 如果门店没有分类，跳过校验，保留时长可随意设置
            }
        }
        
        // 1. 先保存或更新设置信息
        StoreBookingSettings settings = new StoreBookingSettings();
        settings.setId(dto.getId());
        settings.setStoreId(dto.getStoreId());
        settings.setRetainPositionFlag(dto.getRetainPositionFlag());
        settings.setRetentionDuration(dto.getRetentionDuration());
        settings.setBookingDateDisplayDays(dto.getBookingDateDisplayDays());
        settings.setBookingTimeType(dto.getBookingTimeType());
        settings.setBookingStartTime(dto.getBookingStartTime());
        settings.setBookingEndTime(dto.getBookingEndTime());
        settings.setMaxCapacityPerSlot(dto.getMaxCapacityPerSlot());
        settings.setReservation(dto.getReservation());
        settings.setReservationMoney(dto.getReservationMoney());
        settings.setOffUnsubscribeHours(dto.getOffUnsubscribeHours());
        settings.setBookingNotAvailableTime(dto.getBookingNotAvailableTime());
        settings.setImgUrl(dto.getImgUrl());
        
        boolean settingsResult = saveOrUpdateSettings(settings);
        if (!settingsResult) {
            log.error("保存预订服务信息设置失败");
            throw new RuntimeException("保存预订服务信息设置失败");
        }
        
        // 2. 获取保存后的设置ID（如果是新增，需要获取新生成的ID）
        Integer settingsId = settings.getId();
        if (settingsId == null) {
            // 如果是新增，重新查询获取ID
            StoreBookingSettings savedSettings = getByStoreId(dto.getStoreId());
            if (savedSettings == null) {
                log.error("保存设置后无法获取设置ID");
                throw new RuntimeException("保存设置后无法获取设置ID");
            }
            settingsId = savedSettings.getId();
        }
        
        // 3. 准备营业时间列表
        List<StoreBookingBusinessHours> businessHoursList = new ArrayList<>();
        
        // 3.1 处理正常营业时间（business_type=1）
        // 如果 normalBusinessHours 为空，则不保存正常营业时间
        if (dto.getNormalBusinessHours() != null) {
            // 校验正常营业时间：预约时间的正常时间不能大于门店营业时间的正常时间
            validateNormalBusinessHours(dto.getStoreId(), dto.getNormalBusinessHours());
            
            StoreBookingBusinessHours normalHours = convertToBusinessHours(dto.getNormalBusinessHours(), settingsId, 1);
            businessHoursList.add(normalHours);
        }
        
        // 3.2 处理特殊营业时间列表（business_type=2）
        // 如果 specialBusinessHoursList 为空或空列表，则不保存特殊营业时间
        if (dto.getSpecialBusinessHoursList() != null && !dto.getSpecialBusinessHoursList().isEmpty()) {
            // 校验特殊营业时间：预约时间的特殊时间不能大于门店营业时间的特殊时间
            validateSpecialBusinessHours(dto.getStoreId(), dto.getSpecialBusinessHoursList());
            
            int sort = 1;
            for (StoreBookingBusinessHoursDTO specialDto : dto.getSpecialBusinessHoursList()) {
                StoreBookingBusinessHours specialHours = convertToBusinessHours(specialDto, settingsId, 2);
                specialHours.setSort(sort++);
                businessHoursList.add(specialHours);
            }
        }
        
        // 4. 批量保存营业时间（如果列表不为空）
        // 如果 normalBusinessHours 和 specialBusinessHoursList 都为空，则不保存任何营业时间
        if (!businessHoursList.isEmpty()) {
            boolean businessHoursResult = storeBookingBusinessHoursService.batchSaveBusinessHours(settingsId, businessHoursList);
            if (!businessHoursResult) {
                log.error("保存营业时间失败");
                throw new RuntimeException("保存营业时间失败");
            }
        } else {
            log.info("normalBusinessHours 和 specialBusinessHoursList 都为空，跳过营业时间保存，settingsId={}", settingsId);
        }
        
        return true;
    }

    @Override
    public StoreBookingSettingsDTO getSettingsWithBusinessHoursByStoreId(Integer storeId) {
        log.info("StoreBookingSettingsServiceImpl.getSettingsWithBusinessHoursByStoreId?storeId={}", storeId);
        
        if (storeId == null) {
            log.warn("查询预订服务信息设置失败：门店ID不能为空");
            return null;
        }
        
        // 1. 查询设置信息
        StoreBookingSettings settings = getByStoreId(storeId);
        if (settings == null) {
            return null;
        }
        
        // 2. 转换为DTO
        StoreBookingSettingsDTO dto = new StoreBookingSettingsDTO();
        BeanUtils.copyProperties(settings, dto);
        
        // 3. 查询营业时间列表
        List<StoreBookingBusinessHours> businessHoursList = storeBookingBusinessHoursService.getListBySettingsId(settings.getId());
        
        // 4. 分离正常营业时间和特殊营业时间
        StoreBookingBusinessHours normalHours = businessHoursList.stream()
                .filter(h -> h.getBusinessType() != null && h.getBusinessType() == 1)
                .findFirst()
                .orElse(null);
        
        List<StoreBookingBusinessHours> specialHoursList = businessHoursList.stream()
                .filter(h -> h.getBusinessType() != null && h.getBusinessType() == 2)
                .collect(Collectors.toList());
        
        // 5. 转换为DTO
        if (normalHours != null) {
            dto.setNormalBusinessHours(convertToBusinessHoursDTO(normalHours));
        }
        
        if (!specialHoursList.isEmpty()) {
            List<StoreBookingBusinessHoursDTO> specialHoursDTOList = specialHoursList.stream()
                    .map(businessHours -> {
                        StoreBookingBusinessHoursDTO hoursDTO = convertToBusinessHoursDTO(businessHours);
                        // 如果有关联的节假日ID，查询节假日信息
                        if (businessHours.getEssentialId() != null) {
                            try {
                                EssentialHolidayComparison holiday = essentialHolidayComparisonMapper.selectById(businessHours.getEssentialId());
                                if (holiday != null) {
                                    hoursDTO.setHolidayInfo(holiday);
                                }
                            } catch (Exception e) {
                                log.warn("查询节假日信息失败，essentialId={}", businessHours.getEssentialId(), e);
                            }
                        }
                        return hoursDTO;
                    })
                    .collect(Collectors.toList());
            dto.setSpecialBusinessHoursList(specialHoursDTOList);
        }
        
        return dto;
    }

    /**
     * 将DTO转换为营业时间实体
     *
     * @param dto DTO对象
     * @param settingsId 设置ID
     * @param businessType 营业类型（1:正常营业时间, 2:特殊营业时间）
     * @return StoreBookingBusinessHours
     */
    private StoreBookingBusinessHours convertToBusinessHours(StoreBookingBusinessHoursDTO dto, Integer settingsId, Integer businessType) {
        StoreBookingBusinessHours businessHours = new StoreBookingBusinessHours();
        businessHours.setId(dto.getId());
        businessHours.setSettingsId(settingsId);
        businessHours.setBusinessType(businessType);
        businessHours.setHolidayType(dto.getHolidayType());
        businessHours.setHolidayDate(dto.getHolidayDate());
        businessHours.setBookingTimeType(dto.getBookingTimeType());
        businessHours.setStartTime(dto.getStartTime());
        businessHours.setEndTime(dto.getEndTime());
        businessHours.setSort(dto.getSort() != null ? dto.getSort() : 0);
        businessHours.setEssentialId(dto.getEssentialId());
        businessHours.setReservation(dto.getReservation());
        businessHours.setReservationMoney(dto.getReservationMoney());
        return businessHours;
    }

    /**
     * 将营业时间实体转换为DTO
     *
     * @param businessHours 营业时间实体
     * @return StoreBookingBusinessHoursDTO
     */
    private StoreBookingBusinessHoursDTO convertToBusinessHoursDTO(StoreBookingBusinessHours businessHours) {
        StoreBookingBusinessHoursDTO dto = new StoreBookingBusinessHoursDTO();
        dto.setId(businessHours.getId());
        dto.setSettingsId(businessHours.getSettingsId());
        dto.setBusinessType(businessHours.getBusinessType());
        dto.setHolidayType(businessHours.getHolidayType());
        dto.setHolidayDate(businessHours.getHolidayDate());
        dto.setBookingTimeType(businessHours.getBookingTimeType());
        dto.setStartTime(businessHours.getStartTime());
        dto.setEndTime(businessHours.getEndTime());
        dto.setSort(businessHours.getSort());
        dto.setEssentialId(businessHours.getEssentialId());
        dto.setReservation(businessHours.getReservation());
        dto.setReservationMoney(businessHours.getReservationMoney());
        return dto;
    }

    /**
     * 校验正常营业时间：预约时间的正常时间不能大于门店营业时间的正常时间
     *
     * @param storeId 门店ID
     * @param normalBusinessHours 预约时间的正常营业时间
     */
    private void validateNormalBusinessHours(Integer storeId, StoreBookingBusinessHoursDTO normalBusinessHours) {
        log.info("开始校验正常营业时间，storeId={}", storeId);
        
        if (storeId == null || normalBusinessHours == null) {
            return;
        }
        
        // 如果是全天营业，跳过校验
        if (normalBusinessHours.getBookingTimeType() != null && normalBusinessHours.getBookingTimeType() == 1) {
            return;
        }
        
        // 如果没有开始时间和结束时间，跳过校验
        if (!StringUtils.hasText(normalBusinessHours.getStartTime()) || 
            !StringUtils.hasText(normalBusinessHours.getEndTime())) {
            return;
        }
        
        // 查询门店的正常营业时间（store_business_info，business_type=1）
        List<StoreBusinessInfo> storeNormalBusinessHours = storeBusinessInfoMapper.selectList(
                new LambdaQueryWrapper<StoreBusinessInfo>()
                        .eq(StoreBusinessInfo::getStoreId, storeId)
                        .eq(StoreBusinessInfo::getBusinessType, 1) // 正常营业时间
                        .eq(StoreBusinessInfo::getDeleteFlag, 0)
        );
        
        if (storeNormalBusinessHours == null || storeNormalBusinessHours.isEmpty()) {
            log.warn("门店未配置正常营业时间，无法校验，storeId={}", storeId);
            return;
        }
        
        // 查找匹配的门店正常营业时间（正常营业时间通常只有一条，或者按 business_date 匹配）
        StoreBusinessInfo matchedStoreHours = null;
        
        // 如果有 holiday_date，尝试通过 business_date 匹配
        if (StringUtils.hasText(normalBusinessHours.getHolidayDate())) {
            matchedStoreHours = storeNormalBusinessHours.stream()
                    .filter(h -> normalBusinessHours.getHolidayDate().equals(h.getBusinessDate()))
                    .findFirst()
                    .orElse(null);
        }
        
        // 如果没有匹配到，使用第一条正常营业时间（通常正常营业时间只有一条）
        if (matchedStoreHours == null && !storeNormalBusinessHours.isEmpty()) {
            matchedStoreHours = storeNormalBusinessHours.get(0);
        }
        
        // 如果没有匹配到门店正常营业时间，跳过校验
        if (matchedStoreHours == null) {
            log.warn("未找到匹配的门店正常营业时间，跳过校验");
            return;
        }
        
        // 如果门店正常营业时间没有开始时间和结束时间，跳过校验
        if (!StringUtils.hasText(matchedStoreHours.getStartTime()) || 
            !StringUtils.hasText(matchedStoreHours.getEndTime())) {
            return;
        }
        
        // 比较时间范围
        String bookingStartTime = normalBusinessHours.getStartTime().trim();
        String bookingEndTime = normalBusinessHours.getEndTime().trim();
        String storeStartTime = matchedStoreHours.getStartTime().trim();
        String storeEndTime = matchedStoreHours.getEndTime().trim();
        
        // 比较开始时间：预约时间的开始时间不能早于门店营业时间的开始时间
        if (compareTime(bookingStartTime, storeStartTime) < 0) {
            log.error("预约时间的正常时间开始时间早于门店营业时间的正常时间，storeId={}, bookingStartTime={}, storeStartTime={}", 
                    storeId, bookingStartTime, storeStartTime);
            throw new RuntimeException("预订时间与营业时间冲突,请重新设置");
        }
        
        // 比较结束时间：预约时间的结束时间不能晚于门店营业时间的结束时间
//        if (compareTime(bookingEndTime, storeEndTime) > 0) {
//            log.error("预约时间的正常时间结束时间晚于门店营业时间的正常时间，storeId={}, bookingEndTime={}, storeEndTime={}",
//                    storeId, bookingEndTime, storeEndTime);
//            throw new RuntimeException("预订时间与营业时间冲突,请重新设置");
//        }
        
        log.info("正常营业时间校验通过，storeId={}", storeId);
    }
    
    /**
     * 校验特殊营业时间：预约时间的特殊时间不能大于门店营业时间的特殊时间
     *
     * @param storeId 门店ID
     * @param specialBusinessHoursList 预约时间的特殊营业时间列表
     */
    private void validateSpecialBusinessHours(Integer storeId, List<StoreBookingBusinessHoursDTO> specialBusinessHoursList) {
        log.info("开始校验特殊营业时间，storeId={}, specialBusinessHoursList.size={}", 
                storeId, specialBusinessHoursList != null ? specialBusinessHoursList.size() : 0);
        
        if (storeId == null || specialBusinessHoursList == null || specialBusinessHoursList.isEmpty()) {
            return;
        }
        
        // 查询门店的特殊营业时间（store_business_info，business_type=2）
        List<StoreBusinessInfo> storeSpecialBusinessHours = storeBusinessInfoMapper.selectList(
                new LambdaQueryWrapper<StoreBusinessInfo>()
                        .eq(StoreBusinessInfo::getStoreId, storeId)
                        .eq(StoreBusinessInfo::getBusinessType, 2) // 特殊营业时间
                        .eq(StoreBusinessInfo::getDeleteFlag, 0)
        );
        
        if (storeSpecialBusinessHours == null || storeSpecialBusinessHours.isEmpty()) {
            log.warn("门店未配置特殊营业时间，无法校验，storeId={}", storeId);
            return;
        }
        
        // 遍历预约时间的特殊营业时间，与门店特殊营业时间进行匹配和比较
        for (StoreBookingBusinessHoursDTO bookingSpecialHours : specialBusinessHoursList) {
            // 如果是全天营业，跳过校验
            if (bookingSpecialHours.getBookingTimeType() != null && bookingSpecialHours.getBookingTimeType() == 1) {
                continue;
            }
            
            // 如果没有开始时间和结束时间，跳过校验
            if (!StringUtils.hasText(bookingSpecialHours.getStartTime()) || 
                !StringUtils.hasText(bookingSpecialHours.getEndTime())) {
                continue;
            }
            
            // 查找匹配的门店特殊营业时间
            StoreBusinessInfo matchedStoreHours = null;
            
            // 优先通过 essential_id 匹配
            if (bookingSpecialHours.getEssentialId() != null) {
                matchedStoreHours = storeSpecialBusinessHours.stream()
                        .filter(h -> {
                            if (h.getEssentialId() == null || h.getEssentialId().trim().isEmpty()) {
                                return false;
                            }
                            try {
                                Integer essentialId = Integer.parseInt(h.getEssentialId().trim());
                                return essentialId.equals(bookingSpecialHours.getEssentialId());
                            } catch (NumberFormatException e) {
                                return false;
                            }
                        })
                        .findFirst()
                        .orElse(null);
            }
            
            // 如果没有通过 essential_id 匹配到，尝试通过 holiday_date 匹配
            if (matchedStoreHours == null && StringUtils.hasText(bookingSpecialHours.getHolidayDate())) {
                matchedStoreHours = storeSpecialBusinessHours.stream()
                        .filter(h -> bookingSpecialHours.getHolidayDate().equals(h.getBusinessDate()))
                        .findFirst()
                        .orElse(null);
            }
            
            // 如果没有匹配到门店特殊营业时间，跳过校验（可能是新增的特殊时间）
            if (matchedStoreHours == null) {
                log.warn("未找到匹配的门店特殊营业时间，跳过校验，essentialId={}, holidayDate={}", 
                        bookingSpecialHours.getEssentialId(), bookingSpecialHours.getHolidayDate());
                continue;
            }
            
            // 如果门店特殊营业时间没有开始时间和结束时间，跳过校验
            if (!StringUtils.hasText(matchedStoreHours.getStartTime()) || 
                !StringUtils.hasText(matchedStoreHours.getEndTime())) {
                continue;
            }
            
            // 比较时间范围
            String bookingStartTime = bookingSpecialHours.getStartTime().trim();
            String bookingEndTime = bookingSpecialHours.getEndTime().trim();
            String storeStartTime = matchedStoreHours.getStartTime().trim();
            String storeEndTime = matchedStoreHours.getEndTime().trim();
            
            // 比较开始时间：预约时间的开始时间不能早于门店营业时间的开始时间
            if (compareTime(bookingStartTime, storeStartTime) < 0) {
                log.error("预约时间的特殊时间开始时间早于门店营业时间的特殊时间，storeId={}, bookingStartTime={}, storeStartTime={}", 
                        storeId, bookingStartTime, storeStartTime);
                throw new RuntimeException("预订时间与营业时间冲突,请重新设置");
            }
            
            // 比较结束时间：预约时间的结束时间不能晚于门店营业时间的结束时间
//            if (compareTime(bookingEndTime, storeEndTime) > 0) {
//                log.error("预约时间的特殊时间结束时间晚于门店营业时间的特殊时间，storeId={}, bookingEndTime={}, storeEndTime={}",
//                        storeId, bookingEndTime, storeEndTime);
//                throw new RuntimeException("预订时间与营业时间冲突,请重新设置");
//            }
        }
        
        log.info("特殊营业时间校验通过，storeId={}", storeId);
    }
    
    /**
     * 比较两个时间（HH:mm格式）
     * 
     * @param time1 时间1
     * @param time2 时间2
     * @return 负数表示time1 < time2，0表示相等，正数表示time1 > time2
     */
    private int compareTime(String time1, String time2) {
        try {
            String[] parts1 = time1.split(":");
            String[] parts2 = time2.split(":");
            
            int hour1 = Integer.parseInt(parts1[0]);
            int minute1 = Integer.parseInt(parts1[1]);
            int hour2 = Integer.parseInt(parts2[0]);
            int minute2 = Integer.parseInt(parts2[1]);
            
            int totalMinutes1 = hour1 * 60 + minute1;
            int totalMinutes2 = hour2 * 60 + minute2;
            
            return totalMinutes1 - totalMinutes2;
        } catch (Exception e) {
            log.error("比较时间失败，time1={}, time2={}", time1, time2, e);
            throw new RuntimeException("时间格式错误");
        }
    }
    
    /**
     * 从JWT获取当前登录用户ID
     *
     * @return 用户ID，如果未登录返回null
     */
    private Integer getCurrentUserId() {
        try {
            JSONObject userInfo = JwtUtil.getCurrentUserInfo();
            if (userInfo != null) {
                return userInfo.getInteger("userId");
            }
        } catch (Exception e) {
            log.warn("获取当前登录用户ID失败: {}", e.getMessage());
        }
        return null;
    }
}
