using Contracts.BindingModels;
using Contracts.StorageContracts;
using Contracts.ViewModels;
using DatabaseImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DatabaseImplement.Implements
{
	public class BookStorage:IBookStorage
	{
		public void Delete(BookBindingModel model)
		{
			var context = new LibraryDatabase();
			var book = context.Books.FirstOrDefault(rec => rec.Id == model.Id);
			if (book != null)
			{
				context.Books.Remove(book);
				context.SaveChanges();
			}
			else
			{
				throw new Exception("Книга не найдена");
			}
		}

		public BookViewModel GetElement(BookBindingModel model)
		{
			if (model == null)
			{
				return null;
			}
			using var context = new LibraryDatabase();
			var book = context.Books
					.ToList()
					.FirstOrDefault(rec => rec.Id == model.Id);
			return book != null ? CreateModel(book) : null;
		}

		public List<BookViewModel> GetFilteredList(BookBindingModel model)
		{
			var context = new LibraryDatabase();
			return context.Books
				.Where(book => book.Name.Contains(model.Name) && book.Author.Contains(model.Author))
				.ToList()
				.Select(CreateModel)
				.ToList();
		}

		public List<BookViewModel> GetFullList()
		{
			using (var context = new LibraryDatabase())
			{
				return context.Books
				.ToList()
				.Select(CreateModel)
				.ToList();
			}
		}

		public void Insert(BookBindingModel model)
		{
			var context = new LibraryDatabase();
			var transaction = context.Database.BeginTransaction();
			try
			{
				context.Books.Add(CreateModel(model, new Book()));
				context.SaveChanges();
				transaction.Commit();
			}
			catch
			{
				transaction.Rollback();
				throw;
			}
		}

		public void Update(BookBindingModel model)
		{
			var context = new LibraryDatabase();
			var transaction = context.Database.BeginTransaction();
			try
			{
				var book = context.Books.FirstOrDefault(rec => rec.Id == model.Id);
				if (book == null)
				{
					throw new Exception("Книга не найдена");
				}
				CreateModel(model, book);
				context.SaveChanges();
				transaction.Commit();
			}
			catch
			{
				transaction.Rollback();
				throw;
			}
		}

		private static Book CreateModel(BookBindingModel model, Book book)
		{
			book.Name = model.Name;
			book.PublicationDate = model.PublicationDate;
			book.PicturePath = model.PicturePath;
			book.Author = model.Author;

			return book;
		}

		private BookViewModel CreateModel(Book book)
		{
			return new BookViewModel
			{
				Id = book.Id,
				Name = book.Name,
				Author = book.Author,
				PublicationDate = book.PublicationDate
			};
		}
	}
}