<?php

/**
 * Created by PhpStorm.
 * User: leos
 * Date: 8/4/17
 * Time: 2:56 PM.
 */
use KupShop\AdminBundle\AdminList\BaseList;
use KupShop\KupShopBundle\Util\HtmlBuilder\HTML;
use Query\Operator;

class FiltersList extends BaseList
{
    use AdminListSortable;
    protected $template = 'list/filters.tpl';
    protected $pageDivide = 0;

    protected $tableDef = [
        'id' => 'id',
        'fields' => [
            'name' => ['field' => 'name', 'render' => 'getTitle', 'size' => 3],
            'description' => ['field' => 'description', 'size' => 3],
            'id_admin' => ['field' => 'id_admin', 'size' => 2],
            'favorite' => ['field' => 'favorite', 'render' => 'renderBoolean', 'class' => 'alignCenter', 'size' => 1],
            'default' => ['field' => 'default_filter', 'render' => 'renderBoolean', 'class' => 'alignCenter', 'size' => 1],
            'layouts' => ['field' => 'columns', 'render' => 'renderColumns', 'class' => 'alignCenter', 'size' => 2],
        ],
        'sections' => [],
    ];

    public function getTitle($values, $column)
    {
        return [
            HTML::create('span')
                ->class('drag-drop-mover')
                    ->tag('i')
                    ->class('bi bi-arrows-move handle')
                    ->end(),
            HTML::create('span')
                ->text($this->getListRowValue($values, $column['field']) ?? ''),
        ];
    }

    public function renderColumns($values, $column, $tooltip = '')
    {
        return $this->renderBoolean(['columns' => !empty($values['columns'])], $column);
    }

    public function getSQL(Query\QueryBuilder $qb)
    {
        $data = parent::getSQL($qb);

        $vars['list'][] = $this->createList(clone $qb, 'N');
        $vars['list'][] = $this->createList(clone $qb, 'Y');

        $data['SQL'] = $vars;

        return $data;
    }

    public function createList(Query\QueryBuilder $qb, $global)
    {
        global $adminID;
        $id = ($adminID == 0) ? null : $adminID;

        $this->tableDef['sections'][] = translate('local', 'filters');
        $this->tableDef['sections'][] = translate('global', 'filters');
        $type = getVal('pg');

        $sql = $qb->resetQueryPart('where')
            ->where(\Query\Operator::equals(['admin_filters.global' => $global]))
            ->andWhere(\Query\Operator::equals(['admin_filters.type' => $type]))
            ->andWhere(
                \Query\Operator::orX(
                    \Query\Operator::equalsNullable(['admin_filters.id_admin' => $id]),
                    \Query\Operator::equals(['admin_filters.global' => 'Y'])
                )
            )
            ->orderBy('case when admin_filters.position is null then 1 else 0 end, position')
            ->groupBy('admin_filters.id')
            ->setParameter('ida', $id)
            ->execute()->fetchAll();

        foreach ($sql as &$row) {
            $admin = $this->getQueryBuilder()
                ->select('login')
                ->from('admins', 'a')
                ->where('id = :id')
                ->setParameters(['id' => $row['id_admin']])
                ->execute()->fetchColumn();

            $row['id_admin'] = (empty($admin)) ? 'wpj admin' : $admin;
        }

        return $sql;
    }

    public function handleDrag()
    {
        $tree = getVal('tree');
        $id_menu = getVal('id_menu');
        $type = getVal('pg');
        if ($tree && isset($id_menu)) {
            sqlGetConnection()->transactional(function () use ($tree, $type, $id_menu) {
                $oldItem = sqlQueryBuilder()->select('global', 'position')->from('admin_filters')
                    ->where(\Query\Operator::equals(['id' => $tree['id']]))
                    ->execute()->fetch();

                if (!empty($tree['after'])) {
                    $id_anchor = $tree['after'];
                    $compare = ' > ';
                } elseif (!empty($tree['before'])) {
                    $id_anchor = $tree['before'];
                    $compare = ' >= ';
                } else {
                    $compare = ' > ';
                    $id_anchor = $tree['target'] ?? null;
                }
                if ($id_anchor) {
                    $anchorPosition = sqlQueryBuilder()->select('position')->from('admin_filters')
                        ->where(\Query\Operator::equals(['id' => $id_anchor]))
                        ->execute()->fetchColumn();
                } else {
                    // Insert as the only child
                    $anchorPosition = 0;
                }

                $global = ($id_menu == 0) ? 'N' : 'Y';
                global $adminID;
                $id = ($adminID == 0) ? null : $adminID;

                sqlQueryBuilder()->update('admin_filters')
                    ->set('position', 'position + 2')
                    ->andWhere("position {$compare} :anchor_position")
                    ->setParameter('anchor_position', $anchorPosition)
                    ->andWhere(\Query\Operator::equals(['type' => $type, 'global' => $global]))
                    ->andWhere(
                        \Query\Operator::orX(
                            \Query\Operator::equals(['global' => 'Y']),
                            \Query\Operator::equalsNullable(['id_admin' => $id])
                        )
                    )->execute();

                sqlQueryBuilder()->update('admin_filters')
                    ->set('position', $anchorPosition + 1)
                    ->set('global', ':global')->setParameter('global', $global)
                    ->where(\Query\Operator::equalsNullable(['id' => $tree['id']]))->execute();

                $this->filtersPositionReindex(['admin' => $id, 'id_menu' => $global, 'type' => $type]);
                if ($global != $oldItem['global']) {
                    $this->filtersPositionReindex(['admin' => $id, 'id_menu' => $oldItem['global'], 'type' => $type]);
                }
            });
            exit('OK');
        }
        exit('Err');
    }

    public function filtersPositionReindex($where)
    {
        $cond = (empty($where['admin'])) ? 'IS' : '=';
        sqlQuery("SELECT @i := -1; UPDATE admin_filters SET position = (select @i := @i + 1) 
                WHERE type = :type AND (global=:id_menu AND (global='Y' OR id_admin ".$cond.' :admin)) 
                ORDER BY case when position is null then 1 else 0 end, position', $where);
    }

    public function getQuery()
    {
        return sqlQueryBuilder()
            ->select('*')
            ->from('admin_filters')
            ->andWhere(Operator::equals(['default_filter' => 'N']));
    }
}
