<?php

namespace Tests\Feature;

use App\Models\Label;
use App\Models\Service;
use App\Models\ServiceSong;
use App\Models\Song;
use App\Services\PlaylistExportService;
use App\Services\ProBundleExportService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Storage;
use RuntimeException;
use Tests\TestCase;

/**
 * FIX 5: A song whose default arrangement contains only EMPTY locked prefix/postfix
 * sections has zero content slides. It must be skipped (not exported as an empty .pro)
 * and a German warning must be surfaced. A normal song still exports.
 */
final class ExportSkipEmptyLockedSongTest extends TestCase
{
    use RefreshDatabase;

    protected function setUp(): void
    {
        parent::setUp();
        Storage::fake('public');
    }

    /** Song whose default arrangement only references an empty, locked section. */
    private function createEmptyLockedSong(string $title = 'Leeres Lied'): Song
    {
        $song = Song::create([
            'title' => $title,
            'ccli_id' => fake()->unique()->numerify('#####'),
            'author' => 'Author',
        ]);

        $label = Label::firstOrCreate(['name' => 'Intro - '.$title], ['color' => '#000000']);
        // Locked section with NO slides.
        $section = $song->sections()->create([
            'label_id' => $label->id,
            'order' => 0,
            'locked' => true,
        ]);

        $arrangement = $song->arrangements()->create(['name' => 'normal', 'is_default' => true]);
        $arrangement->arrangementSections()->create(['song_section_id' => $section->id, 'order' => 0]);

        return $song;
    }

    private function createNormalSong(string $title = 'Normales Lied'): Song
    {
        $song = Song::create([
            'title' => $title,
            'ccli_id' => fake()->unique()->numerify('#####'),
            'author' => 'Author',
        ]);

        $label = Label::firstOrCreate(['name' => 'Verse 1 - '.$title], ['color' => '#2196F3']);
        $section = $song->sections()->create(['label_id' => $label->id, 'order' => 0, 'locked' => false]);
        $section->slides()->create(['order' => 0, 'text_content' => 'Strophentext']);

        $arrangement = $song->arrangements()->create(['name' => 'normal', 'is_default' => true]);
        $arrangement->arrangementSections()->create(['song_section_id' => $section->id, 'order' => 0]);

        return $song;
    }

    private function testable_export_service(): PlaylistExportService
    {
        return new class(app(\App\Services\MacroResolutionService::class)) extends PlaylistExportService
        {
            protected function writeProFile(string $path, string $name, array $groups, array $arrangements, array $options = []): void
            {
                file_put_contents($path, 'mock-pro:'.$name);
            }

            protected function writePlaylistFile(string $path, string $name, array $items, array $embeddedFiles): void
            {
                $content = 'mock-playlist:'.$name;
                foreach ($items as $item) {
                    $content .= "\n".($item['name'] ?? '');
                }
                file_put_contents($path, $content);
            }
        };
    }

    public function test_playlist_legacy_ueberspringt_leeres_locked_lied_mit_warnung(): void
    {
        $service = Service::factory()->create(['finalized_at' => now(), 'title' => 'Mix Service']);

        $emptySong = $this->createEmptyLockedSong('Leeres Lied');
        $normalSong = $this->createNormalSong('Normales Lied');

        ServiceSong::create([
            'service_id' => $service->id,
            'song_id' => $emptySong->id,
            'cts_song_name' => 'Leeres Lied',
            'order' => 1,
        ]);
        ServiceSong::create([
            'service_id' => $service->id,
            'song_id' => $normalSong->id,
            'cts_song_name' => 'Normales Lied',
            'order' => 2,
        ]);

        $result = $this->testable_export_service()->generatePlaylist($service);

        $content = file_get_contents($result['path']);

        // Empty locked song skipped, normal song exported.
        $this->assertStringNotContainsString('Leeres Lied', $content);
        $this->assertStringContainsString('Normales Lied', $content);

        // German warning present.
        $this->assertContains(
            "Lied 'Leeres Lied' übersprungen: keine Inhaltsfolien.",
            $result['warnings'],
        );
        $this->assertGreaterThanOrEqual(1, $result['skipped']);

        $this->cleanupTempDir($result['temp_dir']);
    }

    public function test_probundle_agenda_song_wirft_fehler_bei_leerem_locked_lied(): void
    {
        $service = Service::factory()->create(['finalized_at' => now()]);
        $emptySong = $this->createEmptyLockedSong('Leeres Lied');

        $serviceSong = ServiceSong::create([
            'service_id' => $service->id,
            'song_id' => $emptySong->id,
            'cts_song_name' => 'Leeres Lied',
            'order' => 1,
        ]);

        $agendaItem = \App\Models\ServiceAgendaItem::factory()->create([
            'service_id' => $service->id,
            'title' => 'Leeres Lied',
            'service_song_id' => $serviceSong->id,
            'sort_order' => 1,
            'is_before_event' => false,
        ]);

        $this->expectException(RuntimeException::class);
        $this->expectExceptionMessage('keine Inhaltsfolien');

        app(ProBundleExportService::class)->generateAgendaItemBundle($agendaItem);
    }

    public function test_probundle_agenda_song_exportiert_normales_lied(): void
    {
        $service = Service::factory()->create(['finalized_at' => now()]);
        $normalSong = $this->createNormalSong('Normales Lied');

        $serviceSong = ServiceSong::create([
            'service_id' => $service->id,
            'song_id' => $normalSong->id,
            'cts_song_name' => 'Normales Lied',
            'order' => 1,
        ]);

        $agendaItem = \App\Models\ServiceAgendaItem::factory()->create([
            'service_id' => $service->id,
            'title' => 'Normales Lied',
            'service_song_id' => $serviceSong->id,
            'sort_order' => 1,
            'is_before_event' => false,
        ]);

        $bundlePath = app(ProBundleExportService::class)->generateAgendaItemBundle($agendaItem);

        $this->assertFileExists($bundlePath);
        $this->assertGreaterThan(0, filesize($bundlePath));

        @unlink($bundlePath);
    }

    private function cleanupTempDir(string $dir): void
    {
        if (! is_dir($dir)) {
            return;
        }

        foreach (scandir($dir) as $item) {
            if ($item === '.' || $item === '..') {
                continue;
            }
            $path = $dir.'/'.$item;
            is_dir($path) ? $this->cleanupTempDir($path) : unlink($path);
        }
        rmdir($dir);
    }
}
