﻿using GenderPayGap.BusinessLogic.Models.Organisation;
using GenderPayGap.Core;
using GenderPayGap.Core.Models.HttpResultModels;
using GenderPayGap.Database;
using GenderPayGap.Extensions;
using GenderPayGap.WebUI.Classes;
using GenderPayGap.WebUI.Models.Organisation;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace GenderPayGap.WebUI.Controllers
{

    public partial class OrganisationController : BaseController
    {

        [Authorize]
        [HttpGet("~/manage-organisations/{id}")]
        public async Task<IActionResult> ManageOrganisation(string id)
        {
            //Ensure user has completed the registration process
            var checkResult = base.CheckUserRegisteredOk(out User currentUser);
            if (checkResult != null) return checkResult;

            // Decrypt org id
            if (!id.DecryptToId(out long organisationId)) return new HttpBadRequestResult($"Cannot decrypt organisation id {id}");

            // Check the user has permission for this organisation
            var userOrg = currentUser.UserOrganisations.FirstOrDefault(uo => uo.OrganisationId == organisationId);
            if (userOrg == null) return new HttpForbiddenResult($"User {currentUser?.EmailAddress} is not registered for organisation id {organisationId}");

            // clear the stash
            this.ClearStash();

            //Get the current snapshot date
            var currentSnapshotDate = SubmissionService.GetCurrentSnapshotDate(userOrg.Organisation.SectorType);

            //Make sure we have an explicit scope for last and year for organisations new to this year
            if (userOrg.PINConfirmedDate != null && userOrg.Organisation.Created >= currentSnapshotDate)
            {
                var scopeStatus = await ScopeBusinessLogic.GetLatestScopeStatusForSnapshotYearAsync(organisationId, currentSnapshotDate.Year - 1);
                if (!scopeStatus.IsAny(ScopeStatuses.InScope, ScopeStatuses.OutOfScope))
                    return RedirectToAction(nameof(OrganisationController.DeclareScope), "Organisation", new { id });
            }

            // get any associated users for the current org
            var associatedUserOrgs = userOrg.GetAssociatedUsers().ToList();

            // get all editable reports
            List<ReportInfoModel> reportInfos = await SubmissionService.GetAllEditableReportsAsync(userOrg, currentSnapshotDate);

            // build the view model
            var model = new ManageOrganisationModel {
                CurrentUserOrg = userOrg,
                AssociatedUserOrgs = associatedUserOrgs,
                EncCurrentOrgId = Encryption.EncryptQuerystring(organisationId.ToString()),
                ReportInfoModels = reportInfos.OrderBy(r => r.ReportingStartDate).ToList()
            };

            return View(model);
        }

        [Authorize]
        [HttpGet("~/manage-organisations")]
        public IActionResult ManageOrganisations()
        {
            //Clear all the stashes
            this.ClearAllStashes();

            //Remove any previous searches from the cache
            PrivateSectorRepository.ClearSearch();

            //Reset the current reporting organisation
            base.ReportingOrganisation = null;

            //Ensure user has completed the registration process
            var checkResult = base.CheckUserRegisteredOk(out User currentUser);
            if (checkResult != null && base.IsImpersonatingUser == false) return checkResult;

            // check if the user has accepted the privacy statement (unless admin or impersonating)
            if (!base.IsImpersonatingUser && !base.CurrentUser.IsAdministrator())
            {
                var hasReadPrivacy = currentUser.AcceptedPrivacyStatement;
                if (hasReadPrivacy == null || hasReadPrivacy.Value < Global.PrivacyChangedDate) return RedirectToAction(nameof(HomeController.PrivacyPolicy), "Home");
            }

            //If there is a pending organisation next organisations awaiting fasttrack registration
            if (!string.IsNullOrWhiteSpace(base.PendingFasttrackCodes)) return RedirectToAction(nameof(RegisterController.EnterFasttrackCodes), "Register");

            //create the new view model 
            var model = currentUser.UserOrganisations.OrderBy(uo => uo.Organisation.OrganisationName);
            return View(nameof(OrganisationController.ManageOrganisations), model);
        }

    }

}