using Butter.Types;
using Lactose.Configuration;
using Lactose.Models;
using Microsoft.Extensions.Options;
using System.Security.Claims;

namespace Lactose.Services;

public class LactoseAuthService(
    ILogger<LactoseAuthService> logger,
    ITokenService tokenService)
{
    public const int BaseExpirationTime = 10;
    public const int LongExpirationTime = 60;

    public string GenerateAccessToken(User user) => tokenService.GenerateToken(GenerateClaims(user), BaseExpirationTime);

    public string GenerateRefreshToken(User user) {
        var token =tokenService.GenerateToken(LongExpirationTime);
        user.RefreshToken = token;
        user.RefreshTokenExpires = DateTime.Now.AddMinutes(LongExpirationTime);
        return token;
    }

    static ClaimsIdentity GenerateClaims(User user) {
        ClaimsIdentity claims = new ClaimsIdentity();
        claims.AddClaim(new Claim(ClaimTypes.Email, user.Email));
        claims.AddClaim(new Claim(ClaimTypes.Name, user.Username));
        claims.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()));
        claims.AddClaim(new Claim(ClaimTypes.Role, user.AccessLevel.ToString()));
        return claims;
    }
    
    public LactoseAuthenticatedUser? GetUserData(ClaimsPrincipal user) {
        string? id = user.FindFirst(ClaimTypes.NameIdentifier)?.Value;
        if (id == null) return null;
        string? name = user.FindFirst(ClaimTypes.Name)?.Value;
        if(name == null) return null;
        string? email = user.FindFirst(ClaimTypes.Email)?.Value;
        if (email==null) return null;
        string? eAccessLevel = user.FindFirst(ClaimTypes.Role)?.Value;
        if (eAccessLevel == null) return null;
        
        return new LactoseAuthenticatedUser(
            Guid.Parse(id),
            user.FindFirst(ClaimTypes.Name)!.Value,
            email,
            (EAccessLevel)Enum.Parse(typeof(EAccessLevel),eAccessLevel)
        );
    }

    public bool ValidateRefreshToken(User user, string tokenRefreshToken) {
        if (user.RefreshToken != tokenRefreshToken) return false;
        if (user.RefreshTokenExpires < DateTime.Now) return false;
        return true;
    }
}

public sealed class LactoseAuthenticatedUser(Guid id, string username, string email, EAccessLevel accessLevel) {
    public Guid         Id          { get; } = id;
    public string       Username    { get; } = username;
    public string      Email       { get; } = email;
    public EAccessLevel AccessLevel { get; } = accessLevel;
}
    
    
