using System;
using System.Collections.Generic;
using System.Data.Entity.Infrastructure;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using InventoryTraker.Web.Core;
using InventoryTraker.Web.Data;
using InventoryTraker.Web.Services;
using InventoryTraker.Web.Utilities;
using NLog;

namespace InventoryTraker.Web.Controllers
{
	public class ImportController : ApiController
	{
		private readonly AppDbContext _context;
		private readonly InventoryImporter _inventoryImporter;

		public ImportController(AppDbContext context, InventoryImporter inventoryImporter)
		{
			_context = context;
			_inventoryImporter = inventoryImporter;
		}

		[HttpPost]
		public async Task<HttpResponseMessage> Upload()
		{
			if (!Request.Content.IsMimeMultipartContent())
				return Request.CreateResponse(HttpStatusCode.UnsupportedMediaType);

			var provider = GetMultipartProvider();
			var result = await Request.Content.ReadAsMultipartAsync(provider);

			// uploadedFileInfo object will give you some additional stuff like file length,
			// creation time, directory name, a few filesystem methods etc..
			var uploadedFileInfo = new FileInfo(result.FileData.First().LocalFileName);

			IEnumerable<Inventory> inventories;
			try
			{
				inventories = _inventoryImporter.Import(uploadedFileInfo);
			}
			catch (ImportException e)
			{
				LogManager.GetCurrentClassLogger().Info("Import Exception : {0}", e.Message);
				return Request.CreateResponse(HttpStatusCode.BadRequest, e.Messages);
			}

			foreach (var inventory in inventories)
			{
				_context.Inventories.Add(inventory);
				inventory.Transactions = ModelHelper.GetAddedTransaction(inventory.AddedDate);
			}
			try
			{
				_context.SaveChanges();
			}
			catch (Exception e)
			{
				var message = ModelHelper.GetUpdateExceptionMessage(e);

				LogManager.GetCurrentClassLogger().Info("Import Exception : {0}", message);
				return Request.CreateResponse(HttpStatusCode.BadRequest, message);
			}

			return Request.CreateResponse(HttpStatusCode.OK, new {});
		}

		private MultipartFormDataStreamProvider GetMultipartProvider()
		{
			var uploadFolder = "~/App_Data/Tmp/FileUploads";
			var root = HttpContext.Current.Server.MapPath(uploadFolder);
			Directory.CreateDirectory(root);
			return new MultipartFormDataExentisionStreamProvider(root);
		}

		// http://stackoverflow.com/questions/16800820/asp-net-webapi-file-upload-using-guid-and-file-extension
		private class MultipartFormDataExentisionStreamProvider 
			: MultipartFormDataStreamProvider
		{
			public MultipartFormDataExentisionStreamProvider(string rootPath) : base(rootPath)
			{
			}

			public override string GetLocalFileName(HttpContentHeaders headers)
			{
				// override the filename which is stored by the provider (by default is bodypart_x)
				var oldfileName = headers.ContentDisposition.FileName.Replace("\"", string.Empty);
				var newFileName = Guid.NewGuid() + Path.GetExtension(oldfileName);

				return newFileName;
			}
		}
	}
}