<?php

namespace Tests\Feature;

use App\Models\Service;
use App\Models\ServiceSong;
use App\Models\Song;
use App\Models\SongArrangement;
use App\Models\SongArrangementSection;
use App\Models\SongSection;
use App\Models\SongSlide;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

final class ServiceSongContentSlidesTest extends TestCase
{
    use RefreshDatabase;

    private function makeServiceWithSong(callable $buildSong): array
    {
        $service = Service::factory()->create([
            'date' => Carbon::today(),
            'finalized_at' => null,
        ]);

        $song = Song::factory()->create();
        $arrangement = $buildSong($song);

        $serviceSong = ServiceSong::factory()->create([
            'service_id' => $service->id,
            'song_id' => $song->id,
            'song_arrangement_id' => $arrangement->id,
            'order' => 1,
        ]);

        return [$service, $serviceSong];
    }

    private function defaultArrangementWithContentSlide(Song $song): SongArrangement
    {
        $arrangement = SongArrangement::factory()->create([
            'song_id' => $song->id,
            'is_default' => true,
        ]);

        $section = SongSection::factory()->create([
            'song_id' => $song->id,
            'locked' => false,
        ]);
        SongSlide::factory()->create(['song_section_id' => $section->id]);

        SongArrangementSection::factory()->create([
            'song_arrangement_id' => $arrangement->id,
            'song_section_id' => $section->id,
            'order' => 0,
        ]);

        return $arrangement;
    }

    public function test_has_content_slides_ist_true_wenn_standard_arrangement_inhaltsfolie_hat(): void
    {
        Carbon::setTestNow('2026-03-01 10:00:00');
        $this->withoutVite();

        [$service, $serviceSong] = $this->makeServiceWithSong(
            fn (Song $song) => $this->defaultArrangementWithContentSlide($song)
        );

        $response = $this->actingAs(User::factory()->create())
            ->get(route('services.edit', $service->id));

        $response->assertInertia(
            fn ($page) => $page
            ->component('Services/Edit')
            ->where('serviceSongs.0.has_content_slides', true)
        );
    }

    public function test_has_content_slides_ist_false_wenn_section_gesperrt(): void
    {
        Carbon::setTestNow('2026-03-01 10:00:00');
        $this->withoutVite();

        [$service, $serviceSong] = $this->makeServiceWithSong(function (Song $song): SongArrangement {
            $arrangement = SongArrangement::factory()->create([
                'song_id' => $song->id,
                'is_default' => true,
            ]);

            // Locked section with slides -> not a content slide.
            $section = SongSection::factory()->create([
                'song_id' => $song->id,
                'locked' => true,
            ]);
            SongSlide::factory()->create(['song_section_id' => $section->id]);

            SongArrangementSection::factory()->create([
                'song_arrangement_id' => $arrangement->id,
                'song_section_id' => $section->id,
                'order' => 0,
            ]);

            return $arrangement;
        });

        $response = $this->actingAs(User::factory()->create())
            ->get(route('services.edit', $service->id));

        $response->assertInertia(
            fn ($page) => $page
            ->component('Services/Edit')
            ->where('serviceSongs.0.has_content_slides', false)
        );
    }

    public function test_has_content_slides_ist_false_wenn_section_keine_folien_hat(): void
    {
        Carbon::setTestNow('2026-03-01 10:00:00');
        $this->withoutVite();

        [$service, $serviceSong] = $this->makeServiceWithSong(function (Song $song): SongArrangement {
            $arrangement = SongArrangement::factory()->create([
                'song_id' => $song->id,
                'is_default' => true,
            ]);

            // Non-locked section but NO slides -> not a content slide.
            $section = SongSection::factory()->create([
                'song_id' => $song->id,
                'locked' => false,
            ]);

            SongArrangementSection::factory()->create([
                'song_arrangement_id' => $arrangement->id,
                'song_section_id' => $section->id,
                'order' => 0,
            ]);

            return $arrangement;
        });

        $response = $this->actingAs(User::factory()->create())
            ->get(route('services.edit', $service->id));

        $response->assertInertia(
            fn ($page) => $page
            ->component('Services/Edit')
            ->where('serviceSongs.0.has_content_slides', false)
        );
    }

    public function test_has_content_slides_ist_null_wenn_kein_song_zugeordnet(): void
    {
        Carbon::setTestNow('2026-03-01 10:00:00');
        $this->withoutVite();

        $service = Service::factory()->create([
            'date' => Carbon::today(),
            'finalized_at' => null,
        ]);

        ServiceSong::create([
            'service_id' => $service->id,
            'song_id' => null,
            'song_arrangement_id' => null,
            'use_translation' => false,
            'order' => 1,
            'cts_song_name' => 'Unmatched Song',
            'cts_ccli_id' => '999999',
        ]);

        $response = $this->actingAs(User::factory()->create())
            ->get(route('services.edit', $service->id));

        $response->assertInertia(
            fn ($page) => $page
            ->component('Services/Edit')
            ->where('serviceSongs.0.has_content_slides', null)
        );
    }
}
