using Core.Enumerations;
using DataProviders.Collections;

using Microsoft.AspNetCore.Authorization;
using WeatherForecast.Policies.Abstractions;
using WeatherForecast.Services;

namespace WeatherForecast.Policies;

/// <summary>
/// 
/// </summary>
public class CategoryAuthorizationHandler : AuthorizationHandlerBase<CategoryAuthorizationRequirement> {

  /// <summary>
  /// 
  /// </summary>
  /// <param name="contextAccessor"></param>
  /// <param name="userDataProvider"></param>
  /// <param name="accountService"></param>
  public CategoryAuthorizationHandler(
  IHttpContextAccessor contextAccessor,
  IUserDataProvider userDataProvider,
  IAccountPolicyService accountService
) : base(contextAccessor, userDataProvider, accountService) { }

  /// <summary>
  /// 
  /// </summary>
  /// <param name="context"></param>
  /// <param name="requirement"></param>
  /// <returns></returns>
  protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CategoryAuthorizationRequirement requirement) {

    var user = GetUser(context);
    if (user == null)
      return Task.CompletedTask;

    // Can Admin, Editor, Shop manager
    if ((requirement.Action == CrudActions.Create || requirement.Action == CrudActions.Update)
      && (user.Role != Roles.Admin
      && user.Role != Roles.Editor
      && user.Role != Roles.ShopManager))
      return Task.CompletedTask;

    // Can Admin, Editor, Author, Contributor, Shop manager
    if (requirement.Action == CrudActions.Read
      && (user.Role != Roles.Admin
      && user.Role != Roles.Editor
      && user.Role != Roles.Author
      && user.Role != Roles.Contributor
      && user.Role != Roles.ShopManager))
      return Task.CompletedTask;

    // Can Admin only
    if (requirement.Action == CrudActions.Delete
      && user.Role != Roles.Admin)
      return Task.CompletedTask;

    context.Succeed(requirement);

    return Task.CompletedTask;
  }
}

/// <summary>
/// 
/// </summary>
public class CategoryAuthorizationRequirement : AuthorizationRequirementBase { }
