<?php

namespace App\Support;

class PermissionCatalog
{
    public static function actions(): array
    {
        return ['view', 'create', 'update', 'delete'];
    }

    public static function roleSections(): array
    {
        return [
            [
                'resource' => 'dashboard',
                'title' => __('dashboard'),
                'include' => ['dashboard'],
            ],
            [
                'resource' => 'pos',
                'title' => __('pos'),
                'include' => self::collectSubtreeKeys('pos'),
            ],
            [
                'resource' => 'operations.sections.consultations',
                'title' => __('nav.operations').' - '.__('operations.sections.consultations'),
                'include' => ['operations.sections.consultations'],
            ],
            [
                'resource' => 'operations.sections.ads',
                'title' => __('nav.operations').' - '.__('operations.sections.ads'),
                'include' => ['operations.sections.ads'],
            ],
            [
                'resource' => 'operations.sections.custom_app',
                'title' => __('nav.operations').' - '.__('operations.sections.custom_app'),
                'include' => ['operations.sections.custom_app'],
            ],
            [
                'resource' => 'operations.sections.custom_website',
                'title' => __('nav.operations').' - '.__('operations.sections.custom_website'),
                'include' => ['operations.sections.custom_website'],
            ],
            [
                'resource' => 'operations.sections.wordpress',
                'title' => __('nav.operations').' - '.__('operations.sections.wordpress'),
                'include' => ['operations.sections.wordpress'],
            ],
            [
                'resource' => 'operations.sections.domains_emails',
                'title' => __('nav.operations').' - '.__('operations.sections.domains_emails'),
                'include' => ['operations.sections.domains_emails'],
            ],
            [
                'resource' => 'facebook_integration',
                'title' => __('facebook.integration.menu'),
                'include' => ['facebook_integration'],
            ],
            [
                'resource' => 'renewals.software',
                'title' => __('renewals').' - '.__('renewals.software.title'),
                'include' => ['renewals.software'],
            ],
            [
                'resource' => 'renewals.promotion',
                'title' => __('renewals').' - '.__('renewals.promotion.title'),
                'include' => ['renewals.promotion'],
            ],
            [
                'resource' => 'customers',
                'title' => __('customers'),
                'include' => self::collectSubtreeKeys('customers'),
            ],
            [
                'resource' => 'system_assistant',
                'title' => __('system_assistant.menu'),
                'include' => self::collectSubtreeKeys('system_assistant'),
            ],
            [
                'resource' => 'accounts',
                'title' => __('accounts'),
                'include' => self::collectSubtreeKeys('accounts'),
            ],
            [
                'resource' => 'employees',
                'title' => __('employees'),
                'include' => ['employees'],
            ],
            [
                'resource' => 'services',
                'title' => __('services'),
                'include' => self::collectSubtreeKeys('services'),
            ],
            [
                'resource' => 'products.hub',
                'title' => __('products.title'),
                'include' => self::collectSubtreeKeys('products'),
            ],
            [
                'resource' => 'stage_academy',
                'title' => __('nav.stage_academy'),
                'include' => self::collectSubtreeKeys('stage_academy'),
            ],
            [
                'resource' => 'roles',
                'title' => __('roles'),
                'include' => self::collectSubtreeKeys('roles'),
            ],
            [
                'resource' => 'tickets',
                'title' => __('tickets'),
                'include' => ['tickets'],
            ],
            [
                'resource' => 'news',
                'title' => __('news'),
                'include' => ['news'],
            ],
            [
                'resource' => 'settings',
                'title' => __('settings'),
                'include' => self::collectSubtreeKeys('settings'),
            ],
        ];
    }

    public static function expandRoleSectionPermissionKeys(array $selectedPermissionKeys): array
    {
        $sectionMap = self::roleSectionResourceIncludeMap();
        $expanded = [];

        foreach ($selectedPermissionKeys as $permissionKey) {
            $permissionKey = (string) $permissionKey;
            $pos = strrpos($permissionKey, '.');
            if ($pos === false) {
                continue;
            }

            $resourceKey = substr($permissionKey, 0, $pos);
            $action = substr($permissionKey, $pos + 1);

            if (! in_array($action, self::actions(), true)) {
                continue;
            }

            $includeResourceKeys = $sectionMap[$resourceKey] ?? [$resourceKey];
            foreach ($includeResourceKeys as $includeResourceKey) {
                $expanded[] = $includeResourceKey.'.'.$action;
                if ($action !== 'view') {
                    $expanded[] = $includeResourceKey.'.view';
                }
            }
        }

        return array_values(array_unique($expanded));
    }

    public static function selectedRoleSectionPermissionKeys(array $assignedPermissionKeys): array
    {
        $assigned = array_fill_keys(array_values($assignedPermissionKeys), true);
        $sectionMap = self::roleSectionResourceIncludeMap();
        $selected = [];

        foreach ($sectionMap as $sectionResource => $includeResources) {
            foreach (self::actions() as $action) {
                foreach ($includeResources as $includeResource) {
                    if (isset($assigned[$includeResource.'.'.$action])) {
                        $selected[] = $sectionResource.'.'.$action;
                        break;
                    }
                }
            }
        }

        return array_values(array_unique($selected));
    }

    public static function tree(): array
    {
        return [
            [
                'key' => 'dashboard',
            ],
            [
                'key' => 'services',
                'children' => [
                    ['key' => 'services.monthly_subscription_limited'],
                    ['key' => 'services.monthly_subscription_open'],
                    ['key' => 'services.ads_creation'],
                    ['key' => 'services.web_development'],
                    ['key' => 'services.app_development'],
                    ['key' => 'services.domains_emails'],
                    ['key' => 'services.wordpress_templates'],
                    ['key' => 'services.one_time_service'],
                ],
            ],
            [
                'key' => 'pos',
                'children' => [
                    ['key' => 'pos.services'],
                    ['key' => 'pos.products'],
                    [
                        'key' => 'pos.stage_academy',
                        'children' => [
                            ['key' => 'pos.stage_academy.users'],
                            ['key' => 'pos.stage_academy.activations'],
                        ],
                    ],
                ],
            ],
            [
                'key' => 'operations',
                'children' => [
                    ['key' => 'operations.sections.consultations'],
                    ['key' => 'operations.sections.ads'],
                    ['key' => 'operations.sections.custom_app'],
                    ['key' => 'operations.sections.custom_website'],
                    ['key' => 'operations.sections.wordpress'],
                    ['key' => 'operations.sections.domains_emails'],
                    ['key' => 'operations.services'],
                    ['key' => 'operations.products'],
                    ['key' => 'operations.campaigns'],
                    ['key' => 'operations.ads'],
                    ['key' => 'operations.tasks'],
                    [
                        'key' => 'operations.marketing_intelligence',
                        'children' => [
                            ['key' => 'operations.marketing_intelligence.performance_insights'],
                            ['key' => 'operations.marketing_intelligence.optimize_budget'],
                            ['key' => 'operations.marketing_intelligence.client_report'],
                            ['key' => 'operations.marketing_intelligence.suggest_interests'],
                            ['key' => 'operations.marketing_intelligence.suggest_ad_copies'],
                        ],
                    ],
                    ['key' => 'operations.marketing'],
                ],
            ],
            [
                'key' => 'products',
                'children' => [
                    ['key' => 'products.hub'],
                    ['key' => 'products.main_categories'],
                    ['key' => 'products.sub_categories'],
                    [
                        'key' => 'products.details',
                        'children' => [
                            ['key' => 'products.details.colors'],
                            ['key' => 'products.details.sizes'],
                            ['key' => 'products.details.measurements'],
                        ],
                    ],
                    ['key' => 'products.items'],
                    ['key' => 'products.inventory'],
                    ['key' => 'products.delivery'],
                ],
            ],
            [
                'key' => 'stage_academy',
                'children' => [
                    [
                        'key' => 'stage_academy.courses',
                        'children' => [
                            ['key' => 'stage_academy.courses.categories'],
                            ['key' => 'stage_academy.courses.sub_categories'],
                            ['key' => 'stage_academy.courses.items'],
                            ['key' => 'stage_academy.courses.videos'],
                            ['key' => 'stage_academy.courses.questions'],
                        ],
                    ],
                    ['key' => 'stage_academy.users'],
                    ['key' => 'stage_academy.activations'],
                    ['key' => 'stage_academy.trainers'],
                    ['key' => 'stage_academy.institutions'],
                    ['key' => 'stage_academy.banner'],
                    ['key' => 'stage_academy.offers'],
                    ['key' => 'stage_academy.settings'],
                ],
            ],
            [
                'key' => 'customers',
                'children' => [
                    ['key' => 'customers.subscriptions'],
                    ['key' => 'customers.renewals'],
                ],
            ],
            [
                'key' => 'facebook_integration',
            ],
            [
                'key' => 'system_assistant',
                'children' => [
                    ['key' => 'system_assistant.appointments'],
                    ['key' => 'system_assistant.notes_reminders'],
                    ['key' => 'system_assistant.tasks'],
                    ['key' => 'system_assistant.chat'],
                ],
            ],
            [
                'key' => 'accounts',
                'children' => [
                    ['key' => 'accounts.monthly_settlement'],
                    ['key' => 'accounts.expenses'],
                    ['key' => 'accounts.expenses_archives'],
                    ['key' => 'accounts.employee_withdrawals'],
                    ['key' => 'accounts.employee_penalties'],
                    ['key' => 'accounts.penalties'],
                    ['key' => 'accounts.employee_bonuses'],
                    ['key' => 'accounts.boxes'],
                    ['key' => 'accounts.partners'],
                    ['key' => 'accounts.reports'],
                    ['key' => 'accounts.cash_box'],
                    ['key' => 'accounts.online_box'],
                    ['key' => 'accounts.reserve_box'],
                    [
                        'key' => 'accounts.debts',
                        'children' => [
                            ['key' => 'accounts.debts.payments'],
                            ['key' => 'accounts.debts.invoice'],
                        ],
                    ],
                    ['key' => 'accounts.transfers'],
                    [
                        'key' => 'accounts.attendance',
                        'children' => [
                            ['key' => 'accounts.attendance.today'],
                            ['key' => 'accounts.attendance.absences'],
                            ['key' => 'accounts.attendance.time_records'],
                            ['key' => 'accounts.attendance.leaves'],
                            ['key' => 'accounts.attendance.reports'],
                        ],
                    ],
                ],
            ],
            [
                'key' => 'employees',
            ],
            [
                'key' => 'users',
            ],
            [
                'key' => 'news',
            ],
            [
                'key' => 'tickets',
            ],
            [
                'key' => 'settings',
                'children' => [
                    ['key' => 'settings.company_info'],
                    ['key' => 'settings.pos_settings'],
                    ['key' => 'settings.attendance_settings'],
                    ['key' => 'settings.deleted_records'],
                ],
            ],
            [
                'key' => 'profile',
            ],
            [
                'key' => 'roles',
                'children' => [
                    ['key' => 'roles.roles'],
                    ['key' => 'roles.jobs'],
                ],
            ],
            [
                'key' => 'notifications',
            ],
            [
                'key' => 'chat',
                'children' => [
                    ['key' => 'chat.admin'],
                ],
            ],
            [
                'key' => 'renewals',
                'children' => [
                    ['key' => 'renewals.software'],
                    ['key' => 'renewals.promotion'],
                ],
            ],
        ];
    }

    public static function allPermissionKeys(): array
    {
        $resourceKeys = self::collectResourceKeys(self::tree());
        $permissionKeys = [];

        foreach ($resourceKeys as $resourceKey) {
            foreach (self::actions() as $action) {
                $permissionKeys[] = $resourceKey.'.'.$action;
            }
        }

        return $permissionKeys;
    }

    private static function collectResourceKeys(array $tree): array
    {
        $keys = [];

        foreach ($tree as $node) {
            if (! empty($node['key'])) {
                $keys[] = $node['key'];
            }

            if (! empty($node['children']) && is_array($node['children'])) {
                $keys = array_merge($keys, self::collectResourceKeys($node['children']));
            }
        }

        return array_values(array_unique($keys));
    }

    private static function roleSectionResourceIncludeMap(): array
    {
        $map = [];

        foreach (self::roleSections() as $section) {
            $resource = (string) ($section['resource'] ?? '');
            $include = $section['include'] ?? [];
            if ($resource === '' || ! is_array($include) || empty($include)) {
                continue;
            }

            $map[$resource] = array_values(array_unique(array_map('strval', $include)));
        }

        return $map;
    }

    private static function collectSubtreeKeys(string $rootKey): array
    {
        $node = self::findNodeByKey(self::tree(), $rootKey);
        if (! $node) {
            return [$rootKey];
        }

        return self::collectResourceKeys([$node]);
    }

    private static function findNodeByKey(array $tree, string $searchKey): ?array
    {
        foreach ($tree as $node) {
            $key = (string) ($node['key'] ?? '');
            if ($key === $searchKey) {
                return $node;
            }

            $children = $node['children'] ?? [];
            if (! empty($children) && is_array($children)) {
                $found = self::findNodeByKey($children, $searchKey);
                if ($found) {
                    return $found;
                }
            }
        }

        return null;
    }
}
