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 shop.alien.entity.store.StoreCuisineCategory;
import shop.alien.mapper.StoreCuisineCategoryMapper;
import shop.alien.store.service.StoreCuisineCategoryService;
import shop.alien.util.common.JwtUtil;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 菜品分类表 服务实现类
 *
 * @author system
 * @since 2025-01-XX
 */
@Slf4j
@Service
@Transactional
@RequiredArgsConstructor
public class StoreCuisineCategoryServiceImpl extends ServiceImpl<StoreCuisineCategoryMapper, StoreCuisineCategory> implements StoreCuisineCategoryService {

    @Override
    public List<StoreCuisineCategory> getCategoryList(Integer storeId) {
        log.info("StoreCuisineCategoryServiceImpl.getCategoryList?storeId={}", storeId);
        
        LambdaQueryWrapper<StoreCuisineCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StoreCuisineCategory::getStoreId, storeId)
                .eq(StoreCuisineCategory::getStatus, 1) // 只查询启用的分类
                .orderByAsc(StoreCuisineCategory::getSort) // 按排序字段升序
                .orderByDesc(StoreCuisineCategory::getCreatedTime); // 如果排序字段相同，按创建时间倒序
        
        return this.list(wrapper);
    }

    @Override
    public boolean batchCreateCategories(Integer storeId, List<String> categoryNames) {
        log.info("StoreCuisineCategoryServiceImpl.batchCreateCategories?storeId={}&categoryNames={}", storeId, categoryNames);
        
        // 从JWT获取当前登录用户ID
        Integer userId = getCurrentUserId();
        
        if (storeId == null || categoryNames == null || categoryNames.isEmpty()) {
            log.warn("批量创建菜品分类失败：参数不完整");
            return false;
        }

        // 验证分类名称长度（限5字）
        for (String categoryName : categoryNames) {
            if (categoryName != null && categoryName.length() > 5) {
                log.warn("批量创建菜品分类失败：分类名称长度超过5字，{}", categoryName);
                throw new RuntimeException("分类名称长度不能超过5字：" + categoryName);
            }
        }
        
        // 检查分类名称是否已存在
        LambdaQueryWrapper<StoreCuisineCategory> checkWrapper = new LambdaQueryWrapper<>();
        checkWrapper.eq(StoreCuisineCategory::getStoreId, storeId)
                .in(StoreCuisineCategory::getCategoryName, categoryNames);
        List<StoreCuisineCategory> existingCategories = this.list(checkWrapper);
        
        if (!existingCategories.isEmpty()) {
            List<String> existingNames = existingCategories.stream()
                    .map(StoreCuisineCategory::getCategoryName)
                    .collect(Collectors.toList());
            log.warn("批量创建菜品分类失败：分类名称已存在，{}", existingNames);
            throw new RuntimeException("此分类名称已存在：" + String.join(",", existingNames));
        }

        // 查询当前最大的排序值
        LambdaQueryWrapper<StoreCuisineCategory> maxSortWrapper = new LambdaQueryWrapper<>();
        maxSortWrapper.eq(StoreCuisineCategory::getStoreId, storeId)
                .orderByDesc(StoreCuisineCategory::getSort)
                .last("LIMIT 1");
        StoreCuisineCategory maxSortCategory = this.getOne(maxSortWrapper);
        int maxSort = (maxSortCategory != null && maxSortCategory.getSort() != null) ? maxSortCategory.getSort() : 0;

        // 使用 AtomicInteger 解决 lambda 表达式中的变量问题
        AtomicInteger sortCounter = new AtomicInteger(maxSort);

        // 批量创建
        List<StoreCuisineCategory> categories = categoryNames.stream()
                .map(categoryName -> {
                    StoreCuisineCategory category = new StoreCuisineCategory();
                    category.setStoreId(storeId);
                    category.setCategoryName(categoryName);
                    category.setStatus(1); // 默认启用
                    category.setSort(sortCounter.incrementAndGet()); // 设置排序值
                    category.setCreatedUserId(userId);
                    return category;
                })
                .collect(Collectors.toList());

        return this.saveBatch(categories);
    }

    @Override
    public boolean updateCategory(Integer id, String categoryName) {
        log.info("StoreCuisineCategoryServiceImpl.updateCategory?id={}&categoryName={}", id, categoryName);
        
        StoreCuisineCategory category = this.getById(id);
        if (category == null) {
            log.warn("更新菜品分类失败：分类不存在，id={}", id);
            return false;
        }

        // 验证分类名称长度（限5字）
        if (categoryName.length() > 5) {
            log.warn("更新菜品分类失败：分类名称长度超过5字，{}", categoryName);
            throw new RuntimeException("分类名称长度不能超过5字");
        }
        
        // 如果修改了分类名称，检查新分类名称是否已存在
        if (!categoryName.equals(category.getCategoryName())) {
            LambdaQueryWrapper<StoreCuisineCategory> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(StoreCuisineCategory::getStoreId, category.getStoreId())
                    .eq(StoreCuisineCategory::getCategoryName, categoryName)
                    .ne(StoreCuisineCategory::getId, id);
            StoreCuisineCategory existingCategory = this.getOne(wrapper);
            if (existingCategory != null) {
                log.warn("更新菜品分类失败：分类名称已存在，categoryName={}", categoryName);
                throw new RuntimeException("此分类名称已存在");
            }
        }

        // 从JWT获取当前登录用户ID
        Integer userId = getCurrentUserId();

        LambdaUpdateWrapper<StoreCuisineCategory> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(StoreCuisineCategory::getId, id)
                .set(StoreCuisineCategory::getCategoryName, categoryName);
        if (userId != null) {
            updateWrapper.set(StoreCuisineCategory::getUpdatedUserId, userId);
        }

        return this.update(updateWrapper);
    }

    @Override
    public boolean deleteCategory(Integer id) {
        log.info("StoreCuisineCategoryServiceImpl.deleteCategory?id={}", id);
        
        StoreCuisineCategory category = this.getById(id);
        if (category == null) {
            log.warn("删除菜品分类失败：分类不存在，id={}", id);
            return false;
        }

        // 逻辑删除
        return this.removeById(id);
    }

    @Override
    public boolean updateCategorySort(Integer storeId, List<Integer> categoryIds) {
        log.info("StoreCuisineCategoryServiceImpl.updateCategorySort?storeId={}&categoryIds={}", storeId, categoryIds);
        
        if (storeId == null || categoryIds == null || categoryIds.isEmpty()) {
            log.warn("更新菜品分类排序失败：参数不完整");
            return false;
        }

        // 验证所有分类ID是否属于该门店
        LambdaQueryWrapper<StoreCuisineCategory> checkWrapper = new LambdaQueryWrapper<>();
        checkWrapper.eq(StoreCuisineCategory::getStoreId, storeId)
                .in(StoreCuisineCategory::getId, categoryIds);
        long count = this.count(checkWrapper);
        if (count != categoryIds.size()) {
            log.warn("更新菜品分类排序失败：部分分类ID不属于该门店");
            throw new RuntimeException("部分分类ID不属于该门店");
        }

        // 从JWT获取当前登录用户ID
        Integer userId = getCurrentUserId();

        // 批量更新排序值
        for (int i = 0; i < categoryIds.size(); i++) {
            LambdaUpdateWrapper<StoreCuisineCategory> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(StoreCuisineCategory::getId, categoryIds.get(i))
                    .set(StoreCuisineCategory::getSort, i + 1);
            if (userId != null) {
                updateWrapper.set(StoreCuisineCategory::getUpdatedUserId, userId);
            }
            this.update(updateWrapper);
        }

        return true;
    }

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