<?php

namespace App\Support;

use App\Models\Disk;
use App\Models\Pipeline;
use App\Models\Task;
use App\Models\User;

class SectionAccessManager
{
    public function __construct(
        private readonly MenuManager $menuManager
    ) {
    }

    /**
     * @var list<string>
     */
    private const SUPPORTED_ENTITIES = [
        'tasks',
        'pipelines',
        'disks',
        'hr',
        'onec',
        'telephony',
        'messengers',
        'mail',
    ];

    /**
     * @return list<string>
     */
    public static function supportedEntities(): array
    {
        return self::SUPPORTED_ENTITIES;
    }

    public function supports(string $entity): bool
    {
        return in_array($entity, self::SUPPORTED_ENTITIES, true);
    }

    public function canManage(User $user, string $entity): bool
    {
        if (! $this->supports($entity)) {
            return false;
        }

        if (AccessControl::isAdministrator($user)) {
            return true;
        }

        return match ($entity) {
            'tasks' => Task::query()->where('creator_id', $user->id)->exists(),
            'pipelines' => Pipeline::query()->where('creator_id', $user->id)->exists(),
            'disks' => Disk::query()->where('owner_id', $user->id)->exists(),
            'hr' => AccessControl::isAdministrator($user),
            'onec' => AccessControl::isAdministrator($user),
            'telephony' => AccessControl::isAdministrator($user),
            'messengers' => AccessControl::isAdministrator($user),
            'mail' => AccessControl::isAdministrator($user),
            default => false,
        };
    }

    /**
     * @param  array<string, mixed>  $requestedActions
     */
    public function applyPermissions(User $target, string $entity, array $requestedActions): void
    {
        $permissions = is_array($target->permissions) ? $target->permissions : [];
        foreach (array_keys(AccessControl::actions()) as $action) {
            $permissions[AccessControl::permissionKey($entity, $action)] = (bool) ($requestedActions[$action] ?? false);
        }

        $target->forceFill([
            'permissions' => $permissions,
        ])->save();

        $this->menuManager->forgetUserCaches($target->id);
    }
}
