<?php

declare(strict_types=1);

use App\DTOs\UserRecoProfileDTO;
use App\Models\Artwork;
use App\Models\User;
use App\Models\UserRecoProfile;
use App\Services\Recommendation\UserPreferenceBuilder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;

uses(RefreshDatabase::class);

// ─────────────────────────────────────────────────────────────────────────────
// UserRecoProfileDTO
// ─────────────────────────────────────────────────────────────────────────────

it('DTO serialises and round-trips correctly', function () {
    $dto = new UserRecoProfileDTO(
        topTagSlugs:      ['space', 'nature'],
        topCategorySlugs: ['wallpapers'],
        strongCreatorIds: [1, 2, 3],
        tagWeights:       ['space' => 0.6, 'nature' => 0.4],
        categoryWeights:  ['wallpapers' => 1.0],
    );

    $arr = $dto->toArray();
    $restored = UserRecoProfileDTO::fromArray($arr);

    expect($restored->topTagSlugs)->toBe(['space', 'nature'])
        ->and($restored->topCategorySlugs)->toBe(['wallpapers'])
        ->and($restored->strongCreatorIds)->toBe([1, 2, 3])
        ->and($restored->tagWeight('space'))->toBe(0.6)
        ->and($restored->followsCreator(2))->toBeTrue()
        ->and($restored->followsCreator(99))->toBeFalse();
});

it('DTO hasSignals returns false for empty profile', function () {
    $empty = new UserRecoProfileDTO();
    expect($empty->hasSignals())->toBeFalse();
});

it('DTO hasSignals returns true when tags are present', function () {
    $dto = new UserRecoProfileDTO(topTagSlugs: ['space']);
    expect($dto->hasSignals())->toBeTrue();
});

// ─────────────────────────────────────────────────────────────────────────────
// UserPreferenceBuilder
// ─────────────────────────────────────────────────────────────────────────────

it('UserPreferenceBuilder returns empty DTO for user with no activity', function () {
    $user    = User::factory()->create();
    $builder = app(UserPreferenceBuilder::class);

    $dto = $builder->build($user);

    expect($dto)->toBeInstanceOf(UserRecoProfileDTO::class)
        ->and($dto->topTagSlugs)->toBe([])
        ->and($dto->strongCreatorIds)->toBe([]);
});

it('UserPreferenceBuilder persists profile row on first build', function () {
    $user    = User::factory()->create();
    $builder = app(UserPreferenceBuilder::class);

    $builder->buildFresh($user);

    expect(UserRecoProfile::find($user->id))->not->toBeNull();
});

it('UserPreferenceBuilder produces stable output on repeated calls', function () {
    $user    = User::factory()->create();
    $builder = app(UserPreferenceBuilder::class);

    $first  = $builder->buildFresh($user)->toArray();
    $second = $builder->buildFresh($user)->toArray();

    expect($first)->toBe($second);
});
