<?php

namespace Tests\Unit\Storage;

use CodeIgniter\HTTP\DownloadResponse;
use InvalidArgumentException;
use Tests\Support\Storage\StorageTestCase;

/**
 * @internal
 */
final class PolicyStorageHelperTest extends StorageTestCase
{
    public function testPolicyFileTypeMapContainsExpectedTypes(): void
    {
        $map = policy_file_type_map();

        $this->assertArrayHasKey('policy_pdf', $map);
        $this->assertArrayHasKey('policy_payment_receipt', $map);
        $this->assertSame('policy_pdf', $map['policy_pdf']['folder']);
        $this->assertSame('policy_payment_receipt', $map['policy_payment_receipt']['folder']);
    }

    public function testPolicyMdFileNameConvertsPdfToMd(): void
    {
        $this->assertSame('1764999905_abc.md', policy_md_file_name('1764999905_abc.pdf'));
        $this->assertSame('file.md', policy_md_file_name('file'));
    }

    public function testPolicyUploadPdfStoresFile(): void
    {
        $file = $this->createUploadedFile('%PDF policy', 'policy.pdf', 'application/pdf');

        $stored = policy_upload_pdf($file);

        $this->assertNotNull($stored);
        $this->assertTrue(policy_exists_by_type($stored, 'policy_pdf'));
    }

    public function testPolicyUploadReceiptStoresFile(): void
    {
        $file = $this->createUploadedFile('receipt image', 'receipt.jpg', 'image/jpeg');

        $stored = policy_upload_receipt($file);

        $this->assertNotNull($stored);
        $this->assertTrue(policy_exists_by_type($stored, 'policy_payment_receipt'));
    }

    public function testPolicyUploadReturnsNullWhenNoFile(): void
    {
        $this->assertNull(policy_upload_pdf(null));
        $this->assertNull(policy_upload_receipt(null));
    }

    public function testPolicyExistsByTypeReturnsFalseForInvalidType(): void
    {
        $this->assertFalse(policy_exists_by_type('any.pdf', 'invalid_type'));
    }

    public function testPolicyDownloadByTypeAttachment(): void
    {
        storage_put('policy', 'policy_pdf', 'download.pdf', 'policy-body');

        $response = policy_download_by_type('download.pdf', 'policy_pdf');

        $this->assertInstanceOf(DownloadResponse::class, $response);
        $this->assertDownloadHeaders($response, 'attachment');
        $this->assertGreaterThan(0, $response->getContentLength());
    }

    public function testPolicyDownloadByTypeInline(): void
    {
        storage_put('policy', 'policy_payment_receipt', 'receipt.pdf', 'receipt-body');

        $response = policy_download_by_type('receipt.pdf', 'policy_payment_receipt', true);

        $this->assertInstanceOf(DownloadResponse::class, $response);
        $this->assertDownloadHeaders($response, 'inline');
        $this->assertGreaterThan(0, $response->getContentLength());
    }

    public function testPolicyDownloadByTypeThrowsForInvalidType(): void
    {
        $this->expectException(InvalidArgumentException::class);

        policy_download_by_type('file.pdf', 'unknown');
    }

    public function testPolicyLocalPdfPathResolvesStoredPdf(): void
    {
        storage_put('policy', 'policy_pdf', 'rag.pdf', 'rag-pdf');

        $path = policy_local_pdf_path('rag.pdf');

        $this->assertFileExists($path);
        $this->assertSame('rag-pdf', file_get_contents($path));
    }

    public function testPolicyMarkdownPutReadAndExists(): void
    {
        policy_put_md('sample.md', str_repeat('x', 600));

        $this->assertTrue(policy_md_exists('sample.md'));
        $this->assertSame(str_repeat('x', 600), policy_read_md('sample.md'));
    }
}

/**
 * @internal
 */
final class EndorsementStorageHelperTest extends StorageTestCase
{
    public function testEndorsementSubfolderForType(): void
    {
        $this->assertSame('', endorsement_subfolder_for_type('original'));
        $this->assertSame('', endorsement_subfolder_for_type(null));
        $this->assertSame('endorsement_pdf', endorsement_subfolder_for_type('completion'));
    }

    public function testEndorsementUploadOriginalStoresInRootFolder(): void
    {
        $file = $this->createUploadedFile('original endorsement', 'endorsement.pdf', 'application/pdf');

        $stored = endorsement_upload_original($file);

        $this->assertNotNull($stored);
        $this->assertTrue(endorsement_exists_by_type($stored, 'original'));
        $this->assertFileExists($this->localFilePath('uploads/endorsement/' . $stored));
    }

    public function testEndorsementUploadCompletionStoresInSubfolder(): void
    {
        $file = $this->createUploadedFile('completion endorsement', 'completion.pdf', 'application/pdf');

        $stored = endorsement_upload_completion($file);

        $this->assertNotNull($stored);
        $this->assertTrue(endorsement_exists_by_type($stored, 'completion'));
        $this->assertFileExists($this->localFilePath('uploads/endorsement/endorsement_pdf/' . $stored));
    }

    public function testEndorsementDownloadOriginalAndCompletion(): void
    {
        storage_put('endorsement', '', 'orig.pdf', 'orig-body');
        storage_put('endorsement', 'endorsement_pdf', 'done.pdf', 'done-body');

        $originalResponse   = endorsement_download_by_type('orig.pdf', 'original');
        $completionResponse = endorsement_download_by_type('done.pdf', 'completion');

        $this->assertInstanceOf(DownloadResponse::class, $originalResponse);
        $this->assertInstanceOf(DownloadResponse::class, $completionResponse);
        $this->assertGreaterThan(0, $originalResponse->getContentLength());
        $this->assertGreaterThan(0, $completionResponse->getContentLength());
    }

    public function testEndorsementDownloadInlineUsesInlineDisposition(): void
    {
        storage_put('endorsement', 'endorsement_pdf', 'view.pdf', 'view-body');

        $response = endorsement_download_by_type('view.pdf', 'completion', true);

        $this->assertStringContainsString('inline', $response->getHeaderLine('Content-Disposition'));
    }

    public function testEndorsementDeleteCompletionRemovesFile(): void
    {
        storage_put('endorsement', 'endorsement_pdf', 'old.pdf', 'old');

        $this->assertTrue(endorsement_delete_completion('old.pdf'));
        $this->assertFalse(endorsement_exists_by_type('old.pdf', 'completion'));
    }

    public function testEndorsementUploadReturnsNullWhenNoFile(): void
    {
        $this->assertNull(endorsement_upload_original(null));
        $this->assertNull(endorsement_upload_completion(null));
    }
}
