<?php

class PolylangLexiconEntriesGetListProcessor extends modProcessor
{
    public $classKey = 'LexiconEntries';
    public $permission = 'polylang_lexicon_list';
    /** @var Polylang $polylang */
    public $polylang;

    public function initialize()
    {
        if (!$this->modx->hasPermission($this->permission)) {
            return $this->modx->lexicon('access_denied');
        }
        $initialized = parent::initialize();
        if ($initialized) {
            // $this->polylang = $this->modx->getService('polylang', 'Polylang');
            $this->setDefaultProperties(array(
                'start' => 0,
                'limit' => 10,
                'sort' => 'name',
                'dir' => 'ASC',
                'language' => 'en',
                'namespace' => 'polylang',
                'topic' => 'site',
            ));
            if ($this->getProperty('language') == '') $this->setProperty('language', 'en');
            if ($this->getProperty('namespace') == '') $this->setProperty('namespace', 'polylang');
            if ($this->getProperty('topic') == '') $this->setProperty('topic', 'site');
        }
        return $initialized;
    }

    public function getLanguageTopics()
    {
        return array('polylang:default');
    }

    public function process()
    {
        $where = array(
            'namespace' => $this->getProperty('namespace'),
            'topic' => $this->getProperty('topic'),
            'language' => $this->getProperty('language'),
        );

        $query = $this->getProperty('query');
        if (!empty($query)) {
            $where[] = array(
                'name:LIKE' => '%' . $query . '%',
                'OR:value:LIKE' => '%' . $query . '%',
            );
        }

        /* setup query for db based lexicons */
        $c = $this->modx->newQuery('modLexiconEntry');
        $c->where($where);
        $c->sortby('name', 'ASC');
        $results = $this->modx->getCollection('modLexiconEntry', $c);
        $dbEntries = array();
        /** @var modLexiconEntry $r */
        foreach ($results as $r) {
            $dbEntries[$r->get('name')] = $r->toArray();
        }
        /* first get file-based lexicon */
        $entries = $this->modx->lexicon->getFileTopic($this->getProperty('language'), $this->getProperty('namespace'), $this->getProperty('topic'));
        $entries = is_array($entries) ? $entries : array();
        /* if searching */
        if (!empty($query)) {
            function parseArray($needle, array $haystack = array())
            {
                if (!is_array($haystack)) return false;
                $results = array();
                foreach ($haystack as $key => $value) {
                    if (strpos($key, $needle) !== false || strpos($value, $needle) !== false) {
                        $results[$key] = $value;
                    }
                }
                return $results;
            }

            $entries = parseArray($query, $entries);
        }

        /* add in unique entries */
        $es = array_diff(array_keys($dbEntries), array_keys($entries));
        foreach ($es as $n) {
            $entries[$n] = $dbEntries[$n]['value'];
        }
        $count = count($entries);
        ksort($entries);
        $entries = array_slice($entries, $this->getProperty('start'), $this->getProperty('limit'), true);

        /* loop through */
        $list = array();
        foreach ($entries as $name => $value) {
            $entryArray = array(
                'name' => $name,
                'value' => $value,
                'namespace' => $this->getProperty('namespace'),
                'topic' => $this->getProperty('topic'),
                'language' => $this->getProperty('language'),
                'createdon' => null,
                'editedon' => null,
                'overridden' => 0,
            );
            /* if override in db, load */
            if (array_key_exists($name, $dbEntries)) {
                $entryArray = array_merge($entryArray, $dbEntries[$name]);

                $entryArray['editedon'] = strtotime($entryArray['editedon']) ? strtotime($entryArray['editedon']) : strtotime($entryArray['createdon']);

                $entryArray['overridden'] = 1;
            }
            $entryArray = $this->prepareEntry($entryArray);
            $list[] = $entryArray;
        }

        return $this->outputArray($list, $count);
    }

    /**
     * @param array $data
     *
     * @return array
     */
    public function prepareEntry(array $data)
    {
        $data['actions'] = array(
            array(
                'cls' => array(
                    'menu' => 'green',
                    'button' => 'green',
                ),
                'icon' => 'icon icon-edit',
                'title' => $this->modx->lexicon('polylang_lexiconentries_menu_update'),
                'action' => 'updateItem',
                'button' => true,
                'menu' => true,
            ), array(
                'cls' => array(
                    'menu' => 'blue',
                    'button' => 'blue',
                ),
                'icon' => 'icon icon-clone',
                'title' => $this->modx->lexicon('polylang_lexiconentries_menu_clone'),
                'multiple' => $this->modx->lexicon('polylang_lexiconentries_menu_multiple_clone'),
                'action' => 'cloneItem',
                'button' => true,
                'menu' => true,
            ), array(
                'cls' => array(
                    'menu' => 'gray',
                    'button' => 'gray',
                ),
                'icon' => 'icon icon-language',
                'title' => $this->modx->lexicon('polylang_lexiconentries_menu_translate'),
                'multiple' => $this->modx->lexicon('polylang_lexiconentries_menu_multiple_translate'),
                'action' => 'translateItem',
                'button' => true,
                'menu' => true,
            ),
        );
        if (!empty($data['id'])) {
            $data['actions'][] = array(
                'cls' => array(
                    'menu' => 'red',
                    'button' => 'red',
                ),
                'icon' => 'icon icon-trash-o',
                'title' => $this->modx->lexicon('polylang_lexiconentries_menu_remove'),
                'multiple' => $this->modx->lexicon('polylang_lexiconentries_menu_multiple_remove'),
                'action' => 'removeItem',
                'button' => true,
                'menu' => true,
            );
        }
        return $data;
    }
}

return 'PolylangLexiconEntriesGetListProcessor';