<?php


return [
    'name' => 'content:collection',
    'label' => 'Collection',
    'info' => 'Index content collection items',
    'icon' => 'content:assets/icons/collection.svg',
    'meta' => [
        [
            'name' => 'model',
            'type' => 'options-linkModel',
            'label' => 'Model',
            'info' => 'Select the model to index',
            'required' => true,
        ],
        [
            'name' => 'populate',
            'type' => 'number',
            'label' => 'Populate',
            'info' => 'Populate level of linked content before indexing',
            'required' => true,
            'opts' => ['default' => '0']
        ],
        [
            'name' => 'locale',
            'type' => 'boolean',
            'label' => 'Locale versions',
            'info' => 'Index locale versions of content items',
        ]
    ],

    'fields' => function($meta = null) {
        return include(__DIR__.'/fields.php');
    },

    'index' => function($index, $idx) {

        $model = $index['meta']['model'] ?? null;
        $populate = $index['meta']['populate'] ?? 0;
        $indexLocale = $index['meta']['locale'] ?? false;

        if (!isset($model) || !$this->app->module('content')->model($model)) {
            return;
        }

        $fields = $this->app->module('content')->model($model)['fields'];

        // does the model have localized fields?
        $hasLocaleFields = false;
        $hasIndexLocaleField = false;
        $locales = [];

        foreach ($fields as $field) {
            if (isset($field['i18n']) && $field['i18n']) {
                $hasLocaleFields = true;
                break;
            }
        }

        // collect available locales
        if ($hasLocaleFields) {

            foreach ($index['fields'] as $field) {
                if ($field === 'locale') {
                    $hasIndexLocaleField = true;
                    break;
                }
            }

            foreach ($this->app->helper('locales')->locales() as $locale) {

                if ($locale['i18n'] == 'default') continue;
                $locales[] = $locale['i18n'];
            }
        }

        $run = 0;
        $limit = 20;
        $indexed = 0;
        $totalIndexed = 0;
        $nextProgressLog = 200;

        $idx->clear();

        while (true) {

            $this->heartbeat(['indexed' => $totalIndexed]);

            // Check if indexer was not stopped
            if ($indexed > 50) {
                if (!$this->isIndexerRunning()) return;
                $indexed = 0;
            }

            $items = $this->app->module('content')->items($model, [
                'filter' => ['_state' => 1],
                'limit' => $limit,
                'skip' => $run * $limit,
            ], ['populate' => $populate]);

            $documents = [];

            if (!count($items)) {
                break;
            }

            foreach ($items as &$item) {

                $item['id'] = $item['_id'];
                unset($item['_id']);

                if ($indexLocale && count($locales)) {

                    $doc = $this->app->helper('locales')->applyLocales($item, 'default');

                    if ($hasIndexLocaleField) {
                        $item['locale'] = 'default';
                    }

                    $documents[] = $doc;

                    foreach ($locales as $locale) {

                        $doc = $this->app->helper('locales')->applyLocales($item, $locale);
                        $doc['id'] = "{$item['id']}_{$locale}";

                        if ($hasIndexLocaleField) {
                            $doc['locale'] = $locale;
                        }

                        $documents[] = $doc;
                    }

                } else {
                    $documents[] = $item;
                }
            }

            $idx->addDocuments($documents);

            $count = \count($documents);
            $run += 1;
            $indexed += $count;
            $totalIndexed += $count;

            $this->heartbeat(['indexed' => $totalIndexed]);

            if ($totalIndexed >= $nextProgressLog) {
                $this->log("Indexed {$totalIndexed} documents");
                $nextProgressLog = $totalIndexed + 200;
            }
        }
    }
];
