using Microsoft.EntityFrameworkCore;
using WorkClub.Application.Interfaces;
using WorkClub.Domain.Entities;
using WorkClub.Domain.Enums;
using WorkClub.Infrastructure.Data;

namespace WorkClub.Api.Services;

public class MemberSyncService
{
    private readonly AppDbContext _context;
    private readonly ITenantProvider _tenantProvider;

    public MemberSyncService(AppDbContext context, ITenantProvider tenantProvider)
    {
        _context = context;
        _tenantProvider = tenantProvider;
    }

    public async Task EnsureMemberExistsAsync(HttpContext httpContext)
    {
        if (httpContext?.User?.Identity?.IsAuthenticated != true)
        {
            return;
        }

        var externalUserId = httpContext.User.FindFirst("sub")?.Value;
        if (string.IsNullOrEmpty(externalUserId))
        {
            return;
        }

        var tenantId = _tenantProvider.GetTenantId();

        var existingMember = await _context.Members
            .FirstOrDefaultAsync(m => m.ExternalUserId == externalUserId && m.TenantId == tenantId);

        if (existingMember != null)
        {
            return;
        }

        var email = httpContext.User.FindFirst("email")?.Value ?? httpContext.User.FindFirst("preferred_username")?.Value ?? "unknown@example.com";

        // If not found by ExternalUserId, try to find by Email (for seeded users)
        var memberByEmail = await _context.Members
            .FirstOrDefaultAsync(m => m.Email == email && m.TenantId == tenantId);
            
        if (memberByEmail != null)
        {
            // Update the seeded user with the real ExternalUserId
            memberByEmail.ExternalUserId = externalUserId;
            memberByEmail.UpdatedAt = DateTimeOffset.UtcNow;
            await _context.SaveChangesAsync();
            return;
        }

        var name = httpContext.User.FindFirst("name")?.Value ?? email.Split('@')[0];

        var roleClaim = httpContext.User.FindFirst(System.Security.Claims.ClaimTypes.Role)?.Value ?? "Member";
        var clubRole = roleClaim.ToLowerInvariant() switch
        {
            "manager" => ClubRole.Manager,
            "member" => ClubRole.Member,
            "viewer" => ClubRole.Viewer,
            _ => ClubRole.Member
        };

        var club = await _context.Clubs.FirstOrDefaultAsync(c => c.TenantId == tenantId);
        if (club == null)
        {
            return;
        }

        var newMember = new Member
        {
            Id = Guid.NewGuid(),
            TenantId = tenantId,
            ExternalUserId = externalUserId,
            DisplayName = name,
            Email = email,
            Role = clubRole,
            ClubId = club.Id,
            CreatedAt = DateTimeOffset.UtcNow,
            UpdatedAt = DateTimeOffset.UtcNow
        };

        _context.Members.Add(newMember);
        await _context.SaveChangesAsync();
    }
}
