
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System.Reflection.Metadata.Ecma335;
using AyCode.Core.Extensions;
using AyCode.Interfaces.Addresses;
using AyCode.Interfaces.Profiles;
using AyCode.Interfaces.Profiles.Dtos;
using AyCode.Interfaces.ServiceProviders;
using AyCode.Interfaces.Users;
using AyCode.Utils.Extensions;

namespace AyCode.Entities.ServiceProviders
{
    [Table("ServiceProviders")]
    public abstract class AcCompany<TUser, TUserToCompany, TProfile, TAddress> : IAcCompany<TUser, TUserToCompany, TProfile, TAddress>
        where TUser : class, IAcUserBase
        where TUserToCompany : class, IAcUserToCompanyBase
        where TProfile : class, IAcProfile<TAddress>
        where TAddress : class, IAcAddress
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
        public Guid Id { get; set; }

        //[Required]
        public Guid? OwnerId { get; set; }

        [Required]
        public Guid ProfileId { get; set; }
        public virtual TProfile Profile { get; set; }

        [Required]
        public string Name { get; set; }

        public double CommissionPercent { get; set; }

        [Required]
        public Guid AffiliateId { get; set; }
        public Guid? ReferralId { get; set; }

        public virtual List<TUser> Users { get; set; } = [];
        public virtual List<TUserToCompany> UserToServiceProviders { get; set; } = [];

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


        protected AcCompany()
        {
        }

        protected AcCompany(string name, Guid? ownerId) : this(Guid.NewGuid(), name, ownerId)
        {
        }

        protected AcCompany(Guid id, string name, Guid? ownerId) : this(id, name, ownerId, Guid.NewGuid())
        {
        }

        protected AcCompany(Guid id, string name, Guid? ownerId, Guid affiliateId, double commissionPercent = 0) : this()
        {
            Id = id;
            Name = name;
            OwnerId = ownerId == Guid.Empty ? null : ownerId;

            AffiliateId = affiliateId;
            CommissionPercent = commissionPercent;
        }

        public void SetProfile(TProfile profile)
        {
            if (profile.Id.IsNullOrEmpty()) profile.Id = Guid.NewGuid();

            Profile = profile;
            ProfileId = profile.Id;
        }

        public bool HasUser(Guid userId)
            => UserToServiceProviders.Any(x => x.UserId == userId);

        public void AddUser(Guid userId, int permissions)
        {
            if (UserToServiceProviders.Any(x => x.UserId == userId))
                return;

            var userToCompany = Activator.CreateInstance<TUserToCompany>();

            userToCompany.Id = Guid.NewGuid();
            userToCompany.UserId = userId;
            userToCompany.ServiceProviderId = Id;
            userToCompany.Permissions = permissions;

            UserToServiceProviders.Add(userToCompany);
        }
    }
}
