package com.dora.service.impl;

import com.dora.dto.CategoryCreateDto;
import com.dora.dto.CategoryDto;
import com.dora.dto.CategoryListDto;
import com.dora.dto.CategoryUpdateDto;
import com.dora.dto.PageResultDto;
import com.dora.entity.Category;
import com.dora.exception.BusinessException;
import com.dora.mapper.CategoryMapper;
import com.dora.mapper.CourseMapper;
import com.dora.service.CategoryService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 类目服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CategoryServiceImpl implements CategoryService {
    
    private final CategoryMapper categoryMapper;
    private final CourseMapper courseMapper;
    
    @Override
    public List<CategoryDto> getEnabledCategoriesByType(Integer type) {
        List<Category> categories = categoryMapper.selectEnabledByType(type);
        return categories.stream().map(this::convertToDto).toList();
    }
    
    @Override
    public List<CategoryDto> getAllEnabledCategories() {
        List<Category> categories = categoryMapper.selectAllEnabled();
        return categories.stream().map(this::convertToDto).toList();
    }
    
    @Override
    public PageResultDto<CategoryListDto> getCategoriesByPage(Integer type, int page, int size) {
        int offset = (page - 1) * size;
        List<Category> categories = categoryMapper.selectByPage(type, offset, size);
        Long total = categoryMapper.countByType(type);
        
        List<CategoryListDto> categoryListDtos = categories.stream()
                .map(this::convertToListDto)
                .toList();
        
        return new PageResultDto<>(total, (long)page, (long)size, categoryListDtos);
    }
    
    @Override
    public CategoryDto getCategoryById(Long id) {
        Category category = categoryMapper.selectById(id);
        if (category == null) {
            throw new BusinessException("类目不存在");
        }
        return convertToDto(category);
    }
    
    @Override
    @Transactional
    public CategoryDto createCategory(CategoryCreateDto createDto) {
        // 检查名称是否重复
        if (isNameExists(createDto.getName(), createDto.getType(), null)) {
            throw new BusinessException("该类型下已存在同名类目");
        }
        
        // 验证类目类型
        if (!isValidType(createDto.getType())) {
            throw new BusinessException("无效的类目类型");
        }
        
        Category category = new Category();
        // 手动设置字段，处理类型转换
        category.setName(createDto.getName());
        category.setType(createDto.getType());
        category.setDescription(createDto.getDescription());
        category.setSortOrder(createDto.getSortOrder());
        
        // 正确处理 Boolean 到 Integer 的转换
        if (createDto.getIsEnabled() != null) {
            category.setIsEnabled(Boolean.TRUE.equals(createDto.getIsEnabled()) ? 1 : 0);
        } else {
            category.setIsEnabled(1); // 默认启用
        }
        
        // 设置默认值
        if (category.getSortOrder() == null) {
            category.setSortOrder(0);
        }
        
        category.setCreateTime(LocalDateTime.now());
        category.setUpdateTime(LocalDateTime.now());
        category.setIsDeleted(0);
        
        int result = categoryMapper.insert(category);
        if (result <= 0) {
            throw new BusinessException("创建类目失败");
        }
        
        return convertToDto(category);
    }
    
    @Override
    @Transactional
    public CategoryDto updateCategory(CategoryUpdateDto updateDto) {
        Category existingCategory = categoryMapper.selectById(updateDto.getId());
        if (existingCategory == null) {
            throw new BusinessException("类目不存在");
        }
        
        // 检查名称是否重复（排除自己）
        if (isNameExists(updateDto.getName(), existingCategory.getType(), updateDto.getId())) {
            throw new BusinessException("该类型下已存在同名类目");
        }
        
        Category category = new Category();
        // 手动设置字段，处理类型转换
        category.setId(updateDto.getId());
        category.setName(updateDto.getName());
        category.setDescription(updateDto.getDescription());
        category.setSortOrder(updateDto.getSortOrder());
        category.setType(existingCategory.getType()); // 不允许修改类型
        category.setUpdateTime(LocalDateTime.now());
        
        // 正确处理 Boolean 到 Integer 的转换
        if (updateDto.getIsEnabled() != null) {
            category.setIsEnabled(Boolean.TRUE.equals(updateDto.getIsEnabled()) ? 1 : 0);
        } else {
            category.setIsEnabled(1); // 默认启用
        }
        
        // 设置默认值
        if (category.getSortOrder() == null) {
            category.setSortOrder(0);
        }
        
        int result = categoryMapper.updateById(category);
        if (result <= 0) {
            throw new BusinessException("更新类目失败");
        }
        
        return getCategoryById(updateDto.getId());
    }
    
    @Override
    @Transactional
    public void deleteCategory(Long id) {
        Category category = categoryMapper.selectById(id);
        if (category == null) {
            throw new BusinessException("类目不存在");
        }
        
        // 检查是否有课程或工作流使用此类目
        // 如果有关联数据，可以考虑不允许删除或者提示用户
        // 这里暂时允许删除，实际项目中需要根据业务需求决定
        
        int result = categoryMapper.deleteById(id);
        if (result <= 0) {
            throw new BusinessException("删除类目失败");
        }
    }
    
    @Override
    @Transactional
    public void batchUpdateSortOrder(List<CategoryUpdateDto> updateDtos) {
        if (updateDtos == null || updateDtos.isEmpty()) {
            return;
        }
        
        List<Category> categories = updateDtos.stream().map(dto -> {
            Category category = new Category();
            category.setId(dto.getId());
            category.setSortOrder(dto.getSortOrder());
            return category;
        }).toList();
        
        categoryMapper.batchUpdateSortOrder(categories);
    }
    
    @Override
    public boolean isNameExists(String name, Integer type, Long excludeId) {
        Category category = categoryMapper.selectByNameAndType(name, type);
        if (category == null) {
            return false;
        }
        return excludeId == null || !excludeId.equals(category.getId());
    }
    
    /**
     * 验证类目类型是否有效
     */
    private boolean isValidType(Integer type) {
        return Category.TYPE_COURSE.equals(type) || Category.TYPE_WORKFLOW.equals(type);
    }
    
    /**
     * 转换为DTO
     */
    private CategoryDto convertToDto(Category category) {
        CategoryDto dto = new CategoryDto();
        BeanUtils.copyProperties(category, dto);
        dto.setIsEnabled(category.getIsEnabled() == 1);
        dto.setTypeName(getTypeName(category.getType()));
        return dto;
    }
    
    /**
     * 转换为ListDTO
     */
    private CategoryListDto convertToListDto(Category category) {
        CategoryListDto dto = new CategoryListDto();
        BeanUtils.copyProperties(category, dto);
        dto.setIsEnabled(category.getIsEnabled() == 1);
        dto.setTypeName(getTypeName(category.getType()));
        return dto;
    }
    
    /**
     * 获取类型名称
     */
    private String getTypeName(Integer type) {
        if (Category.TYPE_COURSE.equals(type)) {
            return "课程分类";
        } else if (Category.TYPE_WORKFLOW.equals(type)) {
            return "工作流分类";
        }
        return "未知类型";
    }

    @Override
    @Transactional
    public String migrateCourseData() {
        try {
            log.info("开始迁移课程分类数据：将老的category字段同步到新的category_id字段");
            
            // 执行数据迁移
            int updatedRows = courseMapper.migrateCategoryToId();
            
            log.info("课程分类数据迁移完成，更新了 {} 条记录", updatedRows);
            
            return String.format("数据迁移成功！已更新 %d 条课程记录的分类关联。", updatedRows);
            
        } catch (Exception e) {
            log.error("课程分类数据迁移失败", e);
            throw new BusinessException("数据迁移失败：" + e.getMessage());
        }
    }
}
