<?php

use App\Models\Song;
use App\Models\User;

/*
|--------------------------------------------------------------------------
| Song Index Page Tests (Inertia)
|--------------------------------------------------------------------------
*/

beforeEach(function () {
    $this->user = User::factory()->create();
    $this->withoutVite();
});

test('songs index page renders for authenticated users', function () {
    $response = $this->actingAs($this->user)
        ->get('/songs');

    $response->assertOk();
    $response->assertInertia(fn ($page) => $page->component('Songs/Index'));
});

test('songs index page redirects unauthenticated users to login', function () {
    $response = $this->get('/songs');

    $response->assertRedirect('/login');
});

test('songs index route is named songs.index', function () {
    $this->actingAs($this->user);

    $url = route('songs.index');

    expect($url)->toContain('/songs');
});

test('songs api returns data for songs page', function () {
    Song::factory()->count(3)->create();

    $response = $this->actingAs($this->user)
        ->getJson('/api/songs');

    $response->assertOk()
        ->assertJsonStructure([
            'data' => [['id', 'title', 'ccli_id', 'has_translation', 'has_content', 'created_at', 'updated_at']],
            'meta' => ['current_page', 'last_page', 'per_page', 'total'],
        ]);
    expect($response->json('meta.total'))->toBe(3);
});

test('songs api marks songs without slides as no content', function () {
    $song = Song::factory()->create();

    $response = $this->actingAs($this->user)
        ->getJson('/api/songs');

    $response->assertOk();
    expect($response->json('data.0.has_content'))->toBeFalse();
});

test('songs api with_content filter hides songs without content', function () {
    $withContent = Song::factory()->create(['title' => 'Mit Inhalt']);
    $section = $withContent->sections()->create([
        'label_id' => \App\Models\Label::factory()->create()->id,
        'order' => 1,
    ]);
    $section->slides()->create(['order' => 1, 'text_content' => 'Zeile']);

    Song::factory()->create(['title' => 'Ohne Inhalt']);

    $response = $this->actingAs($this->user)
        ->getJson('/api/songs?with_content=1');

    $response->assertOk();
    expect($response->json('meta.total'))->toBe(1);
    expect($response->json('data.0.title'))->toBe('Mit Inhalt');
    expect($response->json('data.0.has_content'))->toBeTrue();
});

test('songs api search filters by title', function () {
    Song::factory()->create(['title' => 'Großer Gott wir loben dich']);
    Song::factory()->create(['title' => 'Amazing Grace']);

    $response = $this->actingAs($this->user)
        ->getJson('/api/songs?search=Großer');

    $response->assertOk();
    expect($response->json('meta.total'))->toBe(1);
    expect($response->json('data.0.title'))->toBe('Großer Gott wir loben dich');
});

test('songs api search filters by ccli id', function () {
    Song::factory()->create(['ccli_id' => '7654321', 'title' => 'Song A']);
    Song::factory()->create(['ccli_id' => '1234567', 'title' => 'Song B']);

    $response = $this->actingAs($this->user)
        ->getJson('/api/songs?search=7654321');

    $response->assertOk();
    expect($response->json('meta.total'))->toBe(1);
    expect($response->json('data.0.ccli_id'))->toBe('7654321');
});

test('songs api does not return soft-deleted songs', function () {
    Song::factory()->count(2)->create();
    Song::factory()->create(['deleted_at' => now()]);

    $response = $this->actingAs($this->user)
        ->getJson('/api/songs');

    $response->assertOk();
    expect($response->json('meta.total'))->toBe(2);
});

test('songs api paginates results', function () {
    Song::factory()->count(25)->create();

    $response = $this->actingAs($this->user)
        ->getJson('/api/songs?per_page=10');

    $response->assertOk();
    expect($response->json('meta.total'))->toBe(25);
    expect($response->json('meta.per_page'))->toBe(10);
    expect($response->json('meta.last_page'))->toBe(3);
    expect(count($response->json('data')))->toBe(10);
});

test('songs api delete soft-deletes a song', function () {
    $song = Song::factory()->create(['title' => 'To Delete']);

    $response = $this->actingAs($this->user)
        ->deleteJson("/api/songs/{$song->id}");

    $response->assertOk();
    expect(Song::find($song->id))->toBeNull();
    expect(Song::withTrashed()->find($song->id))->not->toBeNull();
});
