using Modules.User.Domain.Gateways;

namespace Modules.User.Domain.Entities.Account;

public class Session
{
    public Guid Id { get; private set; }
    public string RefreshToken { get; private set; } = default!;

    public ClientInfo ClientInfo { get; private set; } = default!;

    public DateTime ExpiredDate { get; private set; } = default!;

    public Guid AccountId { get; private set; }

    private Session() { }

    public Session(Models.Session model)
    {
        Id = model.Id;
        RefreshToken = model.RefreshToken;
        AccountId = model.AccountId;
        ClientInfo = new(model.ClientInfo);
        ExpiredDate = model.ExpiredDate;
        AccountId = model.AccountId;
    }

    internal static Session Create(Guid accountId, TimeSpan expirationTime, IRefreshTokenGateway gateway, string? userAgent, string? country, string? city)
    {
        return new()
        {
            RefreshToken = gateway.GenerateRefreshToken(),
            ClientInfo = ClientInfo.Create(userAgent, city, country),
            ExpiredDate = DateTime.UtcNow.Add(expirationTime),
            AccountId = accountId,
        };
    }

    internal void SetId(Guid id)
    {
        Id = id;
    }

    internal string UpdateRefreshToken(IRefreshTokenGateway gateway, TimeSpan expirationTime, string? userAgent, string? country, string? city)
    {
        RefreshToken = gateway.GenerateRefreshToken();
        ExpiredDate = DateTime.UtcNow.Add(expirationTime);
        ClientInfo = ClientInfo.Create(userAgent, country, city);
        return RefreshToken;
    }
}