using Infrastructure.DataAccess;
using Infrastructure.Interfaces;
using Infrastructure.Models;
using System;
using System.Web;
using System.Linq;
using System.Threading.Tasks;
using System.Data.Entity;
using System.Collections.Generic;

namespace Infrastructure.Services
{
    public class TestProjectService : ITestProjectService, IDisposable
    {
        private const string CookieName = "TestCasePlanner-SelectedProjectID";

        private readonly AppDbContext _context;

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

        public TestProjectService() : this(new AppDbContext())
        {

        }

        public TestProject Project
        {
            get 
            {
                if (System.Web.HttpContext.Current.Items["ProjectID"] == null)
                {
                    if (HttpContext.Current.Request.Cookies[CookieName] == null)
                    {
                         return _context.TestProjects.First();
                    }
                    else
                    {
                        var projectID = HttpContext.Current.Request.Cookies[CookieName].Value;
                        var projectIDNum = Convert.ToInt32(projectID);
                        var currentProject = _context.TestProjects.Find(projectIDNum);
                        if (currentProject == null)
                        {
                            // TO DO - if there isnt any project in system
                            return null;
                        }
                        else
                        {
                            return currentProject;
                        }
                    }
                }
                else
                {
                    var projectID = System.Web.HttpContext.Current.Items["ProjectID"];
                    var projectIDNum = Convert.ToInt32(projectID);
                    return _context.TestProjects.Find(projectIDNum);
                }
            }
        }

        public void SetProject(int? projectID)
        {
            if (HttpContext.Current.Request.Cookies[CookieName] == null) // project selected for the first time
            {
                // create new cookie
                var projectIDCookie = new HttpCookie(CookieName, projectID.ToString());
                HttpContext.Current.Response.Cookies.Add(projectIDCookie);
            }
            else if (HttpContext.Current.Request.Cookies[CookieName].Value != projectID.ToString()) // project changed
            {
                // create new cookie with updated project ID
                var projectIDCookie = new HttpCookie(CookieName, projectID.ToString());
                HttpContext.Current.Response.Cookies.Set(projectIDCookie);
            }

            // set item for dropdown refresh
            System.Web.HttpContext.Current.Items["ProjectID"] = projectID.ToString();
        }

        public Task CreateTestProject(TestProject project)
        {
            project.ShortName = project.ShortName.ToUpper();
            _context.TestProjects.Add(project);
            return _context.SaveChangesAsync();
        }

        public Task<TestProject> GetTestProject(int projectID)
        {
            return _context.TestProjects.FindAsync(projectID);
        }

        public Task EditTestProject(TestProject project)
        {
            _context.Entry(project).State = EntityState.Modified;
            return _context.SaveChangesAsync();
        }

        public IEnumerable<TestProject> ListTestProjects()
        {
            return _context.TestProjects.ToList();
        }

        public bool VerifyProjectName(string name, int? id)
        {
            var filteredProjectNames = _context.TestProjects.Where(x => x.Name == name);

            if(id == null) // new project is being created
            {
                return filteredProjectNames.Count() == 0;
            }
            else // project is being edited
            {
                return filteredProjectNames.Where(x => x.ID != id).Count() == 0;
            }
        }

        public Task DeleteTestProject(TestProject project)
        {
            // resolve foreign keys
            _context.TestProjects.Remove(project);
            return _context.SaveChangesAsync();
        }

        public async void UpdateExternalIDCounter(int projectID)
        {
            var project = await _context.TestProjects.FindAsync(projectID);
            project.ExternalIDCounter = project.ExternalIDCounter + 1;
            _context.SaveChanges();
        }

        public void Dispose()
        {
            _context.Dispose();
        }
    }
}