<?php namespace Tobuli\Services;


use Tobuli\Entities\BillingPlan;

class PermissionService
{
    const GROUP_ADMIN = 1;
    const GROUP_USER = 2;
    const GROUP_MANAGER = 3;
    const GROUP_DEMO = 4;

    public function getByUser($user)
    {
        $permissions = $this->getList();

        $permissions = $this->applyManagerPermissions($user, $permissions);

        return $this->applyUserRestrictions($user, $permissions);
    }

    public function getByGroupId($group_id)
    {
        $permissions = $this->getList();

        $role = $this->getGroupRole($group_id);

        return $this->applyRoleRestrictions($role, $permissions);
    }

    public function getByUserRole()
    {
        return $this->getByGroupId(self::GROUP_USER);
    }

    public function getByManagerRole()
    {
        return $this->getByGroupId(self::GROUP_MANAGER);
    }

    public function group($permissions)
    {
        $grouped = [];

        foreach ($permissions as $key => $val) {
            $parts = explode('.', $key);
            $entity = isset($parts[1]) ? $parts[0] : 'main';

            $grouped[$entity][$key] = $val;
        }

        return $grouped;
    }

    public function getUserDefaults()
    {
        if ( ! settings('main_settings.enable_plans'))
            return settings('main_settings.user_permissions');

        return $this->defaultPlanPermissions();
    }

    public function getGroupDefaults($group_id)
    {
        if ($group_id == self::GROUP_ADMIN)
            return $this->getList();

        return $this->getUserDefaults();
    }

    private function getList()
    {
        $permissions = config('tobuli.permissions');

        if ( ! settings('plugins.additional_installation_fields.status')) {
            unset(
                $permissions['device.installation_date'],
                $permissions['device.sim_activation_date'],
                $permissions['device.sim_expiration_date']
            );
        }

        if (! env('SERVICE_CHECKLISTS', false)) {
            unset($permissions['checklist'],
                $permissions['checklist_activity'],
                $permissions['checklist_template'],
                $permissions['checklist_qr_code'],
                $permissions['checklist_qr_pre_start_only']);
        }

        if (! settings('plugins.call_actions.status')) {
            unset($permissions['call_actions']);
        }

        return $permissions;
    }

    private function applyManagerPermissions($user, $permissions)
    {
        if (is_null($manager = $user->manager))
            return $permissions;

        foreach ($permissions as $permission => $modes) {
            $permissions[$permission]['view'] = $modes['view'] && $manager->perm($permission, 'view');
            $permissions[$permission]['edit'] = $modes['edit'] && $manager->perm($permission, 'edit');
            $permissions[$permission]['remove'] = $modes['remove'] && $manager->perm($permission, 'remove');
        }

        return $permissions;
    }

    private function applyUserRestrictions($user, $permissions)
    {
        $role = $this->getUserRole($user);

        return $this->applyRoleRestrictions($role, $permissions);
    }

    private function applyRoleRestrictions($role, $permissions)
    {
        $restricted_permissions = config("tobuli.restricted_permissions.$role");

        if (is_null($restricted_permissions))
            return $permissions;

        return $this->applyRestrictions($permissions, $restricted_permissions);
    }

    private function applyRestrictions($permissions, $restricted)
    {
        foreach ($restricted as $permission => $modes) {
            foreach ($modes as $key => $value)
                $permissions[$permission][$key] = $permissions[$permission][$key] && $value;
        }

        return $permissions;
    }

    private function getUserRole($user)
    {
        return $this->getGroupRole($user->group_id);
    }

    private function getGroupRole($group_id)
    {
        switch ($group_id) {
            case self::GROUP_ADMIN:
                $role = 'admin';
                break;
            case self::GROUP_USER:
                $role = 'user';
                break;
            case self::GROUP_MANAGER:
                $role = 'manager';
                break;
            case self::GROUP_DEMO:
                $role = 'demo';
                break;
            default:
                throw new \Exception('User group not found!');
                break;
        }

        return $role;
    }

    private function defaultPlanPermissions()
    {
        $plan = BillingPlan::find(settings('main_settings.default_billing_plan'));

        return $plan->getPermissions();
    }
}