<?php

namespace KupShop\BonusProgramBundle\Actions\Frontend;

use KupShop\BonusProgramBundle\Utils\BonusProvider;
use KupShop\KupShopBundle\Context\UserContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\OrderDiscountBundle\Actions\Frontend\AbstractHandler;

class BonusProgramHandler extends AbstractHandler
{
    protected $template = 'order_discount/actions/bonus_program.tpl';
    protected BonusProvider $bonusProvider;

    public $templateSize = 'half';

    /** @required */
    public function setBonusProvider(BonusProvider $bonusProvider)
    {
        $this->bonusProvider = $bonusProvider;

        return $this;
    }

    public function handleData($data): array
    {
        $data = parent::handleData($data);

        $bonus_points = intval($data['bonus_points'] ?? 0);

        if ($bonus_points <= 0) {
            return [];
        }
        /** @var UserContext $userContext */
        $userContext = ServiceContainer::getService(UserContext::class);
        $activePoints = $this->bonusProvider->getActivePointsAmount($userContext->getActive());
        $maxActivePoints = max($activePoints - $this->getUsedBonusPoints(), 0);
        $bonus_points = min([$bonus_points, $maxActivePoints]);

        return ['bonus_points' => $bonus_points];
    }

    public function getVars(): array
    {
        $vars = parent::getVars();
        $user = Contexts::get(UserContext::class)->getActive();
        $activePoints = $user ? $this->bonusProvider->getActivePointsAmount($user) : 0;
        $vars['activePoints'] = $activePoints;
        $bonus_points = intval($vars['frontend_data']['bonus_points'] ?? 0);
        if ($bonus_points > 0) {
            $maxActivePoints = max($activePoints - $this->getUsedBonusPoints(), 0);
            $bonus_points = min([$bonus_points, $maxActivePoints]);
            $vars['bonus_points'] = $bonus_points;
            $vars['frontend_data']['bonus_points'] = $bonus_points;
        }

        return $vars;
    }

    public function getUsedBonusPoints(): int
    {
        $used_bonus_points = 0;
        foreach (getVal('action_handler', null, []) as $id => $handler) {
            if ($id != $this->getActionId()) {
                $used_bonus_points += intval($handler['bonus_points'] ?? 0);
            }
        }

        return $used_bonus_points;
    }

    public function __sleep()
    {
        $vars = array_keys(get_object_vars($this));

        return array_diff($vars, ['bonusProvider']);
    }

    public function __wakeup()
    {
        // Povolené použití ServiceContainer, protože DI v deserializaci nejde
        $this->setBonusProvider(ServiceContainer::getService(BonusProvider::class));
    }
}
