<?php

namespace Chatbeep\LaravelSdk;

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

class ChatbeepManager
{
    public function __construct(
        private readonly string $apiBase,
        private readonly ?string $token,
        private readonly int $timeout,
    ) {}

    public function withToken(?string $token = null): self
    {
        return new self($this->apiBase, $token ?? $this->token, $this->timeout);
    }

    public function health(): array
    {
        return $this->client()->get('/health')->json();
    }

    public function widgetConfig(string $installationToken): array
    {
        return $this->client()->get('/widget/config/'.$installationToken)->json();
    }

    public function widgetInstallationHealth(string $installationToken, ?string $currentUrl = null): array
    {
        return $this->client()->get('/widget/installations/'.$installationToken.'/health', [
            'current_url' => $currentUrl,
        ])->json();
    }

    public function installationHealth(string $installationToken, ?string $currentUrl = null): array
    {
        return $this->widgetInstallationHealth($installationToken, $currentUrl);
    }

    public function widgetPing(array $payload): array
    {
        return $this->client()->post('/widget/ping', $payload)->json();
    }

    public function upsertWidgetVisitor(array $payload): array
    {
        return $this->client()->post('/widget/visitors', $payload)->json();
    }

    public function createWidgetConversation(array $payload): array
    {
        return $this->client()->post('/widget/conversations', $payload)->json();
    }

    public function createConversation(array $payload): array
    {
        return $this->createWidgetConversation($payload);
    }

    public function getWidgetConversationMessages(string $conversation, string $widgetToken, array $query = []): array
    {
        return $this->client()->get('/widget/conversations/'.$conversation.'/messages', array_merge([
            'token' => $widgetToken,
        ], $query))->json();
    }

    public function sendWidgetConversationMessage(string $conversation, array $payload): array
    {
        return $this->client()->post('/widget/conversations/'.$conversation.'/messages', $payload)->json();
    }

    public function startWidgetVerification(string $conversation, array $payload): array
    {
        return $this->client()->post('/widget/conversations/'.$conversation.'/verification/start', $payload)->json();
    }

    public function confirmWidgetVerification(string $conversation, array $payload): array
    {
        return $this->client()->post('/widget/conversations/'.$conversation.'/verification/confirm', $payload)->json();
    }

    public function mobileLogin(string $email, string $password, string $deviceName): array
    {
        return $this->client()->post('/mobile/login', [
            'email' => $email,
            'password' => $password,
            'device_name' => $deviceName,
        ])->json();
    }

    public function mobileMe(): array
    {
        return $this->client(true)->get('/mobile/me')->json();
    }

    public function mobileConversations(array $query = []): array
    {
        return $this->client(true)->get('/mobile/conversations', $query)->json();
    }

    public function mobileConversation(int|string $conversation): array
    {
        return $this->client(true)->get('/mobile/conversations/'.$conversation)->json();
    }

    public function sendMobileConversationMessage(int|string $conversation, array $payload): array
    {
        return $this->client(true)->post('/mobile/conversations/'.$conversation.'/messages', $payload)->json();
    }

    public function assignMobileConversation(int|string $conversation, array $payload): array
    {
        return $this->client(true)->post('/mobile/conversations/'.$conversation.'/assign', $payload)->json();
    }

    public function transferMobileConversation(int|string $conversation, array $payload): array
    {
        return $this->client(true)->post('/mobile/conversations/'.$conversation.'/transfer', $payload)->json();
    }

    public function closeMobileConversation(int|string $conversation, array $payload = []): array
    {
        return $this->client(true)->post('/mobile/conversations/'.$conversation.'/close', $payload)->json();
    }

    private function client(bool $requiresAuth = false): PendingRequest
    {
        $request = Http::baseUrl(rtrim($this->apiBase, '/'))
            ->acceptJson()
            ->timeout($this->timeout);

        if ($requiresAuth && $this->token) {
            $request = $request->withToken($this->token);
        }

        return $request;
    }
}
