<?php

use App\Models\Artwork;
use App\Models\ArtworkComment;
use App\Models\Story;
use App\Models\User;

test('authenticated user can like artwork through generic social endpoint and owner is notified', function () {
    $owner = User::factory()->create();
    $actor = User::factory()->create();
    $artwork = Artwork::factory()->create(['user_id' => $owner->id]);

    $this->actingAs($actor)
        ->postJson('/api/like', [
            'entity_type' => 'artwork',
            'entity_id' => $artwork->id,
            'state' => true,
        ])
        ->assertOk()
        ->assertJsonPath('is_liked', true)
        ->assertJsonPath('stats.likes', 1);

    $this->assertDatabaseHas('artwork_likes', [
        'artwork_id' => $artwork->id,
        'user_id' => $actor->id,
    ]);

    $notification = $owner->fresh()
        ->notifications()
        ->where('type', 'artwork_liked')
        ->latest()
        ->first();

    expect($notification)->not->toBeNull();
    expect($notification->data['type'] ?? null)->toBe('artwork_liked');
    expect($notification->data['actor_id'] ?? null)->toBe($actor->id);
});

test('authenticated user can comment on artwork through generic social endpoint and send owner and mention notifications', function () {
    $owner = User::factory()->create();
    $actor = User::factory()->create();
    $mentioned = User::factory()->create();
    $artwork = Artwork::factory()->create(['user_id' => $owner->id]);

    $this->actingAs($actor)
        ->postJson('/api/comments', [
            'entity_type' => 'artwork',
            'entity_id' => $artwork->id,
            'content' => 'Great work @' . $mentioned->username,
        ])
        ->assertCreated()
        ->assertJsonPath('data.user.id', $actor->id);

    $comment = ArtworkComment::query()->latest('id')->first();

    expect($comment)->not->toBeNull();
    expect($comment->artwork_id)->toBe($artwork->id);

    $ownerNotification = $owner->fresh()
        ->notifications()
        ->where('type', 'artwork_commented')
        ->latest()
        ->first();

    $mentionedNotification = $mentioned->fresh()
        ->notifications()
        ->where('type', 'artwork_mentioned')
        ->latest()
        ->first();

    expect($ownerNotification)->not->toBeNull();
    expect($ownerNotification->data['type'] ?? null)->toBe('artwork_commented');
    expect($mentionedNotification)->not->toBeNull();
    expect($mentionedNotification->data['type'] ?? null)->toBe('artwork_mentioned');

    $this->assertDatabaseHas('user_mentions', [
        'comment_id' => $comment->id,
        'mentioned_user_id' => $mentioned->id,
    ]);
});

test('generic comments endpoint lists artwork comments', function () {
    $artwork = Artwork::factory()->create();
    $comment = ArtworkComment::factory()->create(['artwork_id' => $artwork->id]);

    $this->getJson('/api/comments?entity_type=artwork&entity_id=' . $artwork->id)
        ->assertOk()
        ->assertJsonCount(1, 'data')
        ->assertJsonPath('data.0.id', $comment->id);
});

test('authenticated user can bookmark artwork through generic endpoint and see it in bookmarks list', function () {
    $user = User::factory()->create();
    $artwork = Artwork::factory()->create();

    $this->actingAs($user)
        ->postJson('/api/bookmark', [
            'entity_type' => 'artwork',
            'entity_id' => $artwork->id,
            'state' => true,
        ])
        ->assertOk()
        ->assertJsonPath('is_bookmarked', true)
        ->assertJsonPath('stats.bookmarks', 1);

    $this->assertDatabaseHas('artwork_bookmarks', [
        'artwork_id' => $artwork->id,
        'user_id' => $user->id,
    ]);

    $this->actingAs($user)
        ->getJson('/api/bookmarks?entity_type=artwork')
        ->assertOk()
        ->assertJsonCount(1, 'data')
        ->assertJsonPath('data.0.type', 'artwork')
        ->assertJsonPath('data.0.id', $artwork->id);
});

test('authenticated user can like and bookmark a story through generic social endpoints', function () {
    $owner = User::factory()->create();
    $actor = User::factory()->create();
    $story = Story::query()->create([
        'creator_id' => $owner->id,
        'title' => 'Published Story',
        'slug' => 'published-story-' . strtolower((string) \Illuminate\Support\Str::random(6)),
        'content' => '<p>Story body</p>',
        'story_type' => 'creator_story',
        'status' => 'published',
        'published_at' => now()->subMinute(),
    ]);

    $this->actingAs($actor)
        ->postJson('/api/like', [
            'entity_type' => 'story',
            'entity_id' => $story->id,
            'state' => true,
        ])
        ->assertOk()
        ->assertJsonPath('is_liked', true)
        ->assertJsonPath('stats.likes', 1);

    $this->assertDatabaseHas('story_likes', [
        'story_id' => $story->id,
        'user_id' => $actor->id,
    ]);

    $likeNotification = $owner->fresh()
        ->notifications()
        ->where('type', 'story_liked')
        ->latest()
        ->first();

    expect($likeNotification)->not->toBeNull();
    expect($likeNotification->data['type'] ?? null)->toBe('story_liked');

    $this->actingAs($actor)
        ->postJson('/api/bookmark', [
            'entity_type' => 'story',
            'entity_id' => $story->id,
            'state' => true,
        ])
        ->assertOk()
        ->assertJsonPath('is_bookmarked', true)
        ->assertJsonPath('stats.bookmarks', 1);

    $this->assertDatabaseHas('story_bookmarks', [
        'story_id' => $story->id,
        'user_id' => $actor->id,
    ]);

    $this->actingAs($actor)
        ->getJson('/api/bookmarks?entity_type=story')
        ->assertOk()
        ->assertJsonCount(1, 'data')
        ->assertJsonPath('data.0.type', 'story')
        ->assertJsonPath('data.0.id', $story->id);
});

test('authenticated user can comment on a story through generic social endpoint and send owner and mention notifications', function () {
    $owner = User::factory()->create();
    $actor = User::factory()->create();
    $mentioned = User::factory()->create();
    $story = Story::query()->create([
        'creator_id' => $owner->id,
        'title' => 'Commentable Story',
        'slug' => 'commentable-story-' . strtolower((string) \Illuminate\Support\Str::random(6)),
        'content' => '<p>Story body</p>',
        'story_type' => 'creator_story',
        'status' => 'published',
        'published_at' => now()->subMinute(),
    ]);

    $this->actingAs($actor)
        ->postJson('/api/comments', [
            'entity_type' => 'story',
            'entity_id' => $story->id,
            'content' => 'Great story @' . $mentioned->username,
        ])
        ->assertCreated()
        ->assertJsonPath('data.user.id', $actor->id);

    $this->assertDatabaseHas('story_comments', [
        'story_id' => $story->id,
        'user_id' => $actor->id,
    ]);

    $ownerNotification = $owner->fresh()
        ->notifications()
        ->where('type', 'story_commented')
        ->latest()
        ->first();

    $mentionedNotification = $mentioned->fresh()
        ->notifications()
        ->where('type', 'story_mentioned')
        ->latest()
        ->first();

    expect($ownerNotification)->not->toBeNull();
    expect($ownerNotification->data['type'] ?? null)->toBe('story_commented');
    expect($mentionedNotification)->not->toBeNull();
    expect($mentionedNotification->data['type'] ?? null)->toBe('story_mentioned');

    $this->actingAs($actor)
        ->getJson('/api/comments?entity_type=story&entity_id=' . $story->id)
        ->assertOk()
        ->assertJsonCount(1, 'data')
        ->assertJsonPath('data.0.user.id', $actor->id);
});