<?php
declare(strict_types = 1);

namespace BewitchingSource\CreamailerAPI;

use GuzzleHttp\Client;

class Resource {
    public function __construct($parent) {
        $this->parent = $parent;
    }

    public function form_uri(array $xs = []): string {
        $ys = array_merge([$this->resource], $xs);
        return implode("/", $ys) . ".json";
    }

    public function get_response_content($response) {
        $body = $response->getBody();
        $body->rewind();
        $contents = $body->getContents();

        return !empty($contents)
            ? \json_decode($contents)
            : (object)[];
    }

    public function get(string $id = null, array $payload = []) {
        $xs = $id ? [$id] : [];
        return $this->request("GET", $this->form_uri($xs), $payload);
    }
    
    public function put(string $id, array $payload) {
        return $this->request("PUT", $this->form_uri([$id]), $payload);
    }
    
    public function post(string $id, array $payload) {
        return $this->request("POST", $this->form_uri([$id]), $payload);
    }
    
    public function delete(string $id, array $payload) {
        return $this->request("DELETE", $this->form_uri([$id]), $payload);
    }

    public function request(string $method, string $resource, array $payload = []) {
        $r = null;
        $ok = false;
        $q = isset($payload['query'])
            ? $payload["query"]
            : [];
        $j = isset($payload["json"])
            ? $payload["json"]
            : [];
        $qs = empty($q)
            ? ""
            : "?" . \http_build_query($q);
        $uri = $this->parent->api_settings->url . $resource . $qs;
        $payload_ = array_merge(
            $this->parent->headers($uri, $j),
            $payload
        );

        try {
            $r = $this->parent->client->request($method, $resource, $payload_);
            $ok = true;
        } catch (\GuzzleHttp\Exception\ClientException $e) {
            $r = $e->getResponse();
        }

        return (object)[
            "is_ok" => $ok,
            "status" => $r->getStatusCode(),
            "response" => $r,
            "body" => $this->get_response_content($r)
        ];
    }
}
