<?php

declare(strict_types=1);

use Builder\Core\Foundation\Concerns\HasRevisionHistory;
use Builder\Core\Models\Revision;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

final class HasRevisionHistoryTestModel extends Model
{
    use HasRevisionHistory;

    protected $table = 'has_revisions_items';

    protected $guarded = [];
}

beforeEach(function (): void {
    Schema::create('has_revisions_items', function (Blueprint $table): void {
        $table->id();
        $table->string('name');
        $table->timestamps();
    });

    if (! Schema::hasTable('revisions')) {
        Schema::create('revisions', function (Blueprint $table): void {
            $table->id();
            $table->string('revisable_type');
            $table->unsignedBigInteger('revisable_id');
            $table->unsignedBigInteger('user_id')->nullable();
            $table->json('revision_data');
            $table->timestamps();
        });
    }
});

it('revisions() returns a MorphMany relation', function (): void {
    $model = new HasRevisionHistoryTestModel;

    expect($model->revisions())->toBeInstanceOf(MorphMany::class);
});

it('latestRevision() returns the most recent revision', function (): void {
    $record = HasRevisionHistoryTestModel::create(['name' => 'Test']);

    Revision::create([
        'revisable_type' => HasRevisionHistoryTestModel::class,
        'revisable_id' => $record->id,
        'user_id' => null,
        'revision_data' => ['name' => 'Old'],
        'created_at' => now()->subMinute(),
        'updated_at' => now()->subMinute(),
    ]);

    $latest = Revision::create([
        'revisable_type' => HasRevisionHistoryTestModel::class,
        'revisable_id' => $record->id,
        'user_id' => null,
        'revision_data' => ['name' => 'New'],
    ]);

    expect($record->latestRevision()?->id)->toBe($latest->id);
});

it('latestRevision() returns null when there are no revisions', function (): void {
    $record = HasRevisionHistoryTestModel::create(['name' => 'Test']);

    expect($record->latestRevision())->toBeNull();
});
