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 AuthorStorage:IAuthorStorage
	{
		public void Delete(AuthorBindingModel model)
		{
			var context = new LibraryDatabase();
			var author = context.Authors.FirstOrDefault(rec => rec.Id == model.Id);
			if (author != null)
			{
				context.Authors.Remove(author);
				context.SaveChanges();
			}
			else
			{
				throw new Exception("Автор не найден");
			}
		}

		public AuthorViewModel GetElement(AuthorBindingModel model)
		{
			if (model == null)
			{
				return null;
			}
			using var context = new LibraryDatabase();

			var author = context.Authors
					.ToList()
					.FirstOrDefault(rec => rec.Id == model.Id || rec.FIO == model.FIO);
			return author != null ? CreateModel(author) : null;
		}


		public List<AuthorViewModel> GetFilteredList(AuthorBindingModel model)
		{
			if (model == null)
			{
				return null;
			}
			using var context = new LibraryDatabase();
			return context.Authors
				.Where(rec => rec.FIO.Contains(model.FIO))
				.Select(CreateModel)
				.ToList();
		}

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

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

		public void Update(AuthorBindingModel model)
		{
			var context = new LibraryDatabase();
			var transaction = context.Database.BeginTransaction();
			try
			{
				var author = context.Authors.FirstOrDefault(rec => rec.Id == model.Id);
				if (author == null)
				{
					throw new Exception("Автор не найден");
				}
				CreateModel(model, author);
				context.SaveChanges();
				transaction.Commit();
			}
			catch
			{
				transaction.Rollback();
				throw;
			}
		}

		private static Author CreateModel(AuthorBindingModel model, Author author)
		{
			author.FIO = model.FIO;
			return author;
		}

		private static AuthorViewModel CreateModel(Author author)
		{
			return new AuthorViewModel
			{
				Id = author.Id,
				FIO = author.FIO
			};
		}
	}
}