<?php

namespace xlvask\classes;
require_once WD . '/modules/xlvask/interfaces/xlvask_endpoints_i.php';
require_once WD . '/modules/xlvask/classes/xlvask_request.php';

use Exception;
use helpers\xlvask_customer;
use helpers\xlvask_vehicle;
use xlvask\interfaces\xlvask_endpoints_i;

abstract class xlvask_endpoints extends xlvask_request implements xlvask_endpoints_i
{

    /**
     * @inheritDoc
     * @throws Exception If the module is not enabled
     * @throws Exception If the username is not set
     * @throws Exception If the password is not set
     * @throws Exception If the response is not valid JSON
     * @throws Exception If the response is not successful
     * @throws Exception If there is an error with the request
     */
    public function getUsageLog(?string $dateFrom = null, ?string $regNr = null, ?string $vehicleId = null, ?string $customerId = null): array
    {
        $url = $this->config->api_url . '/usageLog';

        $params = [
            'dateFrom' => $dateFrom,
            'regNr' => $regNr,
            'vehicleId' => $vehicleId,
            'customerId' => $customerId,
        ];

        // Remove null values from the params array
        $params = array_filter($params, function ($value) {
            return !is_null($value);
        });

        return $this->sendRequest(
            $url,
            'GET',
            $params,
            [self::getAuthHeader(),]
        );
    }

    /**
     * @inheritDoc
     */
    public function getAuthHeader(): string
    {
        $this->requireModuleEnabled();
        $username = $this->config->username->getVariableValue();
        $password = $this->config->password->getVariableValue();
        if (empty($username)) {
            throw new Exception('Username is not set');
        }
        if (empty($password)) {
            throw new Exception('Password is not set');
        }
        // Generate the Basic Auth header
        return $this->generateBasicAuthHeader(
            (string)$username,
            (string)$password
        );
    }

    /**
     * @inheritDoc
     * @throws Exception If the module is not enabled
     * @throws Exception If the username is not set
     * @throws Exception If the password is not set
     * @throws Exception If the response is not valid JSON
     * @throws Exception If the response is not successful
     * @throws Exception If there is an error with the request
     */
    public function getVehicles(?string $customerId = null, ?string $vehicleId = null, ?string $registrationNumber = null, ?string $changeDate = null): array
    {
        $url = $this->config->api_url . '/vehicles';

        $params = [
            'customerId' => $customerId,
            'vehicleId' => $vehicleId,
            'registrationNumber' => $registrationNumber,
            'changeDate' => $changeDate,
        ];

        // Remove null values from the params array
        $params = array_filter($params, function ($value) {
            return !is_null($value);
        });

        return $this->sendRequest(
            $url,
            'GET',
            $params,
            [self::getAuthHeader(),]
        );
    }

    /**
     * @inheritDoc
     * @throws Exception If the module is not enabled
     * @throws Exception If the username is not set
     * @throws Exception If the password is not set
     * @throws Exception If the response is not valid JSON
     * @throws Exception If the response is not successful
     * @throws Exception If there is an error with the request
     */
    public function getCustomers(?string $customerId = null, ?string $customerName = null, ?string $customerExternalId = null, ?string $vatNumber = null, ?string $changeDate = null, ?bool $users = null): array
    {
        $url = $this->config->api_url . '/customers';

        $params = [
            'customerId' => $customerId,
            'customerName' => $customerName,
            'customerExternalId' => $customerExternalId,
            'vatNumber' => $vatNumber,
            'changeDate' => $changeDate,
            'users' => $users,
        ];

        // Remove null values from the params array
        $params = array_filter($params, function ($value) {
            return !is_null($value);
        });

        return $this->sendRequest(
            $url,
            'GET',
            $params,
            [self::getAuthHeader(),]
        );
    }

    /**
     * @inheritDoc
     * @throws Exception If the module is not enabled
     * @throws Exception If the username is not set
     * @throws Exception If the password is not set
     * @throws Exception If the response is not valid JSON
     * @throws Exception If the response is not successful
     * @throws Exception If there is an error with the request
     * @throws Exception If the vehicle data is not valid
     * @throws Exception If the vehicle creation fails
     */
    public function createVehicle(xlvask_vehicle $xlvaskVehicle): array
    {
        $url = $this->config->api_url . '/vehicles';
        return $this->sendRequest(
            $url,
            'POST',
            $xlvaskVehicle->toArray(),
            [self::getAuthHeader(),]
        );
    }

    /**
     * @inheritDoc
     * @throws Exception If the module is not enabled
     * @throws Exception If the username is not set
     * @throws Exception If the password is not set
     * @throws Exception If the response is not valid JSON
     * @throws Exception If the response is not successful
     * @throws Exception If there is an error with the request
     * @throws Exception If the vehicle data is not valid
     * @throws Exception If the vehicle update fails
     * @note This method deletes a vehicle from the XLVask API. (This is an irreversible destructive action.)
     */
    public function deleteVehicle(xlvask_vehicle $xlvaskVehicle): array
    {
        // Make sure the vehicleId is set
        if (empty($xlvaskVehicle->vehicleId)) {
            throw new Exception('Vehicle ID is not set');
        }
        $url = $this->config->api_url . '/vehicles/' . $xlvaskVehicle->vehicleId;
        return $this->sendRequest(
            $url,
            'DELETE',
            [],
            [self::getAuthHeader(),]
        );
    }

    /**
     * @inheritDoc
     * @throws Exception If the module is not enabled
     * @throws Exception If the username is not set
     * @throws Exception If the password is not set
     * @throws Exception If the response is not valid JSON
     * @throws Exception If the response is not successful
     * @throws Exception If there is an error with the request
     * @throws Exception If the vehicle data is not valid
     * @throws Exception If the vehicle update fails
     */
    public function updateVehicle(xlvask_vehicle $xlvaskVehicle): array
    {
        $url = $this->config->api_url . '/vehicles';
        return $this->sendRequest(
            $url,
            'PUT',
            $xlvaskVehicle->toArray(),
            [self::getAuthHeader(),]
        );
    }

    /**
     * @inheritDoc
     * @throws Exception If the module is not enabled
     * @throws Exception If the username is not set
     * @throws Exception If the password is not set
     * @throws Exception If the response is not valid JSON
     * @throws Exception If the response is not successful
     * @throws Exception If there is an error with the request
     * @see xlvask_customer
     * @see xlvask_customer::isValid()
     */
    public function createCustomer(xlvask_customer $xlvaskCustomer): array
    {
        $url = $this->config->api_url . '/customers';
        return $this->sendRequest(
            $url,
            'POST',
            $xlvaskCustomer->toArray(),
            [self::getAuthHeader(),]
        );
    }

    /**
     * @inheritDoc
     * @throws Exception If the module is not enabled
     * @throws Exception If the username is not set
     * @throws Exception If the password is not set
     * @throws Exception If the response is not valid JSON
     * @throws Exception If the response is not successful
     * @throws Exception If there is an error with the request
     */
    public function updateCustomer(xlvask_customer $xlvaskCustomer): array
    {
        $url = $this->config->api_url . '/customers';
        return $this->sendRequest(
            $url,
            'PUT',
            $xlvaskCustomer->toArray(),
            [self::getAuthHeader(),]
        );
    }

}