<?php

use App\Services\FileConversionService;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;

beforeEach(function () {
    Storage::fake('public');
});

test('convert image creates 1920x1080 jpg with black bars and thumbnail', function () {
    $service = app(FileConversionService::class);
    $file = makePngUpload('landscape.png', 400, 300);

    $result = $service->convertImage($file);

    expect($result)->toHaveKeys(['filename', 'thumbnail']);
    expect($result['filename'])->toStartWith('slides/')->toEndWith('.jpg');
    expect($result['thumbnail'])->toStartWith('slides/thumbnails/')->toEndWith('.jpg');

    expect(Storage::disk('public')->exists($result['filename']))->toBeTrue();
    expect(Storage::disk('public')->exists($result['thumbnail']))->toBeTrue();

    $mainPath = Storage::disk('public')->path($result['filename']);
    [$width, $height] = getimagesize($mainPath);

    expect($width)->toBe(1920);
    expect($height)->toBe(1080);

    $image = imagecreatefromjpeg($mainPath);
    expect($image)->not->toBeFalse();

    $corner = imagecolorsforindex($image, imagecolorat($image, 0, 0));
    $center = imagecolorsforindex($image, imagecolorat($image, 960, 540));

    expect($corner['red'] + $corner['green'] + $corner['blue'])->toBeLessThan(20);
    expect($center['red'])->toBeGreaterThan(100);

    $thumbPath = Storage::disk('public')->path($result['thumbnail']);
    [$thumbWidth, $thumbHeight] = getimagesize($thumbPath);

    expect($thumbWidth)->toBe(320);
    expect($thumbHeight)->toBe(180);
});

test('small image is upscaled with at most two black bars', function () {
    $service = app(FileConversionService::class);
    // 4:3 image → taller than 16:9 → pillarbox (left/right only)
    $file = makePngUpload('small.png', 400, 300);

    $result = $service->convertImage($file);
    $mainPath = Storage::disk('public')->path($result['filename']);

    $image = imagecreatefromjpeg($mainPath);
    expect($image)->not->toBeFalse();

    // Left/right edges must be black (pillarbox)
    $left = imagecolorsforindex($image, imagecolorat($image, 0, 540));
    $right = imagecolorsforindex($image, imagecolorat($image, 1919, 540));
    expect($left['red'] + $left['green'] + $left['blue'])->toBeLessThan(20);
    expect($right['red'] + $right['green'] + $right['blue'])->toBeLessThan(20);

    // Top/bottom center must be image content (red), NOT black
    $topCenter = imagecolorsforindex($image, imagecolorat($image, 960, 0));
    $bottomCenter = imagecolorsforindex($image, imagecolorat($image, 960, 1079));
    expect($topCenter['red'])->toBeGreaterThan(100);
    expect($bottomCenter['red'])->toBeGreaterThan(100);
});

test('exact 16:9 image has no black bars', function () {
    $service = app(FileConversionService::class);
    $file = makePngUpload('exact.png', 1920, 1080);

    $result = $service->convertImage($file);
    $mainPath = Storage::disk('public')->path($result['filename']);

    $image = imagecreatefromjpeg($mainPath);
    expect($image)->not->toBeFalse();

    // All corners must be image content (red), no black bars
    $tl = imagecolorsforindex($image, imagecolorat($image, 0, 0));
    $tr = imagecolorsforindex($image, imagecolorat($image, 1919, 0));
    $bl = imagecolorsforindex($image, imagecolorat($image, 0, 1079));
    $br = imagecolorsforindex($image, imagecolorat($image, 1919, 1079));
    expect($tl['red'])->toBeGreaterThan(100);
    expect($tr['red'])->toBeGreaterThan(100);
    expect($bl['red'])->toBeGreaterThan(100);
    expect($br['red'])->toBeGreaterThan(100);
});

test('small 16:9 image is upscaled without black bars', function () {
    $service = app(FileConversionService::class);
    $file = makePngUpload('small169.png', 320, 180);

    $result = $service->convertImage($file);
    $mainPath = Storage::disk('public')->path($result['filename']);

    [$width, $height] = getimagesize($mainPath);
    expect($width)->toBe(1920);
    expect($height)->toBe(1080);

    $image = imagecreatefromjpeg($mainPath);
    expect($image)->not->toBeFalse();

    // All corners must be image content (red), no black bars
    $tl = imagecolorsforindex($image, imagecolorat($image, 0, 0));
    $br = imagecolorsforindex($image, imagecolorat($image, 1919, 1079));
    expect($tl['red'])->toBeGreaterThan(100);
    expect($br['red'])->toBeGreaterThan(100);
});

test('portrait image gets pillarbox bars on left and right', function () {
    $service = app(FileConversionService::class);
    $file = makePngUpload('portrait.png', 1080, 1920);

    $result = $service->convertImage($file);
    $mainPath = Storage::disk('public')->path($result['filename']);

    [$width, $height] = getimagesize($mainPath);
    expect($width)->toBe(1920);
    expect($height)->toBe(1080);

    $image = imagecreatefromjpeg($mainPath);
    expect($image)->not->toBeFalse();

    $left = imagecolorsforindex($image, imagecolorat($image, 10, 540));
    $right = imagecolorsforindex($image, imagecolorat($image, 1910, 540));
    $center = imagecolorsforindex($image, imagecolorat($image, 960, 540));

    expect($left['red'] + $left['green'] + $left['blue'])->toBeLessThan(20);
    expect($right['red'] + $right['green'] + $right['blue'])->toBeLessThan(20);
    expect($center['red'])->toBeGreaterThan(100);
});

function makePngUpload(string $name, int $width, int $height): UploadedFile
{
    $path = tempnam(sys_get_temp_dir(), 'cts-img-');
    if ($path === false) {
        throw new RuntimeException('Temp-Datei konnte nicht erstellt werden.');
    }

    $image = imagecreatetruecolor($width, $height);
    if ($image === false) {
        throw new RuntimeException('Bild konnte nicht erstellt werden.');
    }

    $red = imagecolorallocate($image, 255, 0, 0);
    imagefill($image, 0, 0, $red);
    imagepng($image, $path);

    return new UploadedFile($path, $name, 'image/png', null, true);
}
