using ErsatzTV.Core.Api.ChannelTemplates;
using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Repositories;
using ErsatzTV.Infrastructure.Data;
using ErsatzTV.Infrastructure.Extensions;
using Microsoft.EntityFrameworkCore;

namespace ErsatzTV.Application.ChannelTemplates;

public class GetDefaultChannelTemplateHandler(
    IDbContextFactory<TvContext> dbContextFactory,
    IConfigElementRepository configElementRepository)
    : IRequestHandler<GetDefaultChannelTemplate, Option<ChannelTemplateResponseModel>>
{
    public async Task<Option<ChannelTemplateResponseModel>> Handle(
        GetDefaultChannelTemplate request,
        CancellationToken cancellationToken)
    {
        await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
        int? defaultTemplateId =
            await ChannelTemplateDefault.GetDefaultTemplateId(configElementRepository, cancellationToken);
        foreach (int id in Optional(defaultTemplateId))
        {
            Option<ChannelTemplate> maybeConfigured = await dbContext.ChannelTemplates
                .AsNoTracking()
                .SelectOneAsync(t => t.Id, t => t.Id == id, cancellationToken);
            foreach (ChannelTemplate template in maybeConfigured)
            {
                return ChannelTemplateMapper.ProjectToResponseModel(template, id);
            }
        }

        ChannelTemplate fallback = await dbContext.ChannelTemplates
            .AsNoTracking()
            .Where(t => t.IsSystem)
            .OrderBy(t => t.Name)
            .FirstOrDefaultAsync(cancellationToken);
        return Optional(fallback).Map(t => ChannelTemplateMapper.ProjectToResponseModel(t, t.Id));
    }
}
