<?php

use \GuzzleHttp\Client;

$app = $this->app;

return [
    'name' => 'system:roles',
    'label' => 'User roles',
    'icon' => 'system:assets/icons/users.svg',
    'fields' => (function() use($app) {

        $roles = [];

        $_roles = $app->dataStorage->find('system/roles', [
            'sort' => ['name' => 1]
        ])->toArray();

        foreach ($_roles as $role) {
            $roles[] = [
                'value' => $role['appid'],
                'label' => $role['name'] ?: $role['appid'],
            ];
        }

        return [
            [
                'name' => 'roles',
                'type' => 'select',
                'info' => 'User roles',
                'opts' => [
                    'options' => $roles,
                    'multiple' => true
                ],
            ],
        ];
    })(),

    'sync:push' => function(array $settings = [], ?array $target = null, ?Client $client = null) {

        $settings = array_merge([
            'syncAll' => true,
            'roles' => []
        ], $settings);

        $roles = $this->dataStorage->find('system/roles', [])->toArray();

        if (!$settings['syncAll']) {
            $roles = array_filter($roles, fn($role) => in_array($role['appid'], $settings['roles']));
        }

        if (!count($roles)) {
            return;
        }

        $payload = [
            'roles' => $roles
        ];

        $this->helper('sync')->log('Pushing user roles...');

        $client->request('POST', 'api/sync/job', [
            'json' => [
                'job' => 'system:roles',
                'mode' => 'push',
                'payload' => $this->helper('jwt')->encode($payload, $target['syncKey'])
            ]
        ]);

        $this->helper('sync')->log("user roles synced...");
    },

    'on:push' => function($payload = null) {

        if (isset($payload['roles']) && is_array($payload['roles'])) {

            foreach ($payload['roles'] as $role) {

                if (isset($role['_id'])) {
                    unset($role['_id']);
                }

                $_role = $this->dataStorage->findOne('system/roles', ['appid' => $role['appid']]);

                if ($_role) {
                    $role['_id'] = $_role['id'];
                    $role['permissions'] = array_merge($_role['permissions'], $role['permissions']);
                }

                $this->dataStorage->save('system/roles', $role);
            }

            $this->helper('acl')->cache();
        }

    },

    'sync:pull' => function(array $settings = [], ?array $target = null, ?Client $client = null) {

        $settings = array_merge([
            'syncAll' => true,
            'roles' => []
        ], $settings);

        if (!$settings['syncAll'] && !count($settings['roles'])) {
            return;
        }

        $this->helper('sync')->log('Pulling user roles...');

        $response = $client->request('POST', 'api/sync/job', [
            'json' => [
                'job' => 'system:roles',
                'mode' => 'pull',
                'payload' => $this->helper('jwt')->encode([
                    'roles' => $settings['syncAll'] ? true : $settings['roles']
                ], $target['syncKey'])
            ]
        ]);

        $payload = json_decode($response->getBody()->getContents(), true);

        if (isset($payload['roles']) && is_array($payload['roles'])) {

            foreach ($payload['roles'] as $role) {

                if (isset($role['_id'])) {
                    unset($role['_id']);
                }

                $_role = $this->dataStorage->findOne('system/roles', ['appid' => $role['appid']]);

                if ($_role) {
                    $role['_id'] = $_role['id'];
                    $role['permissions'] = array_merge($_role['permissions'], $role['permissions']);
                }

                $this->dataStorage->save('system/roles', $role);
            }

            $this->helper('acl')->cache();
        }

        $this->helper('sync')->log('Pulling user roles finished...');
    },

    'on:pull' => function($payload = null) {

        if (isset($payload['roles']) && $payload['roles']) {

            $roles = $this->dataStorage->find('system/roles', [])->toArray();

            if (is_array($payload['roles'])) {
                $roles = array_filter($roles, fn($role) => in_array($role['appid'], $payload['roles']));
            }

            return ['roles' => $roles];
        }
    }
];
