<?php

namespace App\Services\Integrations;

use Illuminate\Http\Client\ConnectionException;
use Illuminate\Support\Facades\Http;

class EventsClient
{
    private function client()
    {
        return Http::baseUrl(rtrim((string) config('meet.events_api_url'), '/'))
            ->withToken((string) config('meet.events_api_key'))
            ->acceptJson()
            ->asJson()
            ->connectTimeout(10)
            ->timeout(20);
    }

    public function isConfigured(): bool
    {
        return filled(config('meet.events_api_url')) && filled(config('meet.events_api_key'));
    }

    /**
     * @return list<array<string, mixed>>
     */
    public function linkableEvents(string $ownerRef): array
    {
        $response = $this->get('events', ['owner_ref' => $ownerRef]);

        return (array) ($response['events'] ?? []);
    }

    /**
     * @param  array<string, mixed>  $payload
     * @return array<string, mixed>
     */
    public function linkRoom(int $eventId, array $payload): array
    {
        $response = $this->post("events/{$eventId}/link-room", $payload);

        return (array) ($response['event'] ?? []);
    }

    /** @return array<string, mixed>|null */
    public function verifySpeakerInvite(int $eventId, string $ownerRef, string $speakerToken): ?array
    {
        try {
            $response = $this->client()->post("events/{$eventId}/verify-speaker", [
                'owner_ref' => $ownerRef,
                'speaker_token' => $speakerToken,
            ]);
        } catch (ConnectionException) {
            throw new \RuntimeException('Could not reach Ladill Events.');
        }

        if ($response->status() === 404) {
            return null;
        }

        if ($response->failed()) {
            throw new \RuntimeException('Events service error: '.($response->json('message') ?? $response->body()));
        }

        $speaker = $response->json('speaker');

        return is_array($speaker) ? $speaker : null;
    }

    /** @return array<string, mixed>|null */
    public function verifyRegistration(int $eventId, string $ownerRef, string $badgeCode): ?array
    {
        try {
            $response = $this->client()->post("events/{$eventId}/verify-registration", [
                'owner_ref' => $ownerRef,
                'badge_code' => $badgeCode,
            ]);
        } catch (ConnectionException) {
            throw new \RuntimeException('Could not reach Ladill Events.');
        }

        if ($response->status() === 404) {
            return null;
        }

        if ($response->failed()) {
            throw new \RuntimeException('Events service error: '.($response->json('message') ?? $response->body()));
        }

        $registration = $response->json('registration');

        return is_array($registration) ? $registration : null;
    }

    /**
     * @return array<string, mixed>
     */
    private function get(string $path, array $query = []): array
    {
        try {
            $response = $this->client()->get($path, $query);
        } catch (ConnectionException) {
            throw new \RuntimeException('Could not reach Ladill Events.');
        }

        if ($response->failed()) {
            throw new \RuntimeException('Events service error: '.($response->json('message') ?? $response->body()));
        }

        return (array) $response->json();
    }

    /**
     * @return array<string, mixed>
     */
    private function post(string $path, array $data): array
    {
        try {
            $response = $this->client()->post($path, $data);
        } catch (ConnectionException) {
            throw new \RuntimeException('Could not reach Ladill Events.');
        }

        if ($response->failed()) {
            throw new \RuntimeException('Events service error: '.($response->json('message') ?? $response->body()));
        }

        return (array) $response->json();
    }
}
