<?php

namespace Skeleton;

use Helpers\Ariane\Ariane;
use Helpers\Log\LogSysteme;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamInterface;

class Request
{

    /** @var ServerRequestInterface */
    protected $request;

    protected $resultAttribut;

    /**
     * router
     *
     * @var Router
     */
    protected $router;

    public function __construct($request, Router $router)
    {
        $this->request = $request;
        $this->router = $router;
    }

    /**
     * getParsedBody
     *
     * @return array<mixed>
     */
    public function getParsedBody(bool $ignoreCSRF = false, bool $deleteToken = true): array
    {
        $array = $this->request->getParsedBody();
        
        $CSRFTokens = [];
        /** @phpstan-ignore-next-line */
        foreach ($array as $key => $value) {
            if (strpos(strtolower($key), "tokencsrf") !== false) {
                $CSRFTokens[$key] = $value;
            }
        }

        $array = array_merge(
            Ariane::getPostArianArray(),
            (array) $array
        );

        if (isset($_SESSION['redirect_post'])) {
            $array = array_merge(
                $array,
                $_SESSION['redirect_post']
            );
            unset($_SESSION['redirect_post']);
        }

        if ($ignoreCSRF == true) {
            if (count($CSRFTokens) > 0 && $deleteToken == true) {
                foreach ($CSRFTokens as $key => $value) {
                    unset($array[$key]);
                }
            }

            if (isset($array['tokenCSRF']) && $deleteToken == true) {
                unset($array['tokenCSRF']);
            }
            return $array;
        }

        /**
         * CSRF : Prise en compte de la gestion du CSRF
         */

        $resultConditionCSRF = \Helpers\Securite\CSRF::checkCSRFTokenPair($CSRFTokens);
        if (isset($array['tokenCSRF'])) {
            $resultConditionCSRF = \Helpers\Securite\Securite::ifCSRFValid($array);
        }

        if (count($array) && $resultConditionCSRF) {
            if (count($CSRFTokens) > 0 && $deleteToken == true) {
                foreach ($CSRFTokens as $key => $value) {
                    unset($array[$key]);
                }
            }
            if (isset($array['tokenCSRF']) && $deleteToken == true) {
                unset($array['tokenCSRF']);
            }
            return $array;
        } else {
            if (($CSRFTokens || isset($array['tokenCSRF'])) && $resultConditionCSRF === false) {
                \Helpers\Log\LogSysteme::prefixErrorLog("ERREUR CSRF");
                header('Location : ' . $this->router->generateUri('Index.Index.redirectionCSRF'));
                @exit();
            }
            return [];
        }
    }

    public function getAttribute($id)
    {
        $this->resultAttribut = $this->request->getAttribute($id);
        if ($this->resultAttribut && strpos($this->resultAttribut, '%') !== false) {
            //return utf8_encode(rawurldecode($this->request->getAttribute($id)));
            return urldecode($this->request->getAttribute($id));
        } else {
            return $this->resultAttribut;
        }
    }

    /**
     * @return string[]
     */
    public function getAttributes()
    {
        return array_map('urldecode', $this->request->getAttributes());
    }

    public function getMethod()
    {
        return $this->request->getMethod();
    }

    /**
     * @return \GuzzleHttp\Psr7\UploadedFile[]
     */
    public function getUploadedFiles()
    {
        return $this->request->getUploadedFiles();
    }
    /**
     * Gets the body of the message.
     *
     * @return \Psr\Http\Message\StreamInterface Returns the body as a stream.
     */
    public function getBody()
    {
        return $this->request->getBody();
    }

    /**
     * getServerParams
     *
     * @return array<mixed>
     */
    public function getServerParams()
    {
        return $this->request->getServerParams();
    }

    /**
     * getQueryParams
     *
     * @return array<mixed>
     */
    public function getQueryParams()
    {
        return $this->request->getQueryParams();
    }

    /**
     * @return array<array<string>>
     */
    public function getHeaders(): array
    {
        return $this->request->getHeaders();
    }

    public function isAjax() :bool
    {
        return strtolower(
            $this->request->getHeader('X-Requested-With')[0] ?? ''
        ) === 'xmlhttprequest';
    }
}
