<?php

namespace App\Support;

class ApiTokenPermissionMatrix
{
    /**
     * @var array<string, string>
     */
    private const MODULES = [
        'tasks' => 'Tasks',
        'deals' => 'Transactions',
        'products' => 'Products',
        'warehouses' => 'Warehouses',
        'hr' => 'HR Service',
        'onec' => '1C Integration',
        'telephony' => 'Telephony',
        'messengers' => 'Messengers',
        'mail' => 'Mail Service',
        'updates' => 'Updates',
        'companies' => 'Companies',
        'contacts' => 'Contacts',
        'projects' => 'Projects',
        'disks' => 'Disk',
    ];

    /**
     * @var array<string, string>
     */
    private const ACTIONS = [
        'read' => 'Reading',
        'create' => 'Creation',
        'update' => 'Change',
        'delete' => 'Removal',
    ];

    /**
     * @return array<string, string>
     */
    public static function modules(): array
    {
        return self::MODULES;
    }

    /**
     * @return array<string, string>
     */
    public static function actions(): array
    {
        return self::ACTIONS;
    }

    public static function ability(string $module, string $action): string
    {
        return "{$module}.{$action}";
    }

    /**
     * @return list<string>
     */
    public static function allAbilities(): array
    {
        $abilities = [];

        foreach (array_keys(self::MODULES) as $module) {
            foreach (array_keys(self::ACTIONS) as $action) {
                $abilities[] = self::ability($module, $action);
            }
        }

        return $abilities;
    }

    /**
     * @param  array<string, mixed>  $input
     * @return list<string>
     */
    public static function abilitiesFromInput(array $input): array
    {
        $abilities = [];

        foreach (array_keys(self::MODULES) as $module) {
            $moduleInput = $input[$module] ?? [];
            if (! is_array($moduleInput)) {
                continue;
            }

            foreach (array_keys(self::ACTIONS) as $action) {
                if (! empty($moduleInput[$action])) {
                    $abilities[] = self::ability($module, $action);
                }
            }
        }

        return $abilities;
    }

    /**
     * @param  array<int, mixed>|null  $abilities
     * @return list<string>
     */
    public static function labelsForToken(?array $abilities): array
    {
        if (! is_array($abilities) || $abilities === []) {
            return [];
        }

        if (in_array('*', $abilities, true)) {
            return ['Full access'];
        }

        $grouped = [];

        foreach (self::MODULES as $module => $moduleLabel) {
            $actionLabels = [];

            foreach (self::ACTIONS as $action => $actionLabel) {
                $ability = self::ability($module, $action);
                if (in_array($ability, $abilities, true)) {
                    $actionLabels[] = mb_strtolower($actionLabel);
                }
            }

            if ($actionLabels !== []) {
                $grouped[] = $moduleLabel.': '.implode(', ', $actionLabels);
            }
        }

        return $grouped;
    }
}
