using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using AutoMapper.QueryableExtensions;
using InventoryTraker.Web.Core;
using InventoryTraker.Web.Data;
using InventoryTraker.Web.Models;

namespace InventoryTraker.Web.Controllers
{
	public class TransactionController : ControllerBase
	{
		private readonly AppDbContext _context;

		public TransactionController(AppDbContext context)
		{
			_context = context;
		}

		public ActionResult Index()
		{
			return View();
		}

		public JsonResult All()
		{
			var viewModels =
				_context.Transactions
				.ProjectTo<TransactionViewModel>()
				.ToArray();

			return BetterJson(viewModels);
		}

		public JsonResult Get(int? pageNumber, int? pageSize, int? inventoryId)
		{
			IQueryable<Transaction> query =
				_context.Transactions
				.OrderByDescending(t => t.Timestamp);

			if (inventoryId.HasValue)
				query = 
					query.Where(t => t.Inventory.Id == inventoryId.Value);

			if (pageNumber.HasValue && pageSize.HasValue)
				query = query
				.Skip((pageNumber.Value - 1) * pageSize.Value)
				.Take(pageSize.Value);
			
			var totalItems = _context.Transactions.Count();
			var transactions = query
						.ProjectTo<TransactionViewModel>()
						.ToArray();
			return BetterJson(new { totalItems, transactions });
		}

		public JsonResult Delete(int transactionId)
		{
			var transaction = _context.Transactions.Find(transactionId);

			if (transaction == null)
				return GetErrorListJson("Transaction not found");

			var inventory = transaction.Inventory;
			var inventoryId = inventory.Id;

			var inventoryTransactionsMostRecent =
				inventory
					.Transactions.OrderByDescending(t => t.TransactionDate)
					.First() == transaction;
			
			if (!inventoryTransactionsMostRecent)
				return GetErrorListJson("Delete permitted only when transaction is the most recent");

			// roll back that transaction
			inventory.Quantity -= transaction.AddedQuantity;
			inventory.Quantity += transaction.RemovedQuantity;

			inventory.Transactions.Remove(transaction);
			_context.Transactions.Remove(transaction);

			if (!inventory.Transactions.Any())
				_context.Inventories.Remove(inventory);

			_context.SaveChanges();

			return BetterJson(new { inventoryId});
		}
	}
}