using Contracts.BindingModels;
using Contracts.SearchModels;
using Contracts.ViewModels;
using DataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DatabaseImplement.Models
{
    public class User : IUser
    {
        public Guid Id { get; set; }

        [Required]
        public string FirstName { get; set; } = string.Empty;

        [Required]
        public string SecondName { get; set; } = string.Empty;

        [Required]
        public string PasswordHash { get; set; } = string.Empty;

        [Required]
        public string Email { get; set; } = string.Empty;

        [Required]
        public DateTime Birthday { get; set; }

        public Role? Role { get; set; }

        public bool OnlyImportantMails { get; set; } = false;

        public UserBindingModel GetBindingModel() => new()
        {
            Id = Id,
            FirstName = FirstName,
            SecondName = SecondName,
            Email = Email,
            PasswordHash = PasswordHash,
            Birthday = Birthday,
            OnlyImportantMails = OnlyImportantMails,
            Role = Role?.GetBindingModel() ?? new()
        };

        public static User ToUserFromView(UserViewModel model, Role role) => new()
        {
            Id = model.Id,
            FirstName = model.FirstName,
            SecondName = model.SecondName,
            Email = model.Email,
            Birthday = model.Birthday,
            Role = role
        };

        public static User ToUserFromBinding(UserBindingModel model, Role role) => new()
        {
            Id = model.Id,
            FirstName = model.FirstName,
            SecondName = model.SecondName,
            Email = model.Email,
            PasswordHash = model.PasswordHash,
            Birthday = model.Birthday,
            OnlyImportantMails = model.OnlyImportantMails,
            Role = role
        };

        public void Update(UserBindingModel model, Role role)
        {
            if (model is null)
            {
                throw new ArgumentNullException("Update user: binding model is null");
            }

            Email = model.Email ?? Email;
            FirstName = model.FirstName ?? FirstName;
            SecondName = model.SecondName ?? SecondName;
            PasswordHash = model.PasswordHash ?? PasswordHash;
            Birthday = model.Birthday;
            OnlyImportantMails = model.OnlyImportantMails;
            Role = role ?? Role;
        }
    }
}