<?php

declare(strict_types=1);

namespace KupShop\SellerBundle\Context;

use KupShop\I18nBundle\Util\IPGeoLocator;
use KupShop\KupShopBundle\Context\ContextInterface;
use KupShop\KupShopBundle\Context\EmptiableContext;
use KupShop\SellerBundle\Utils\SellerUtil;
use Symfony\Component\HttpFoundation\RequestStack;

class SellerContext implements ContextInterface, EmptiableContext
{
    protected ?string $activeId = null;

    protected SellerUtil $sellerUtil;
    protected RequestStack $requestStack;
    protected IPGeoLocator $geoLocator;

    private bool $loaded = false;

    public function __construct(SellerUtil $sellerUtil, RequestStack $requestStack, IPGeoLocator $geoLocator)
    {
        $this->sellerUtil = $sellerUtil;
        $this->requestStack = $requestStack;
        $this->geoLocator = $geoLocator;
    }

    public function remember(string $id): void
    {
        if (!($request = $this->requestStack->getMainRequest())) {
            return;
        }

        $request->attributes->set('sellerId', $id);
    }

    public function activate(string $id): bool
    {
        if (!($this->getSupported()[$id] ?? false)) {
            return false;
        }

        $this->activeId = $id;

        return true;
    }

    public function getActiveId(): ?string
    {
        if (!$this->activeId && !$this->loaded) {
            $this->activeId = $this->loadActive();
        }

        return $this->activeId;
    }

    public function getActive(): ?array
    {
        return $this->getSupported()[$this->getActiveId()] ?? null;
    }

    public function getSupported(): array
    {
        return $this->sellerUtil->getSellers();
    }

    public function getDefaultId(): ?int
    {
        return null;
    }

    protected function loadActive(): ?string
    {
        if (!($request = $this->requestStack->getMainRequest())) {
            return null;
        }

        if (!($sellerId = $request->cookies->get('sellerId'))) {
            if ($info = $this->geoLocator->getInfo(true)) {
                if (!empty($info->city)) {
                    if ($seller = $this->sellerUtil->getClosestSeller((float) $info->latitude, (float) $info->longitude)) {
                        $sellerId = $seller['id'];
                    }
                }
            }

            if (!$sellerId) {
                $sellerId = $this->getDefaultId();
            }

            if (!findModule(\Modules::PROXY_CACHE)) {
                $request->attributes->set('sellerId', $sellerId);
            }
        }

        if ($sellerId) {
            return (string) $sellerId;
        }

        return null;
    }

    public function clearCache(): void
    {
        $this->loaded = false;
        $this->activeId = null;
    }

    public function isValid(string $id): bool
    {
        return true;
    }

    public function forceEmpty(): void
    {
        $this->loaded = true;
        $this->activeId = null;
    }

    public function isEmpty(): bool
    {
        return $this->loaded && $this->activeId === null;
    }
}
