<?php

namespace Tests\Feature;

use App\Models\Service;
use App\Models\Slide;
use App\Services\PlaylistExportService;
use App\Services\ProBundleExportService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Storage;
use ProPresenter\Parser\ProBundleReader;
use Tests\Support\InspectsSlideFillMedia;
use Tests\TestCase;

/**
 * FIX 2: Foreground image slide data (information/moderation/sermon blocks) must
 * carry 'bundleRelative' => true so the .pro references the embedded image by a
 * bundle-relative resource URL instead of an absolute path. Otherwise the slide
 * renders blank on the presenter PC.
 */
final class ExportBundleRelativeMediaTest extends TestCase
{
    use InspectsSlideFillMedia;
    use RefreshDatabase;

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

    private function createSlideFile(string $storedFilename): void
    {
        $image = imagecreatetruecolor(1920, 1080);
        ob_start();
        imagejpeg($image);
        $contents = ob_get_clean();
        imagedestroy($image);
        Storage::disk('public')->put($storedFilename, $contents);
    }

    private function createSlide(array $attributes): Slide
    {
        return Slide::create(array_merge([
            'thumbnail_filename' => 'thumb.jpg',
            'uploaded_at' => now()->subDay(),
        ], $attributes));
    }

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

        $this->createSlideFile('slides/info1.jpg');
        $this->createSlide([
            'type' => 'information',
            'service_id' => null,
            'original_filename' => 'info1.jpg',
            'stored_filename' => 'slides/info1.jpg',
            'sort_order' => 1,
        ]);

        $capturedGroups = [];

        $exportService = new class($capturedGroups) extends PlaylistExportService
        {
            /** @var array<int, array> */
            private array $captured;

            public function __construct(array &$captured)
            {
                parent::__construct(app(\App\Services\MacroResolutionService::class));
                $this->captured = &$captured;
            }

            protected function writeProFile(string $path, string $name, array $groups, array $arrangements, array $options = []): void
            {
                $this->captured[] = $groups;
                file_put_contents($path, 'mock-pro:'.$name);
            }

            protected function writePlaylistFile(string $path, string $name, array $items, array $embeddedFiles): void
            {
                file_put_contents($path, 'mock-playlist:'.$name);
            }
        };

        $result = $exportService->generatePlaylist($service);

        // Find the slide data array carrying our image media.
        $found = false;
        foreach ($capturedGroups as $groups) {
            foreach ($groups as $group) {
                foreach ($group['slides'] ?? [] as $slideData) {
                    if (isset($slideData['media'])) {
                        $found = true;
                        $this->assertArrayHasKey('bundleRelative', $slideData);
                        $this->assertTrue($slideData['bundleRelative']);
                    }
                }
            }
        }

        $this->assertTrue($found, 'Expected at least one media slide in captured pro groups.');

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

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

        $this->createSlideFile('slides/mod1.jpg');
        $this->createSlide([
            'type' => 'moderation',
            'service_id' => $service->id,
            'original_filename' => 'mod1.jpg',
            'stored_filename' => 'slides/mod1.jpg',
            'sort_order' => 1,
        ]);

        $bundlePath = app(ProBundleExportService::class)->generateBundle($service, 'moderation');

        $this->assertFileExists($bundlePath);

        $bundle = ProBundleReader::read($bundlePath);
        $slides = $bundle->getSong()->getSlides();

        // The foreground image is now a content fill.media element, not a media ACTION.
        $mediaSlides = array_filter($slides, fn ($slide) => $this->fillMediaUrls($slide) !== []);
        $this->assertNotEmpty($mediaSlides, 'Expected a foreground-image content slide in the bundle.');

        foreach ($mediaSlides as $slide) {
            $this->assertFalse($this->hasImageMediaAction($slide), 'No image media ACTION may remain.');
            foreach ($this->fillMediaUrls($slide) as $url) {
                // Bundle-relative resources use a bare basename (no absolute path / no slash).
                $this->assertStringNotContainsString('/', $url, 'Foreground media URL must be bundle-relative (basename only).');
            }
        }

        @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);
    }
}
