<?php

class HikvisionClient
{
    private string $ip;
    private int $port;
    private string $user;
    private string $pass;
    private string $protocol;
    private int $timeout;

    public function __construct(array $config)
    {
        $this->ip       = $config['ip'] ?? '';
        $this->port     = (int)($config['port'] ?? 80);
        $this->user     = $config['user'] ?? '';
        $this->pass     = $config['pass'] ?? '';
        $this->protocol = $config['protocol'] ?? 'http';
        $this->timeout  = (int)($config['timeout'] ?? 20);
    }

    public function get(string $path, array $headers = []): array
    {
        return $this->request('GET', $path, null, $headers);
    }

    public function post(string $path, $body = null, array $headers = []): array
    {
        return $this->request('POST', $path, $body, $headers);
    }

    public function request(string $method, string $path, $body = null, array $headers = []): array
    {
        $url = $this->buildUrl($path);

        $ch = curl_init($url);

        $defaultHeaders = [
            'Accept: application/json, application/xml, text/plain, */*',
        ];

        if (is_array($body)) {
            $body = json_encode($body, JSON_UNESCAPED_UNICODE);
            $defaultHeaders[] = 'Content-Type: application/json';
        }

        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPAUTH       => CURLAUTH_DIGEST,
            CURLOPT_USERPWD        => $this->user . ':' . $this->pass,
            CURLOPT_CUSTOMREQUEST  => strtoupper($method),
            CURLOPT_TIMEOUT        => $this->timeout,
            CURLOPT_CONNECTTIMEOUT => 10,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_HTTPHEADER     => array_merge($defaultHeaders, $headers),
        ]);

        if ($body !== null) {
            curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
        }

        $response = curl_exec($ch);
        $errno    = curl_errno($ch);
        $error    = curl_error($ch);
        $code     = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $info     = curl_getinfo($ch);

        curl_close($ch);

        return [
            'ok'         => ($errno === 0 && $code >= 200 && $code < 300),
            'http_code'  => $code,
            'body'       => $response,
            'error'      => $errno ? "cURL errno {$errno}: {$error}" : null,
            'curl_info'  => $info,
            'url'        => $url,
            'method'     => strtoupper($method),
        ];
    }

    private function buildUrl(string $path): string
    {
        $path = '/' . ltrim($path, '/');
        return "{$this->protocol}://{$this->ip}:{$this->port}{$path}";
    }
}