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.LessonCreateRequest;
import com.reading.platform.dto.request.LessonUpdateRequest;
import com.reading.platform.entity.Lesson;
import com.reading.platform.mapper.LessonMapper;
import com.reading.platform.service.LessonService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.util.List;

@Service
@RequiredArgsConstructor
public class LessonServiceImpl implements LessonService {

    private final LessonMapper lessonMapper;

    @Override
    @Transactional
    public Lesson createLesson(Long tenantId, LessonCreateRequest request) {
        Lesson lesson = new Lesson();
        lesson.setTenantId(tenantId);
        lesson.setCourseId(request.getCourseId());
        lesson.setClassId(request.getClassId());
        lesson.setTeacherId(request.getTeacherId());
        lesson.setTitle(request.getTitle());
        lesson.setLessonDate(request.getLessonDate());
        lesson.setStartTime(request.getStartTime());
        lesson.setEndTime(request.getEndTime());
        lesson.setLocation(request.getLocation());
        lesson.setNotes(request.getNotes());
        lesson.setStatus("scheduled");

        lessonMapper.insert(lesson);
        return lesson;
    }

    @Override
    @Transactional
    public Lesson updateLesson(Long id, LessonUpdateRequest request) {
        Lesson lesson = getLessonById(id);

        if (StringUtils.hasText(request.getTitle())) {
            lesson.setTitle(request.getTitle());
        }
        if (request.getLessonDate() != null) {
            lesson.setLessonDate(request.getLessonDate());
        }
        if (request.getStartTime() != null) {
            lesson.setStartTime(request.getStartTime());
        }
        if (request.getEndTime() != null) {
            lesson.setEndTime(request.getEndTime());
        }
        if (request.getLocation() != null) {
            lesson.setLocation(request.getLocation());
        }
        if (StringUtils.hasText(request.getStatus())) {
            lesson.setStatus(request.getStatus());
        }
        if (request.getNotes() != null) {
            lesson.setNotes(request.getNotes());
        }

        lessonMapper.updateById(lesson);
        return lesson;
    }

    @Override
    public Lesson getLessonById(Long id) {
        Lesson lesson = lessonMapper.selectById(id);
        if (lesson == null) {
            throw new BusinessException(ErrorCode.DATA_NOT_FOUND, "Lesson not found");
        }
        return lesson;
    }

    @Override
    public Page<Lesson> getLessonPage(Long tenantId, Integer pageNum, Integer pageSize, Long classId, Long teacherId, String status, LocalDate startDate, LocalDate endDate) {
        Page<Lesson> page = PageUtils.of(pageNum, pageSize);
        LambdaQueryWrapper<Lesson> wrapper = new LambdaQueryWrapper<>();

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

        if (classId != null) {
            wrapper.eq(Lesson::getClassId, classId);
        }
        if (teacherId != null) {
            wrapper.eq(Lesson::getTeacherId, teacherId);
        }
        if (StringUtils.hasText(status)) {
            wrapper.eq(Lesson::getStatus, status);
        }
        if (startDate != null) {
            wrapper.ge(Lesson::getLessonDate, startDate);
        }
        if (endDate != null) {
            wrapper.le(Lesson::getLessonDate, endDate);
        }
        wrapper.orderByAsc(Lesson::getLessonDate, Lesson::getStartTime);

        return lessonMapper.selectPage(page, wrapper);
    }

    @Override
    public Page<Lesson> getTeacherLessons(Long teacherId, Integer pageNum, Integer pageSize, String status, LocalDate startDate, LocalDate endDate) {
        Page<Lesson> page = PageUtils.of(pageNum, pageSize);
        LambdaQueryWrapper<Lesson> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(Lesson::getTeacherId, teacherId);

        if (StringUtils.hasText(status)) {
            wrapper.eq(Lesson::getStatus, status);
        }
        if (startDate != null) {
            wrapper.ge(Lesson::getLessonDate, startDate);
        }
        if (endDate != null) {
            wrapper.le(Lesson::getLessonDate, endDate);
        }
        wrapper.orderByAsc(Lesson::getLessonDate, Lesson::getStartTime);

        return lessonMapper.selectPage(page, wrapper);
    }

    @Override
    @Transactional
    public void deleteLesson(Long id) {
        getLessonById(id);
        lessonMapper.deleteById(id);
    }

    @Override
    @Transactional
    public void startLesson(Long id) {
        Lesson lesson = getLessonById(id);
        lesson.setStatus("in_progress");
        lessonMapper.updateById(lesson);
    }

    @Override
    @Transactional
    public void completeLesson(Long id) {
        Lesson lesson = getLessonById(id);
        lesson.setStatus("completed");
        lessonMapper.updateById(lesson);
    }

    @Override
    @Transactional
    public void cancelLesson(Long id) {
        Lesson lesson = getLessonById(id);
        lesson.setStatus("cancelled");
        lessonMapper.updateById(lesson);
    }

    @Override
    public List<Lesson> getTodayLessons(Long tenantId) {
        return lessonMapper.selectList(
                new LambdaQueryWrapper<Lesson>()
                        .eq(Lesson::getTenantId, tenantId)
                        .eq(Lesson::getLessonDate, LocalDate.now())
                        .in(Lesson::getStatus, "scheduled", "in_progress")
                        .orderByAsc(Lesson::getStartTime)
        );
    }

}
