<?php

namespace Tests\Feature;

use App\Models\Song;
use App\Models\SongSection;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Tests\TestCase;

final class ProFileImportTest extends TestCase
{
    use RefreshDatabase;

    private function test_pro_file(): UploadedFile
    {
        $sourcePath = base_path('tests/fixtures/propresenter/Test.pro');

        return new UploadedFile($sourcePath, 'Test.pro', 'application/octet-stream', null, true);
    }

    public function test_import_pro_datei_erstellt_song_mit_gruppen_und_slides(): void
    {
        $user = User::factory()->create();

        $response = $this->actingAs($user)->postJson(route('api.songs.import-pro'), [
            'file' => $this->test_pro_file(),
        ]);

        $response->assertOk();
        $response->assertJsonPath('songs.0.title', 'Test');

        $song = Song::where('title', 'Test')->first();
        $this->assertNotNull($song);

        $this->assertSame(6, \App\Models\Label::count());

        // The imported lyric content is 5 slides. SongPrefixPostfixService::ensure()
        // now always adds a COPYRIGHT slide + a BLANK slide in locked sections, so
        // the 5 content slides live in non-locked sections and the total is 7.
        $contentSlideCount = \App\Models\SongSlide::whereHas('section', function ($query): void {
            $query->where('locked', false)->orWhereNull('locked');
        })->count();
        $this->assertSame(5, $contentSlideCount);
        $this->assertSame(7, \App\Models\SongSlide::count());

        $this->assertSame(2, $song->arrangements()->count());
        $this->assertTrue($song->has_translation);
    }

    public function test_import_pro_mit_ccli_upserted_bei_doppeltem_import(): void
    {
        $user = User::factory()->create();

        $this->actingAs($user)->postJson(route('api.songs.import-pro'), [
            'file' => $this->test_pro_file(),
        ]);

        $this->assertSame(1, Song::count());

        // Second import of same file with same CCLI should upsert, not duplicate
        $this->actingAs($user)->postJson(route('api.songs.import-pro'), [
            'file' => $this->test_pro_file(),
        ]);

        $this->assertSame(1, Song::count());
    }

    public function test_import_pro_upsert_mit_ccli_dupliziert_nicht(): void
    {
        $user = User::factory()->create();

        $existingSong = Song::create([
            'title' => 'Old Title',
            'ccli_id' => '999',
        ]);

        $arrangement = $existingSong->arrangements()->create([
            'name' => 'Normal',
            'is_default' => true,
        ]);
        $oldLabel = \App\Models\Label::firstOrCreate(['name' => 'Old Group'], ['color' => '#FF0000']);
        $oldSection = SongSection::factory()->create(['song_id' => $existingSong->id, 'label_id' => $oldLabel->id]);
        $arrangement->arrangementLabels()->create([
            'song_section_id' => $oldSection->id,
            'order' => 0,
        ]);

        $this->assertSame(1, $arrangement->arrangementLabels()->count());

        $existingSong->update(['ccli_id' => '999']);
        $this->assertSame(1, Song::count());

        $response = $this->actingAs($user)->postJson(route('api.songs.import-pro'), [
            'file' => $this->test_pro_file(),
        ]);

        $response->assertOk();
        $this->assertSame(2, Song::count());
    }

    public function test_import_pro_lehnt_ungueltige_datei_ab(): void
    {
        $user = User::factory()->create();

        $invalidFile = UploadedFile::fake()->create('test.txt', 100);

        $response = $this->actingAs($user)->postJson(route('api.songs.import-pro'), [
            'file' => $invalidFile,
        ]);

        $response->assertStatus(422);
    }

    public function test_import_pro_erfordert_authentifizierung(): void
    {
        $response = $this->postJson(route('api.songs.import-pro'), [
            'file' => $this->test_pro_file(),
        ]);

        $response->assertUnauthorized();
    }

    public function test_import_pro_erstellt_arrangement_gruppen(): void
    {
        $user = User::factory()->create();

        $this->actingAs($user)->postJson(route('api.songs.import-pro'), [
            'file' => $this->test_pro_file(),
        ]);

        $song = Song::where('title', 'Test')->first();
        $normalArrangement = $song->arrangements()->where('name', 'normal')->first();

        $this->assertNotNull($normalArrangement);
        $this->assertTrue($normalArrangement->is_default);
        $this->assertSame(7, $normalArrangement->arrangementLabels()->count());
    }
}
