using AutoMapper;
using SportsDivision.Application.DTOs;
using SportsDivision.Application.Interfaces;
using SportsDivision.Domain.Entities;
using SportsDivision.Domain.Interfaces;

namespace SportsDivision.Application.Services;

public class StudentService : IStudentService
{
    private readonly IUnitOfWork _uow;
    private readonly IMapper _mapper;

    public StudentService(IUnitOfWork uow, IMapper mapper)
    {
        _uow = uow;
        _mapper = mapper;
    }

    public async Task<IEnumerable<StudentDto>> GetAllAsync()
    {
        var students = await _uow.Students.GetAllAsync();
        return _mapper.Map<IEnumerable<StudentDto>>(students);
    }

    public async Task<StudentDto?> GetByIdAsync(int id)
    {
        var student = await _uow.Students.GetByIdAsync(id);
        return student == null ? null : _mapper.Map<StudentDto>(student);
    }

    public async Task<StudentDto?> GetByExistingIdAsync(string existingStudentId)
    {
        var student = await _uow.Students.GetByExistingIdAsync(existingStudentId);
        return student == null ? null : _mapper.Map<StudentDto>(student);
    }

    public async Task<IEnumerable<StudentDto>> GetBySchoolAsync(int schoolId)
    {
        var students = await _uow.Students.GetBySchoolAsync(schoolId);
        return _mapper.Map<IEnumerable<StudentDto>>(students);
    }

    public async Task<IEnumerable<StudentDto>> SearchAsync(string searchTerm)
    {
        var students = await _uow.Students.SearchAsync(searchTerm);
        return _mapper.Map<IEnumerable<StudentDto>>(students);
    }

    public async Task<StudentDto> CreateAsync(StudentCreateDto dto)
    {
        var student = _mapper.Map<Student>(dto);
        await _uow.Students.AddAsync(student);
        await _uow.SaveChangesAsync();
        return _mapper.Map<StudentDto>(student);
    }

    public async Task UpdateAsync(StudentUpdateDto dto)
    {
        var student = await _uow.Students.GetByIdAsync(dto.StudentId)
            ?? throw new KeyNotFoundException("Student not found.");
        _mapper.Map(dto, student);
        _uow.Students.Update(student);
        await _uow.SaveChangesAsync();
    }

    public async Task DeleteAsync(int id)
    {
        var student = await _uow.Students.GetByIdAsync(id)
            ?? throw new KeyNotFoundException("Student not found.");
        _uow.Students.Remove(student);
        await _uow.SaveChangesAsync();
    }
}
