<?php

namespace App\Services;

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\ServiceProvider;

class Auth0Service extends ServiceProvider {
    public function getToken() {
        $token = Redis::get('auth0_token');
        if (empty($token)) {
            $auth0Token = $this->queryAuth0ForToken();
            if ($auth0Token == null)
                return null;
            Redis::set(
                'auth0_token', $auth0Token['access_token'],
                'EX', $auth0Token['expires_in']
            );
            $token = $auth0Token['access_token'];
        }
        return $token;
    }

    private function queryAuth0ForToken() {
        $endpoint = env('AUTH0_DOMAIN') . 'oauth/token';
        $payload = [
            "client_id" => env('AUTH0_CLIENT_ID'),
            "client_secret" => env('AUTH0_CLIENT_SECRET'),
            "audience" => env('AUTH0_API_AUD'),
            "grant_type" => "client_credentials"
        ];

        $response = Http::post($endpoint, $payload);

        $json = $response->json();

        if (array_key_exists('error', $json)) {
            return null;
        } else {
            return $json;
        }
    }

    public function getUser($id) {
        $endpoint = env('AUTH0_DOMAIN') . 'api/v2/users/' . $id;
        return Http::withToken($this->getToken())
            ->get($endpoint)
            ->json();
    }

    public function createUser($email, $username, $password, $metadata) {
        $endpoint = env('AUTH0_DOMAIN') . 'api/v2/users';

        $payload = [
            "email" => $email,
            "username" => $username,
            "password" => $password,
            "app_metadata" => $metadata,
            "connection" => env('AUTH0_CONNECTION'),
            "verify_email" => env('AUTH0_VERIFY_MAIL'),
        ];

        return Http::withToken($this->getToken())
            ->post($endpoint, $payload)
            ->json();
    }

    public function updateUser($auth0_id, $email, $username, $password, $metadata) {
        $endpoint = env('AUTH0_DOMAIN') . 'api/v2/users/' . $auth0_id;

        $payload = ["connection" => env('AUTH0_CONNECTION')];

        if ($email) $payload["email"] = $email;
        if ($username) $payload["username"] = $username;
        if ($password) $payload["password"] = $password;
        if ($metadata) $payload["app_metadata"] = $metadata;

        return Http::withToken($this->getToken())
            ->patch($endpoint, $payload)
            ->json();
    }

    public function deleteUser($auth0_id) {
        $endpoint = env('AUTH0_DOMAIN') . 'api/v2/users/' . $auth0_id;

        return Http::withToken($this->getToken())
            ->delete($endpoint)
            ->json();
    }
}
