using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using AyCode.Interfaces.Profiles;
using AyCode.Interfaces.Users;
using AyCode.Interfaces.Addresses;
using AyCode.Interfaces.ServiceProviders;

//- szétszedni az UserToServiceProvider és UserToProduct mapping list-eket külön interface-re
//- külön interface-ek az entity foreignId -khoz! pl: IUserForeignKey, IProductForeignKey, stb...
//- ModelDto Initialize(...)
namespace AyCode.Entities.Users
{
    [Table("Users")]
    public abstract class AcUser<TProfile, TCompany, TUserToServiceProvider, TProfileAddress>() : IAcUser<TProfile, TCompany, TUserToServiceProvider, TProfileAddress>
        where TProfile : class, IAcProfile<TProfileAddress>
        where TCompany : class, IAcCompanyBase
        where TUserToServiceProvider : class, IAcUserToCompanyBase
        where TProfileAddress : class, IAcAddress
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
        public Guid Id { get; set; }

        [NotMapped]
        [JsonIgnore]
        [Newtonsoft.Json.JsonIgnore]
        public string? FullName => Profile.FullName;

        [Required, Column("Email")]
        public string EmailAddress { get; set; }
        //public string NormalizedEmail { get; set; }
        public string? PhoneNumber { get; set; }
        public string Password { get; set; }
        public string? RefreshToken { get; set; }
        
        public bool EmailConfirmed { get; set; }

        [Required]
        public Guid AffiliateId { get; set; } = Guid.NewGuid();
        public Guid? RefferalId { get; set; }

        [Required]
        public Guid ProfileId { get; set; }
        [ForeignKey(nameof(ProfileId))]
        public virtual TProfile Profile { get; set; }

        //[NotMapped]
        public virtual List<TCompany> ServiceProviders { get; set; }
        public virtual List<TUserToServiceProvider> UserToServiceProviders { get; set; }

        public DateTime Created { get; set; }
        public DateTime Modified { get; set; }


        protected AcUser(string email, string password) : this(Guid.NewGuid(), email, password) { }

        protected AcUser(Guid id, string email, string password) : this()
        {
            Id = id;
            EmailAddress = email;           
            Password = password;
        }

        protected AcUser(string email, string phoneNumber, string password) : this(Guid.NewGuid(), email, phoneNumber, password) { }

        protected AcUser(Guid id, string email, string phoneNumber, string password) : this(id, email, password)
        {
            PhoneNumber = phoneNumber;
        }

        protected AcUser(string email, string phoneNumber, string password, string refreshToken) : this(Guid.NewGuid(), email, phoneNumber, password, refreshToken) { }

        protected AcUser(Guid id, string email, string phoneNumber, string password, string refreshToken) : this(id, email, phoneNumber, password)
        {
            RefreshToken = refreshToken;
        }
    }
}
