<?php

class fieldParent extends cmsFormField {

    public $title                = LANG_PARSER_PARENT;
    public $is_public            = false;
    public $sql                  = 'varchar(1024) NULL DEFAULT NULL';
    public $allow_index          = false;
    public $var_type             = 'string';
    public $filter_type          = 'str';

    protected $input_action      = 'bind';
    protected $parent_ctype_name = false;
    protected $parent_items      = null;

    public function getOptions() {
        return [
            new fieldList('item_style', [
                'title'   => LANG_PARSER_PARENT_STYLE,
                'default' => 'ctype_list',
                'items'   => [
                    'ctype_list' => LANG_PARSER_PARENT_STYLE1,
                    'links_list' => LANG_PARSER_PARENT_STYLE2,
                    'only_breadcrumbs' => LANG_PARSER_PARENT_STYLE3
                ]
            ])
        ];
    }

    public function __construct($name, $options = false) {

        parent::__construct($name, $options);

        $this->setParentContentTypeName();
    }

    private function setParentContentTypeName() {

        if ($this->name) {

            preg_match('/parent_([a-z0-9\-\_]+)_id/i', $this->name, $matches);

            if (!empty($matches[1])) {
                $this->parent_ctype_name = $matches[1];
            }
        }

        return $this;
    }

    public function setItem($item) {

        parent::setItem($item);

        if (!empty($item['ctype']['name'])) {
            $this->item['ctype_name'] = $item['ctype']['name'];
        }

        return $this;
    }

    public function getStringValue($value) {

        if (!$value) {
            return '';
        }

        $parent_items = $this->getParentItems();

        if (!$parent_items) {
            return '';
        }

        $result = [];

        foreach ($parent_items as $parent_item) {
            $result[] = $parent_item['title'];
        }

        return $result ? implode(', ', $result) : '';
    }

    public function parseTeaser($value) {

        if (!$value) {
            return '';
        }

        $parent_items = $this->getParentItems(false);

        if (!$parent_items) {
            return '';
        }

        $result = [];

        foreach ($parent_items as $parent_item) {
            $parent_url = href_to($this->parent_ctype_name, $parent_item['slug'] . '.html');
            $result[]   = '<a href="' . $parent_url . '">' . $parent_item['title'] . '</a>';
        }

        return $result ? implode(', ', $result) : '';
    }

    public function parse($value) {

        if (!$value) {
            return '';
        }

        if ($this->getOption('item_style', 'ctype_list') === 'links_list') {
            return $this->parseTeaser($value);
        }

        if (!$this->parent_ctype_name) {
            return '';
        }

        if (empty($this->item['id'])) {
            return '';
        }

        $controller = cmsCore::getController('content', $this->request);

        $ctypes = $controller->model->getContentTypes();

        $parent_ctype = $child_ctype = false;

        foreach ($ctypes as $ctype) {
            if ($ctype['name'] === $this->parent_ctype_name) {
                $parent_ctype = $ctype;
            }
            if ($ctype['name'] === $this->item['ctype_name']) {
                $child_ctype = $ctype;
            }
        }

        if (!$parent_ctype) {
            return '';
        }

        if (!$child_ctype) {

            if (cmsController::enabled($this->item['ctype_name'])) {

                $child_ctype = [
                    'name'       => $this->item['ctype_name'],
                    'controller' => $this->item['ctype_name'],
                    'id'         => null
                ];
            } else {
                return '';
            }

        } else {

            $child_ctype['controller'] = 'content';
        }

        if ($this->getOption('item_style') === 'only_breadcrumbs') {

            return $this->addBreadcrumb($value, $parent_ctype, $child_ctype, $controller);
        }

        $filter = "r.parent_ctype_id = {$parent_ctype['id']} AND " .
                "r.child_item_id = {$this->item['id']} AND " .
                'r.child_ctype_id ' . ($child_ctype['id'] ? '=' . $child_ctype['id'] : 'IS NULL' ) . ' AND ' .
                "r.parent_item_id = i.id AND r.target_controller = '{$child_ctype['controller']}'";

        $controller->model->join('content_relations_bind', 'r', $filter);
        $controller->model->limit(false);

        $controller->setListContext('form_field');

        $parent_ctype['options']['limit'] = 0;

        return $controller->renderItemsList($parent_ctype, '', true);
    }

    private function addBreadcrumb($value, $parent_ctype, $child_ctype, $controller) {

        $template = cmsTemplate::getInstance();

        $template->addBreadcrumb($parent_ctype['title'], href_to($parent_ctype['name']));

        $parent_item = $controller->model->selectOnly('title')->select('slug')->
                getItemById(
                    $controller->model->getContentTypeTableName($parent_ctype['name']),
                    $value
                );

        if ($parent_item) {

            $template->addBreadcrumb($parent_item['title'], href_to($parent_ctype['name'], $parent_item['slug'] . '.html'));

            $controller->model->selectOnly('title')->select('layout')->
                    filterEqual('ctype_id', $parent_ctype['id'])->
                    filterEqual('child_ctype_id', $child_ctype['id'])->
                    filterEqual('target_controller', $child_ctype['controller']);

            $relation = $controller->model->getItem('content_relations');

            if ($relation && $relation['layout'] === 'tab') {
                $template->addBreadcrumb($relation['title'], href_to($parent_ctype['name'], $parent_item['slug'], ['view-'.$child_ctype['name']]));
            }
        }

        return '';
    }

    public function getInput($value) {

        if (!$this->parent_ctype_name) {
            return '';
        }

        $parent_ctype = cmsCore::getModel('content')->getContentTypeByName($this->parent_ctype_name);

        if (!$parent_ctype) {
            return '';
        }

        $this->title = $this->element_title;

        $parent_items = false;
        $auth_user_id = cmsUser::get('id');

        $author_id = isset($this->item['user_id']) ? $this->item['user_id'] : $auth_user_id;

        if ($value) {
            $parent_items = $this->getParentItemsByIds($value);
        } else {
            $parent_items = $this->getParentItems();
        }

        $perm = cmsUser::getPermissionValue($this->item['ctype_name'], 'bind_to_parent');

        $is_allowed_to_bind = ($perm && (
                ($perm === 'all_to_all') || ($perm === 'all_to_own') || ($perm === 'all_to_other') ||
                ($perm === 'own_to_all' && $author_id == $auth_user_id) ||
                ($perm === 'own_to_other' && $author_id == $auth_user_id) ||
                ($perm === 'own_to_own' && $author_id == $auth_user_id) ||
                ($perm === 'other_to_own' && $author_id != $auth_user_id) ||
                ($perm === 'other_to_other' && $author_id != $auth_user_id) ||
                ($perm === 'other_to_all' && $author_id != $auth_user_id)
                )) || cmsUser::isAdmin();

        $allowed_to_unbind_perm = cmsUser::getPermissionValue($this->item['ctype_name'], 'bind_off_parent');
        if (cmsUser::isAdmin()) {
            $allowed_to_unbind_perm = 'all';
        }

        if (!$parent_items && !$is_allowed_to_bind) {
            return '';
        }

        return cmsTemplate::getInstance()->renderFormField($this->class, [
            'ctype_name'             => $this->parent_ctype_name,
            'child_ctype_name'       => $this->item ? $this->item['ctype_name'] : false,
            'parent_ctype'           => $parent_ctype,
            'field'                  => $this,
            'input_action'           => $this->input_action,
            'value'                  => $value,
            'field_item'             => $this->item,
            'items'                  => $parent_items,
            'auth_user_id'           => $auth_user_id,
            'allowed_to_unbind_perm' => $allowed_to_unbind_perm,
            'is_allowed_to_bind'     => $is_allowed_to_bind
        ]);
    }

    public function getFilterInput($value) {

        if (!$this->show_filter_input_title) {
            $this->title = false;
        }

        $this->input_action = 'select';

        if ($value) {
            $parent_items = $this->getParentItemsByIds($value);
        } else {
            $parent_items = [];
        }

        $parent_ctype = [];

        if($this->parent_ctype_name){
            $parent_ctype = cmsCore::getModel('content')->getContentTypeByName($this->parent_ctype_name);
        }

        return cmsTemplate::getInstance()->renderFormField($this->class, [
            'ctype_name'             => $this->parent_ctype_name,
            'child_ctype_name'       => $this->item ? $this->item['ctype_name'] : false,
            'parent_ctype'           => $parent_ctype,
            'field'                  => $this,
            'input_action'           => $this->input_action,
            'value'                  => $value,
            'field_item'             => [],
            'items'                  => $parent_items,
            'auth_user_id'           => cmsUser::get('id'),
            'allowed_to_unbind_perm' => true,
            'is_allowed_to_bind'     => true
        ]);
    }

    public function applyFilter($model, $values) {

        $ids = $this->idsStringToArray($values);
        if (!$ids) {
            return parent::applyFilter($model, $values);
        }

        return $model->filter('i.id IN (SELECT child_item_id FROM {#}content_relations_bind WHERE child_ctype_id' . ($this->ctype_id ? ' = ' . $this->ctype_id : ' IS NULL').' AND parent_item_id IN ('.implode(',', $ids).'))');
    }

    private function idsStringToArray($ids_list) {

        $ids = [];

        if (!$ids_list) {
            return $ids;
        }

        foreach (explode(',', $ids_list) as $id) {
            $id = trim($id);
            if (!is_numeric($id)) {
                continue;
            }
            $ids[] = (int) $id;
        }

        return $ids;
    }

    private function getParentItemsByIds($ids_list) {

        $ids = $this->idsStringToArray($ids_list);
        if (!$ids) {
            return false;
        }

        $content_model = cmsCore::getModel('content');
        $content_model->filterIn('id', $ids);

        return $content_model->getContentItems($this->parent_ctype_name);
    }

    private function getParentItems($store_result = true) {

        if ($this->parent_items !== null) {
            return $this->parent_items;
        }

        if (!$this->parent_ctype_name) {
            return false;
        }

        if (empty($this->item['id'])) {
            return false;
        }

        $content_model = cmsCore::getModel('content');

        $ctypes = $content_model->getContentTypes();

        $parent_ctype = $child_ctype = false;

        foreach ($ctypes as $ctype) {
            if ($ctype['name'] === $this->parent_ctype_name) {
                $parent_ctype = $ctype;
            }
            if ($ctype['name'] === $this->item['ctype_name']) {
                $child_ctype = $ctype;
            }
        }

        if (!$parent_ctype) {
            return false;
        }

        if (!$child_ctype) {

            if (cmsController::enabled($this->item['ctype_name'])) {

                $child_ctype = [
                    'name'       => $this->item['ctype_name'],
                    'controller' => $this->item['ctype_name'],
                    'id'         => null
                ];

            } else {
                return false;
            }

        } else {
            $child_ctype['controller'] = 'content';
        }

        $filter = "r.parent_ctype_id = {$parent_ctype['id']} AND " .
                "r.child_item_id = {$this->item['id']} AND " .
                'r.child_ctype_id ' . ($child_ctype['id'] ? '=' . $child_ctype['id'] : 'IS NULL' ) . ' AND ' .
                "r.parent_item_id = i.id AND r.target_controller = '{$child_ctype['controller']}'";

        $content_model->join('content_relations_bind', 'r', $filter);

        $items = $content_model->selectList([
            'i.id'      => 'id',
            'i.user_id' => 'user_id',
            'i.title'   => 'title',
            'i.slug'    => 'slug'
        ], true, $content_model->getContentTypeTableName($this->parent_ctype_name))->getContentItems($this->parent_ctype_name);

        if ($items) {
            foreach ($items as $id => $item) {
                $items[$id]['ctype_name'] = $this->parent_ctype_name;
            }
        }

        if ($store_result) {
            $this->parent_items = $items;
        }

        return $items;
    }

    public function store($value, $is_submitted, $old_value = null) {

        $ids = $this->idsStringToArray($value);
        if (!$ids) {
            return null;
        }

        $value = implode(',', $ids);

        return parent::store($value, $is_submitted, $old_value);
    }

}
