<?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_CUSTOMER     = 'customer';
    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_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_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_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_NEWS             = 'view-menu-news';
    const PERMISSION_NEWS_MANAGE                = 'manage-news';
    const PERMISSION_NEWS_ONLY_MANAGE           = 'manage-news-only';
    const PERMISSION_NEWS_CREATE_MANAGE         = 'manage-news-create';
    const PERMISSION_NEWS_EDIT_MANAGE           = 'manage-news-edit';
    const PERMISSION_NEWS_DELETE_MANAGE         = 'manage-news-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_PROJECT             = 'view-menu-project';
    const PERMISSION_PROJECT_MANAGE                = 'manage-project';
    const PERMISSION_PROJECT_ONLY_MANAGE           = 'manage-project-only';
    const PERMISSION_PROJECT_CREATE_MANAGE         = 'manage-project-create';
    const PERMISSION_PROJECT_EDIT_MANAGE           = 'manage-project-edit';
    const PERMISSION_PROJECT_DELETE_MANAGE         = 'manage-project-delete';

    const PERMISSION_VIEW_MENU_CARE             = 'view-menu-care';
    const PERMISSION_CARE_MANAGE                = 'manage-care';
    const PERMISSION_CARE_ONLY_MANAGE           = 'manage-care-only';
    const PERMISSION_CARE_CREATE_MANAGE         = 'manage-care-create';
    const PERMISSION_CARE_EDIT_MANAGE           = 'manage-care-edit';
    const PERMISSION_CARE_DELETE_MANAGE         = 'manage-care-delete';

    const PERMISSION_VIEW_MENU_COUNSELING             = 'view-menu-counseling';
    const PERMISSION_COUNSELING_MANAGE                = 'manage-counseling';
    const PERMISSION_COUNSELING_ONLY_MANAGE           = 'manage-counseling-only';
    const PERMISSION_COUNSELING_CREATE_MANAGE         = 'manage-counseling-create';
    const PERMISSION_COUNSELING_EDIT_MANAGE           = 'manage-counseling-edit';
    const PERMISSION_COUNSELING_DELETE_MANAGE         = 'manage-counseling-delete';

    const PERMISSION_VIEW_MENU_CUSTOMER             = 'view-menu-customer';
    const PERMISSION_CUSTOMER_MANAGE                = 'manage-customer';
    const PERMISSION_CUSTOMER_ONLY_MANAGE           = 'manage-customer-only';
    const PERMISSION_CUSTOMER_CREATE_MANAGE         = 'manage-customer-create';
    const PERMISSION_CUSTOMER_EDIT_MANAGE           = 'manage-customer-edit';
    const PERMISSION_CUSTOMER_DELETE_MANAGE         = 'manage-customer-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_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_NEWS_MANAGE                      = 'manage-dashboard-news';
    const PERMISSION_DASHBOARD_CATEGORY_MANAGE                  = 'manage-dashboard-category';
    const PERMISSION_DASHBOARD_FAQ_MANAGE                       = 'manage-dashboard-faq';
    const PERMISSION_DASHBOARD_CARE_MANAGE                      = 'manage-dashboard-care';
    const PERMISSION_DASHBOARD_COUNSELING_MANAGE                = 'manage-dashboard-counseling';
    const PERMISSION_DASHBOARD_PROJECT_MANAGE                   = 'manage-dashboard-project';
    const PERMISSION_DASHBOARD_CUSTOMER_MANAGE                  = 'manage-dashboard-customer';

    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',
    ];

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