<?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 ApiBulkImportExportAndPartialFailureExpansionTest extends FullSurfaceE2EContractCase
{
    public function test_bulk_routes_handle_mixed_valid_and_invalid_ids_cleanly(): void
    {
        foreach ($this->bulkRoutes() as $route) {
            $method = $this->primaryMethod($route);
            $uri = $route->uri();
            $response = $this->requestAs($this->actorFor($uri), $method, $uri, [
                'ids' => [$this->ids['studentId'], 999999999, null, 'not-an-id'],
                'student_ids' => [$this->ids['studentId'], 999999999],
                'class_section_id' => $this->ids['classSectionId'],
                'school_year' => self::E2E_SCHOOL_YEAR,
                'semester' => self::E2E_SEMESTER,
            ]);

            $this->assertControlled($response, $method, $uri);
            $this->assertNoServerError($response, "$method $uri mixed bulk payload");
        }
    }

    public function test_import_routes_reject_wrong_file_types_with_validation_not_crashes(): void
    {
        Storage::fake('local');

        foreach ($this->importRoutes() as $route) {
            $method = $this->primaryMethod($route);
            $uri = $route->uri();
            $response = $this->requestAs($this->actorFor($uri), $method, $uri, [
                'file' => UploadedFile::fake()->create('not-a-spreadsheet.exe', 4, 'application/x-msdownload'),
                'school_year' => self::E2E_SCHOOL_YEAR,
                'semester' => self::E2E_SEMESTER,
            ]);

            $this->assertControlled($response, $method, $uri);
            $this->assertNoServerError($response, "$method $uri wrong import file type");
        }
    }

    public function test_export_download_routes_do_not_return_mutating_statuses(): void
    {
        foreach ($this->exportRoutes() as $route) {
            $method = $this->primaryMethod($route);
            $uri = $route->uri();
            $response = $this->requestAs($this->actorFor($uri), $method, $uri, [
                'school_year' => self::E2E_SCHOOL_YEAR,
                'semester' => self::E2E_SEMESTER,
                'format' => 'xlsx',
            ]);

            $this->assertStatusIn($response, [200, 202, 204, 302, 400, 401, 403, 404, 405, 409, 419, 422], "$method $uri export/download");
            $this->assertNoServerError($response, "$method $uri export/download");
        }
    }

    /** @return list<LaravelRoute> */
    private function bulkRoutes(): array
    {
        return array_slice(array_filter($this->apiRoutes(), fn (LaravelRoute $route): bool => preg_match('/bulk|batch|selected|import|assign|sync/i', $route->uri()) === 1), 0, 80);
    }

    /** @return list<LaravelRoute> */
    private function importRoutes(): array
    {
        return array_slice(array_filter($this->apiRoutes(), fn (LaravelRoute $route): bool => preg_match('/import|upload|attachment|document/i', $route->uri()) === 1 && in_array($this->primaryMethod($route), ['POST', 'PUT', 'PATCH'], true)), 0, 50);
    }

    /** @return list<LaravelRoute> */
    private function exportRoutes(): array
    {
        return array_slice(array_filter($this->apiRoutes(), fn (LaravelRoute $route): bool => preg_match('/export|download|pdf|print|receipt|certificate|badge/i', $route->uri()) === 1), 0, 80);
    }
}
