<?php

namespace App\Services\Meet;

use Illuminate\Http\Client\ConnectionException;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Facades\Http;
use Illuminate\Validation\ValidationException;

/**
 * Client for the Ladill Meet service API — schedule rooms linked to Care records.
 */
class MeetClient
{
    public function __construct(private readonly string $ownerRef) {}

    public static function for(string $ownerRef): self
    {
        return new self($ownerRef);
    }

    /**
     * @param  array<string, mixed>  $data
     * @return array<string, mixed>
     */
    public function createRoom(array $data): array
    {
        return $this->post('rooms', array_merge($data, [
            'owner_ref' => $this->ownerRef,
            'host_user_ref' => $data['host_user_ref'] ?? $this->ownerRef,
        ]));
    }

    /**
     * @return array<string, mixed>
     */
    public function startRoom(string $roomUuid, ?string $hostUserRef = null): array
    {
        return $this->post("rooms/{$roomUuid}/start", [
            'host_user_ref' => $hostUserRef ?? $this->ownerRef,
        ]);
    }

    /**
     * @return array<string, mixed>
     */
    public function cancelRoom(string $roomUuid, ?string $hostUserRef = null): array
    {
        return $this->post("rooms/{$roomUuid}/cancel", [
            'owner_ref' => $this->ownerRef,
            'host_user_ref' => $hostUserRef ?? $this->ownerRef,
        ]);
    }

    private function client(): PendingRequest
    {
        return Http::baseUrl((string) config('meet.url'))
            ->withToken((string) config('meet.key'))
            ->acceptJson()
            ->asJson()
            ->connectTimeout(10)
            ->timeout(20);
    }

    /**
     * @return array<string, mixed>
     */
    private function post(string $path, array $data): array
    {
        if (trim((string) config('meet.key')) === '') {
            throw ValidationException::withMessages([
                'meet' => ['Video visits are not configured. Set MEET_API_KEY_CARE on Care and Meet to the same value.'],
            ]);
        }

        try {
            $response = $this->client()->post($path, $data);
        } catch (ConnectionException) {
            throw ValidationException::withMessages([
                'meet' => ['Could not reach the Meet service. Please try again in a moment.'],
            ]);
        }

        if ($response->status() === 422) {
            throw ValidationException::withMessages(
                $response->json('errors') ?: ['meet' => [$response->json('message') ?: 'Request failed.']]
            );
        }

        if ($response->status() === 401 || $response->status() === 403) {
            throw ValidationException::withMessages([
                'meet' => ['Video visits are not authorized. Set the same MEET_API_KEY_CARE on Care and Meet, then clear config cache.'],
            ]);
        }

        if ($response->status() === 404) {
            throw ValidationException::withMessages([
                'meet' => ['No Meet workspace was found for this account. Sign into meet.ladill.com once to create one, then retry.'],
            ]);
        }

        if ($response->failed()) {
            $message = $response->json('error')
                ?? $response->json('message')
                ?? 'Meet could not schedule this video visit. Please try again.';

            throw ValidationException::withMessages([
                'meet' => [is_string($message) ? $message : 'Meet service error.'],
            ]);
        }

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