<?php

namespace Detektivo\Controller;

use Closure;

class Detektivo extends Controller {

    public function index($name = null) {

        if ($name) {
            if (!$this->module('detektivo')->exists($name)) return false;

            return $this->render('detektivo:views/indexform.php', ['index' => $this->module('detektivo')->indexes($name)]);
        }

        return $this->render('detektivo:views/index.php');
    }

    public function create() {
        return $this->render('detektivo:views/indexform.php');
    }

    public function save() {

        $this->hasValidCsrfToken(true);

        $index = $this->param('index');
        $isUpdate = $this->param('isUpdate', false);

        if (!$index || !isset($index['name'], $index['type'])) {
            return false;
        }

        if ($isUpdate) {

            if (!$this->module('detektivo')->exists($index['name'])) {
                $this->stop(['error' => "Index - {$index['name']} - does not exists!"], 400);
            }

            $this->module('detektivo')->removeIndex($index['name']);

        } else {

            if ($this->module('detektivo')->exists($index['name'])) {
                $this->stop(['error' => "Index - {$index['name']} - already exists!"], 400);
            }
        }

        $idx = $this->module('detektivo')->createIndex($index['name'], $index);

        $this->helper('eventStream')->add('detektivo.indexes.updated', ['action' => 'create', 'name' => $index['name']]);

        return $idx;
    }

    public function remove($name = null, $id = null) {

        $this->hasValidCsrfToken(true);

        if (!$name || !$this->module('detektivo')->exists($name)) {
            return false;
        }

        $this->module('detektivo')->removeIndex($name);

        $this->helper('eventStream')->add('detektivo.indexes.updated', ['action' => 'remove', 'name' => $name]);

        return ['success' => true];
    }

    public function load() {

        $this->hasValidCsrfToken(true);

        $indexes = $this->module('detektivo')->indexes();

        if (!$this->helper('acl')->isSuperAdmin()) {

            $acl = $this->helper('acl');

            $indexes = \array_filter($indexes, function($index) use($acl) {

                if ($acl->isAllowed('content/indexes/manage')) {
                    return true;
                }

                return $acl->isAllowed("content/{$index['name']}/read");
            });
        }

        return \array_values($indexes);
    }

    public function search($name = null) {

        $this->hasValidCsrfToken(true);

        if (!$name || !$this->module('detektivo')->exists($name)) {
            return false;
        }

        $query = $this->param('q:string', '');
        $limit = $this->param('limit:int', 20);
        $offset = $this->param('offset:int', 0);

        $idx = $this->module('detektivo')->index($name);

        $result = $idx->search($query, [
            'limit' => $limit,
            'offset' => $offset,
        ]);

        $pages = \ceil($result['estimatedTotalHits'] ?? 0 / $limit);
        $page  = 1;

        if ($pages > 1 && $offset) {
            $page = \ceil($offset / $limit) + 1;
        }

        $result['pages'] = $pages;
        $result['page'] = $page;
        $result['total'] = $idx->countDocuments();

        return $result;
    }

    public function fieldSuggestions() {

        $this->hasValidCsrfToken(true);

        $type = $this->param('type', []);
        $meta = $this->param('meta', []);

        if (!$type) return [];

        $type = $this->module('detektivo')->indexTypes($type);

        if (!$type || !isset($type['fields'])) return [];

        $callback = Closure::bind($type['fields'], $this, $this);

        return $callback($meta);
    }

}
