using Coscine.Database.Models;
using Coscine.ApiCommons;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using System;
using System.Linq;
using Coscine.Database.Util;
using System.Collections.Generic;

namespace Coscine.Api.Project.Controllers
{

    /// <summary>
    /// This controller represents the action which can be taken with a subproject object
    /// </summary>
    [Authorize]
    public class SubProjectController : Controller
    {
        private readonly Authenticator _authenticator;
        private readonly SubProjectModel _subProjectModel;

        /// <summary>
        /// SubProjectController specifying a SubProjectModel
        /// </summary>
        public SubProjectController()
        {
            _authenticator = new Authenticator(this, Program.Configuration);
            _subProjectModel = new SubProjectModel();
        }

        /// <summary>
        /// This method gets the Id of the parent
        /// </summary>
        /// <param name="parentId">Id of parent</param>
        /// <returns>Json Object or Statuscode 401</returns>
        [HttpGet("[controller]/{parentId}")]
        public IActionResult Get(string parentId)
        {
            var parentGuid = new Guid(parentId);
            var projectModel = new ProjectModel();
            var projectRoleModel = new ProjectRoleModel();
            var user = _authenticator.GetUser();
            string[] allowedRoles = { UserRoles.Owner, UserRoles.Member };
            allowedRoles = allowedRoles.Select(x => x.ToLower().Trim()).ToArray();
            if (projectModel.HasAccess(user, projectModel.GetById(parentGuid), allowedRoles))
            {
                
                var subProjects = _subProjectModel.GetAllWhere((subProjectM) => (subProjectM.ProjectId == parentGuid
                                                                                 // Corrosponing subproject must exist
                                                                                 && subProjectM.SubProjectNavigation.Deleted == false

                                                                                 // select only subprojects to which the user has access
                                                                                 && (from projectRole in subProjectM.SubProjectNavigation.ProjectRoles
                                                                                     where projectRole.User.Id == user.Id
                                                                                     && allowedRoles.Contains(projectRole.Role.DisplayName.ToLower())
                                                                                     select projectRole).Any())
                                                                                 )
                                                    .Select((subProject) => projectModel.GetById(subProject.SubProjectId))
                                                    .Select((project) => projectModel.CreateReturnObjectFromDatabaseObject(project, parentGuid))
                                                    .OrderBy(element => element.DisplayName);
                return Json(subProjects);
            }
            else
            {
                return Unauthorized("User is not allowed to create a subproject for the given project id!");
            }
        }

        /// <summary>
        /// This method retrieves the accessible Parent
        /// </summary>
        /// <param name="childId">Id of the child</param>
        /// <returns>Json or Statuscode 401</returns>
        [HttpGet("[controller]/{childId}/accessibleParent")]
        public IActionResult GetAccessibleParent(string childId)
        {
            var childGuid = new Guid(childId);
            var projectModel = new ProjectModel();
            var projectRoleModel = new ProjectRoleModel();
            var user = _authenticator.GetUser();
            string[] allowedRoles = { UserRoles.Owner, UserRoles.Member };
            allowedRoles = allowedRoles.Select(x => x.ToLower().Trim()).ToArray();
            if (projectModel.HasAccess(user, projectModel.GetById(childGuid), allowedRoles))
            {
                var subProjects = _subProjectModel.GetAllWhere((subProjectM) => (subProjectM.SubProjectId == childGuid)).ToArray();
                var json = new JObject();
                json["id"] = "00000000-0000-0000-0000-000000000000";
                if (subProjects.Count() == 1 && projectModel.HasAccess(user, projectModel.GetById(subProjects[0].ProjectId), allowedRoles))
                {
                    json["id"] = subProjects[0].ProjectId;
                }
                return Json(json);
            }
            else
            {
                return Unauthorized("User is not allowed to create a subproject for the given project id!");
            }
        }
    }
}