using AutoMapper;
using Infrastructure.Interfaces;
using Infrastructure.Models;
using Infrastructure.Services;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Web.Mvc;
using TestCasePlanner.Helpers;
using TestCasePlanner.ViewModels;

namespace TestCasePlanner.Controllers
{
    [RoutePrefix("manage/projects"), Route("{action=index}")]
    public class ProjectController : AppBaseController
    {       
        public ProjectController() : this(new TestProjectService())
        {
        }

        public ProjectController(ITestProjectService testProjectService)
        {
            _testProjectService = testProjectService;
        }

        public ITestProjectService _testProjectService { get; private set; }


        // GET: /manage/projects
        public ActionResult Index(ReturnedMessage? message)
        {
            ViewBag.StatusMessage = AlertHelper.Process(message);

            return View(Mapper.Map<IEnumerable<TestProject>, IEnumerable<EditTestProjectViewModel>>(_testProjectService.ListTestProjects()));
        }


        // GET: /manage/projects/details/1
        [Route("details/{id}")]
        public async Task<ActionResult> Details(int id)
        {
            var model = Mapper.Map<TestProject, EditTestProjectViewModel>(await _testProjectService.GetTestProject(id));

            if (model == null) return HttpNotFound();

            return View(model);
        }


        // GET: /manage/projects/new
        public ActionResult New()
        {
            return View();
        }


        // POST: manage/projects/new
        [HttpPost, ValidateAntiForgeryToken]
        public async Task<ActionResult> New(NewTestProjectViewModel model)
        {
            if (!ModelState.IsValid) return View(model);

            await _testProjectService.CreateTestProject(Mapper.Map<NewTestProjectViewModel, TestProject>(model));

            return RedirectToAction("Index");
        }


        // GET: /manage/projects/edit/5
        [Route("edit/{id}")]
        public async Task<ActionResult> Edit(int id)
        {
            var model = Mapper.Map<TestProject, EditTestProjectViewModel>(await _testProjectService.GetTestProject(id));

            if (model == null) return HttpNotFound();

            return View(model);
        }


        // POST: manage/projects/edit/5
        [HttpPost, ValidateAntiForgeryToken, Route("edit/{id}")]
        public async Task<ActionResult> Edit(EditTestProjectViewModel testProject)
        {
            if (!ModelState.IsValid) return View(testProject);

            await _testProjectService.EditTestProject(Mapper.Map<EditTestProjectViewModel, TestProject>(testProject));
            
            return RedirectToAction("Index");
        }


        // GET: /manage/projects/delete/5
        [Route("delete/{id}")]
        public async Task<ActionResult> Delete(int id)
        {
            if (_testProjectService.Project.ID == id) // active project cannot be deleted
            {
                return RedirectToAction("Index", new { message = ReturnedMessage.ActiveProjectDeleteFailure });
            }

            var model = Mapper.Map<TestProject, EditTestProjectViewModel>(await _testProjectService.GetTestProject(id));

            if (model == null) return HttpNotFound();

            return View(model);
        }


        // POST: /manage/projects/delete/5
        [HttpPost, Route("delete/{id}"), ValidateAntiForgeryToken, ActionName("Delete")]
        public async Task<ActionResult> DeleteConfirmed(int id)
        {
            await _testProjectService.DeleteTestProject(await _testProjectService.GetTestProject(id));

            return RedirectToAction("Index", new { message = ReturnedMessage.ProjectDeleteSuccess });
        }


        // POST: to validate project name dynamically
        [HttpPost]
        public JsonResult DoesProjectNameExist(string name, int? id)
        {
            return Json(_testProjectService.VerifyProjectName(name, id));
        }
    }
}