<?php

namespace Drupal\user_provisioning\ProviderSpecific\APIHandler\UserAPIHandler;

use Drupal\Core\Config\ImmutableConfig;
use Drupal\user_provisioning\Helpers\moUserProvisioningLogger;
use Drupal\user_provisioning\ProviderSpecific\APIHandler\moAPIHandlerInterface;
use GuzzleHttp\Client;

class moUserKeycloakAPIHandler implements moAPIHandlerInterface {
    private string $keycloak_domain;

    private string $keycloak_client_id;

    private string $keycloak_client_secret;

    private string $keycloak_realm;

    private Client $http_client;

    private ImmutableConfig $config;

    private moUserProvisioningLogger $mo_logger;

    public function __constructor(){
        $this->config = \Drupal::config('keycloak_user_provisioning.settings');
        $this->http_client = \Drupal::httpClient();
        $this->mo_logger = new moUserProvisioningLogger();
        $this->keycloak_client_id = $this->config->get('keycloak_user_provisioning_client_id');
        $this->keycloak_client_secret = $this->config->get('keycloak_user_provisioning_client_secret');
        $this->keycloak_realm = $this->config->get('keycloak_user_provisioning_realm');
        $this->keycloak_domain = $this->config->get('keycloak_user_provisioning_base_url');
    }

    public function getKeyCloakAccessToken(){

        $this->config = \Drupal::config('keycloak_user_provisioning.settings');
        $this->http_client = \Drupal::httpClient();
        $this->mo_logger = new moUserProvisioningLogger();
        $this->keycloak_client_id = $this->config->get('keycloak_user_provisioning_client_id');
        $this->keycloak_client_secret = $this->config->get('keycloak_user_provisioning_client_secret');
        $this->keycloak_realm = $this->config->get('keycloak_user_provisioning_realm');
        $this->keycloak_domain = $this->config->get('keycloak_user_provisioning_base_url');

        $token_url = rtrim($this->keycloak_domain, '/') .
            '/realms/' . $this->keycloak_realm .
            '/protocol/openid-connect/token';

        $response = $this->http_client->request('POST', $token_url, [
            'timeout' => 30,
            'headers' => [
                'Content-Type' => 'application/x-www-form-urlencoded',
            ],
            'form_params' => [
                'grant_type' => 'client_credentials',
                'client_id' => $this->keycloak_client_id,
                'client_secret' => $this->keycloak_client_secret,
            ],
        ]);

        $token = json_decode($response->getBody()->getContents(), TRUE);

        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new \Exception('Invalid JSON response from Keycloak');
        }

        return $token['access_token'];
    }

    /**
     * @throws \Exception
     */
    public function get(string $query)
    {
        $access_token = $this->getKeyCloakAccessToken();

        if(empty($access_token)){
            throw new \Exception('Unable to get access token');
        }
        $url = $this->getUsersEndPointUrl($query);

        $options = ['timeout' => 30, 'headers' => ['Authorization' => 'Bearer ' . $access_token, 'Content-Type' => 'application/json',]];

        return $this->http_client->request('GET', $url, $options);
    }

    public function getUsersEndPointUrl(string $query)
    {
        return rtrim($this->keycloak_domain, '/') . '/admin/realms/' . $this->keycloak_realm . '/users/'. $query;
    }

    public function post(array $body)
    {
        $this->config = \Drupal::config('keycloak_user_provisioning.settings');
        $this->http_client = \Drupal::httpClient();
        $this->mo_logger = new moUserProvisioningLogger();
        $this->keycloak_client_id = $this->config->get('keycloak_user_provisioning_client_id');
        $this->keycloak_client_secret = $this->config->get('keycloak_user_provisioning_client_secret');
        $this->keycloak_realm = $this->config->get('keycloak_user_provisioning_realm');
        $this->keycloak_domain = $this->config->get('keycloak_user_provisioning_base_url');
        $access_token = $this->getKeyCloakAccessToken();
        $header = [
            'Accept' => 'application/json',
            'Authorization' => 'Bearer ' . $access_token,
            'Content-Type' => 'application/json',
        ];
        $user_creation_url = rtrim($this->keycloak_domain, '/')
            . '/admin/realms/'. $this->keycloak_realm . '/users';
        $options = [
            'headers' => $header,
            'json' => $body,
        ];

        return $this->http_client->request(
            'POST',
            $user_creation_url,
            $options,
        );
    }

    #[\Override] public function put(array $body)
    {
        // TODO: Implement put() method.
    }

    #[\Override] public function patch(array $patch)
    {
        // TODO: Implement patch() method.
    }

    #[\Override] public function delete($resource_id)
    {
        // TODO: Implement delete() method.
    }

    #[\Override] public function deactivate(array $body)
    {
        // TODO: Implement deactivate() method.
    }
}