<?php

app_require('classes/attachments.php');

use classes\attachments;

final class AttachmentsListManyTestDouble extends attachments
{
    /** @var array<int, array<string, mixed>> */
    public array $fixtureRows = [];

    public function __construct()
    {
        // Intentionally skip module config bootstrap in unit tests.
    }

    protected function fetchAttachmentRows(string $type, array $object_ids, array $options = []): array
    {
        $wanted = array_flip(array_map('intval', $object_ids));
        return array_values(array_filter(
            $this->fixtureRows,
            static fn(array $row): bool => isset($wanted[(int)($row['object_id'] ?? 0)])
        ));
    }
}

/**
 * @param array<int, object> $attachments
 * @return array<int, array<string, mixed>>
 */
function attachments_to_shape(array $attachments): array
{
    return array_map(static function (object $attachment): array {
        return [
            'id' => $attachment->id,
            'object_id' => $attachment->object_id,
            'document' => $attachment->content->document,
            'other' => $attachment->content->other,
        ];
    }, $attachments);
}

it('groups attachments by object id and preserves empty object groups', function (): void {
    $attachments = new AttachmentsListManyTestDouble();
    $attachments->fixtureRows = [
        ['id' => 1, 'object_type' => 'orders', 'object_id' => 10, 'content' => '{"document":"a.pdf","other":"x"}', 'created_at' => '2026-01-01 10:00:00', 'updated_at' => '2026-01-01 10:00:00'],
        ['id' => 2, 'object_type' => 'orders', 'object_id' => 10, 'content' => '{"document":"b.pdf","other":"y"}', 'created_at' => '2026-01-01 10:00:00', 'updated_at' => '2026-01-01 10:00:00'],
        ['id' => 3, 'object_type' => 'orders', 'object_id' => 12, 'content' => '{"document":"c.pdf","other":"z"}', 'created_at' => '2026-01-01 10:00:00', 'updated_at' => '2026-01-01 10:00:00'],
    ];

    $grouped = $attachments->listMany('orders', [10, 11, 12]);

    expect(array_keys($grouped))->toBe([10, 11, 12]);
    expect(attachments_to_shape($grouped[10]))->toBe([
        ['id' => 1, 'object_id' => 10, 'document' => 'a.pdf', 'other' => 'x'],
        ['id' => 2, 'object_id' => 10, 'document' => 'b.pdf', 'other' => 'y'],
    ]);
    expect($grouped[11])->toBe([]);
    expect(attachments_to_shape($grouped[12]))->toBe([
        ['id' => 3, 'object_id' => 12, 'document' => 'c.pdf', 'other' => 'z'],
    ]);
});

it('keeps listMany payload parity with list for one object id', function (): void {
    $attachments = new AttachmentsListManyTestDouble();
    $attachments->fixtureRows = [
        ['id' => 21, 'object_type' => 'orders', 'object_id' => 100, 'content' => '{"document":"d.pdf","other":"foo"}', 'created_at' => '2026-01-01 10:00:00', 'updated_at' => '2026-01-01 10:00:00'],
        ['id' => 22, 'object_type' => 'orders', 'object_id' => 100, 'content' => '{"document":"e.pdf","other":"bar"}', 'created_at' => '2026-01-01 10:00:00', 'updated_at' => '2026-01-01 10:00:00'],
    ];

    $single = $attachments->list('orders', 100);
    $many = $attachments->listMany('orders', [100]);

    expect(attachments_to_shape($single))->toBe(attachments_to_shape($many[100]));
});
