<?php

namespace KupShop\ComponentsBundle\Twig\Components\Account;

use KupShop\BonusProgramBundle\Utils\BonusComputer;
use KupShop\BonusProgramBundle\Utils\BonusProvider;
use KupShop\ComponentsBundle\Attributes\Component;
use KupShop\ComponentsBundle\Attributes\Version;
use KupShop\ComponentsBundle\Twig\BaseComponent;
use KupShop\ComponentsBundle\Twig\DataProvider\TextHelperTrait;
use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Context\UserContext;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\KupShopBundle\Util\Price\Price;
use Query\Operator;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
use Symfony\UX\TwigComponent\Attribute\PostMount;

#[AsTwigComponent(template: '@Components/components/Account/UserDashboard/UserDashboard.1.html.twig')]
#[Component(1, [
    new Version(1, newJs: null),
])]
class UserDashboard extends BaseComponent
{
    use TextHelperTrait;
    use UserInfoTrait;

    public function __construct(
        protected ?BonusComputer $bonusComputer,
        protected ?BonusProvider $bonusProvider,
        protected readonly TranslatorInterface $translator,
    ) {
    }

    public ?int $id_user;

    public bool $show_user_info = true;
    public bool $show_active_orders_count = false;
    public bool $show_bonus_points = false;
    public bool $show_pricelevel = false;

    protected ?\User $user;
    protected int $activeOrdersCount;
    protected int $bonusPoints;

    #[PostMount]
    public function setUser()
    {
        if (!isset($this->id_user)) {
            $this->id_user = Contexts::get(UserContext::class)->getActiveId();
            $this->user = Contexts::get(UserContext::class)->getActive();
        } else {
            $this->user = \User::createFromId($this->id_user);
        }
    }

    public function getActiveOrdersCount(): ?int
    {
        if (isset($this->activeOrdersCount)) {
            return $this->activeOrdersCount;
        }

        if (isset($this->id_user)) {
            $this->activeOrdersCount = sqlQueryBuilder()->select('COUNT(o.id)')->from('orders', 'o')
                ->andWhere(Operator::equals(['o.id_user' => $this->id_user]))
                ->andWhere(Operator::inIntArray(getStatuses('active'), 'o.status'))
                ->execute()->fetchOne();

            return $this->activeOrdersCount;
        }

        return null;
    }

    public function spending(array $params)
    {
        // TODO: prekopirovano z get_stat. Az budeme vedet co poradne s tim, tak treba udelat dve solo funkce pres QB
        if ($this->id_user) {
            $where = 'o.id_user = :user_id';
            $data = [
                'user_id' => $this->id_user,
            ];

            if (!empty($params['year'])) {
                $where .= ' AND YEAR(o.date_created) = :year ';
                $data['year'] = $params['year'];
            }

            if (!empty($params['last_year'])) {
                $year = intval($params['last_year']);
                $where .= " AND date_created > DATE_SUB( NOW(), INTERVAL {$year} YEAR) ";
            }
            // Pokud chtějí zobrazovat přesný součet objednávek v dané měně
            if (isset($params['currency'])) {
                $spendActiveCurrency = sqlQueryBuilder()
                ->select('SUM(o.total_price) as total')
                ->from(getTableName('orders'), 'o')
                ->andWhere(\Query\Operator::equals(['id_user' => $data['user_id'], 'o.currency' => $params['currency']]))
                ->execute()->fetchOne();

                $result = toDecimal($spendActiveCurrency);
                $result = new Price($result, $params['currency'], \DecimalConstants::zero());
            } else {
                $result = applyCurrency(returnSQLResult('SELECT SUM(o.total_price'.(findModule('currencies') ? '* o.currency_rate' : '').') FROM orders AS o WHERE '.$where, $data));
                $result = new Price($result, Contexts::get(CurrencyContext::class)->getActive(), \DecimalConstants::zero());
            }
        } else {
            $result = null;
        }

        return $result;
    }
}
