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 TenantService : ITenantService
{
    private readonly MemberCenterDbContext _dbContext;

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

    public async Task<IReadOnlyList<TenantDto>> ListAsync()
    {
        var tenants = await _dbContext.Tenants.ToListAsync();
        return tenants.Select(MapTenant).ToList();
    }

    public async Task<TenantDto?> GetAsync(Guid id)
    {
        var tenant = await _dbContext.Tenants.FindAsync(id);
        return tenant is null ? null : MapTenant(tenant);
    }

    public async Task<TenantDto> CreateAsync(string name, List<string> domains, string status)
    {
        var tenant = new Tenant
        {
            Id = Guid.NewGuid(),
            Name = name,
            Domains = domains,
            Status = status
        };

        _dbContext.Tenants.Add(tenant);
        await _dbContext.SaveChangesAsync();
        return MapTenant(tenant);
    }

    public async Task<TenantDto?> UpdateAsync(Guid id, string name, List<string> domains, string status)
    {
        var tenant = await _dbContext.Tenants.FindAsync(id);
        if (tenant is null)
        {
            return null;
        }

        tenant.Name = name;
        tenant.Domains = domains;
        tenant.Status = status;
        await _dbContext.SaveChangesAsync();
        return MapTenant(tenant);
    }

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

        _dbContext.Tenants.Remove(tenant);
        await _dbContext.SaveChangesAsync();
        return true;
    }

    private static TenantDto MapTenant(Tenant tenant)
    {
        return new TenantDto(tenant.Id, tenant.Name, tenant.Domains, tenant.Status);
    }
}
