<?php

namespace KupShop\ReclamationsBundle\Admin\lists;

use KupShop\AdminBundle\AdminList\BaseList;
use KupShop\AdminBundle\AdminList\FiltersStorage;
use KupShop\AdminBundle\Query\Invert;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\HtmlBuilder\HTML;
use KupShop\ReclamationsBundle\Util\ReclamationsUtil;
use Query\Operator;

class ReclamationsList extends BaseList
{
    use FiltersStorage;

    protected $showMassEdit = true;
    protected $tableName = 'reclamations';
    protected ?string $tableAlias = 'r';

    protected $tableDef = [
        'id' => 'r.id',
        'fields' => [
            'code' => ['translate' => true, 'translation_section' => 'Reclamations', 'field' => 'r.id', 'render' => 'renderCode', 'size' => 0.25],
            'created' => ['translate' => true, 'translation_section' => 'Reclamations', 'field' => 'r.date_created', 'render' => 'renderDateTime'],
            'accepted' => ['translate' => true, 'translation_section' => 'Reclamations', 'field' => 'r.date_accepted', 'render' => 'renderDateTime'],
            'handle' => ['translate' => true, 'translation_section' => 'Reclamations', 'field' => 'r.date_handle', 'render' => 'renderDateTime'],
            'status' => ['translate' => true, 'translation_section' => 'Reclamations', 'field' => 'r.status', 'spec' => 'r.status', 'render' => 'renderStatus', 'size' => 0.5, 'fieldType' => ReclamationsList::TYPE_LIST],
            'customer' => ['translate' => true, 'translation_section' => 'Reclamations', 'field' => 'id_user', 'render' => 'renderCustomer', 'size' => 0.75],
            'item' => ['translate' => true, 'translation_section' => 'Reclamations', 'field' => 'id_product', 'render' => 'renderProduct'],
            'id_order' => ['translate' => true, 'translation_section' => 'Reclamations', 'field' => 'r.id', 'render' => 'renderOrderId'],
            'user_note' => ['translate' => true, 'translation_section' => 'Reclamations', 'field' => 'r.user_note', 'spec' => 'r.user_note', 'visible' => 'N', 'fieldType' => BaseList::TYPE_STRING],
            'descr' => ['translate' => true, 'translations_sections' => 'Reclamations', 'field' => 'r.descr', 'spec' => 'r.descr', 'visible' => 'N', 'fieldType' => BaseList::TYPE_STRING],
            'deadline' => ['translate' => true, 'translation_section' => 'Reclamations', 'render' => 'renderDeadline', 'size' => 0.5],
        ],
        'class' => 'getRowClass',
    ];

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

        $tableDef['fields']['status']['fieldOptions'] = [
            2 => translate('handled', 'Reclamations'),
            1 => translate('accepted', 'Reclamations'),
            0 => translate('new', 'Reclamations'),
        ];

        return $tableDef;
    }

    protected $orderParam = [
        'sort' => 'code',
        'direction' => 'DESC',
    ];

    /** @var ReclamationsUtil */
    protected $reclamations;

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

    public function getRowClass($values)
    {
        $class = '';
        if (in_array($values['status'], $this->reclamations->getHandleStatuses())) {
            $class = ' row-green';
        }

        // upcoming
        if (in_array($values['status'], $this->reclamations->getAcceptedStatuses())) {
            $dateAccepted = \DateTime::createFromFormat('Y-m-d H:i:s', $values['date_accepted']);
            if ($dateAccepted) {
                $diff = $dateAccepted->diff(new \DateTime());
                if (abs($diff->days) > 15) {
                    $class = ' row-orange';
                }
                if (abs($diff->days) > 30) {
                    $class = ' row-red';
                }
            }
        }

        return $class;
    }

    public function renderCode($values)
    {
        return $values['code'];
    }

    public function renderDeadline($values)
    {
        if (in_array($values['status'], $this->reclamations->getAcceptedStatuses())) {
            $dateAccepted = \DateTime::createFromFormat('Y-m-d H:i:s', $values['date_accepted']);
            if ($dateAccepted) {
                $diff = $dateAccepted->diff(new \DateTime());
                $text = 'za '.(30 - $diff->days).' dnů';
                $class = '';

                if (abs($diff->days) > 15) {
                    $class = 'badge-warning';
                }

                if (abs($diff->days) > 30) {
                    $class = 'badge-danger';
                    $text = '-'.($diff->days - 30).' dnů';
                }

                if (abs($diff->days) === 30) {
                    $text = 'dnes';
                }

                return HTML::create('span')
                    ->attr('class', 'badge '.$class)
                    ->text($text);
            }
        }
    }

    public function renderOrderId($values)
    {
        return HTML::create('a')
            ->attr('href', 'javascript:nw(\'orders\', '.$values['id_order'].')')
            ->text($values['order_no']);
    }

    public function renderCustomer($values, $column)
    {
        $userID = $values['id_user'];
        if (!$userID) {
            return $values['name'].' '.$values['surname'];
        }

        return HTML::create('a')
            ->attr('href', 'javascript:nw(\'users\', \''.$values['id_user'].'\')')
            ->text($values['name'].' '.$values['surname']);
    }

    public function renderProduct($values, $column)
    {
        $product = new \Product();
        $product->createFromDB($values['id_product']);

        return HTML::create('a')
            ->attr('href', 'javascript:nw(\'products\', \''.$values['id_product'].'\')')
            ->text($product->title);
    }

    public function renderStatus($values, $column)
    {
        return $this->reclamations->getStatuses()[$values['status']];
    }

    public function getQuery()
    {
        $qb = sqlQueryBuilder()->select('r.*, oi.id_product, o.id_user, o.id as id_order, o.order_no as order_no')
            ->from('reclamations', 'r')
            ->leftJoin('r', 'order_items', 'oi', 'oi.id = r.id_item')
            ->leftJoin('oi', 'orders', 'o', 'o.id = oi.id_order')
            ->groupBy('r.id');

        if (getVal('upcoming')) {
            $qb->andWhere('DATEDIFF(NOW(), r.date_accepted) > 15')
                ->andWhere(Operator::inIntArray($this->reclamations->getAcceptedStatuses(), 'r.status'));
        }

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

        if ($code = getVal('code')) {
            $qb->andWhere(
                Invert::checkInvert(
                    Operator::orX(
                        [
                            Operator::equals(['r.id' => $code]),
                            Operator::equals(['r.code' => $code]),
                        ]
                    ), getVal('code_invert')
                )
            );
        }

        if ($productId = getVal('id_product')) {
            $qb->andWhere('oi.id_product = :id_product')
                ->setParameter('id_product', $productId);

            if ($variationId = getVal('id_variation')) {
                if (intval($variationId) > 0) {
                    $qb->andWhere('oi.id_variation = :id_variation')
                        ->setParameter('id_variation', $variationId);
                }
            }
        }

        if ($handleType = getVal('handle_type')) {
            $qb->andWhere(Operator::inIntArray($handleType, 'r.handle_type'));
        }

        if ($name = getVal('surname')) {
            $qb->andWhere(Invert::checkInvert(Operator::like(['r.surname' => "%{$name}%", 'r.name' => "%{$name}%"], 'OR'), getVal('surname_invert')));
        }

        if ($id_order = getVal('id_order')) {
            $qb->andWhere(Invert::checkInvert(Operator::like(['o.order_no' => "%{$id_order}%"]), getVal('id_order_invert')));
        }

        $dateRange = getVal('date_range');

        if ($from = $dateRange['from'] ?? null) {
            $from = \DateTime::createFromFormat(\Settings::getDateFormat(), $from)->format('Y-m-d 00:00:00');
        }
        if ($to = $dateRange['to'] ?? null) {
            $to = \DateTime::createFromFormat(\Settings::getDateFormat(), $to)->format('Y-m-d 23:59:59');
        }
        if ($from || $to) {
            $qb->andWhere(Operator::between('r.date_created', new \Range($from, $to)));
        }

        if ($accepted_from = $dateRange['accepted_from'] ?? null) {
            $accepted_from = \DateTime::createFromFormat(\Settings::getDateFormat(), $accepted_from)->format('Y-m-d 00:00:00');
        }
        if ($accepted_to = $dateRange['accepted_to'] ?? null) {
            $accepted_to = \DateTime::createFromFormat(\Settings::getDateFormat(), $accepted_to)->format('Y-m-d 23:59:59');
        }
        if ($accepted_from || $accepted_to) {
            $qb->andWhere(Operator::between('r.date_accepted', new \Range($accepted_from, $accepted_to)));
        }
        if ($handle_from = $dateRange['handle_from'] ?? null) {
            $handle_from = \DateTime::createFromFormat(\Settings::getDateFormat(), $handle_from)->format('Y-m-d 00:00:00');
        }
        if ($handle_to = $dateRange['handle_to'] ?? null) {
            $handle_to = \DateTime::createFromFormat(\Settings::getDateFormat(), $handle_to)->format('Y-m-d 23:59:59');
        }
        if ($handle_from || $handle_to) {
            $qb->andWhere(Operator::between('r.date_handle', new \Range($handle_from, $handle_to)));
        }

        return $qb;
    }
}

return ReclamationsList::class;
