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.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import shop.alien.entity.store.StoreBookingBusinessHours;
import shop.alien.mapper.StoreBookingBusinessHoursMapper;
import shop.alien.store.service.StoreBookingBusinessHoursService;
import shop.alien.util.common.JwtUtil;

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

/**
 * 预订服务营业时间表 服务实现类
 *
 * @author system
 * @since 2025-01-XX
 */
@Slf4j
@Service
@Transactional
@RequiredArgsConstructor
public class StoreBookingBusinessHoursServiceImpl extends ServiceImpl<StoreBookingBusinessHoursMapper, StoreBookingBusinessHours> implements StoreBookingBusinessHoursService {

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


    @Override
    public List<StoreBookingBusinessHours> getListBySettingsId(Integer settingsId) {
        log.info("StoreBookingBusinessHoursServiceImpl.getListBySettingsId?settingsId={}", settingsId);
        
        if (settingsId == null) {
            log.warn("查询营业时间列表失败：设置ID不能为空");
            return Collections.emptyList();
        }
        
        LambdaQueryWrapper<StoreBookingBusinessHours> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StoreBookingBusinessHours::getSettingsId, settingsId);
        wrapper.orderByAsc(StoreBookingBusinessHours::getSort);
        wrapper.orderByAsc(StoreBookingBusinessHours::getId);
        // @TableLogic 会自动过滤已删除的记录（delete_flag=0）
        
        return this.list(wrapper);
    }

    @Override
    public List<StoreBookingBusinessHours> getListBySettingsIdAndType(Integer settingsId, Integer businessType) {
        log.info("StoreBookingBusinessHoursServiceImpl.getListBySettingsIdAndType?settingsId={}, businessType={}", settingsId, businessType);
        
        if (settingsId == null) {
            log.warn("查询营业时间列表失败：设置ID不能为空");
            return Collections.emptyList();
        }
        
        LambdaQueryWrapper<StoreBookingBusinessHours> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StoreBookingBusinessHours::getSettingsId, settingsId);
        if (businessType != null) {
            wrapper.eq(StoreBookingBusinessHours::getBusinessType, businessType);
        }
        wrapper.orderByAsc(StoreBookingBusinessHours::getSort);
        wrapper.orderByAsc(StoreBookingBusinessHours::getId);
        // @TableLogic 会自动过滤已删除的记录（delete_flag=0）
        
        return this.list(wrapper);
    }

    @Override
    public boolean saveOrUpdateBusinessHours(StoreBookingBusinessHours businessHours) {
        log.info("StoreBookingBusinessHoursServiceImpl.saveOrUpdateBusinessHours?businessHours={}", businessHours);
        
        // 从JWT获取当前登录用户ID
        Integer userId = getCurrentUserId();
        
        // 参数验证
        if (businessHours.getSettingsId() == null) {
            log.warn("保存营业时间失败：设置ID不能为空");
            throw new RuntimeException("设置ID不能为空");
        }
//        if (businessHours.getBusinessType() == null) {
//            log.warn("保存营业时间失败：营业类型不能为空");
//            throw new RuntimeException("营业类型不能为空");
//        }
//        if (businessHours.getBookingTimeType() == null) {
//            log.warn("保存营业时间失败：预订时间类型不能为空");
//            throw new RuntimeException("预订时间类型不能为空");
//        }
        
        // 如果是特殊营业（节假日），验证节假日类型
//        if (businessHours.getBusinessType() != null && businessHours.getBusinessType() == 2) {
//            if (!StringUtils.hasText(businessHours.getHolidayType())) {
//                log.warn("保存营业时间失败：特殊营业时必须填写节假日类型");
//                throw new RuntimeException("特殊营业时必须填写节假日类型");
//            }
//        }
        
        // 如果选择非全天，必须填写开始时间和结束时间
//        if (businessHours.getBookingTimeType() != null && businessHours.getBookingTimeType() == 0) {
//            if (!StringUtils.hasText(businessHours.getStartTime())) {
//                log.warn("保存营业时间失败：非全天时必须填写开始时间");
//                throw new RuntimeException("非全天时必须填写开始时间");
//            }
//            if (!StringUtils.hasText(businessHours.getEndTime())) {
//                log.warn("保存营业时间失败：非全天时必须填写结束时间");
//                throw new RuntimeException("非全天时必须填写结束时间");
//            }
//            // 验证时间格式
//            if (!TIME_PATTERN.matcher(businessHours.getStartTime()).matches()) {
//                log.warn("保存营业时间失败：开始时间格式不正确，应为HH:mm格式");
//                throw new RuntimeException("开始时间格式不正确，应为HH:mm格式");
//            }
//            if (!TIME_PATTERN.matcher(businessHours.getEndTime()).matches()) {
//                log.warn("保存营业时间失败：结束时间格式不正确，应为HH:mm格式");
//                throw new RuntimeException("结束时间格式不正确，应为HH:mm格式");
//            }
            // 验证开始时间必须小于结束时间（支持跨天，如22:00到次日02:00）
            // 这里只做基本格式验证，跨天逻辑由业务层处理
//        } else {
//            // 如果是全天，清空开始时间和结束时间
//            businessHours.setStartTime(null);
//            businessHours.setEndTime(null);
//        }
        
        // 设置排序，如果为空则默认为0
        if (businessHours.getSort() == null) {
            businessHours.setSort(0);
        }
        
        if (businessHours.getId() != null) {
            // 更新
            LambdaUpdateWrapper<StoreBookingBusinessHours> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(StoreBookingBusinessHours::getId, businessHours.getId());
            
            updateWrapper.set(StoreBookingBusinessHours::getBusinessType, businessHours.getBusinessType());
            updateWrapper.set(StoreBookingBusinessHours::getHolidayType, businessHours.getHolidayType());
            updateWrapper.set(StoreBookingBusinessHours::getHolidayDate, businessHours.getHolidayDate());
            updateWrapper.set(StoreBookingBusinessHours::getBookingTimeType, businessHours.getBookingTimeType());
            updateWrapper.set(StoreBookingBusinessHours::getStartTime, businessHours.getStartTime());
            updateWrapper.set(StoreBookingBusinessHours::getEndTime, businessHours.getEndTime());
            updateWrapper.set(StoreBookingBusinessHours::getSort, businessHours.getSort());
            
            if (userId != null) {
                updateWrapper.set(StoreBookingBusinessHours::getUpdatedUserId, userId);
            }
            
            return this.update(updateWrapper);
        } else {
            // 新增
            businessHours.setCreatedUserId(userId);
            return this.save(businessHours);
        }
    }

    @Override
    public boolean batchSaveBusinessHours(Integer settingsId, List<StoreBookingBusinessHours> businessHoursList) {
        log.info("StoreBookingBusinessHoursServiceImpl.batchSaveBusinessHours?settingsId={}, size={}", settingsId, businessHoursList != null ? businessHoursList.size() : 0);
        
//        if (settingsId == null) {
//            log.warn("批量保存营业时间失败：设置ID不能为空");
//            throw new RuntimeException("设置ID不能为空");
//        }
//        if (businessHoursList == null || businessHoursList.isEmpty()) {
//            log.warn("批量保存营业时间失败：营业时间列表不能为空");
//            throw new RuntimeException("营业时间列表不能为空");
//        }
        
        // 从JWT获取当前登录用户ID
        Integer userId = getCurrentUserId();
        
        // 处理空列表情况
        if (businessHoursList == null || businessHoursList.isEmpty()) {
            // 如果列表为空，删除该设置下的所有营业时间（逻辑删除）
            LambdaUpdateWrapper<StoreBookingBusinessHours> deleteWrapper = new LambdaUpdateWrapper<>();
            deleteWrapper.eq(StoreBookingBusinessHours::getSettingsId, settingsId);
            deleteWrapper.set(StoreBookingBusinessHours::getDeleteFlag, 1);
            if (userId != null) {
                deleteWrapper.set(StoreBookingBusinessHours::getUpdatedUserId, userId);
            }
            this.update(deleteWrapper);
            return true;
        }
        
        // 1. 收集所有传入的id（有id的项，用于编辑）
        List<Integer> incomingIds = businessHoursList.stream()
                .map(StoreBookingBusinessHours::getId)
                .filter(id -> id != null)
                .collect(Collectors.toList());
        
        // 2. 查询现有的营业时间
        List<StoreBookingBusinessHours> existingHours = getListBySettingsId(settingsId);
        List<Integer> existingIds = existingHours.stream()
                .map(StoreBookingBusinessHours::getId)
                .filter(id -> id != null)
                .collect(Collectors.toList());
        
        // 3. 删除不在传入列表中的记录（逻辑删除）
        // 如果传入列表中有id，则删除那些不在传入列表中的记录
        if (!incomingIds.isEmpty()) {
            List<Integer> idsToDelete = existingIds.stream()
                    .filter(id -> !incomingIds.contains(id))
                    .collect(Collectors.toList());
            
            if (!idsToDelete.isEmpty()) {
                LambdaUpdateWrapper<StoreBookingBusinessHours> deleteWrapper = new LambdaUpdateWrapper<>();
                deleteWrapper.in(StoreBookingBusinessHours::getId, idsToDelete);
                deleteWrapper.set(StoreBookingBusinessHours::getDeleteFlag, 1);
                if (userId != null) {
                    deleteWrapper.set(StoreBookingBusinessHours::getUpdatedUserId, userId);
                }
                this.update(deleteWrapper);
            }
        } else {
            // 如果传入列表中没有id，说明全部是新增，先删除该设置下的所有营业时间（逻辑删除）
            LambdaUpdateWrapper<StoreBookingBusinessHours> deleteWrapper = new LambdaUpdateWrapper<>();
            deleteWrapper.eq(StoreBookingBusinessHours::getSettingsId, settingsId);
            deleteWrapper.set(StoreBookingBusinessHours::getDeleteFlag, 1);
            if (userId != null) {
                deleteWrapper.set(StoreBookingBusinessHours::getUpdatedUserId, userId);
            }
            this.update(deleteWrapper);
        }
        
        // 4. 遍历传入的列表，有id的更新，没有id的新增
        for (StoreBookingBusinessHours businessHours : businessHoursList) {
            businessHours.setSettingsId(settingsId);
            if (businessHours.getId() != null) {
                // 有id，走更新逻辑
                businessHours.setCreatedUserId(null); // 更新时不需要设置创建人
            } else {
                // 没有id，走新增逻辑
                businessHours.setId(null); // 确保是新增
                businessHours.setCreatedUserId(userId);
            }
            // 验证并保存
            saveOrUpdateBusinessHours(businessHours);
        }
        
        return true;
    }

    @Override
    public boolean deleteBusinessHours(Integer id) {
        log.info("StoreBookingBusinessHoursServiceImpl.deleteBusinessHours?id={}", id);
        
        if (id == null) {
            log.warn("删除营业时间失败：营业时间ID不能为空");
            throw new RuntimeException("营业时间ID不能为空");
        }
        
        // 从JWT获取当前登录用户ID
        Integer userId = getCurrentUserId();
        
        // 逻辑删除
        LambdaUpdateWrapper<StoreBookingBusinessHours> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(StoreBookingBusinessHours::getId, id);
        updateWrapper.set(StoreBookingBusinessHours::getDeleteFlag, 1);
        if (userId != null) {
            updateWrapper.set(StoreBookingBusinessHours::getUpdatedUserId, userId);
        }
        
        return this.update(updateWrapper);
    }

    /**
     * 从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;
    }
}
