using Contracts.BindingModels;
using Contracts.SearchModels;
using Contracts.StorageContracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DatabaseImplement.Implements
{
    public class RoleStorage : IRoleStorage
    {
        public RoleBindingModel? Delete(RoleSearchModel model)
        {
            if (model.Id is null)
            {
                return null;
            }

            var context = new Database();
            var role = context.Roles.FirstOrDefault(r => r.Id == model.Id);
            if (role is null)
            {
                return null;
            }

            context.Remove(role);
            context.SaveChanges();
            return role.GetBindingModel();
        }

        public RoleBindingModel? GetElement(RoleSearchModel model)
        {
            if (model.Id is null && string.IsNullOrWhiteSpace(model?.Name))
            {
                return null;
            }
            var context = new Database();
            return context.Roles
                .FirstOrDefault(r => (model.Id.HasValue && r.Id == model.Id)
                    || (!string.IsNullOrWhiteSpace(model.Name) && r.Name.Contains(model.Name)))
                ?.GetBindingModel();
        }

        public IEnumerable<RoleBindingModel> GetList(RoleSearchModel? model)
        {
            var context = new Database();
            if (model is null && string.IsNullOrWhiteSpace(model?.Name))
            {
                return context.Roles.Select(r => r.GetBindingModel());
            }
            if (model.Id is null)
            {
                return [];
            }
            return context.Roles
                .Where(r => (model.Id.HasValue && r.Id == model.Id)
                    || (!string.IsNullOrWhiteSpace(model.Name) && r.Name.Contains(model.Name)))
                .Select(r => r.GetBindingModel());
        }

        public RoleBindingModel? Insert(RoleBindingModel model)
        {
            var context = new Database();
            var newRole = Models.Role.ToRoleFromBinding(model);

            context.Roles.Add(newRole);
            context.SaveChanges();

            return newRole.GetBindingModel();
        }

        public RoleBindingModel? Update(RoleBindingModel model)
        {
            var context = new Database();
            var role = context.Roles.FirstOrDefault(r => r.Id == model.Id);

            if (role is null)
            {
                return null;
            }

            role.Update(model);

            context.SaveChanges();
            return role.GetBindingModel();
        }
    }
}