using System;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using LeafWeb.Core.Entities;
using LeafWeb.Web.Attributes;
using LeafWeb.Web.ViewModels;
using LeafWeb.Web.ViewModels.LeafInput;

namespace LeafWeb.Web.Controllers
{
	public class LeafInputController : ControllerBase
	{
		public ActionResult Index()
		{
			// initialize the session storage to retain SessionID between requests
			Session["placeholder"] = 0;
			var viewModel = new CreateViewModel();
			HydrateCreateViewModel(viewModel);
			return View(viewModel);
		}

		[HttpParamAction]
		[HttpPost]
		public ActionResult Index(CreateViewModel viewModel)
		{
			// directory name is the sessionID
			var files = GetBackloadDirectoryFiles(Session.SessionID);

			if (!files.Any())
				ModelState.AddModelError("Files", "Must select at least one file");

			if (ModelState.IsValid && !IsHttpParamActionMatch()) // HttpParamMatch indicates it's backing out from Confirm
			{
				// Go to confirmation
				var confirmViewModel = new ConfirmViewModel(viewModel, files.Select(f => f.Name).ToArray());
				HydrateCreateViewModel(confirmViewModel);

				return View("Confirm", confirmViewModel);
			}

			HydrateCreateViewModel(viewModel);
			return View("Index", viewModel);
		}

		private void HydrateCreateViewModel(dynamic viewModel)
		{
			if (viewModel.PhotosynthesisType == null)
				viewModel.PhotosynthesisType = new SelectListViewModel();
			if (viewModel.PhotosynthesisType.ListItems == null)
				viewModel.PhotosynthesisType.ListItems = GetPhotosynthesisTypeSelectList();
		}

		[HttpParamAction]
		[HttpPost]
		public ActionResult Confirm(CreateViewModel viewModel)
		{
			// directory name is the sessionID
			var files = GetBackloadDirectoryFiles(Session.SessionID);

			if (!files.Any())
			{
				ModelState.AddModelError("Files", "Must select at least one file");
			}

			if (ModelState.IsValid)
			{
				// convert viewModel into Model
				var leafInput = viewModel.GetFileInput(DataService);
				// load files into LeafInputFile
				leafInput.LeafInputFiles =
					(from f in files
					let bytes = System.IO.File.ReadAllBytes(f.FullName)
					select new LeafInputFile {Filename = f.Name, Contents = bytes}).ToList();

				// Save to db
				DataService.AddLeafInput(leafInput);

				DeleteBackloadDirectory(Session.SessionID);
			
				SetStatusMessage(
					HttpUtility.HtmlEncode(
					$"A data set has submitted for '{viewModel.Identifier}' from '{viewModel.SiteId}'. " + Environment.NewLine
					+ $"When complete, an email will be delivered to {viewModel.Name} <{viewModel.Email}> with results."),
					StatusType.Success);
				return RedirectToAction("Index");
			}

			HydrateCreateViewModel(viewModel);
			return View("Index", viewModel);
		}

		private FileInfo[] GetBackloadDirectoryFiles(string directoryName)
		{
			var path = Path.Combine(Server.MapPath("~/Files/"), directoryName + "\\");
			var directory = new DirectoryInfo(path);
			return
				!directory.Exists
				? new FileInfo[] { }
				: directory.GetFiles();
		}

		private void DeleteBackloadDirectory(string directoryName)
		{
			var path = Path.Combine(Server.MapPath("~/Files/"), directoryName + "\\");
			var directory = new DirectoryInfo(path);
			if (directory.Exists)
				directory.Delete(true);
		}
	}
}