<?php

namespace App\Domains\StorageTest\Services;

use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use RuntimeException;

class S3TestService
{
    /**
     * @return array<string, int|string|null>
     */
    public function storeTestFile(
        UploadedFile $file,
        ?string $directory = null,
        int $expiresInMinutes = 10,
    ): array {
        $directory = $this->normalizeDirectory($directory);
        $disk = Storage::disk('s3');
        $path = $disk->putFile($directory, $file);

        if (! is_string($path) || $path === '') {
            Log::error('S3 upload returned an empty path.', [
                'disk' => 's3',
                'directory' => $directory,
                'original_name' => $file->getClientOriginalName(),
                'mime_type' => $file->getClientMimeType(),
                'size' => $file->getSize(),
            ]);

            throw new RuntimeException('No se pudo subir el archivo al disco s3.');
        }

        return [
            'disk' => 's3',
            'directory' => $directory,
            'key' => $path,
            'path' => $path,
            'filename' => basename($path),
            'original_name' => $file->getClientOriginalName(),
            'mime_type' => $file->getClientMimeType(),
            'extension' => $file->extension(),
            'size' => $file->getSize(),
            'temporary_url' => $disk->temporaryUrl($path, now()->addMinutes($expiresInMinutes)),
            'temporary_url_expires_at' => now()->addMinutes($expiresInMinutes)->toIso8601String(),
        ];
    }

    /**
     * @return array<string, string>
     */
    public function generateTemporaryUrl(string $path, int $expiresInMinutes = 10): array
    {
        return [
            'disk' => 's3',
            'key' => $path,
            'path' => $path,
            'temporary_url' => $this->temporaryUrlForPath($path, $expiresInMinutes),
            'temporary_url_expires_at' => now()->addMinutes($expiresInMinutes)->toIso8601String(),
        ];
    }

    protected function temporaryUrlForPath(string $path, int $expiresInMinutes): string
    {
        return Storage::disk('s3')->temporaryUrl($path, now()->addMinutes($expiresInMinutes));
    }

    protected function normalizeDirectory(?string $directory): string
    {
        $directory = trim((string) $directory, '/');

        if ($directory !== '') {
            return $directory;
        }

        return 'testing/attachments/'.now()->format('Y/m/d').'/'.Str::uuid();
    }
}
