<?php

namespace KupShop\ComponentsBundle\Twig\Components\Product\Variations;

use KupShop\CatalogBundle\Entity\Variation;
use KupShop\ComponentsBundle\Attributes\Component;
use KupShop\ComponentsBundle\Attributes\Version;
use KupShop\ComponentsBundle\Twig\Components\Product\Variations;
use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Context\UserContext;
use KupShop\KupShopBundle\Util\Database\QueryHint;
use KupShop\KupShopBundle\Util\Price\Price;
use KupShop\KupShopBundle\Wrapper\PriceWrapper;
use KupShop\WatchdogBundle\Util\Watchdog;
use Symfony\Contracts\Service\Attribute\Required;
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Attribute\LiveAction;
use Symfony\UX\LiveComponent\Attribute\LiveArg;
use Symfony\UX\LiveComponent\DefaultActionTrait;

#[AsLiveComponent(template: '@Components/components/Product/Variations/PhotoList/PhotoList.1.html.twig')]
#[Component(1, [
    new Version(1),
])]
class PhotoList extends Variations
{
    use DefaultActionTrait;

    private UserContext $userContext;
    private CurrencyContext $currencyContext;
    private Watchdog $watchdog;

    public bool $showPricePerUnit = true;

    /** @return Variation[] */
    #[\Override]
    public function getVariations(): array
    {
        $this->multiFetch()->fetchVariationsEntities();
        $this->multiFetch()->prefetchPriceTypes();
        $this->multiFetch()->fetchMeasureUnits();

        return $this->product->variations;
    }

    public function getMeasureUnits($idVariation): ?array
    {
        if (!property_exists($this->product, 'measureUnits')) {
            return null;
        }

        $price = PriceWrapper::wrap($this->product->getProductPrice())->field_value_without_vat_no_rounding();
        $measureQuantity = toDecimal($this->product->measureUnits[$idVariation]['measure_quantity']);
        $measureUnit = toDecimal($this->product->measureUnits[$idVariation]['recalculate_to']);

        if (!$measureQuantity->isPositive() || !$measureUnit->isPositive()) {
            return null;
        }

        $pricePerUnit = $price->div($measureQuantity->div($measureUnit, 4), 4);

        return [
            'price' => new Price($pricePerUnit, $this->currencyContext->getActive(), $this->product->getProductPrice()->getVat()),
            'recalculate_to' => $this->product->measureUnits[$idVariation]['recalculate_to'],
            'unit_name' => $this->product->measureUnits[$idVariation]['short_name'],
        ];
    }

    private function getFirstLabelFromVariations(): array
    {
        $variations = $this->getVariations();

        return reset($variations)->getLabels();
    }

    public function getLabel(): string
    {
        $labels = $this->getFirstLabelFromVariations();
        if (count($labels) > 1) {
            return $this->translator->trans('variations.select', [], 'products');
        }

        return reset($labels)['title'];
    }

    public function getCustomTitle($id): string
    {
        $variation = $this->getVariationById($id);
        $labelValues = $variation->getValues();
        if (count($this->getFirstLabelFromVariations()) <= 1) {
            return reset($labelValues)['title'];
        }

        $labels = $variation->getLabels();
        $results = [];
        foreach ($labelValues as $key => $value) {
            $results[] = "{$labels[$key]['title']} : {$value['title']}";
        }

        return join('<br>', $results);
    }

    #[Required]
    public function setUserContext(UserContext $userContext): void
    {
        $this->userContext = $userContext;
    }

    #[Required]
    public function setCurrencyContext(CurrencyContext $currencyContext): void
    {
        $this->currencyContext = $currencyContext;
    }

    public function getActiveUserId(): ?int
    {
        return $this->userContext->getActiveId();
    }

    public function getIsWatchdog(?int $idVariation = null): bool
    {
        if (empty($this->getActiveUserId())) {
            return false;
        }

        return QueryHint::withRouteToMaster(function () use ($idVariation) {
            return $this->watchdog->isWatchdog((int) $this->getActiveUserId(), $this->id_product, $idVariation);
        });
    }

    #[LiveAction]
    public function addWatchdog(#[LiveArg] ?int $idVariation = null): void
    {
        if (empty($this->getActiveUserId())) {
            return;
        }

        $this->watchdog->addWatchdog($this->getActiveUserId(), $this->id_product, $idVariation);
    }

    #[LiveAction]
    public function removeWatchdog(#[LiveArg] int $idVariation): void
    {
        if (empty($this->getActiveUserId())) {
            return;
        }

        $this->watchdog->dropWatchdog($this->getActiveUserId(), $this->id_product, $idVariation, true, false);
    }

    #[Required]
    public function setWatchdog(Watchdog $watchdog): void
    {
        $this->watchdog = $watchdog;
    }
}
