<?php
class Dalten_Export_Api_Backend_Bazos implements Dalten_Export_Api_Backend_LoggableBackendInterface
{
    protected $_jmeno = '';
    protected $_heslo = '';
    /**
     * @var Dalten_Http_ClientInterface
     */
    private $httpClient;

    public function __construct(Dalten_Http_Client $httpClient)
    {
        $this->httpClient = $httpClient;
    }

    public function prihlasit($jmeno, $heslo): bool
    {
        $this->_jmeno = $jmeno;
        $this->_heslo = $heslo;

        $seznamInzeratu = $this->httpClient->get(sprintf('https://rk.bazos.cz/ads.php?idcomp=%s&password=%s&limit=10000&offset=0', $jmeno, $heslo));
        $responseJson = json_decode($seznamInzeratu, true);

        if (is_null($responseJson)) {
            return false;
        }

        if (isset($responseJson['error_code'])) {
            return false;
        }

        return true;
    }

    public function pridani($data, $obrazky)
    {
        $data['idcomp'] = $this->_jmeno; // ID RK
        $data['heslo'] = $this->_heslo;

        $obrazky = array_slice($obrazky, 0, 10);
        $poslaneSoubory = [];
        foreach ($obrazky as $ord=>$obrazek) {
            $poslaneSoubory['souborp' . ($ord > 0 ? $ord+1 : '')] = $obrazek['soubor'];
        }

        $responseXml = $this->httpClient->post('http://reality.bazos.cz/insertport.php', $data, $poslaneSoubory);

        return simplexml_load_string($responseXml);
    }

    public function smazani($id)
    {
        $responseXml = $this->httpClient->post('https://reality.bazos.cz/topdelport.php', [
            'idcomp'=> $this->_jmeno,
            'heslo' => $this->_heslo,
            'idad' => $id,
            'operace' => 'smazat'
        ]);

        return simplexml_load_string($responseXml);
    }

    public function topovani($id)
    {
        $responseXml = $this->httpClient->post('https://reality.bazos.cz/topdelport.php', [
            'idcomp'=> $this->_jmeno,
            'heslo' => $this->_heslo,
            'idad' => $id,
            'operace' => 'topovat'
        ]);

        return simplexml_load_string($responseXml);
    }

    public function getAnswers(DateTime $from, DateTime $to): array
    {
        $responseBody = $this->httpClient->get(
            sprintf(
                'https://rk.bazos.cz/answers.php?idcomp=%s&password=%s&limit=1000&offset=0&date_from=%d&date_to=%d',
                $this->_jmeno,
                $this->_heslo,
                $from->format('U'),
                $to->format('U')
            )
        );

        $htmlErrorCode = $this->detectKnownHtmlErrorResponse($responseBody);
        if ($htmlErrorCode !== null) {
            return [
                'error_code' => $htmlErrorCode < 300 ? 500 : $htmlErrorCode, // abychom nevrátili omylem 0 nebo 200
                'message' => sprintf('HTML error page (%d) returned instead of JSON.', $htmlErrorCode),
            ];
        }

        try {
            return $decoded = json_decode($responseBody, true, 512, JSON_THROW_ON_ERROR);
        } catch (\JsonException $e) {
            return ['error_code' => 500, 'message' => 'Not valid JSON.'];
        }
    }

    public function setLogger(Dalten_Export_Api_Backend_Logger_LoggerInterface $logger)
    {
        $this->httpClient->setLogger($logger);
        return $this;
    }

    public function removeLogger()
    {
        $this->httpClient->removeLogger();
        return $this;
    }

    private function detectKnownHtmlErrorResponse(string $responseBody): ?int
    {
        $responseBody = strtolower(trim($responseBody));

        $titleMatch = [];

        // Příklad: <html> <head><title>400 Bad Request</title></head> <body> <center><h1>400 Bad Request</h1></center> <hr><center>nginx</center> </body> </html>

        if (
            str_contains($responseBody, '<html')
            && str_contains($responseBody, '<h1>')
            && str_contains($responseBody, '<center>nginx</center>')
            && preg_match('~<title>\s*(\d{3})\s+[^<]+\s*</title>~', $responseBody, $titleMatch)
        ) {
            return (int) $titleMatch[1];
        }

        return null;
    }

}
