using DressAtelierContracts.BindingModels;
using DressAtelierContracts.SearchModels;
using DressAtelierContracts.StorageContracts;
using DressAtelierContracts.ViewModels;
using DressAtelierDatabaseImplementation.Models;
using DressAtelierDataModels.Enums;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace DressAtelierDatabaseImplementation.Implements
{
    public class OrderStorage : IOrderStorage
    {
        public List<OrderViewModel> GetFullList()
        {
            using var context = new DressAtelierDatabase();
            return context.Orders.Include(x => x.Dress).Include(x => x.Client).Include(x => x.Employee).Select(x => x.GetViewModel).ToList(); 
        }
        public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
        {
            if (!model.ID.HasValue && !model.DateFrom.HasValue && !model.DateTo.HasValue && !model.ClientID.HasValue && !model.Status.HasValue)
            {
                return new();
            }
            using var context = new DressAtelierDatabase();
            if(model.ClientID.HasValue)
            {
                return context.Orders.Include(x => x.Dress).Include(x => x.Client).Include(x => x.Employee).Where(x => x.ClientID == model.ClientID).Select(x => x.GetViewModel).ToList();
            }

            if(model.ID.HasValue)
            {
                return context.Orders.Include(x => x.Dress).Include(x => x.Client).Include(x => x.Employee).Where(x => x.ID == model.ID).Select(x => x.GetViewModel).ToList();
            }

            if(model.DateFrom.HasValue && model.DateTo.HasValue)
            {
                return context.Orders.Include(x => x.Dress).Include(x => x.Client).Include(x => x.Employee).Where(x => model.DateFrom >= x.DateCreate && model.DateTo <= x.DateCreate).Select(x => x.GetViewModel).ToList();
            }

            return context.Orders.Include(x => x.Dress).Include(x => x.Client).Include(x => x.Employee).Where(x => x.Status.Equals(model.Status)).ToList().Select(x => x.GetViewModel).ToList();
        }

        public OrderViewModel? GetElement(OrderSearchModel model)
        {
            if (!model.ID.HasValue && (!model.EmployeeID.HasValue || !model.Status.HasValue))
            {
                return null;
            }

            using var context = new DressAtelierDatabase();

            if(model.ID.HasValue)
            {
                return context.Orders.Include(x => x.Dress).Include(x => x.Client).Include(x => x.Employee).FirstOrDefault(x => x.ID == model.ID)?.GetViewModel;
            }

            return context.Orders.Include(x => x.Dress).Include(x => x.Client).Include(x => x.Employee).FirstOrDefault(x => x.EmployeeID == model.EmployeeID && x.Status == model.Status)?.GetViewModel;
            
        }

        public OrderViewModel? Insert(OrderBindingModel model)
        {
            using var context = new DressAtelierDatabase();
            var newOrder = Order.Create(model);
            if (newOrder == null)
            {
                return null;
            }
            context.Orders.Add(newOrder);
            context.SaveChanges();
            return context.Orders.Include(x => x.Dress).Include(x => x.Client).FirstOrDefault(x => x.ID == newOrder.ID)?.GetViewModel;
        }

        public OrderViewModel? Update(OrderBindingModel model)
        {
            using var context = new DressAtelierDatabase();
                       
            var order = context.Orders.FirstOrDefault(x => x.ID == model.ID);
            if(order == null)
            {
                return null;
            }
            order.Update(model);
            context.SaveChanges();
            return context.Orders.Include(x => x.Dress).Include(x => x.Client).Include(x => x.Employee).FirstOrDefault(x => x.ID == model.ID)?.GetViewModel; 
        }

        public OrderViewModel? Delete(OrderBindingModel model)
        {
            using var context = new DressAtelierDatabase();
            var order = context.Orders.FirstOrDefault(x => x.ID == model.ID);
            if(order == null)
            {
                return null;
            }
            context.Orders.Remove(order);
            context.SaveChanges();           
            return order.GetViewModel;
        }

    }
}
