<?php

namespace KupShop\CommentsBundle\Admin\lists;

use KupShop\AdminBundle\AdminList\BaseList;
use KupShop\AdminBundle\AdminList\FiltersStorage;
use KupShop\AdminBundle\Query\Invert;
use KupShop\CommentsBundle\Comment;
use KupShop\CommentsBundle\Util\CommentsUtil;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\HtmlBuilder\HTML;
use Query\Operator;
use Query\QueryBuilder;

class CommentsList extends BaseList
{
    use FiltersStorage;

    protected static $type;

    protected $template = 'list/Comments.tpl';

    /** @var CommentsUtil */
    private $commentsUtil;

    public function __construct()
    {
        $this->commentsUtil = ServiceContainer::getService(CommentsUtil::class);
    }

    public function customizeTableDef($tableDef)
    {
        $tableDef = parent::customizeTableDef($tableDef);

        $tableDef['id'] = 'id';
        $tableDef['fields'] = [
            'ID' => ['field' => 'id', 'size' => 0.3, 'type' => 'Comments', 'spec' => 'c.id'],
            'author' => ['field' => 'id', 'translate' => true, 'translation_section' => 'Comments', 'render' => 'renderAuthor', 'spec' => function (QueryBuilder $qb) {
                $qb->addSelect('c.id_user, c.id_admin, CONCAT(u.name, " ", u.surname) as username, ad.login as admin')
                    ->leftJoin('c', 'users', 'u', 'u.id = c.id_user')
                    ->leftJoin('c', 'admins', 'ad', 'ad.id = c.id_admin');
            }],
            'content' => ['field' => 'content', 'translate' => true, 'translation_section' => 'Comments', 'render' => 'renderHTML', 'size' => 2, 'spec' => 'c.content'],
            'object' => ['field' => 'id', 'translate' => true, 'translation_section' => 'Comments', 'render' => 'renderObject', 'spec' => function (QueryBuilder $qb) {
                $qb->addSelect('c.id_product, c.id_article, p.title as product_title, a.title as article_title')
                    ->leftJoin('c', 'products', 'p', 'p.id = c.id_product')
                    ->leftJoin('c', 'articles', 'a', 'a.id = c.id_article');
            }],
            'status' => ['field' => 'status', 'translate' => true, 'translation_section' => 'Comments', 'render' => 'renderStatus', 'class' => 'comment-status', 'spec' => 'c.status'],
            'solved' => ['field' => 'solved', 'translate' => true, 'translation_section' => 'Comments', 'render' => 'renderSolved', 'class' => 'comment-solved', 'size' => 0.5, 'spec' => 'c.solved'],
            'date' => ['field' => 'date_add', 'translate' => true, 'translation_section' => 'Comments', 'render' => 'renderDateTime', 'spec' => 'c.date_add'],
            'setSolved' => ['field' => 'solved', 'translate' => true, 'translation_section' => 'Comments', 'render' => 'renderSetSolved', 'size' => 0.7],
            'top' => ['field' => 'figure', 'translate' => true, 'translation_section' => 'Comments', 'render' => 'renderTop', 'size' => 0.3],
            'delete' => ['field' => 'figure', 'translate' => true, 'translation_section' => 'Comments', 'render' => 'renderDelete', 'size' => 0.4],
        ];

        return $tableDef;
    }

    public function renderDelete(array $values)
    {
        return HTML::create('a')
            ->attr('style', 'padding: 1px 0 0 3px;')
            ->attr('class', 'btn-sm btn btn-danger')
            ->attr('data-form-delete', '')
            ->attr('title', 'Smazat hodnocení')
            ->tag('input')
                ->attr('name', "data[comments][{$values['id']}][delete]")
                ->attr('value', '')
                ->attr('data-form-delete-input', $values['id'])
                ->attr('type', 'hidden')
                ->end()
            ->tag('span')
                ->attr('class', 'glyphicon glyphicon-remove')
                ->end();
    }

    public function renderTop(array $values)
    {
        return HTML::create('a')
            ->attr('style', 'padding: 1px 0 0 3px;')
            ->attr('class', 'btn-sm btn btn-success comment-is'.($values['status'] == Comment::STATUS_TOP ? ' disabled' : ''))
            ->attr('data-form-top', '')
            ->attr('title', 'Označit jako TOP (zároveň schválí hodnocení)')
            ->tag('input')
                ->attr('name', "data[comments][{$values['id']}][top]")
                ->attr('value', '')
                ->attr('data-form-top-input', $values['id'])
                ->attr('type', 'hidden')
                ->end()
            ->tag('span')
                ->attr('class', 'glyphicon glyphicon-thumbs-up')
                ->end();
    }

    public function renderSetSolved(array $values)
    {
        return HTML::create('a')
            ->attr('style', 'padding: 1px 0 0 3px;')
            ->attr('class', 'btn-sm btn btn-success comment-is-solved'.($values['solved'] == Comment::SOLVED_YES ? ' disabled' : ''))
            ->attr('data-form-solved', '')
            ->attr('title', 'Označit jako vyřešené')
            ->tag('input')
                ->attr('name', "data[comments][{$values['id']}][solved]")
                ->attr('value', '')
                ->attr('data-form-solved-input', $values['id'])
                ->attr('type', 'hidden')
                ->end()
            ->tag('span')
                ->attr('class', 'glyphicon glyphicon-ok')
                ->end();
    }

    public function renderAuthor(array $values): HTML
    {
        if (!empty($values['id_user'])) {
            return HTML::create('a')
                ->attr('href', 'javascript:nw(\'users\', \''.$values['id_user'].'\')')
                ->text($values['username']);
        }

        return HTML::create('span')
            ->text('Admin: '.$values['admin']);
    }

    public function renderSolved(array $values): string
    {
        switch ($values['solved']) {
            case Comment::SOLVED_YES:
                return translate('yes', 'Comments');
            default:
                return translate('no', 'Comments');
        }
    }

    public function renderStatus(array $values): string
    {
        switch ($values['status']) {
            case Comment::STATUS_CONFIRMED:
                return translate('confirmed', 'Comments');
            case Comment::STATUS_TOP:
                return translate('top', 'Comments');
            default:
                return translate('unconfirmed', 'Comments');
        }
    }

    public function renderObject(array $values): HTML
    {
        if (!empty($values['id_product'])) {
            return HTML::create('a')
                ->attr('href', 'javascript:nw(\'products\', \''.$values['id_product'].'\')')
                ->text($values['product_title']);
        }

        return HTML::create('a')
            ->attr('href', 'javascript:nw(\'articles\', \''.$values['id_article'].'\')')
            ->text($values['article_title']);
    }

    public function handle()
    {
        parent::handle();

        $data = getVal('data');

        if (!empty($data['comments'])) {
            foreach ($data['comments'] as $commentId => $comment) {
                if ($comment['delete']) {
                    $this->deleteSQL('comments', ['id' => $commentId]);
                } elseif ($comment['top']) {
                    $this->updateSQL('comments', ['status' => Comment::STATUS_TOP], ['id' => $commentId]);
                } elseif ($comment['solved']) {
                    $this->updateSQL('comments', ['solved' => Comment::SOLVED_YES], ['id' => $commentId]);
                } elseif (getVal('Submit') == 'Schválit vše') {
                    $this->updateSQL('comments', ['status' => Comment::STATUS_CONFIRMED], ['id' => $commentId]);
                }
            }
        }
    }

    public function getQuery()
    {
        $qb = sqlQueryBuilder()
            ->from('comments', 'c')
            ->andWhere(
                Operator::not(
                    Operator::equalsNullable(['c.'.$this->commentsUtil->getObjectField(static::$type) => null])
                )
            )
            ->groupBy('c.id');

        if ($status = getVal('status')) {
            $qb->andWhere(
                Invert::checkInvert(
                    Operator::inIntArray($status, 'c.status'),
                    getVal('status_invert')
                )
            );
        }

        if ($reply = getVal('solved')) {
            $qb->andWhere(
                Invert::checkInvert(
                    Operator::inIntArray($reply, 'c.solved'),
                    getVal('solved_invert')
                )
            );
        }

        if ($language = getVal('language')) {
            $qb->andWhere(
                Invert::checkInvert(
                    Operator::inStringArray($language, 'c.id_language'),
                    getVal('language_invert')
                )
            );
        }

        return $qb;
    }
}

return CommentsList::class;
