<?php

declare(strict_types=1);

use App\Models\ActivityEvent;
use App\Models\Artwork;
use App\Models\User;
use Illuminate\Support\Facades\DB;

// ── ActivityEvent::record() factory helper ────────────────────────────────────

it('creates a db row via record()', function () {
    $user    = User::factory()->create();
    $artwork = Artwork::factory()->create();

    ActivityEvent::record(
        actorId:    $user->id,
        type:       ActivityEvent::TYPE_FAVORITE,
        targetType: ActivityEvent::TARGET_ARTWORK,
        targetId:   $artwork->id,
        meta:       ['source' => 'test'],
    );

    $this->assertDatabaseHas('activity_events', [
        'actor_id'    => $user->id,
        'type'        => 'favorite',
        'target_type' => 'artwork',
        'target_id'   => $artwork->id,
    ]);
});

it('stores all five event types without error', function () {
    $user    = User::factory()->create();
    $artwork = Artwork::factory()->create();

    $events = [
        [ActivityEvent::TYPE_UPLOAD,   ActivityEvent::TARGET_ARTWORK, $artwork->id],
        [ActivityEvent::TYPE_COMMENT,  ActivityEvent::TARGET_ARTWORK, $artwork->id],
        [ActivityEvent::TYPE_FAVORITE, ActivityEvent::TARGET_ARTWORK, $artwork->id],
        [ActivityEvent::TYPE_AWARD,    ActivityEvent::TARGET_ARTWORK, $artwork->id],
        [ActivityEvent::TYPE_FOLLOW,   ActivityEvent::TARGET_USER,    $user->id],
    ];

    foreach ($events as [$type, $targetType, $targetId]) {
        ActivityEvent::record($user->id, $type, $targetType, $targetId);
    }

    expect(ActivityEvent::where('actor_id', $user->id)->count())->toBe(5);
});

it('created_at is populated on the returned instance', function () {
    $user    = User::factory()->create();
    $artwork = Artwork::factory()->create();

    $event = ActivityEvent::record(
        $user->id,
        ActivityEvent::TYPE_COMMENT,
        ActivityEvent::TARGET_ARTWORK,
        $artwork->id,
    );

    expect($event->created_at)->not->toBeNull();
});

it('actor relation resolves after record()', function () {
    $user    = User::factory()->create();
    $artwork = Artwork::factory()->create();

    $event = ActivityEvent::record($user->id, ActivityEvent::TYPE_UPLOAD, ActivityEvent::TARGET_ARTWORK, $artwork->id);

    expect($event->actor->id)->toBe($user->id);
});

it('meta is null when empty array is passed', function () {
    $user    = User::factory()->create();
    $artwork = Artwork::factory()->create();

    $event = ActivityEvent::record($user->id, ActivityEvent::TYPE_UPLOAD, ActivityEvent::TARGET_ARTWORK, $artwork->id);

    expect($event->meta)->toBeNull();
});

it('meta is stored when non-empty array is passed', function () {
    $user    = User::factory()->create();
    $artwork = Artwork::factory()->create();

    $event = ActivityEvent::record(
        $user->id,
        ActivityEvent::TYPE_AWARD,
        ActivityEvent::TARGET_ARTWORK,
        $artwork->id,
        ['medal' => 'gold'],
    );

    expect($event->meta)->toBe(['medal' => 'gold']);
});

// ── Community activity feed route ─────────────────────────────────────────────

it('global activity feed returns 200 for guests', function () {
    $this->get('/community/activity')->assertStatus(200);
});

it('following tab returns 200 for users with no follows', function () {
    $user = User::factory()->create();

    $this->actingAs($user)
    ->get('/community/activity?filter=following')
        ->assertStatus(200);
});

it('following tab shows only events from followed users', function () {
    $user    = User::factory()->create();
    $creator = User::factory()->create();
    $other   = User::factory()->create();
    $artwork = Artwork::factory()->create();

    // user_followers has no updated_at column
    DB::table('user_followers')->insert([
        'user_id'     => $creator->id,
        'follower_id' => $user->id,
        'created_at'  => now(),
    ]);

    // Event from followed creator
    ActivityEvent::record($creator->id, ActivityEvent::TYPE_UPLOAD, ActivityEvent::TARGET_ARTWORK, $artwork->id);
    // Event from non-followed user (should not appear)
    ActivityEvent::record($other->id, ActivityEvent::TYPE_UPLOAD, ActivityEvent::TARGET_ARTWORK, $artwork->id);

    $response = $this->actingAs($user)->get('/community/activity?filter=following');
    $response->assertStatus(200);

    $props = $response->viewData('props');
    $events = collect($props['initialActivities'] ?? []);

    expect($events)->toHaveCount(1);
    expect(data_get($events->first(), 'user.id'))->toBe($creator->id);
});
