<?php

namespace Tests\Feature;

use PHPUnit\Framework\Attributes\DataProvider;
use Tests\TestCase;

/**
 * store() moves a Livewire temporary upload out of livewire-tmp, so anything
 * that reads the file afterwards reads a path that no longer exists.
 *
 * This is what made every expense receipt fail in production (1b62a44f-…,
 * 2026-09-03): the attachment array had `'path' => …->store(…)` on its first
 * line, PHP evaluates array literals in order, and getMimeType()/getSize() on
 * the lines below then ran against a file that had just been moved — throwing
 * Flysystem's UnableToRetrieveMetadata all the way to the browser.
 *
 * Livewire's test harness swaps the temporary disk for one that does not move
 * the file, so a component test goes green on the broken code. The invariant
 * that actually holds is about the source: every metadata read comes before
 * the store() that invalidates it.
 */
class TemporaryUploadMetadataOrderTest extends TestCase
{
    public static function uploadHandlers(): array
    {
        return [
            // Literal paths, not app_path(): the provider runs before the
            // application container is booted.
            'expense create form' => [dirname(__DIR__, 2) . '/app/Livewire/Financial/ExpenseForm.php'],
            'expense receipt upload' => [dirname(__DIR__, 2) . '/app/Livewire/Financial/ExpenseShow.php'],
        ];
    }

    #[DataProvider('uploadHandlers')]
    public function test_upload_metadata_is_read_before_the_file_is_stored(string $file): void
    {
        $source = file_get_contents($file);

        $store = strpos($source, "->store('expenses/receipts'");

        $this->assertNotFalse($store, "No receipt store() found in {$file}");

        foreach (['getSize()', 'getMimeType()', 'getClientOriginalName()'] as $read) {
            $at = strpos($source, $read);

            $this->assertNotFalse($at, "{$read} missing from {$file}");
            $this->assertLessThan(
                $store,
                $at,
                "{$read} runs after store() in {$file} — the temporary file is already gone by then."
            );
        }
    }
}
