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.TeacherCreateRequest;
import com.reading.platform.dto.request.TeacherUpdateRequest;
import com.reading.platform.entity.Teacher;
import com.reading.platform.mapper.TeacherMapper;
import com.reading.platform.service.TeacherService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

@Service
@RequiredArgsConstructor
public class TeacherServiceImpl implements TeacherService {

    private final TeacherMapper teacherMapper;
    private final PasswordEncoder passwordEncoder;

    @Override
    @Transactional
    public Teacher createTeacher(Long tenantId, TeacherCreateRequest request) {
        // Check if username already exists
        Teacher existing = teacherMapper.selectOne(
                new LambdaQueryWrapper<Teacher>().eq(Teacher::getUsername, request.getUsername())
        );
        if (existing != null) {
            throw new BusinessException(ErrorCode.DATA_ALREADY_EXISTS, "Username already exists");
        }

        Teacher teacher = new Teacher();
        teacher.setTenantId(tenantId);
        teacher.setUsername(request.getUsername());
        teacher.setPassword(passwordEncoder.encode(request.getPassword()));
        teacher.setName(request.getName());
        teacher.setPhone(request.getPhone());
        teacher.setEmail(request.getEmail());
        teacher.setGender(request.getGender());
        teacher.setBio(request.getBio());
        teacher.setStatus("active");

        teacherMapper.insert(teacher);
        return teacher;
    }

    @Override
    @Transactional
    public Teacher updateTeacher(Long id, TeacherUpdateRequest request) {
        Teacher teacher = getTeacherById(id);

        if (StringUtils.hasText(request.getName())) {
            teacher.setName(request.getName());
        }
        if (request.getPhone() != null) {
            teacher.setPhone(request.getPhone());
        }
        if (request.getEmail() != null) {
            teacher.setEmail(request.getEmail());
        }
        if (request.getAvatarUrl() != null) {
            teacher.setAvatarUrl(request.getAvatarUrl());
        }
        if (request.getGender() != null) {
            teacher.setGender(request.getGender());
        }
        if (request.getBio() != null) {
            teacher.setBio(request.getBio());
        }
        if (StringUtils.hasText(request.getStatus())) {
            teacher.setStatus(request.getStatus());
        }

        teacherMapper.updateById(teacher);
        return teacher;
    }

    @Override
    public Teacher getTeacherById(Long id) {
        Teacher teacher = teacherMapper.selectById(id);
        if (teacher == null) {
            throw new BusinessException(ErrorCode.USER_NOT_FOUND, "Teacher not found");
        }
        return teacher;
    }

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

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

        if (StringUtils.hasText(keyword)) {
            wrapper.and(w -> w
                    .like(Teacher::getName, keyword)
                    .or()
                    .like(Teacher::getUsername, keyword)
                    .or()
                    .like(Teacher::getPhone, keyword)
            );
        }
        if (StringUtils.hasText(status)) {
            wrapper.eq(Teacher::getStatus, status);
        }
        wrapper.orderByDesc(Teacher::getCreatedAt);

        return teacherMapper.selectPage(page, wrapper);
    }

    @Override
    @Transactional
    public void deleteTeacher(Long id) {
        getTeacherById(id);
        teacherMapper.deleteById(id);
    }

    @Override
    @Transactional
    public void resetPassword(Long id, String newPassword) {
        Teacher teacher = getTeacherById(id);
        teacher.setPassword(passwordEncoder.encode(newPassword));
        teacherMapper.updateById(teacher);
    }

}
