<?php

namespace KupShop\KupShopBundle\Views;

use KupShop\KupShopBundle\Exception\PermanentRedirectException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener;

class View extends BaseView implements RouteAwareResponderInterface
{
    protected string $smartyFallback = 'index';

    // Fallback entrypoint to have header/footer covered
    protected string $entrypoint = 'home';

    protected bool $components = false;

    /** @var bool */
    public $responseCacheEnabled = false;

    protected $proxyCacheEnabled = false;

    public function getResponse(?Request $request = null)
    {
        /** @var Request $request */
        if (!$request) {
            $request = $this->request ?? false;
        }

        if ($request && ($this->proxyCacheEnabled['revalidate'] ?? false)) {
            $lastModifiedTimestamp = $this->getLastModifiedDate()->getTimestamp();

            if (is_numeric($this->proxyCacheEnabled['revalidate'])) {
                $diff = max((new \DateTime('now'))->getTimestamp() - $lastModifiedTimestamp, 0);
                $forceRevalidationIndex = floor($diff / $this->proxyCacheEnabled['revalidate']);
                $lastModifiedTimestamp .= '-'.$forceRevalidationIndex;
            }
            $etag = md5($lastModifiedTimestamp);

            if (in_array('"'.$etag.'"', $request->getETags())) {
                $response = new Response(status: 304);
                $this->setProxyCacheHeaders($response, $etag);

                return $response;
            }
        }

        if ($request) {
            $request->attributes->set('view', $this);
        }

        // Collect template variables
        $vars = $this->getTemplateVariables();

        // Assign template variables to template
        $this->addTemplateVariables($vars);

        if (getVal('SMARTY_DEBUG')) {
            // If SMARTY_DEBUG, we have to simulate rendering to output to display DEBUG
            ob_start();
            $this->renderToOutput();
            $response = new Response(ob_get_contents());
            ob_end_clean();
        } else {
            // Render template and return result
            $response = new Response($this->render());
        }

        if (!$this->getShowInSearch() || !isLive()) {
            $response->headers->set('X-Robots-Tag', 'noindex, nofollow');
        }

        if ($this->proxyCacheEnabled && !getAdminUser()) {
            $this->setProxyCacheHeaders($response, $etag ?? null);
        } else {
            $response->headers->addCacheControlDirective('must-revalidate', true);
            $response->headers->addCacheControlDirective('no-store', true);
        }

        return $response;
    }

    protected function setProxyCacheHeaders($response, $etag = null)
    {
        $response->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER, 'true');
        $response->setMaxAge(0);
        $response->setSharedMaxAge($this->proxyCacheEnabled['ttl'] ?? 30 * 60);
        $response->setPublic();

        if ($etag) {
            $response->headers->addCacheControlDirective('proxy-revalidate');
            $response->setEtag($etag);
        }
    }

    protected function getLastModifiedDate(): \DateTime
    {
        return new \DateTime('now');
    }

    public function getTemplateData()
    {
        return $this->templateVariables;
    }

    public function getEntrypoint(): string
    {
        return $this->entrypoint;
    }

    public function getCorrectUrl(): ?string
    {
        return null;
    }

    public function checkCorrectUrl(Request $request): void
    {
        if (!($correctUrl = $this->getCorrectUrl())) {
            return;
        }

        $urlCorrect = parse_url($correctUrl, PHP_URL_PATH);
        $urlCurrent = $this->getCurrentUrl($request);

        if ($urlCurrent === $urlCorrect) {
            return;
        }

        $query = parse_url($request->getRequestUri(), PHP_URL_QUERY);
        $query = $query ? "?{$query}" : '';

        throw new PermanentRedirectException($urlCorrect.$query);
    }

    protected function getCurrentUrl(Request $request): string
    {
        return urldecode(parse_url($request->getRequestUri(), PHP_URL_PATH));
    }
}
