<?php

// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedNamespaceFound -- APD is the established namespace shared with the Pro add-on and retained for backward compatibility.
namespace APD\Support;

defined('ABSPATH') || exit;

class Capabilities
{
    public const MANAGE = 'manage_asuka_designer';

    public static function all() : array
    {
        return [
            self::MANAGE,
            'read',
            'edit_posts',
            'upload_files',
            'edit_asuka_product_config',
            'read_asuka_product_config',
            'delete_asuka_product_config',
            'edit_asuka_product_configs',
            'edit_others_asuka_product_configs',
            'publish_asuka_product_configs',
            'read_private_asuka_product_configs',
            'delete_asuka_product_configs',
            'delete_private_asuka_product_configs',
            'delete_published_asuka_product_configs',
            'delete_others_asuka_product_configs',
            'edit_private_asuka_product_configs',
            'edit_published_asuka_product_configs',
            'create_asuka_product_configs',
            'edit_asuka_template',
            'read_asuka_template',
            'delete_asuka_template',
            'edit_asuka_templates',
            'edit_others_asuka_templates',
            'publish_asuka_templates',
            'read_private_asuka_templates',
            'delete_asuka_templates',
            'delete_private_asuka_templates',
            'delete_published_asuka_templates',
            'delete_others_asuka_templates',
            'edit_private_asuka_templates',
            'edit_published_asuka_templates',
            'create_asuka_templates',
            'edit_asuka_user_design',
            'read_asuka_user_design',
            'delete_asuka_user_design',
            'edit_asuka_user_designs',
            'edit_others_asuka_user_designs',
            'publish_asuka_user_designs',
            'read_private_asuka_user_designs',
            'delete_asuka_user_designs',
            'delete_private_asuka_user_designs',
            'delete_published_asuka_user_designs',
            'delete_others_asuka_user_designs',
            'edit_private_asuka_user_designs',
            'edit_published_asuka_user_designs',
            'create_asuka_user_designs',
            'edit_asuka_designs',
            'edit_asuka_colors',
            'edit_asuka_fonts',
            'edit_asuka_pricing_rules',
            'view_asuka_production_data',
        ];
    }

    public static function syncAdministratorCaps() : void
    {
        self::syncRoleCaps('administrator', self::all());
    }

    public static function syncShopManagerCaps() : void
    {
        if (! class_exists('WooCommerce')) {
            return;
        }

        self::syncRoleCaps('shop_manager', [
            self::MANAGE,
            'read',
            'edit_posts',
            'upload_files',
            'edit_asuka_product_configs',
            'create_asuka_product_configs',
            'publish_asuka_product_configs',
            'read_private_asuka_product_configs',
            'edit_published_asuka_product_configs',
            'edit_asuka_product_config',
            'read_asuka_product_config',
            'edit_asuka_templates',
            'create_asuka_templates',
            'publish_asuka_templates',
            'read_private_asuka_templates',
            'edit_published_asuka_templates',
            'edit_asuka_template',
            'read_asuka_template',
            'edit_asuka_user_designs',
            'create_asuka_user_designs',
            'publish_asuka_user_designs',
            'read_private_asuka_user_designs',
            'edit_published_asuka_user_designs',
            'edit_asuka_user_design',
            'read_asuka_user_design',
        ]);
    }

    public static function demo() : array
    {
        return [
            self::MANAGE,
            'read',
            'upload_files',
            'edit_asuka_product_config',
            'read_asuka_product_config',
            'delete_asuka_product_config',
            'edit_asuka_product_configs',
            'publish_asuka_product_configs',
            'delete_asuka_product_configs',
            'delete_published_asuka_product_configs',
            'edit_published_asuka_product_configs',
            'create_asuka_product_configs',
            'edit_asuka_template',
            'read_asuka_template',
            'delete_asuka_template',
            'edit_asuka_templates',
            'publish_asuka_templates',
            'delete_asuka_templates',
            'delete_published_asuka_templates',
            'edit_published_asuka_templates',
            'create_asuka_templates',
            'edit_asuka_designs',
            'edit_asuka_colors',
            'edit_asuka_fonts',
            'edit_asuka_pricing_rules',
            'edit_product',
            'read_product',
            'delete_product',
            'edit_products',
            'publish_products',
            'delete_products',
            'delete_published_products',
            'edit_published_products',
        ];
    }

    public static function syncDemoRole() : void
    {
        $role = get_role('apd_demo_manager');
        if (! $role) {
            add_role(
                'apd_demo_manager',
                __('Asuka demo manager', 'asuka-product-designer'),
                array_fill_keys(self::demo(), true)
            );
            return;
        }

        foreach (self::demo() as $cap) {
            if (! $role->has_cap($cap)) {
                $role->add_cap($cap);
            }
        }

        foreach (array_keys($role->capabilities) as $cap) {
            if (! in_array($cap, self::demo(), true)) {
                $role->remove_cap($cap);
            }
        }
    }

    public static function removeAllRoleCaps() : void
    {
        $pluginCaps = array_values(array_filter(
            self::all(),
            static fn(string $cap) : bool => ! in_array($cap, ['read', 'edit_posts', 'upload_files'], true)
        ));

        self::removeRoleCaps('administrator', $pluginCaps);
        self::removeRoleCaps('shop_manager', $pluginCaps);
    }

    private static function removeRoleCaps(string $roleName, array $caps) : void
    {
        $role = get_role($roleName);

        if (! $role) {
            return;
        }

        foreach ($caps as $cap) {
            $role->remove_cap($cap);
        }
    }

    private static function syncRoleCaps(string $roleName, array $caps) : void
    {
        $role = get_role($roleName);

        if (! $role) {
            return;
        }

        foreach ($caps as $cap) {
            if (! $role->has_cap($cap)) {
                $role->add_cap($cap);
            }
        }
    }
}
