<?php

namespace App\Services;

use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class S3PresignedService
{
    private const ALLOWED_MIME_TYPES = [
        'image/jpeg',
        'image/png',
        'image/webp',
        'image/gif',
    ];

    public function createUploadUrl(string $fileName, string $mimeType, ?string $folder = null): array
    {
        if (! in_array($mimeType, self::ALLOWED_MIME_TYPES)) {
            abort(422, 'Tipe file tidak didukung. Hanya JPG, PNG, WebP, dan GIF yang diizinkan.');
        }

        $disk = Storage::disk('s3');
        $client = $disk->getClient();
        $bucket = config('filesystems.disks.s3.bucket');

        $key = $this->generateKey($fileName, $folder);
        $uuid = pathinfo($key, PATHINFO_FILENAME);

        $command = $client->getCommand('PutObject', [
            'Bucket' => $bucket,
            'Key' => $key,
            'ContentType' => $mimeType,
            'ACL' => 'public-read',
        ]);

        $presignedUrl = (string) $client->createPresignedRequest($command, '+15 minutes')->getUri();

        return [
            'upload_url' => $presignedUrl,
            'key' => $key,
            'uuid' => $uuid,
        ];
    }

    public function getTemporaryUrl(string $key, int $minutes = 60): string
    {
        $disk = Storage::disk('s3');
        $client = $disk->getClient();
        $bucket = config('filesystems.disks.s3.bucket');

        $command = $client->getCommand('GetObject', [
            'Bucket' => $bucket,
            'Key' => $key,
        ]);

        return (string) $client->createPresignedRequest($command, "+{$minutes} minutes")->getUri();
    }

    public function deleteFile(string $key): bool
    {
        return Storage::disk('s3')->delete($key);
    }

    private function generateKey(string $fileName, ?string $folder): string
    {
        $date = now()->format('Y/m/d');
        $uuid = Str::uuid();
        $extension = pathinfo($fileName, PATHINFO_EXTENSION);
        $safeName = Str::slug(pathinfo($fileName, PATHINFO_FILENAME));

        $prefix = $folder ? "{$folder}/{$date}" : $date;

        return "{$prefix}/{$uuid}/{$safeName}.{$extension}";
    }
}
