using MemberCenter.Application.Abstractions;
using MemberCenter.Application.Models.Admin;
using MemberCenter.Domain.Entities;
using MemberCenter.Infrastructure.Persistence;
using Microsoft.EntityFrameworkCore;

namespace MemberCenter.Infrastructure.Services;

public sealed class NewsletterListService : INewsletterListService
{
    private readonly MemberCenterDbContext _dbContext;

    public NewsletterListService(MemberCenterDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public async Task<IReadOnlyList<NewsletterListDto>> ListAsync()
    {
        var lists = await _dbContext.NewsletterLists
            .Include(l => l.Tenant)
            .ToListAsync();
        return lists.Select(l => MapList(l, l.Tenant?.Name)).ToList();
    }

    public async Task<NewsletterListDto?> GetAsync(Guid id)
    {
        var list = await _dbContext.NewsletterLists
            .Include(l => l.Tenant)
            .FirstOrDefaultAsync(l => l.Id == id);
        return list is null ? null : MapList(list, list.Tenant?.Name);
    }

    public async Task<NewsletterListDto> CreateAsync(Guid tenantId, string name, string status)
    {
        var list = new NewsletterList
        {
            Id = Guid.NewGuid(),
            TenantId = tenantId,
            Name = name,
            Status = status
        };

        _dbContext.NewsletterLists.Add(list);
        await _dbContext.SaveChangesAsync();
        var tenantName = await GetTenantNameAsync(tenantId);
        return MapList(list, tenantName);
    }

    public async Task<NewsletterListDto?> UpdateAsync(Guid id, Guid tenantId, string name, string status)
    {
        var list = await _dbContext.NewsletterLists.FindAsync(id);
        if (list is null)
        {
            return null;
        }

        list.TenantId = tenantId;
        list.Name = name;
        list.Status = status;
        await _dbContext.SaveChangesAsync();
        var tenantName = await GetTenantNameAsync(tenantId);
        return MapList(list, tenantName);
    }

    public async Task<bool> DeleteAsync(Guid id)
    {
        var list = await _dbContext.NewsletterLists.FindAsync(id);
        if (list is null)
        {
            return false;
        }

        _dbContext.NewsletterLists.Remove(list);
        await _dbContext.SaveChangesAsync();
        return true;
    }

    private static NewsletterListDto MapList(NewsletterList list, string? tenantName)
    {
        return new NewsletterListDto(list.Id, list.TenantId, tenantName ?? string.Empty, list.Name, list.Status);
    }

    private Task<string?> GetTenantNameAsync(Guid tenantId)
    {
        return _dbContext.Tenants
            .Where(t => t.Id == tenantId)
            .Select(t => t.Name)
            .FirstOrDefaultAsync();
    }
}
