using Microsoft.EntityFrameworkCore;
using UniVerse.Application.DTOs.Locations;
using UniVerse.Application.Interfaces;
using UniVerse.Application.Mappings;
using UniVerse.Domain.Entities;
using UniVerse.Domain.Exceptions;
using UniVerse.Infrastructure.Data;

namespace UniVerse.Infrastructure.Services;

public class LocationService : ILocationService
{
    private readonly AppDbContext _db;

    public LocationService(AppDbContext db) => _db = db;

    public async Task<List<LocationDto>> GetAllAsync() =>
        await _db.Locations.OrderBy(l => l.Name)
            .Select(l => new LocationDto(l.Id, l.Name, l.Building, l.Room, l.Address, l.CreatedAt))
            .ToListAsync();

    public async Task<LocationDto> GetByIdAsync(int id)
    {
        var loc = await _db.Locations.FindAsync(id)
            ?? throw new NotFoundException("Location", id);
        return loc.ToDto();
    }

    public async Task<LocationDto> CreateAsync(CreateLocationRequest request)
    {
        var loc = new Location
        {
            Name = request.Name,
            Building = request.Building,
            Room = request.Room,
            Address = request.Address
        };
        _db.Locations.Add(loc);
        await _db.SaveChangesAsync();
        return loc.ToDto();
    }

    public async Task<LocationDto> UpdateAsync(int id, UpdateLocationRequest request)
    {
        var loc = await _db.Locations.FindAsync(id)
            ?? throw new NotFoundException("Location", id);

        loc.Name = request.Name;
        loc.Building = request.Building;
        loc.Room = request.Room;
        loc.Address = request.Address;

        await _db.SaveChangesAsync();
        return loc.ToDto();
    }

    public async Task DeleteAsync(int id)
    {
        var loc = await _db.Locations.FindAsync(id)
            ?? throw new NotFoundException("Location", id);
        _db.Locations.Remove(loc);
        await _db.SaveChangesAsync();
    }
}
