<?php

namespace App\Infrastructure\External\Api;

use Psr\Http\Message\ResponseInterface;
use stdClass;

/**
 * Class ResponseHandler Обработчик ответа API.
 *
 * После того как получили ответ api, оборачиваем его обработчик из которого мы можем получить ответ в любом формате,
 * а так же применит дополнительную фильтрацию или корректировку ответа
 */
class ResponseHandler
{
    protected ResponseInterface $response;
    private array $contentFilters = [];

    public function contentIsEmpty(): bool
    {
        return empty($this->response->getBody()->getSize());
    }

    /**
     * Возвращает ответ в текстовом виде, применит фильтры при их наличие.
     *
     * @return string
     */
    public function getContent(): string
    {
        $content = (string)$this->response->getBody();

        return $this->filterContent($content);
    }

    /**
     * Добавляет фильтр контента иногда необходимо поправить ответ, что бы в итоге возвращался нужный тип данных.
     * Бывает иногда сервер, возвращает массив данных и при преобразовании json_decode возвращается
     * массив вместо stdClass.
     */
    public function addContentFilter(callable $filter): self
    {
        $this->contentFilters[] = $filter;

        return $this;
    }

    /**
     * Преобразует json в объект
     *
     * @return stdClass
     */
    public function getContentStdFromJson(): stdClass
    {
        return json_decode($this->getContent());
    }

    public function getContentAsBinaryStingResult(): BinaryStringFileResult
    {
        return new BinaryStringFileResult($this->getContent());
    }

    /**
     * @return stdClass[]
     */
    public function getContentArrayStdFromJson(): array
    {
        return json_decode($this->getContent());
    }

    /**
     * Преобразует json в массив.
     */
    public function getContentJsonToArray(): array
    {
        return $this->contentIsEmpty() ? [] : json_decode($this->getContent(), true);
    }

    /**
     * Устанавливает ответ в обработчик.
     */
    public function setResponse(ResponseInterface $response): self
    {
        $this->response = $response;

        return $this;
    }

    /**
     * Фильтруем ответ
     *
     * @param string $content
     *
     * @return string
     */
    private function filterContent(string $content): string
    {
        if (!$this->contentFilters) {
            return $content;
        }

        foreach ($this->contentFilters as $filter) {
            $content = $filter($content);
        }

        $this->contentFilters = [];

        return $content;
    }
}
