<?php

use Datalumo\PhpSdk\DataObjects\ChatResponse;
use Datalumo\PhpSdk\DataObjects\Collection;
use Datalumo\PhpSdk\DataObjects\Entry;
use Datalumo\PhpSdk\DataObjects\PaginatedResponse;
use Datalumo\PhpSdk\DataObjects\SummaryResponse;
use Datalumo\PhpSdk\HttpClient;
use Datalumo\PhpSdk\Resources\CollectionResource;

beforeEach(function () {
    $this->http = Mockery::mock(HttpClient::class);
    $this->resource = new CollectionResource($this->http);
});

it('lists collections', function () {
    $this->http->shouldReceive('get')
        ->with('collections', ['page' => 1])
        ->once()
        ->andReturn([
            'data' => [
                [
                    'id' => 'col-1',
                    'organisation_id' => 'org-1',
                    'name' => 'Docs',
                    'project' => null,
                    'created_at' => '2026-01-01T00:00:00Z',
                    'updated_at' => '2026-01-01T00:00:00Z',
                ],
            ],
            'meta' => ['current_page' => 1, 'last_page' => 1, 'per_page' => 15, 'total' => 1],
        ]);

    $result = $this->resource->list();

    expect($result)->toBeInstanceOf(PaginatedResponse::class)
        ->and($result->data)->toHaveCount(1)
        ->and($result->data[0])->toBeInstanceOf(Collection::class)
        ->and($result->data[0]->name)->toBe('Docs');
});

it('lists collections filtered by project', function () {
    $this->http->shouldReceive('get')
        ->with('collections', ['project' => 'docs', 'page' => 1])
        ->once()
        ->andReturn([
            'data' => [],
            'meta' => ['current_page' => 1, 'last_page' => 1, 'per_page' => 15, 'total' => 0],
        ]);

    $this->resource->list(project: 'docs');
});

it('creates a collection', function () {
    $this->http->shouldReceive('post')
        ->with('collections', ['name' => 'New Collection'])
        ->once()
        ->andReturn([
            'data' => [
                'id' => 'col-new',
                'organisation_id' => 'org-1',
                'name' => 'New Collection',
                'project' => null,
                'created_at' => '2026-01-01T00:00:00Z',
                'updated_at' => '2026-01-01T00:00:00Z',
            ],
        ]);

    $result = $this->resource->create('New Collection');

    expect($result)->toBeInstanceOf(Collection::class)
        ->and($result->id)->toBe('col-new')
        ->and($result->name)->toBe('New Collection');
});

it('creates a collection with project', function () {
    $this->http->shouldReceive('post')
        ->with('collections', ['name' => 'Docs', 'project' => 'main'])
        ->once()
        ->andReturn([
            'data' => [
                'id' => 'col-new',
                'organisation_id' => 'org-1',
                'name' => 'Docs',
                'project' => 'main',
                'created_at' => '2026-01-01T00:00:00Z',
                'updated_at' => '2026-01-01T00:00:00Z',
            ],
        ]);

    $result = $this->resource->create('Docs', 'main');

    expect($result->project)->toBe('main');
});

it('updates a collection', function () {
    $this->http->shouldReceive('patch')
        ->with('collections/col-1', ['name' => 'Updated'])
        ->once()
        ->andReturn([
            'data' => [
                'id' => 'col-1',
                'organisation_id' => 'org-1',
                'name' => 'Updated',
                'project' => null,
                'created_at' => '2026-01-01T00:00:00Z',
                'updated_at' => '2026-01-02T00:00:00Z',
            ],
        ]);

    $result = $this->resource->update('col-1', 'Updated');

    expect($result->name)->toBe('Updated');
});

it('deletes a collection', function () {
    $this->http->shouldReceive('delete')
        ->with('collections/col-1')
        ->once();

    $this->resource->delete('col-1');
});

it('searches a collection', function () {
    $this->http->shouldReceive('get')
        ->with('collections/col-1/search', ['query' => 'test', 'threshold' => 0.3])
        ->once()
        ->andReturn([
            'data' => [
                [
                    'id' => 'entry-1',
                    'collection_id' => 'col-1',
                    'title' => 'Result',
                    'raw_text' => 'Content',

                    'created_at' => '2026-01-01T00:00:00Z',
                    'updated_at' => '2026-01-01T00:00:00Z',
                ],
            ],
            'meta' => ['current_page' => 1, 'last_page' => 1, 'per_page' => 15, 'total' => 1],
        ]);

    $result = $this->resource->search('col-1', ['query' => 'test', 'threshold' => 0.3]);

    expect($result->data)->toHaveCount(1)
        ->and($result->data[0])->toBeInstanceOf(Entry::class);
});

it('summarises a collection with stream disabled', function () {
    $this->http->shouldReceive('get')
        ->with('collections/col-1/summarise', ['query' => 'test', 'stream' => false])
        ->once()
        ->andReturn([
            'summary' => 'Summary text',
            'references' => [],
            'data' => [],
        ]);

    $result = $this->resource->summarise('col-1', ['query' => 'test']);

    expect($result)->toBeInstanceOf(SummaryResponse::class)
        ->and($result->summary)->toBe('Summary text');
});

it('chats with a collection with stream disabled', function () {
    $this->http->shouldReceive('post')
        ->with('collections/col-1/chat', ['message' => 'hello', 'stream' => false])
        ->once()
        ->andReturn([
            'conversation_id' => 'conv-1',
            'message' => 'Hi there!',
        ]);

    $result = $this->resource->chat('col-1', ['message' => 'hello']);

    expect($result)->toBeInstanceOf(ChatResponse::class)
        ->and($result->conversationId)->toBe('conv-1')
        ->and($result->message)->toBe('Hi there!');
});
