using System;
using System.Collections.Generic;
using System.Linq;
using Kreta.BusinessLogic.Classes.MobileApi.Common.Enum;

namespace Kreta.BusinessLogic.Classes.MobileApi.Common.Co
{
    public class MobileUser
    {
        const int MinimumIdentifierValue = 1;

        public string InstituteCode { get; }

        public int UserId { get; }

        public int? TutelaryId { get; }

        public int ActualUserId => this.TutelaryId ?? this.UserId;

        public int SchoolYearId { get; }

        public IEnumerable<MobileUserRole> Roles { get; }

        public MobileUser(string instituteCode, int userId, int? tutelaryId, IEnumerable<MobileUserRole> roles, int schoolYearId)
        {
            if (string.IsNullOrWhiteSpace(instituteCode))
            {
                throw new ArgumentException($"{nameof(instituteCode)} cannot be null or whitespace");
            }

            this.InstituteCode = instituteCode;

            if (userId < MinimumIdentifierValue)
            {
                throw new ArgumentException($"{nameof(userId)} must be greater or equal to {MinimumIdentifierValue}");
            }

            this.UserId = userId;

            if (roles == null)
            {
                throw new ArgumentNullException(nameof(roles));
            }

            if (!roles.Any())
            {
                throw new ArgumentException($"User \"{instituteCode}/{userId}\" must have at least one role");
            }

            this.Roles = roles;

            if (tutelaryId != null)
            {
                if (tutelaryId < MinimumIdentifierValue)
                {
                    throw new ArgumentException($"{nameof(tutelaryId)} must be greater or equal to {MinimumIdentifierValue}");
                }

                if (!roles.Contains(MobileUserRole.Tutelary))
                {
                    throw new ArgumentException($"{nameof(roles)} must contain {MobileUserRole.Tutelary} because {nameof(tutelaryId)} is not null");
                }
            }

            this.TutelaryId = tutelaryId;
            this.SchoolYearId = schoolYearId;
        }
    }
}