<?php

use \GuzzleHttp\Client;

return [
    'name' => 'layout',
    'label' => 'Layout Components',
    'icon' => 'layout:assets/icons/layout.svg',
    'fields' => (function() use($app) {

        $cfg = [];

        $components = $app->dataStorage->find('layout/components')->toArray();
        $options = [];

        foreach ($components as $component) {

            if (isset($component['core']) && $component['core']) continue;

            $options[] = [
                'value' => $component['name'],
                'label' => isset($component['meta']['label']) && trim($component['meta']['label']) ? $component['meta']['label'] : $component['name'],
            ];
        }

        if (count($options)) {
         
            $cfg[] = [
                'name' => 'components',
                'type' => 'select',
                'info' => 'Custom components',
                'opts' => [
                    'options' => $options,
                    'multiple' => true
                ],
            ];
        }

        $shared = $app->dataStorage->find('layout/components_shared', [
            'sort' => ['name' => 1]
        ])->toArray();

        $options = [];

        foreach ($shared as $component) {

            if (isset($component['core']) && $component['core']) continue;

            $options[] = [
                'value' => $component['_id'],
                'label' => $component['name'],
            ];
        }

        if (count($options)) {
        
            $cfg[] = [
                'name' => 'shared',
                'type' => 'select',
                'info' => 'Shared components',
                'opts' => [
                    'options' => $options,
                    'multiple' => true
                ],
            ];
        }

        $templates = $app->dataStorage->find('layout/templates', [
            'sort' => ['name' => 1]
        ])->toArray();

        $options = [];

        foreach ($templates as $temlate) {

            if (isset($temlate['core']) && $temlate['core']) continue;

            $options[] = [
                'value' => $temlate['_id'],
                'label' => $temlate['name'],
            ];
        }

        if (count($options)) {
        
            $cfg[] = [
                'name' => 'templates',
                'type' => 'select',
                'info' => 'Layout templates',
                'opts' => [
                    'options' => $options,
                    'multiple' => true
                ],
            ];
        }
        
        if (!count($cfg)) {
            return null;
        }

        return $cfg;
    })(),

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

        $settings = array_merge([
            'syncAll' => true,
            'components' => [],
            'shared' => [],
            'templates' => []
        ], $settings);

        $components = $this->dataStorage->find('layout/components', [
            'sort' => ['name' => 1]
        ])->toArray();

        $shared = $this->dataStorage->find('layout/components_shared', [
            'sort' => ['name' => 1]
        ])->toArray();

        $templates = $this->dataStorage->find('layout/templates', [
            'sort' => ['name' => 1]
        ])->toArray();

        if (!$settings['syncAll']) {

            if (!count($settings['components'])) {
                return ['message' => 'no components selected'];
            }

            $components = array_filter($components, function($component) use($settings) {
                return in_array($component['name'], $settings['components']);
            });

            $shared = array_filter($shared, function($component) use($settings) {
                return in_array($component['_id'], $settings['shared'] ?? []);
            });

            $templates = array_filter($templates, function($template) use($settings) {
                return in_array($template['_id'], $settings['templates'] ?? []);
            });
        }

        $payload = [
            'components' => $components,
            'shared' => $shared,
            'templates' => $templates
        ];

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

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

        if (!isset($payload['components'], $payload['shared'], $payload['templates'])) {
            return ['message' => 'no components'];
        }

        $components = $payload['components'] ?? [];
        $shared = $payload['shared'] ?? [];
        $templates = $payload['templates'] ?? [];

        foreach ($components as $component) {

            $this->dataStorage->remove('layout/components', ['$or' => [
                ['_id' => $component['_id']],
                ['name' => $component['name']],
            ]]);

            $this->dataStorage->insert('layout/components', $component);
        }

        foreach ($shared as $component) {

            $this->dataStorage->remove('layout/components_shared', ['$or' => [
                ['_id' => $component['_id']],
                ['name' => $component['name']],
            ]]);

            $this->dataStorage->insert('layout/components_shared', $component);
        }

        foreach ($templates as $template) {

            $this->dataStorage->remove('layout/templates', ['$or' => [
                ['_id' => $template['_id']],
                ['name' => $template['name']],
            ]]);

            $this->dataStorage->insert('layout/templates', $template);
        }
        

        $this->helper('layoutComponents')->cache();

        return ['success' => true];
    },

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

        $settings = array_merge([
            'syncAll' => true,
            'components' => [],
            'shared' => [],
            'templates' => []
        ], $settings);

        $response = $client->request('POST', 'api/sync/job', [
            'json' => [
                'job' => 'layout',
                'mode' => 'pull',
                'payload' => $this->helper('jwt')->encode(['components' => true], $target['syncKey'])
            ]
        ]);

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

        if (!isset($payload['components'], $payload['shared'])) {
            return ['message' => 'no components'];
        }

        $components = $payload['components'] ?? [];
        $shared = $payload['shared'] ?? [];
        $templates = $payload['templates'] ?? [];

        if (!$settings['syncAll']) {

            if (!count($settings['components'])) {
                return ['message' => 'no components selected'];
            }

            $components = array_filter($components, function($component) use($settings) {
                return in_array($component['name'], $settings['components'] ?? []);
            });

            $shared = array_filter($shared, function($component) use($settings) {
                return in_array($component['_id'], $settings['shared'] ?? []);
            });

            $templates = array_filter($templates, function($template) use($settings) {
                return in_array($template['_id'], $settings['templates'] ?? []);
            });
        }

        foreach ($components as $component) {

            $this->dataStorage->remove('layout/components', ['$or' => [
                ['_id' => $component['_id']],
                ['name' => $component['name']],
            ]]);

            $this->dataStorage->insert('layout/components', $component);
        }

        foreach ($shared as $component) {

            $this->dataStorage->remove('layout/components_shared', ['$or' => [
                ['_id' => $component['_id']],
                ['name' => $component['name']],
            ]]);

            $this->dataStorage->insert('layout/components_shared', $component);
        }

        foreach ($templates as $template) {

            $this->dataStorage->remove('layout/templates', ['$or' => [
                ['_id' => $template['_id']],
                ['name' => $template['name']],
            ]]);

            $this->dataStorage->insert('layout/templates', $template);
        }

        $this->helper('layoutComponents')->cache();

        return true;
    },

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

        $payload = [
            'components' => $this->dataStorage->find('layout/components')->toArray(),
            'shared' => $this->dataStorage->find('layout/components_shared')->toArray(),
            'templates' => $this->dataStorage->find('layout/templates')->toArray(),
        ];

        return $payload;
    }
];
