<?php
/**
 * File Acl.php
 *
 * @author Tuan Duong <bacduong@gmail.com>
 * @package Laravue
 * @version 1.0
 */

namespace App\Laravue;

use Illuminate\Support\Arr;
use Illuminate\Support\Str;

/**
 * Class Acl
 *
 * @package App\Laravue
 */
final class Acl
{
    const ROLE_ADMIN        = 'admin';
    const ROLE_MANAGER      = 'manager';
    const ROLE_EDITOR       = 'editor';
    const ROLE_USER         = 'user';
    const ROLE_VISITOR      = 'visitor';

    const PERMISSION_VIEW_MENU_ELEMENT_UI       = 'view-menu-element-ui';
    const PERMISSION_VIEW_MENU_PERMISSION       = 'view-menu-permission';
    const PERMISSION_VIEW_MENU_COMPONENTS       = 'view-menu-components';
    const PERMISSION_VIEW_MENU_CHARTS           = 'view-menu-charts';
    const PERMISSION_VIEW_MENU_NESTED_ROUTES    = 'view-menu-nested-routes';
    const PERMISSION_VIEW_MENU_TABLE            = 'view-menu-table';
    const PERMISSION_VIEW_MENU_ADMINISTRATOR    = 'view-menu-administrator';
    const PERMISSION_VIEW_MENU_THEME            = 'view-menu-theme';
    const PERMISSION_VIEW_MENU_CLIPBOARD        = 'view-menu-clipboard';
    const PERMISSION_VIEW_MENU_EXCEL            = 'view-menu-excel';
    const PERMISSION_VIEW_MENU_ZIP              = 'view-menu-zip';
    const PERMISSION_VIEW_MENU_PDF              = 'view-menu-pdf';
    const PERMISSION_VIEW_MENU_I18N             = 'view-menu-i18n';
    const PERMISSION_VIEW_MENU_POST             = 'view-menu-post';

    const PERMISSION_PERMISSION_MANAGE          = 'manage-permission';

    const PERMISSION_VIEW_MENU_USER             = 'view-menu-user';
    const PERMISSION_USER_MANAGE                = 'manage-user';
    const PERMISSION_USER_ONLY_MANAGE           = 'manage-user-only';
    const PERMISSION_USER_CREATE_MANAGE         = 'manage-user-create';
    const PERMISSION_USER_EDIT_MANAGE           = 'manage-user-edit';
    const PERMISSION_USER_DELETE_MANAGE         = 'manage-user-delete';
    const PERMISSION_USER_SHOP_MANAGE           = 'manage-user-group';

    const PERMISSION_POST_MANAGE                = 'manage-post';
    const PERMISSION_POST_ONLY_MANAGE           = 'manage-post-only';
    const PERMISSION_POST_CREATE_MANAGE         = 'manage-post-create';
    const PERMISSION_POST_EDIT_MANAGE           = 'manage-post-edit';
    const PERMISSION_POST_DELETE_MANAGE         = 'manage-post-delete';

    /*Topic Roles - Not Used*/
    const PERMISSION_VIEW_MENU_TOPIC             = 'view-menu-topic';
    const PERMISSION_TOPIC_MANAGE                = 'manage-topic';
    const PERMISSION_TOPIC_ONLY_MANAGE           = 'manage-topic-only';
    const PERMISSION_TOPIC_CREATE_MANAGE         = 'manage-topic-create';
    const PERMISSION_TOPIC_EDIT_MANAGE           = 'manage-topic-edit';
    const PERMISSION_TOPIC_DELETE_MANAGE         = 'manage-topic-delete';

    const PERMISSION_VIEW_MENU_COMMENT             = 'view-menu-comment';
    const PERMISSION_COMMENT_MANAGE                = 'manage-comment';
    const PERMISSION_COMMENT_ONLY_MANAGE           = 'manage-comment-only';
    const PERMISSION_COMMENT_CREATE_MANAGE         = 'manage-comment-create';
    const PERMISSION_COMMENT_EDIT_MANAGE           = 'manage-comment-edit';
    const PERMISSION_COMMENT_DELETE_MANAGE         = 'manage-comment-delete';

    const PERMISSION_VIEW_MENU_KEYWORD             = 'view-menu-keyword';
    const PERMISSION_KEYWORD_MANAGE                = 'manage-keyword';
    const PERMISSION_KEYWORD_ONLY_MANAGE           = 'manage-keyword-only';
    const PERMISSION_KEYWORD_CREATE_MANAGE         = 'manage-keyword-create';
    const PERMISSION_KEYWORD_EDIT_MANAGE           = 'manage-keyword-edit';
    const PERMISSION_KEYWORD_DELETE_MANAGE         = 'manage-keyword-delete';

    const PERMISSION_VIEW_MENU_FILTER             = 'view-menu-filter';
    const PERMISSION_FILTER_MANAGE                = 'manage-filter';
    const PERMISSION_FILTER_ONLY_MANAGE           = 'manage-filter-only';
    const PERMISSION_FILTER_CREATE_MANAGE         = 'manage-filter-create';
    const PERMISSION_FILTER_EDIT_MANAGE           = 'manage-filter-edit';
    const PERMISSION_FILTER_DELETE_MANAGE         = 'manage-filter-delete';

    /*import-module-auto-do-not-remove-this-line*/
    /*import-permission*/

	const PERMISSION_VIEW_MENU_HEADER             = 'view-menu-header';
	const PERMISSION_HEADER_MANAGE                = 'manage-header';
	const PERMISSION_HEADER_ONLY_MANAGE           = 'manage-header-only';
	const PERMISSION_HEADER_CREATE_MANAGE         = 'manage-header-create';
	const PERMISSION_HEADER_EDIT_MANAGE           = 'manage-header-edit';
	const PERMISSION_HEADER_DELETE_MANAGE         = 'manage-header-delete';

	const PERMISSION_VIEW_MENU_SEO             = 'view-menu-seo';
	const PERMISSION_SEO_MANAGE                = 'manage-seo';
	const PERMISSION_SEO_ONLY_MANAGE           = 'manage-seo-only';
	const PERMISSION_SEO_CREATE_MANAGE         = 'manage-seo-create';
	const PERMISSION_SEO_EDIT_MANAGE           = 'manage-seo-edit';
	const PERMISSION_SEO_DELETE_MANAGE         = 'manage-seo-delete';

	const PERMISSION_VIEW_MENU_AREA             = 'view-menu-area';
	const PERMISSION_AREA_MANAGE                = 'manage-area';
	const PERMISSION_AREA_ONLY_MANAGE           = 'manage-area-only';
	const PERMISSION_AREA_CREATE_MANAGE         = 'manage-area-create';
	const PERMISSION_AREA_EDIT_MANAGE           = 'manage-area-edit';
	const PERMISSION_AREA_DELETE_MANAGE         = 'manage-area-delete';

	const PERMISSION_VIEW_MENU_SHOP             = 'view-menu-shop';
	const PERMISSION_SHOP_MANAGE                = 'manage-shop';
	const PERMISSION_SHOP_ONLY_MANAGE           = 'manage-shop-only';
	const PERMISSION_SHOP_CREATE_MANAGE         = 'manage-shop-create';
	const PERMISSION_SHOP_EDIT_MANAGE           = 'manage-shop-edit';
	const PERMISSION_SHOP_DELETE_MANAGE         = 'manage-shop-delete';
	const PERMISSION_SHOP_IMPORT_MANAGE         = 'manage-shop-import';
	const PERMISSION_SHOP_CUSTOM_MANAGE         = 'manage-shop-custom';

	const PERMISSION_VIEW_MENU_CONTACT             = 'view-menu-contact';
	const PERMISSION_CONTACT_MANAGE                = 'manage-contact';
	const PERMISSION_CONTACT_ONLY_MANAGE           = 'manage-contact-only';
	const PERMISSION_CONTACT_CREATE_MANAGE         = 'manage-contact-create';
	const PERMISSION_CONTACT_EDIT_MANAGE           = 'manage-contact-edit';
	const PERMISSION_CONTACT_DELETE_MANAGE         = 'manage-contact-delete';

	const PERMISSION_VIEW_MENU_SCHEDULE             = 'view-menu-schedule';
	const PERMISSION_SCHEDULE_MANAGE                = 'manage-schedule';
	const PERMISSION_SCHEDULE_ONLY_MANAGE           = 'manage-schedule-only';
	const PERMISSION_SCHEDULE_CREATE_MANAGE         = 'manage-schedule-create';
	const PERMISSION_SCHEDULE_EDIT_MANAGE           = 'manage-schedule-edit';
	const PERMISSION_SCHEDULE_DELETE_MANAGE         = 'manage-schedule-delete';

	const PERMISSION_VIEW_MENU_CONSULTATION             = 'view-menu-consultation';
	const PERMISSION_CONSULTATION_MANAGE                = 'manage-consultation';
	const PERMISSION_CONSULTATION_ONLY_MANAGE           = 'manage-consultation-only';
	const PERMISSION_CONSULTATION_CREATE_MANAGE         = 'manage-consultation-create';
	const PERMISSION_CONSULTATION_EDIT_MANAGE           = 'manage-consultation-edit';
	const PERMISSION_CONSULTATION_DELETE_MANAGE         = 'manage-consultation-delete';

	const PERMISSION_VIEW_MENU_FORTUNEMETHOD             = 'view-menu-fortunemethod';
	const PERMISSION_FORTUNEMETHOD_MANAGE                = 'manage-fortunemethod';
	const PERMISSION_FORTUNEMETHOD_ONLY_MANAGE           = 'manage-fortunemethod-only';
	const PERMISSION_FORTUNEMETHOD_CREATE_MANAGE         = 'manage-fortunemethod-create';
	const PERMISSION_FORTUNEMETHOD_EDIT_MANAGE           = 'manage-fortunemethod-edit';
	const PERMISSION_FORTUNEMETHOD_DELETE_MANAGE         = 'manage-fortunemethod-delete';

	const PERMISSION_VIEW_MENU_FORTUNETELLER             = 'view-menu-fortuneteller';
	const PERMISSION_FORTUNETELLER_MANAGE                = 'manage-fortuneteller';
	const PERMISSION_FORTUNETELLER_ONLY_MANAGE           = 'manage-fortuneteller-only';
	const PERMISSION_FORTUNETELLER_CREATE_MANAGE         = 'manage-fortuneteller-create';
	const PERMISSION_FORTUNETELLER_EDIT_MANAGE           = 'manage-fortuneteller-edit';
	const PERMISSION_FORTUNETELLER_DELETE_MANAGE         = 'manage-fortuneteller-delete';
	const PERMISSION_FORTUNETELLER_SHOP_MANAGE           = 'manage-fortuneteller-group';
	const PERMISSION_FORTUNETELLER_OWNER_MANAGE          = 'manage-fortuneteller-owner';
	const PERMISSION_FORTUNETELLER_ASSIGN_MANAGE         = 'manage-fortuneteller-assign';

	const PERMISSION_VIEW_MENU_ARTICLE             = 'view-menu-article';
	const PERMISSION_ARTICLE_MANAGE                = 'manage-article';
	const PERMISSION_ARTICLE_ONLY_MANAGE           = 'manage-article-only';
	const PERMISSION_ARTICLE_CREATE_MANAGE         = 'manage-article-create';
	const PERMISSION_ARTICLE_EDIT_MANAGE           = 'manage-article-edit';
	const PERMISSION_ARTICLE_DELETE_MANAGE         = 'manage-article-delete';
    const PERMISSION_ARTICLE_SHOP_MANAGE           = 'manage-article-group';
    const PERMISSION_ARTICLE_OWNER_MANAGE          = 'manage-article-owner';
    const PERMISSION_ARTICLE_STORE_MANAGE          = 'manage-article-store';
    const PERMISSION_ARTICLE_TELLER_MANAGE         = 'manage-article-teller';

    const PERMISSION_VIEW_MENU_FEATURE             = 'view-menu-feature';
    const PERMISSION_FEATURE_MANAGE                = 'manage-feature';
    const PERMISSION_FEATURE_ONLY_MANAGE           = 'manage-feature-only';
    const PERMISSION_FEATURE_CREATE_MANAGE         = 'manage-feature-create';
    const PERMISSION_FEATURE_EDIT_MANAGE           = 'manage-feature-edit';
    const PERMISSION_FEATURE_DELETE_MANAGE         = 'manage-feature-delete';

    const PERMISSION_VIEW_MENU_CATEGORY             = 'view-menu-category';
    const PERMISSION_CATEGORY_MANAGE                = 'manage-category';
    const PERMISSION_CATEGORY_ONLY_MANAGE           = 'manage-category-only';
    const PERMISSION_CATEGORY_CREATE_MANAGE         = 'manage-category-create';
    const PERMISSION_CATEGORY_EDIT_MANAGE           = 'manage-category-edit';
    const PERMISSION_CATEGORY_DELETE_MANAGE         = 'manage-category-delete';

	const PERMISSION_VIEW_MENU_SLIDER             = 'view-menu-slider';
	const PERMISSION_SLIDER_MANAGE                = 'manage-slider';
	const PERMISSION_SLIDER_ONLY_MANAGE           = 'manage-slider-only';
	const PERMISSION_SLIDER_CREATE_MANAGE         = 'manage-slider-create';
	const PERMISSION_SLIDER_EDIT_MANAGE           = 'manage-slider-edit';
	const PERMISSION_SLIDER_DELETE_MANAGE         = 'manage-slider-delete';

	const PERMISSION_VIEW_MENU_MENU             = 'view-menu-menu';
	const PERMISSION_MENU_MANAGE                = 'manage-menu';
	const PERMISSION_MENU_ONLY_MANAGE           = 'manage-menu-only';
	const PERMISSION_MENU_CREATE_MANAGE         = 'manage-menu-create';
	const PERMISSION_MENU_EDIT_MANAGE           = 'manage-menu-edit';
	const PERMISSION_MENU_DELETE_MANAGE         = 'manage-menu-delete';

    const PERMISSION_DASHBOARD_FORTUNETELLER_MANAGE             = 'manage-dashboard-fortuneteller';
    const PERMISSION_DASHBOARD_AREA_MANAGE                      = 'manage-dashboard-area';
    const PERMISSION_DASHBOARD_SHOP_MANAGE                      = 'manage-dashboard-shop';
    const PERMISSION_DASHBOARD_CONSULTATION_MANAGE              = 'manage-dashboard-consultation';
    const PERMISSION_DASHBOARD_METHOD_MANAGE                    = 'manage-dashboard-method';
    const PERMISSION_DASHBOARD_ARTICLE_MANAGE                   = 'manage-dashboard-article';
    const PERMISSION_DASHBOARD_HEADER_MANAGE                    = 'manage-dashboard-header';
    const PERMISSION_DASHBOARD_KEYWORD_MANAGE                   = 'manage-dashboard-keyword';
    const PERMISSION_DASHBOARD_USER_MANAGE                      = 'manage-dashboard-user';
    const PERMISSION_DASHBOARD_SCHEDULE_MANAGE                  = 'manage-dashboard-schedule';
    const PERMISSION_DASHBOARD_CONTACT_MANAGE                   = 'manage-dashboard-contact';
    const PERMISSION_DASHBOARD_SEO_MANAGE                       = 'manage-dashboard-seo';
    const PERMISSION_DASHBOARD_LINK_MANAGE                      = 'manage-dashboard-link';

    const PERMISSION_VIEW_MENU_MEDIA             = 'view-menu-media';
    const PERMISSION_MEDIA_MANAGE                = 'manage-media';
    const PERMISSION_MEDIA_ONLY_MANAGE           = 'manage-media-only';
    const PERMISSION_MEDIA_CREATE_MANAGE         = 'manage-media-create';
    const PERMISSION_MEDIA_EDIT_MANAGE           = 'manage-media-edit';
    const PERMISSION_MEDIA_DELETE_MANAGE         = 'manage-media-delete';

    const PERMISSION_VIEW_MENU_LINK             = 'view-menu-link';
    const PERMISSION_LINK_MANAGE                = 'manage-link';
    const PERMISSION_LINK_ONLY_MANAGE           = 'manage-link-only';
    const PERMISSION_LINK_CREATE_MANAGE         = 'manage-link-create';
    const PERMISSION_LINK_EDIT_MANAGE           = 'manage-link-edit';
    const PERMISSION_LINK_DELETE_MANAGE         = 'manage-link-delete';

	const PERMISSION_VIEW_MENU_SETTING             = 'view-menu-setting';
	const PERMISSION_SETTING_MANAGE                = 'manage-setting';
	const PERMISSION_SETTING_ONLY_MANAGE           = 'manage-setting-only';
	const PERMISSION_SETTING_CREATE_MANAGE         = 'manage-setting-create';
	const PERMISSION_SETTING_EDIT_MANAGE           = 'manage-setting-edit';
	const PERMISSION_SETTING_DELETE_MANAGE         = 'manage-setting-delete';

	const IGNORE_PERMISSIONS = [
        'view-menu-element-ui',
        'view-menu-components',
        'view-menu-charts',
        'view-menu-nested-routes',
        'view-menu-table',
        'view-menu-theme',
        'view-menu-clipboard',
        'view-menu-excel',
        'view-menu-zip',
        'view-menu-pdf',
        'view-menu-i18n',

        'view-menu-post',
        'manage-post',
        'manage-post-only',
        'manage-post-create',
        'manage-post-edit',
        'manage-post-delete',

        'view-menu-topic',
        'manage-topic',
        'manage-topic-only',
        'manage-topic-create',
        'manage-topic-edit',
        'manage-topic-delete',

        'view-menu-comment',
        'manage-comment',
        'manage-comment-only',
        'manage-comment-create',
        'manage-comment-edit',
        'manage-comment-delete',

        /*'view-menu-slider',
        'manage-slider',
        'manage-slider-only',
        'manage-slider-create',
        'manage-slider-edit',
        'manage-slider-delete',*/

        'view-menu-filter',
        'manage-filter',
        'manage-filter-only',
        'manage-filter-create',
        'manage-filter-edit',
        'manage-filter-delete',

        'view-menu-magicwands',
        'manage-magicwands',
        'manage-magicwands-only',
        'manage-magicwands-create',
        'manage-magicwands-edit',
        'manage-magicwands-delete',

        'view-menu-magazine',
        'manage-magazine',
        'manage-magazine-only',
        'manage-magazine-create',
        'manage-magazine-edit',
        'manage-magazine-delete',
        'manage-magazine-group',
        'manage-magazine-owner',
        'manage-dashboard-magazine',

        'manage-feature-owner',
        'manage-feature-group',
        'manage-fortuneteller-hidden',
    ];

    /**
     * @param array $exclusives Exclude some permissions from the list
     * @return array
     */
    public static function permissions(array $exclusives = []): array
    {
        try {
            $class = new \ReflectionClass(__CLASS__);
            $constants = $class->getConstants();
            $ignoreList = $class->getConstant('IGNORE_PERMISSIONS');
            $permissions = Arr::where($constants, function ($value, $key) use ($exclusives, $ignoreList) {
                return !in_array($value, $exclusives) && Str::startsWith($key, 'PERMISSION_') && !in_array($value, $ignoreList);
            });

            return array_values($permissions);
        } catch (\ReflectionException $exception) {
            return [];
        }
    }

    public static function permissionsIgnore(array $exclusives = []): array
    {
        try {
            $class = new \ReflectionClass(__CLASS__);
            return $class->getConstant('IGNORE_PERMISSIONS');
        } catch (\ReflectionException $exception) {
            return [];
        }
    }

    public static function menuPermissions(): array
    {
        try {
            $class = new \ReflectionClass(__CLASS__);
            $constants = $class->getConstants();
            $ignoreList = $class->getConstant('IGNORE_PERMISSIONS');
            $permissions = Arr::where($constants, function ($value, $key) use ($ignoreList) {
                return Str::startsWith($key, 'PERMISSION_VIEW_MENU_') && !in_array($value, $ignoreList);
            });

            return array_values($permissions);
        } catch (\ReflectionException $exception) {
            return [];
        }
    }

    /**
     * @return array
     */
    public static function roles(): array
    {
        try {
            $class = new \ReflectionClass(__CLASS__);
            $constants = $class->getConstants();
            $roles = Arr::where($constants, function ($value, $key) {
                return Str::startsWith($key, 'ROLE_');
            });

            return array_values($roles);
        } catch (\ReflectionException $exception) {
            return [];
        }
    }
}
