<?php

namespace Datalumo\PhpSdk\Resources;

use Datalumo\PhpSdk\DataObjects\ChatResponse;
use Datalumo\PhpSdk\DataObjects\Entry;
use Datalumo\PhpSdk\DataObjects\Integration;
use Datalumo\PhpSdk\DataObjects\PaginatedResponse;
use Datalumo\PhpSdk\DataObjects\SearchResult;
use Datalumo\PhpSdk\DataObjects\StreamResponse;
use Datalumo\PhpSdk\DataObjects\SummaryResponse;
use Datalumo\PhpSdk\HttpClient;

class IntegrationResource
{
    public function __construct(private readonly HttpClient $client) {}

    public function list(?string $type = null, ?string $project = null, int $page = 1): PaginatedResponse
    {
        $query = array_filter(['type' => $type, 'project' => $project, 'page' => $page]);

        return PaginatedResponse::fromArray(
            $this->client->get('integrations', $query),
            Integration::fromArray(...),
        );
    }

    public function get(string $integrationId): Integration
    {
        return Integration::fromArray(
            $this->client->get("integrations/{$integrationId}")['data'],
        );
    }

    /**
     * @param array{
     *     type: string,
     *     name: string,
     *     collection_ids: string[],
     *     project?: string,
     *     accent_color?: string,
     *     allowed_domains?: string[],
     *     is_active?: bool,
     *     welcome_message?: string,
     *     instructions?: string,
     *     persona?: string,
     *     unknown_answer_message?: string,
     *     position?: string,
     *     placeholder?: string,
     *     search_mode?: string,
     *     results_display?: string,
     *     label?: string,
     * } $data
     */
    public function create(array $data): Integration
    {
        return Integration::fromArray(
            $this->client->post('integrations', $data)['data'],
        );
    }

    public function update(string $integrationId, array $data): Integration
    {
        return Integration::fromArray(
            $this->client->patch("integrations/{$integrationId}", $data)['data'],
        );
    }

    public function delete(string $integrationId): void
    {
        $this->client->delete("integrations/{$integrationId}");
    }

    /**
     * @param array{
     *     query: string,
     *     threshold?: float,
     *     per_page?: int,
     *     meta?: array<string, string>,
     *     page?: int,
     * } $params
     */
    public function search(string $integrationId, array $params): SearchResult
    {
        return SearchResult::fromArray(
            $this->client->get("integrations/{$integrationId}/search", $params),
            Entry::fromArray(...),
        );
    }

    /**
     * @param array{
     *     query: string,
     *     threshold?: float,
     *     format?: string,
     *     locale?: string,
     * } $params
     */
    public function summarise(string $integrationId, array $params): SummaryResponse
    {
        $params['stream'] = false;

        return SummaryResponse::fromArray(
            $this->client->get("integrations/{$integrationId}/summarise", $params),
        );
    }

    /**
     * @param array{
     *     message: string,
     *     conversation_id?: string,
     * } $params
     */
    public function chat(string $integrationId, array $params): ChatResponse
    {
        $params['stream'] = false;

        return ChatResponse::fromArray(
            $this->client->post("integrations/{$integrationId}/chat", $params),
        );
    }

    /**
     * @param array{
     *     event_type: string,
     *     meta?: array{url?: string},
     * } $data
     */
    public function recordEvent(string $integrationId, array $data): void
    {
        $this->client->post("integrations/{$integrationId}/events", $data);
    }

    /**
     * @param array{
     *     query: string,
     *     threshold?: float,
     *     format?: string,
     *     locale?: string,
     * } $params
     */
    public function streamSummarise(string $integrationId, array $params): StreamResponse
    {
        $params['stream'] = true;

        return $this->client->getStream("integrations/{$integrationId}/summarise", $params);
    }

    /**
     * @param array{
     *     message: string,
     *     conversation_id?: string,
     * } $params
     */
    public function streamChat(string $integrationId, array $params): StreamResponse
    {
        $params['stream'] = true;

        return $this->client->postStream("integrations/{$integrationId}/chat", $params);
    }
}
