<?php

namespace Tests\Feature\Api\V1\FullSurface;

use Illuminate\Http\UploadedFile;
use Illuminate\Routing\Route as LaravelRoute;
use Illuminate\Support\Facades\Storage;
use Tests\Feature\Api\V1\FullSurface\Support\FullSurfaceE2EContractCase;

class ApiDeepFileImportExportAndPrintableContractTest extends FullSurfaceE2EContractCase
{
    public function test_export_download_and_printable_routes_are_controlled_for_authenticated_users(): void
    {
        $failures = [];

        foreach ($this->downloadLikeRoutes() as $route) {
            $method = $this->primaryMethod($route);
            $uri = $route->uri();
            $response = $this->probeRoute($route);
            $status = $response->getStatusCode();

            if ($status >= 500) {
                $failures[] = "$method $uri crashed when generating downloadable/printable output: " . $response->getContent();
                continue;
            }

            if (! in_array($status, [200, 202, 204, 302, 400, 401, 403, 404, 405, 409, 419, 422], true)) {
                $failures[] = "$method $uri returned unexpected $status for downloadable/printable output: " . $response->getContent();
            }
        }

        $this->assertSame([], $failures, "Download/export/print routes must fail cleanly when fixtures are thin:\n" . implode("\n", $failures));
    }

    public function test_import_upload_routes_accept_test_files_or_return_validation_without_server_errors(): void
    {
        Storage::fake('local');
        $failures = [];

        foreach ($this->uploadLikeRoutes() as $route) {
            $method = $this->primaryMethod($route);
            $uri = $route->uri();
            $payload = $this->payloadFor($method, $uri) + [
                'file' => UploadedFile::fake()->create('e2e-import.csv', 2, 'text/csv'),
                'document' => UploadedFile::fake()->create('e2e-document.pdf', 2, 'application/pdf'),
            ];

            $response = $this->requestAs($this->actorFor($uri), $method, $uri, $payload);
            $status = $response->getStatusCode();

            if ($status >= 500) {
                $failures[] = "$method $uri crashed on upload/import probe: " . $response->getContent();
            }
        }

        $this->assertSame([], $failures, "Upload/import routes must validate file input, not panic:\n" . implode("\n", $failures));
    }

    /** @return list<LaravelRoute> */
    private function downloadLikeRoutes(): array
    {
        return $this->apiRoutesContainingAny(['download', 'export', 'pdf', 'print', 'certificate', 'badge', 'receipt']);
    }

    /** @return list<LaravelRoute> */
    private function uploadLikeRoutes(): array
    {
        return array_values(array_filter($this->apiRoutes(), function (LaravelRoute $route): bool {
            if (! in_array($this->primaryMethod($route), ['POST', 'PUT', 'PATCH'], true)) {
                return false;
            }

            $uri = $route->uri();

            return str_contains($uri, 'upload')
                || str_contains($uri, 'import')
                || str_contains($uri, 'scan')
                || str_contains($uri, 'document')
                || str_contains($uri, 'attachment');
        }));
    }
}
