using AspNetCore.Identity.MongoDbCore.Models;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDbGenericRepository.Attributes;
using System.Text.Json.Serialization;

namespace Insight.Infrastructure.Entities
{
    [CollectionName("user"), BsonIgnoreExtraElements]
    public class InsightUser : MongoIdentityUser<ObjectId>
    {
        public InsightUser() : base() { }

        public InsightUser(string userName, string email) : base(userName, email) { }

        [JsonPropertyName("refresh_tokens")]
        public List<RefreshToken>? RefreshTokens { get; set; }
    }

    [BsonIgnoreExtraElements]
    public class InsightUserLogEntity
    {
        [BsonId, BsonRepresentation(BsonType.ObjectId), JsonPropertyName("id")]
        public string? Id { get; set; }

        [BsonElement("_user"), BsonRepresentation(BsonType.ObjectId), JsonPropertyName("user")]
        public string? User { get; set; }

        [BsonElement("insert")]
        public DateTime? Insert { get; set; }

        [BsonElement("timestamp")]
        public DateTime? Timestamp { get; set; }

        [BsonElement("message")]
        public string? Message { get; set; }
    }

    [CollectionName("user_pref"), BsonIgnoreExtraElements]
    public class InsightUserPreferences
    {
        [BsonId, BsonRepresentation(BsonType.ObjectId), JsonPropertyName("id")]
        public string? Id { get; set; }

        [BsonElement("_user"), BsonRepresentation(BsonType.ObjectId), JsonPropertyName("user")]
        public string? User { get; set; }

        [BsonElement("insert")]
        public DateTime? Insert { get; set; }

        [BsonElement("update")]
        public DateTime? Update { get; set; }

        [BsonElement("darkmode")]
        public bool DarkMode { get; set; }
    }

    [CollectionName("role")]
    public class InsightRole : MongoIdentityRole<ObjectId>
    {
        public InsightRole() : base() { }

        public InsightRole(string roleName) : base(roleName) { }
    }

    [BsonIgnoreExtraElements]
    public class RefreshToken
    {
        [BsonElement("token")]
        public string? Token { get; set; }

        [BsonElement("created")]
        public DateTime Created { get; set; }

        [BsonElement("created_ip")]
        public string? CreatedByIp { get; set; }

        [BsonElement("expires")]
        public DateTime Expires { get; set; }

        [BsonElement("revoked")]
        public DateTime? Revoked { get; set; }

        [BsonElement("revoked_ip")]
        public string? RevokedByIp { get; set; }

        [BsonElement("revoked_reason")]
        public string? ReasonRevoked { get; set; }

        [BsonIgnore, JsonIgnore]
        public bool IsExpired => DateTime.Now >= Expires.ToLocalTime();

        [BsonIgnore, JsonIgnore]
        public bool IsRevoked => Revoked != null;

        [BsonIgnore, JsonIgnore]
        public bool IsActive => !IsRevoked && !IsExpired;
    }
}