using CarCenterContracts.BindingModels;
using CarCenterContracts.SearchModels;
using CarCenterContracts.StoragesContracts;
using CarCenterContracts.ViewModels;
using CarCenterDataBaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CarCenterDataBaseImplement.Implements
{
    public class AdministratorStorage : IAdministratorStorage
    {
        public List<AdministratorViewModel> GetFullList()
        {
            using var context = new CarCenterDataBase();

            return context.Administrators
                .Select(x => x.GetViewModel)
                .ToList();
        }

        public List<AdministratorViewModel> GetFilteredList(AdministratorSearchModel model)
        {
            if (string.IsNullOrEmpty(model.AdministratorFIO))
            {
                return new();
            }

            using var context = new CarCenterDataBase();

            return context.Administrators
                .Include(x => x.Inspections)
                .Include(x => x.Cars)
                .Include(x => x.Equipments)
                .Where(x => x.AdministratorLogin.Contains(model.AdministratorLogin) && x.AdministratorPassword == model.AdministratorPassword)
                .Select(x => x.GetViewModel)
                .ToList();
        }

        public AdministratorViewModel? GetElement(AdministratorSearchModel model)
        {
            using var context = new CarCenterDataBase();

            if (model.Id.HasValue)
                return context.Administrators
                    .Include(x => x.Inspections)
                    .Include(x => x.Cars)
                    .Include(x => x.Equipments)
                    .FirstOrDefault(x => x.Id == model.Id)?
                    .GetViewModel;

            if (!string.IsNullOrEmpty(model.AdministratorEmail) && !string.IsNullOrEmpty(model.AdministratorPassword))
                return context.Administrators
                    .Include(x => x.Inspections)
                    .Include(x => x.Cars)
                    .Include(x => x.Equipments)
                    .FirstOrDefault(x => x.AdministratorEmail.Equals(model.AdministratorEmail) && x.AdministratorPassword.Equals(model.AdministratorPassword))?
                    .GetViewModel;

            if (!string.IsNullOrEmpty(model.AdministratorEmail))
                return context.Administrators
                    .Include(x => x.Inspections)
                    .Include(x => x.Cars)
                    .Include(x => x.Equipments)
                    .FirstOrDefault(x => x.AdministratorEmail.Equals(model.AdministratorEmail))?
                    .GetViewModel;

            return null;
        }

        public AdministratorViewModel? Insert(AdministratorBindingModel model)
        {
            var newAdministrator = Administrator.Create(model);

            if (newAdministrator == null)
            {
                return null;
            }

            using var context = new CarCenterDataBase();

            context.Administrators.Add(newAdministrator);
            context.SaveChanges();

            return newAdministrator.GetViewModel;
        }

        public AdministratorViewModel? Update(AdministratorBindingModel model)
        {
            using var context = new CarCenterDataBase();

            var administrator = context.Administrators
                .FirstOrDefault(x => x.Id == model.Id);

            if (administrator == null)
            {
                return null;
            }

            administrator.Update(model);
            context.SaveChanges();

            return administrator.GetViewModel;
        }

        public AdministratorViewModel? Delete(AdministratorBindingModel model)
        {
            using var context = new CarCenterDataBase();

            var element = context.Administrators.FirstOrDefault(rec => rec.Id == model.Id);

            if (element != null)
            {
                context.Administrators.Remove(element);
                context.SaveChanges();

                return element.GetViewModel;
            }

            return null;
        }
    }
}
