<?php

namespace Win7\Application\Controller;

use Slim\Exception\HttpBadRequestException;
use Slim\Exception\HttpNotFoundException;
use Slim\Views\Twig;
use Psr\Http\Message\ServerRequestInterface as Request;
use DI\Annotation\Inject;
use Win7\Application\Payload\PayloadInterface;

/**
 * @author Jerfeson Guerreiro <jerfeson_guerreiro@hotmail.com>
 * @author Thiago Daher
 */
abstract class Controller
{

    /**
     * @Inject()
     * @var Twig
     */
    public Twig $view;

    /**
     * @Inject()
     * @var \Psr\Http\Message\ServerRequestInterface
     */
    public Request $request;

    /**
     * Retorna o BODY da requisição em formato JSON.
     *
     * @return array
     * @throws HttpBadRequestException
     */
    protected function getJsonBody(): array
    {
        $input = json_decode(file_get_contents('php://input'), true);

        if (json_last_error() !== JSON_ERROR_NONE || !is_array($input)) {
            throw new HttpBadRequestException($this->request);
        }

        return $input;
    }

    /**
     * @param \Win7\Application\Payload\PayloadInterface $payload
     * @return void
     */
    protected function respondWithPayload(PayloadInterface $payload): void
    {
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode($payload->toArray());
    }

    /**
     * @param array $data
     * @return void
     */
    protected function respondWithJson(array $data): void
    {
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode($data);
    }

    /**
     * @param string|null $template
     * @param array $params
     * @throws \Twig\Error\LoaderError
     * @throws \Twig\Error\RuntimeError
     * @throws \Twig\Error\SyntaxError
     */
    protected function respondWithHtml(?string $template = null, array $params = []): void
    {
        if (!$this->getView()->getLoader()->exists($template)) {
            throw new HttpNotFoundException($this->getRequest());
        }

        $response = $this->getView()->fetch($template, $params);
        echo $response;
    }

    /**
     * @return \Slim\Views\Twig
     */
    public function getView(): Twig
    {
        return $this->view;
    }

    /**
     * @return \Psr\Http\Message\ServerRequestInterface
     */
    public function getRequest(): Request
    {
        return $this->request;
    }

    /**
     * @param string $name
     * @param $default
     * @return mixed|null
     */
    protected function getQueryParam(string $name, $default = null)
    {
        return $this->getRequest()->getQueryParams()[$name] ?? $default;
    }

    /**
     * @param string $name
     * @param $default
     * @return mixed|null
     */
    protected function getPostParam(string $name, $default = null)
    {
        return $this->getRequest()->getParsedBody()[$name] ?? $default;
    }

    /**
     * @return \Slim\Psr7\UploadedFile[]
     */
    protected function getFiles(): array
    {
        return $this->getRequest()->getUploadedFiles();
    }

    /**
     * @return array|object|null
     */
    protected function getParsedBody()
    {
        return $this->getRequest()->getParsedBody() ?? [];
    }
}