<?php

namespace YSquare\Shipcloud\Application\Controller\Admin;

use YSquare\Shipcloud\Core\Exception\ShipcloudApiException;

class AdminRestController
{
    protected $adminSettings;
    protected $base_url = "https://api.shipcloud.io";
    protected $api_key;
    protected $headers = [
        'Accept: application/json',
        'Content-Type: application/json',
        'Affiliate-ID: plugin.oxid.2odmzYta',
    ];

    public function __construct()
    {
        $this->adminSettings = oxNew(AdminSettings::class, 'main_settings');

        if ($this->adminSettings->sandboxMode) {
            $this->api_key = $this->adminSettings->getSettings('SANDBOX_API_KEY');
        } else {
            $this->api_key = $this->adminSettings->getSettings('API_KEY');
        }
    }

    /**
     * @param $url
     * @return array
     * @throws ShipcloudApiException
     */
    public function delete($url)
    {
        $ch = curl_init($this->base_url . $url);

        // To save response in a variable from server, set headers;
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $this->headers);
        curl_setopt($ch, CURLOPT_USERPWD, $this->api_key);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");

        // Get response
        $response = curl_exec($ch);
        $info = curl_getinfo($ch);
        $result = json_decode($response, true);

        if (in_array($info['http_code'], [200, 204])) {
            return $result;
        } else {
            /** @var  ShipcloudApiException $apiException */
            throw new ShipcloudApiException(implode("<br>", $result['errors']), $info['http_code']);
        }
    }

    public function setApiKey($api_key)
    {
        $this->api_key = $api_key;
    }

    /**
     * @param $data
     * @return mixed|string
     * @throws ShipcloudApiException
     */
    public function getShippingCosts($data): string
    {
        $url = "https://api.shipcloud.io/v1/shipment_quotes";
        $result = $this->post($url, $data);

        if ($result['shipment_quote']) {
            return $result['shipment_quote']['price'];
        }
        return "";
    }

    /**
     * @param $url
     * @param $data
     * @return array
     * @throws ShipcloudApiException
     */
    protected function post($url, $data): array
    {
        $ch = curl_init($url);

        // To save response in a variable from server, set headers;
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $this->headers);
        curl_setopt($ch, CURLOPT_USERPWD, $this->api_key);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

        // Get response
        $response = curl_exec($ch);
        $info = curl_getinfo($ch);
        $result = json_decode($response, true);

        if ($info['http_code'] == 200) {
            return $result;
        } else {
            throw new ShipcloudApiException(implode("<br>", $result['errors']), $info['http_code']);
        }
    }

    /**
     * @param $data
     * @param $id
     * @return array
     * @throws ShipcloudApiException
     */
    public function createShipment($data, $id): array
    {
        if (isset($id) and $id != "") {
            $url = "https://api.shipcloud.io/v1/shipments/" . $id;
            return $this->put($url, $data);
        } else {
            $url = "https://api.shipcloud.io/v1/shipments";
            return $this->post($url, $data);
        }
    }

    /**
     * @param $url
     * @param $data
     * @return array
     * @throws ShipcloudApiException
     */
    protected function put($url, $data): array
    {
        $ch = curl_init($url);

        // To save response in a variable from server, set headers;
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $this->headers);
        curl_setopt($ch, CURLOPT_USERPWD, $this->api_key);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

        // Get response
        $response = curl_exec($ch);
        $info = curl_getinfo($ch);
        $result = json_decode($response, true);

        if ($info['http_code'] == 200) {
            return $result;
        } else {
            throw new ShipcloudApiException(implode("<br>", $result['errors']), $info['http_code']);
        }
    }

    /**
     * @param $data
     * @return mixed
     * @throws ShipcloudApiException
     */
    public function createPickupRequest($data): array
    {
        $url = "https://api.shipcloud.io/v1/pickup_requests";
        return $this->post($url, $data);
    }

    /**
     * @return array
     * @throws ShipcloudApiException
     */
    public function getCarriers(): array
    {
        $url = "https://api.shipcloud.io/v1/carriers";
        return $this->get($url);
    }

    /**
     * @param $url
     * @return array
     * @throws ShipcloudApiException
     */
    protected function get($url): array
    {
        $ch = curl_init($url);

        // To save response in a variable from server, set headers;
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $this->headers);
        curl_setopt($ch, CURLOPT_USERPWD, $this->api_key);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

        // Get response
        $response = curl_exec($ch);
        $info = curl_getinfo($ch);
        $result = json_decode($response, true);

        if ($info['http_code'] == 200) {
            return $result;
        } else {
            throw new ShipcloudApiException(implode("<br>", $result['errors']), $info['http_code']);
        }
    }
}
