using ERPCore.Domain.Entities;
using ERPCore.Dtos.Common;
using ERPCore.Dtos.Uoms;
using ERPCore.Infra.UoW;
using ERPCore.Repositories.Interfaces;
using ERPCore.Services.Interfaces;
using ERPCore.System.Errors;
using Microsoft.EntityFrameworkCore;

namespace ERPCore.Services;

public sealed class UomService : IUomService
{
    private readonly IRepository<Uom> _uoms;
    private readonly IUnitOfWork _uow;

    public UomService(IRepository<Uom> uoms, IUnitOfWork uow)
    {
        _uoms = uoms;
        _uow = uow;
    }

    public async Task<PagedResponse<UomDto>> ListAsync(PageQuery query, CancellationToken ct = default)
    {
        var q = _uoms.Query().AsNoTracking();
        if (!string.IsNullOrWhiteSpace(query.Q))
        {
            var term = query.Q.Trim();
            q = q.Where(u => EF.Functions.ILike(u.Name, $"%{term}%"));
        }

        var total = await q.CountAsync(ct);
        var rows = await q.OrderBy(u => u.Name)
            .Skip(query.Skip).Take(query.PageSize)
            .Select(u => new UomDto(u.UomId, u.Name))
            .ToListAsync(ct);

        return PagedResponse<UomDto>.Create(rows, query.Page, query.PageSize, total);
    }

    public async Task<UomDto> CreateAsync(CreateUomRequest request, CancellationToken ct = default)
    {
        var name = request.Name.Trim();
        if (await _uoms.Query().AnyAsync(u => u.Name == name, ct))
            throw new ConflictException($"A UOM named '{name}' already exists.");

        var uom = new Uom { Name = name };
        await _uoms.AddAsync(uom, ct);
        await _uow.SaveChangesAsync(ct);

        return new UomDto(uom.UomId, uom.Name);
    }
}
