using LiteCqrs;
using Microsoft.EntityFrameworkCore;
using TeleWave.Application.Common.Interfaces;
using TeleWave.Application.Common.Models;
using TeleWave.Domain.Library;

namespace TeleWave.Application.Library.Genres.CreateGenre;

public sealed class CreateGenreCommandHandler(IAppDbContext dbContext)
    : ICommandHandler<CreateGenreCommand, Result<Guid>>
{
    public async Task<Result<Guid>> Handle(
        CreateGenreCommand command,
        CancellationToken cancellationToken
    )
    {
        var slug = GenreAlias.Normalize(command.Slug);
        if (await dbContext.Genres.AnyAsync(g => g.Slug == slug, cancellationToken))
            return Result.Failure<Guid>(GenreErrors.SlugTaken);

        var nextSortOrder = await dbContext.Genres.AnyAsync(cancellationToken)
            ? await dbContext.Genres.MaxAsync(g => g.SortOrder, cancellationToken) + 1
            : 0;

        var genre = Genre.Create(command.Name, slug, nextSortOrder);
        foreach (var alias in GenreAliasInput.Collect(command.Name, slug, command.Aliases))
            genre.AddAlias(alias);

        var values = genre.Aliases.Select(a => a.Value).ToList();
        if (await dbContext.GenreAliases.AnyAsync(a => values.Contains(a.Value), cancellationToken))
            return Result.Failure<Guid>(GenreErrors.AliasTaken);

        dbContext.Genres.Add(genre);
        return Result.Success(genre.Id);
    }
}
