<?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';

	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_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_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_VIEW_MENU_ARTICLE_CATEGORY             = 'view-menu-articleCategory';
	const PERMISSION_ARTICLE_CATEGORY_MANAGE                = 'manage-articleCategory';
	const PERMISSION_ARTICLE_CATEGORY_ONLY_MANAGE           = 'manage-articleCategory-only';
	const PERMISSION_ARTICLE_CATEGORY_CREATE_MANAGE         = 'manage-articleCategory-create';
	const PERMISSION_ARTICLE_CATEGORY_EDIT_MANAGE           = 'manage-articleCategory-edit';
	const PERMISSION_ARTICLE_CATEGORY_DELETE_MANAGE         = 'manage-articleCategory-delete';

    const PERMISSION_VIEW_MENU_PAGE             = 'view-menu-page';
    const PERMISSION_PAGE_MANAGE                = 'manage-page';
    const PERMISSION_PAGE_ONLY_MANAGE           = 'manage-page-only';
    const PERMISSION_PAGE_CREATE_MANAGE         = 'manage-page-create';
    const PERMISSION_PAGE_EDIT_MANAGE           = 'manage-page-edit';
    const PERMISSION_PAGE_DELETE_MANAGE         = 'manage-page-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_ACCESSORY             = 'view-menu-accessory';
	const PERMISSION_ACCESSORY_MANAGE                = 'manage-accessory';
	const PERMISSION_ACCESSORY_ONLY_MANAGE           = 'manage-accessory-only';
	const PERMISSION_ACCESSORY_CREATE_MANAGE         = 'manage-accessory-create';
	const PERMISSION_ACCESSORY_EDIT_MANAGE           = 'manage-accessory-edit';
	const PERMISSION_ACCESSORY_DELETE_MANAGE         = 'manage-accessory-delete';
	
    const PERMISSION_VIEW_MENU_ACCESSORY_CATEGORY             = 'view-menu-accessory-category';
    const PERMISSION_ACCESSORY_CATEGORY_MANAGE                = 'manage-accessory-category';
    const PERMISSION_ACCESSORY_CATEGORY_ONLY_MANAGE           = 'manage-accessory-category-only';
    const PERMISSION_ACCESSORY_CATEGORY_CREATE_MANAGE         = 'manage-accessory-category-create';
    const PERMISSION_ACCESSORY_CATEGORY_EDIT_MANAGE           = 'manage-accessory-category-edit';
    const PERMISSION_ACCESSORY_CATEGORY_DELETE_MANAGE         = 'manage-accessory-category-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_SHIPPING             = 'view-menu-shipping';
	const PERMISSION_SHIPPING_MANAGE                = 'manage-shipping';
	const PERMISSION_SHIPPING_ONLY_MANAGE           = 'manage-shipping-only';
	const PERMISSION_SHIPPING_CREATE_MANAGE         = 'manage-shipping-create';
	const PERMISSION_SHIPPING_EDIT_MANAGE           = 'manage-shipping-edit';
	const PERMISSION_SHIPPING_DELETE_MANAGE         = 'manage-shipping-delete';
	
	const PERMISSION_VIEW_MENU_TEMPLATE             = 'view-menu-template';
	const PERMISSION_TEMPLATE_MANAGE                = 'manage-template';
	const PERMISSION_TEMPLATE_ONLY_MANAGE           = 'manage-template-only';
	const PERMISSION_TEMPLATE_CREATE_MANAGE         = 'manage-template-create';
	const PERMISSION_TEMPLATE_EDIT_MANAGE           = 'manage-template-edit';
	const PERMISSION_TEMPLATE_DELETE_MANAGE         = 'manage-template-delete';

    const PERMISSION_VIEW_MENU_SCENE             = 'view-menu-scene';
    const PERMISSION_SCENE_MANAGE                = 'manage-scene';
    const PERMISSION_SCENE_ONLY_MANAGE           = 'manage-scene-only';
    const PERMISSION_SCENE_CREATE_MANAGE         = 'manage-scene-create';
    const PERMISSION_SCENE_EDIT_MANAGE           = 'manage-scene-edit';
    const PERMISSION_SCENE_DELETE_MANAGE         = 'manage-scene-delete';

    const PERMISSION_VIEW_MENU_COLOR             = 'view-menu-color';
    const PERMISSION_COLOR_MANAGE                = 'manage-color';
    const PERMISSION_COLOR_ONLY_MANAGE           = 'manage-color-only';
    const PERMISSION_COLOR_CREATE_MANAGE         = 'manage-color-create';
    const PERMISSION_COLOR_EDIT_MANAGE           = 'manage-color-edit';
    const PERMISSION_COLOR_DELETE_MANAGE         = 'manage-color-delete';

    const PERMISSION_VIEW_MENU_CONDITION             = 'view-menu-condition';
    const PERMISSION_CONDITION_MANAGE                = 'manage-condition';
    const PERMISSION_CONDITION_ONLY_MANAGE           = 'manage-condition-only';
    const PERMISSION_CONDITION_CREATE_MANAGE         = 'manage-condition-create';
    const PERMISSION_CONDITION_EDIT_MANAGE           = 'manage-condition-edit';
    const PERMISSION_CONDITION_DELETE_MANAGE         = 'manage-condition-delete';

    const PERMISSION_VIEW_MENU_PAYMENT             = 'view-menu-payment';
    const PERMISSION_PAYMENT_MANAGE                = 'manage-payment';
    const PERMISSION_PAYMENT_ONLY_MANAGE           = 'manage-payment-only';
    const PERMISSION_PAYMENT_CREATE_MANAGE         = 'manage-payment-create';
    const PERMISSION_PAYMENT_EDIT_MANAGE           = 'manage-payment-edit';
    const PERMISSION_PAYMENT_DELETE_MANAGE         = 'manage-payment-delete';

    const PERMISSION_VIEW_MENU_ORDER             = 'view-menu-order';
    const PERMISSION_ORDER_MANAGE                = 'manage-order';
    const PERMISSION_ORDER_ONLY_MANAGE           = 'manage-order-only';
    const PERMISSION_ORDER_CREATE_MANAGE         = 'manage-order-create';
    const PERMISSION_ORDER_EDIT_MANAGE           = 'manage-order-edit';
    const PERMISSION_ORDER_DELETE_MANAGE         = 'manage-order-delete';

    const PERMISSION_VIEW_MENU_PRODUCT             = 'view-menu-product';
    const PERMISSION_PRODUCT_MANAGE                = 'manage-product';
    const PERMISSION_PRODUCT_ONLY_MANAGE           = 'manage-product-only';
    const PERMISSION_PRODUCT_OWNER_MANAGE          = 'manage-product-owner';
    const PERMISSION_PRODUCT_CREATE_MANAGE         = 'manage-product-create';
    const PERMISSION_PRODUCT_EDIT_MANAGE           = 'manage-product-edit';
    const PERMISSION_PRODUCT_DELETE_MANAGE         = 'manage-product-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_QUESTION             = 'view-menu-question';
    const PERMISSION_QUESTION_MANAGE                = 'manage-question';
    const PERMISSION_QUESTION_ONLY_MANAGE           = 'manage-question-only';
    const PERMISSION_QUESTION_CREATE_MANAGE         = 'manage-question-create';
    const PERMISSION_QUESTION_EDIT_MANAGE           = 'manage-question-edit';
    const PERMISSION_QUESTION_DELETE_MANAGE         = 'manage-question-delete';

    const PERMISSION_VIEW_MENU_FAQ             = 'view-menu-faq';
    const PERMISSION_FAQ_MANAGE                = 'manage-faq';
    const PERMISSION_FAQ_ONLY_MANAGE           = 'manage-faq-only';
    const PERMISSION_FAQ_CREATE_MANAGE         = 'manage-faq-create';
    const PERMISSION_FAQ_EDIT_MANAGE           = 'manage-faq-edit';
    const PERMISSION_FAQ_DELETE_MANAGE         = 'manage-faq-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_ARTICLE_MANAGE                   = 'manage-dashboard-article';
    const PERMISSION_DASHBOARD_ARTICLE_CATEGORY_MANAGE          = 'manage-dashboard-articleCategory';
    const PERMISSION_DASHBOARD_PAGE_MANAGE                      = 'manage-dashboard-page';
    const PERMISSION_DASHBOARD_KEYWORD_MANAGE                   = 'manage-dashboard-keyword';
    const PERMISSION_DASHBOARD_USER_MANAGE                      = 'manage-dashboard-user';
    const PERMISSION_DASHBOARD_CONTACT_MANAGE                   = 'manage-dashboard-contact';
    const PERMISSION_DASHBOARD_SEO_MANAGE                       = 'manage-dashboard-seo';
    const PERMISSION_DASHBOARD_QUESTION_MANAGE                  = 'manage-dashboard-question';
    const PERMISSION_DASHBOARD_CATEGORY_MANAGE                  = 'manage-dashboard-category';
    const PERMISSION_DASHBOARD_ACCESSORY_MANAGE                 = 'manage-dashboard-accessory';
	const PERMISSION_DASHBOARD_ACCESSORY_CATEGORY_MANAGE        = 'manage-dashboard-accessory-category';
    const PERMISSION_DASHBOARD_AREA_MANAGE                  	= 'manage-dashboard-area';
    const PERMISSION_DASHBOARD_SHIPPING_MANAGE                  = 'manage-dashboard-shipping';
    const PERMISSION_DASHBOARD_SCENE_MANAGE                     = 'manage-dashboard-scene';
    const PERMISSION_DASHBOARD_COLOR_MANAGE                     = 'manage-dashboard-color';
    const PERMISSION_DASHBOARD_CONDITION_MANAGE                 = 'manage-dashboard-condition';
    const PERMISSION_DASHBOARD_ORDER_MANAGE                     = 'manage-dashboard-order';
    const PERMISSION_DASHBOARD_PAYMENT_MANAGE                   = 'manage-dashboard-payment';
    const PERMISSION_DASHBOARD_PRODUCT_MANAGE                   = 'manage-dashboard-product';
    const PERMISSION_DASHBOARD_FAQ_MANAGE                       = 'manage-dashboard-faq';
	const PERMISSION_DASHBOARD_TEMPLATE_MANAGE                  = 'manage-dashboard-template';

    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_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-filter',
        'manage-filter',
        'manage-filter-only',
        'manage-filter-create',
        'manage-filter-edit',
        'manage-filter-delete',

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

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

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

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

        'manage-dashboard-care',
        'manage-dashboard-counseling',
        'manage-dashboard-news',
        'manage-dashboard-manufacturer',
    ];

    /**
     * @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 [];
        }
    }
}
