<?php

declare(strict_types=1);

namespace ApiModel\Tests\Unit\Validation;

use ApiModel\Shared\Exceptions\ValidationException;
use ApiModel\Shared\Validation\CriticalInputValidator;
use PHPUnit\Framework\TestCase;

final class CriticalInputValidatorTest extends TestCase
{
    public function testLoginBodyAcceptsValid(): void
    {
        CriticalInputValidator::loginBody([
            'email' => 'user@example.com',
            'password' => 'secret',
        ]);
        $this->addToAssertionCount(1);
    }

    public function testLoginBodyRejectsInvalidEmail(): void
    {
        try {
            CriticalInputValidator::loginBody(['email' => 'bad', 'password' => 'x']);
            self::fail('Expected ValidationException');
        } catch (ValidationException $e) {
            self::assertSame(422, $e->getCode());
            self::assertArrayHasKey('fields', $e->getDetails() ?? []);
        }
    }

    public function testRefreshBodyRequiresMinLength(): void
    {
        $this->expectException(ValidationException::class);
        CriticalInputValidator::refreshBody(['refresh_token' => 'short']);
    }

    public function testResetPasswordRequiresSixDigitCode(): void
    {
        try {
            CriticalInputValidator::resetPasswordBody([
                'email' => 'a@b.co',
                'code' => '12345',
                'new_password' => 'abc12345',
            ]);
            self::fail('Expected ValidationException');
        } catch (ValidationException $e) {
            $fields = $e->getDetails()['fields'] ?? [];
            self::assertArrayHasKey('code', $fields);
        }
    }

    public function testResetPasswordAcceptsValid(): void
    {
        CriticalInputValidator::resetPasswordBody([
            'email' => 'user@example.com',
            'code' => '123456',
            'new_password' => 'Secure1a',
        ]);
        $this->addToAssertionCount(1);
    }

    public function testCreateExternalClaimBodyMinimalValid(): void
    {
        CriticalInputValidator::createExternalClaimBody([
            'external_id' => 'ext-1',
            'insured_name' => 'Juan',
            'incident_type' => 'CHOQUE',
            'documents' => [
                ['filename' => 'a.pdf', 'storage_path' => '/path/a'],
            ],
        ]);
        $this->addToAssertionCount(1);
    }

    public function testCreateExternalClaimBodyRejectsEmptyDocuments(): void
    {
        $this->expectException(ValidationException::class);
        CriticalInputValidator::createExternalClaimBody([
            'external_id' => 'x',
            'insured_name' => 'Juan',
            'incident_type' => 'T',
            'documents' => [],
        ]);
    }

    public function testOptionalNoteNull(): void
    {
        self::assertNull(CriticalInputValidator::optionalNote(null));
    }

    public function testOptionalNoteEmptyStringBecomesNull(): void
    {
        self::assertNull(CriticalInputValidator::optionalNote(''));
    }

    public function testOptionalNoteRejectsNonString(): void
    {
        $this->expectException(ValidationException::class);
        CriticalInputValidator::optionalNote(['x']);
    }
}
