package com.reading.platform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.reading.platform.common.enums.ErrorCode;
import com.reading.platform.common.exception.BusinessException;
import com.reading.platform.common.util.PageUtils;
import com.reading.platform.dto.request.CourseCreateRequest;
import com.reading.platform.dto.request.CourseUpdateRequest;
import com.reading.platform.entity.Course;
import com.reading.platform.mapper.CourseMapper;
import com.reading.platform.service.CourseService;
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 java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class CourseServiceImpl implements CourseService {

    private final CourseMapper courseMapper;

    @Override
    @Transactional
    public Course createCourse(Long tenantId, CourseCreateRequest request) {
        Course course = new Course();
        course.setTenantId(tenantId);
        course.setName(request.getName());
        course.setCode(request.getCode());
        course.setDescription(request.getDescription());
        course.setCoverUrl(request.getCoverUrl());
        course.setCoverImagePath(request.getCoverImagePath());
        course.setCategory(request.getCategory());
        course.setAgeRange(request.getAgeRange());
        course.setDifficultyLevel(request.getDifficultyLevel());
        course.setDurationMinutes(request.getDurationMinutes());
        course.setObjectives(request.getObjectives());
        course.setStatus("draft");
        course.setIsSystem(0);

        // Course Package Fields
        course.setCoreContent(request.getCoreContent());
        course.setIntroSummary(request.getIntroSummary());
        course.setIntroHighlights(request.getIntroHighlights());
        course.setIntroGoals(request.getIntroGoals());
        course.setIntroSchedule(request.getIntroSchedule());
        course.setIntroKeyPoints(request.getIntroKeyPoints());
        course.setIntroMethods(request.getIntroMethods());
        course.setIntroEvaluation(request.getIntroEvaluation());
        course.setIntroNotes(request.getIntroNotes());
        course.setScheduleRefData(request.getScheduleRefData());
        course.setEnvironmentConstruction(request.getEnvironmentConstruction());
        course.setThemeId(request.getThemeId());
        course.setPictureBookName(request.getPictureBookName());
        course.setEbookPaths(request.getEbookPaths());
        course.setAudioPaths(request.getAudioPaths());
        course.setVideoPaths(request.getVideoPaths());
        course.setOtherResources(request.getOtherResources());
        course.setPptPath(request.getPptPath());
        course.setPptName(request.getPptName());
        course.setPosterPaths(request.getPosterPaths());
        course.setTools(request.getTools());
        course.setStudentMaterials(request.getStudentMaterials());
        course.setLessonPlanData(request.getLessonPlanData());
        course.setActivitiesData(request.getActivitiesData());
        course.setAssessmentData(request.getAssessmentData());
        course.setGradeTags(request.getGradeTags());
        course.setDomainTags(request.getDomainTags());
        course.setHasCollectiveLesson(request.getHasCollectiveLesson() != null && request.getHasCollectiveLesson() ? 1 : 0);

        course.setVersion("1.0");
        course.setIsLatest(1);
        course.setUsageCount(0);
        course.setTeacherCount(0);

        courseMapper.insert(course);
        log.info("Course created: id={}, name={}", course.getId(), course.getName());
        return course;
    }

    @Override
    @Transactional
    public Course updateCourse(Long id, CourseUpdateRequest request) {
        Course course = getCourseById(id);

        // Basic fields
        if (StringUtils.hasText(request.getName())) {
            course.setName(request.getName());
        }
        if (request.getCode() != null) {
            course.setCode(request.getCode());
        }
        if (request.getDescription() != null) {
            course.setDescription(request.getDescription());
        }
        if (request.getCoverUrl() != null) {
            course.setCoverUrl(request.getCoverUrl());
        }
        if (request.getCoverImagePath() != null) {
            course.setCoverImagePath(request.getCoverImagePath());
        }
        if (request.getCategory() != null) {
            course.setCategory(request.getCategory());
        }
        if (request.getAgeRange() != null) {
            course.setAgeRange(request.getAgeRange());
        }
        if (request.getDifficultyLevel() != null) {
            course.setDifficultyLevel(request.getDifficultyLevel());
        }
        if (request.getDurationMinutes() != null) {
            course.setDurationMinutes(request.getDurationMinutes());
        }
        if (request.getObjectives() != null) {
            course.setObjectives(request.getObjectives());
        }
        if (StringUtils.hasText(request.getStatus())) {
            course.setStatus(request.getStatus());
        }

        // Course Package Fields
        if (request.getCoreContent() != null) {
            course.setCoreContent(request.getCoreContent());
        }
        if (request.getIntroSummary() != null) {
            course.setIntroSummary(request.getIntroSummary());
        }
        if (request.getIntroHighlights() != null) {
            course.setIntroHighlights(request.getIntroHighlights());
        }
        if (request.getIntroGoals() != null) {
            course.setIntroGoals(request.getIntroGoals());
        }
        if (request.getIntroSchedule() != null) {
            course.setIntroSchedule(request.getIntroSchedule());
        }
        if (request.getIntroKeyPoints() != null) {
            course.setIntroKeyPoints(request.getIntroKeyPoints());
        }
        if (request.getIntroMethods() != null) {
            course.setIntroMethods(request.getIntroMethods());
        }
        if (request.getIntroEvaluation() != null) {
            course.setIntroEvaluation(request.getIntroEvaluation());
        }
        if (request.getIntroNotes() != null) {
            course.setIntroNotes(request.getIntroNotes());
        }
        if (request.getScheduleRefData() != null) {
            course.setScheduleRefData(request.getScheduleRefData());
        }
        if (request.getEnvironmentConstruction() != null) {
            course.setEnvironmentConstruction(request.getEnvironmentConstruction());
        }
        if (request.getThemeId() != null) {
            course.setThemeId(request.getThemeId());
        }
        if (request.getPictureBookName() != null) {
            course.setPictureBookName(request.getPictureBookName());
        }
        if (request.getEbookPaths() != null) {
            course.setEbookPaths(request.getEbookPaths());
        }
        if (request.getAudioPaths() != null) {
            course.setAudioPaths(request.getAudioPaths());
        }
        if (request.getVideoPaths() != null) {
            course.setVideoPaths(request.getVideoPaths());
        }
        if (request.getOtherResources() != null) {
            course.setOtherResources(request.getOtherResources());
        }
        if (request.getPptPath() != null) {
            course.setPptPath(request.getPptPath());
        }
        if (request.getPptName() != null) {
            course.setPptName(request.getPptName());
        }
        if (request.getPosterPaths() != null) {
            course.setPosterPaths(request.getPosterPaths());
        }
        if (request.getTools() != null) {
            course.setTools(request.getTools());
        }
        if (request.getStudentMaterials() != null) {
            course.setStudentMaterials(request.getStudentMaterials());
        }
        if (request.getLessonPlanData() != null) {
            course.setLessonPlanData(request.getLessonPlanData());
        }
        if (request.getActivitiesData() != null) {
            course.setActivitiesData(request.getActivitiesData());
        }
        if (request.getAssessmentData() != null) {
            course.setAssessmentData(request.getAssessmentData());
        }
        if (request.getGradeTags() != null) {
            course.setGradeTags(request.getGradeTags());
        }
        if (request.getDomainTags() != null) {
            course.setDomainTags(request.getDomainTags());
        }
        if (request.getHasCollectiveLesson() != null) {
            course.setHasCollectiveLesson(request.getHasCollectiveLesson() ? 1 : 0);
        }

        courseMapper.updateById(course);
        log.info("Course updated: id={}", id);
        return course;
    }

    @Override
    public Course getCourseById(Long id) {
        Course course = courseMapper.selectById(id);
        if (course == null) {
            throw new BusinessException(ErrorCode.DATA_NOT_FOUND, "Course not found");
        }
        return course;
    }

    @Override
    public Page<Course> getCoursePage(Long tenantId, Integer pageNum, Integer pageSize, String keyword, String category, String status) {
        Page<Course> page = PageUtils.of(pageNum, pageSize);
        LambdaQueryWrapper<Course> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(Course::getTenantId, tenantId);

        if (StringUtils.hasText(keyword)) {
            wrapper.and(w -> w
                    .like(Course::getName, keyword)
                    .or()
                    .like(Course::getCode, keyword)
            );
        }
        if (StringUtils.hasText(category)) {
            wrapper.eq(Course::getCategory, category);
        }
        if (StringUtils.hasText(status)) {
            wrapper.eq(Course::getStatus, status);
        }
        wrapper.orderByDesc(Course::getCreatedAt);

        return courseMapper.selectPage(page, wrapper);
    }

    @Override
    public Page<Course> getSystemCoursePage(Integer pageNum, Integer pageSize, String keyword, String category) {
        Page<Course> page = PageUtils.of(pageNum, pageSize);
        LambdaQueryWrapper<Course> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(Course::getIsSystem, 1)
                .eq(Course::getStatus, "published");

        if (StringUtils.hasText(keyword)) {
            wrapper.and(w -> w
                    .like(Course::getName, keyword)
                    .or()
                    .like(Course::getCode, keyword)
            );
        }
        if (StringUtils.hasText(category)) {
            wrapper.eq(Course::getCategory, category);
        }
        wrapper.orderByDesc(Course::getCreatedAt);

        return courseMapper.selectPage(page, wrapper);
    }

    @Override
    @Transactional
    public void deleteCourse(Long id) {
        getCourseById(id);
        courseMapper.deleteById(id);
        log.info("Course deleted: id={}", id);
    }

    @Override
    @Transactional
    public void publishCourse(Long id) {
        Course course = getCourseById(id);
        course.setStatus("published");
        course.setPublishedAt(LocalDateTime.now());
        courseMapper.updateById(course);
        log.info("Course published: id={}", id);
    }

    @Override
    @Transactional
    public void archiveCourse(Long id) {
        Course course = getCourseById(id);
        course.setStatus("archived");
        courseMapper.updateById(course);
        log.info("Course archived: id={}", id);
    }

    @Override
    public List<Course> getCoursesByTenantId(Long tenantId) {
        return courseMapper.selectList(
                new LambdaQueryWrapper<Course>()
                        .eq(Course::getTenantId, tenantId)
                        .eq(Course::getStatus, "published")
                        .orderByAsc(Course::getName)
        );
    }

}
