<?php

namespace App\Services;

use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use InvalidArgumentException;

class MediaUploadService
{
    public function uploadImage(
        UploadedFile $file,
        string $disk,
        string $directory,
        array $rules,
    ): array {
        $this->assertValidImage($file, $rules);

        $extension = strtolower($file->getClientOriginalExtension());
        $filename = Str::uuid()->toString().'.'.$extension;
        $path = trim($directory, '/').'/'.$filename;

        Storage::disk($disk)->putFileAs(trim($directory, '/'), $file, $filename);

        return [
            'path' => $path,
            'original_name' => $file->getClientOriginalName(),
            'mime_type' => $file->getMimeType(),
            'size' => $file->getSize(),
            'checksum' => hash_file('sha256', $file->getRealPath()),
        ];
    }

    public function uploadPrivateFile(
        UploadedFile $file,
        string $directory,
        array $rules,
    ): array {
        $allowedMimes = $rules['mimes'] ?? ['jpg', 'jpeg', 'png', 'webp', 'pdf'];
        $extension = strtolower($file->getClientOriginalExtension());

        if (! in_array($extension, $allowedMimes, true)) {
            throw new InvalidArgumentException(__('validation.file_type_invalid'));
        }

        if ($file->getSize() > ($rules['max_kb'] ?? 10240) * 1024) {
            throw new InvalidArgumentException(__('validation.file_too_large'));
        }

        if (in_array($extension, ['jpg', 'jpeg', 'png', 'webp'], true)
            && ! @getimagesize($file->getRealPath())) {
            throw new InvalidArgumentException(__('validation.image_invalid'));
        }

        $filename = Str::uuid()->toString().'.'.$extension;
        $path = trim($directory, '/').'/'.$filename;

        Storage::disk('payment_proofs')->putFileAs(trim($directory, '/'), $file, $filename);

        return [
            'path' => $path,
            'original_name' => $file->getClientOriginalName(),
            'mime_type' => $file->getMimeType(),
            'size' => $file->getSize(),
        ];
    }

    public function deleteIfExists(string $disk, ?string $path): void
    {
        if (blank($path)) {
            return;
        }

        if (Storage::disk($disk)->exists($path)) {
            Storage::disk($disk)->delete($path);
        }
    }

    private function assertValidImage(UploadedFile $file, array $rules): void
    {
        $allowedMimes = $rules['mimes'] ?? ['jpg', 'jpeg', 'png', 'webp'];
        $extension = strtolower($file->getClientOriginalExtension());

        if (! in_array($extension, $allowedMimes, true)) {
            throw new InvalidArgumentException(__('validation.image_type_invalid'));
        }

        if ($file->getSize() > ($rules['max_kb'] ?? 2048) * 1024) {
            throw new InvalidArgumentException(__('validation.file_too_large'));
        }

        if (! @getimagesize($file->getRealPath())) {
            throw new InvalidArgumentException(__('validation.image_invalid'));
        }
    }
}
