<?php

namespace Tests\Support\Storage;

use App\Services\FileStorageService;
use CodeIgniter\HTTP\Files\UploadedFile;
use CodeIgniter\Test\CIUnitTestCase;
use Config\Services;
use Config\Storage;

abstract class StorageTestCase extends CIUnitTestCase
{
    protected string $tempRoot;

    protected Storage $storageConfig;

    protected function setUp(): void
    {
        parent::setUp();

        $this->resetServices();

        $this->tempRoot = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'nhance_storage_test_' . uniqid('', true);
        mkdir($this->tempRoot, 0777, true);

        $this->storageConfig               = new Storage();
        $this->storageConfig->driver       = 'local';
        $this->storageConfig->retainLocal  = false;
        $this->storageConfig->localRoot    = $this->tempRoot . DIRECTORY_SEPARATOR;
        $this->storageConfig->presignedTtl = 900;

        Services::injectMock('fileStorage', new FileStorageService($this->storageConfig));

        helper('storage_helper');
    }

    protected function tearDown(): void
    {
        $this->deleteDirectory($this->tempRoot);
        $this->resetServices();

        parent::tearDown();
    }

    protected function useLocalDriver(): void
    {
        $this->storageConfig->driver = 'local';
        Services::injectMock('fileStorage', new FileStorageService($this->storageConfig));
    }

    protected function useS3DriverFromEnv(): void
    {
        $this->storageConfig->driver       = 's3';
        $this->storageConfig->s3Bucket     = getenv('AWS_BUCKET') ?: '';
        $this->storageConfig->s3Region     = getenv('AWS_DEFAULT_REGION') ?: 'ap-south-1';
        $this->storageConfig->s3AccessKey  = getenv('AWS_ACCESS_KEY_ID') ?: '';
        $this->storageConfig->s3SecretKey  = getenv('AWS_SECRET_ACCESS_KEY') ?: '';
        $this->storageConfig->s3Prefix     = trim(getenv('AWS_S3_PREFIX') ?: '', '/');

        Services::injectMock('fileStorage', new FileStorageService($this->storageConfig));
    }

    protected function s3IntegrationEnabled(): bool
    {
        return getenv('FILE_STORAGE_DRIVER') === 's3'
            && getenv('AWS_BUCKET') !== false
            && getenv('AWS_BUCKET') !== ''
            && getenv('AWS_ACCESS_KEY_ID') !== false
            && getenv('AWS_ACCESS_KEY_ID') !== ''
            && getenv('AWS_SECRET_ACCESS_KEY') !== false
            && getenv('AWS_SECRET_ACCESS_KEY') !== '';
    }

    protected function skipUnlessS3Integration(): void
    {
        if (! $this->s3IntegrationEnabled()) {
            $this->markTestSkipped('S3 integration env is not configured (FILE_STORAGE_DRIVER=s3 and AWS_* vars).');
        }

        $this->useS3DriverFromEnv();
    }

    protected function createUploadedFile(
        string $contents,
        string $originalName,
        string $mime = 'application/octet-stream'
    ): UploadedFile {
        $temp = tempnam(sys_get_temp_dir(), 'ci_upload_');
        file_put_contents($temp, $contents);

        return new TestUploadedFile($temp, $originalName, $mime, strlen($contents), UPLOAD_ERR_OK, false);
    }

    protected function localFilePath(string $key): string
    {
        return $this->tempRoot . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, ltrim($key, '/'));
    }

    protected function deleteDirectory(string $dir): void
    {
        if (! is_dir($dir)) {
            return;
        }

        foreach (scandir($dir) as $item) {
            if ($item === '.' || $item === '..') {
                continue;
            }

            $path = $dir . DIRECTORY_SEPARATOR . $item;

            if (is_dir($path)) {
                $this->deleteDirectory($path);
            } else {
                @unlink($path);
            }
        }

        @rmdir($dir);
    }

    protected function assertDownloadHeaders(\CodeIgniter\HTTP\DownloadResponse $response, string $disposition): void
    {
        $response->buildHeaders();

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