<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class ImageController extends Controller
{
    // Max dimensions for product images
    private const MAX_WIDTH = 1200;
    private const MAX_HEIGHT = 1200;
    // Thumbnail dimensions for listings
    private const THUMB_WIDTH = 400;
    private const THUMB_HEIGHT = 400;
    // Quality (0-100)
    private const QUALITY = 82;

    /**
     * Upload and optimize one or more product images
     * POST /api/images/upload
     */
    public function upload(Request $request)
    {
        $request->validate([
            'images'   => 'required|array|min:1|max:10',
            'images.*' => 'required|image|mimes:jpeg,png,jpg,webp,gif|max:10240',
        ]);

        $uploaded = [];

        foreach ($request->file('images') as $file) {
            $result = $this->processAndStore($file);
            if ($result) {
                $uploaded[] = $result;
            }
        }

        if (empty($uploaded)) {
            return response()->json([
                'success' => false,
                'message' => 'Nenhuma imagem foi processada',
            ], 422);
        }

        return response()->json([
            'success' => true,
            'data' => $uploaded,
        ]);
    }

    /**
     * Upload a single image
     * POST /api/images/upload-single
     */
    public function uploadSingle(Request $request)
    {
        $request->validate([
            'image' => 'required|image|mimes:jpeg,png,jpg,webp|max:10240',
        ]);

        $result = $this->processAndStore($request->file('image'));

        if (!$result) {
            return response()->json([
                'success' => false,
                'message' => 'Erro ao processar imagem',
            ], 422);
        }

        return response()->json([
            'success' => true,
            'data' => $result,
        ]);
    }

    /**
     * Delete an image
     * DELETE /api/images
     */
    public function delete(Request $request)
    {
        $request->validate([
            'path' => 'required|string',
        ]);

        $path = $request->input('path');

        // Security: only allow deletion of files in products/ directory
        if (!str_starts_with($path, 'products/')) {
            return response()->json([
                'success' => false,
                'message' => 'Operação não permitida',
            ], 403);
        }

        $deleted = Storage::disk('public')->delete($path);

        // Also delete thumbnail if it exists
        $thumbPath = str_replace('products/', 'products/thumbs/', $path);
        Storage::disk('public')->delete($thumbPath);

        return response()->json([
            'success' => $deleted,
            'message' => $deleted ? 'Imagem removida' : 'Imagem não encontrada',
        ]);
    }

    private function processAndStore($file): ?array
    {
        try {
            $originalSize = $file->getSize();
            $filename = Str::uuid() . '.webp';
            $thumbFilename = 'thumb_' . $filename;

            $imageData = file_get_contents($file->getRealPath());
            $gdImage = $this->createGdImage($file->getRealPath(), $file->getMimeType());

            if (!$gdImage) {
                return null;
            }

            $origWidth = imagesx($gdImage);
            $origHeight = imagesy($gdImage);

            // Resize main image if needed
            $mainImage = $this->resizeImage($gdImage, $origWidth, $origHeight, self::MAX_WIDTH, self::MAX_HEIGHT);

            // Create thumbnail
            $thumbImage = $this->resizeImage($gdImage, $origWidth, $origHeight, self::THUMB_WIDTH, self::THUMB_HEIGHT);

            // Convert to WebP and save
            $mainPath = 'products/' . $filename;
            $thumbPath = 'products/thumbs/' . $thumbFilename;

            ob_start();
            imagewebp($mainImage, null, self::QUALITY);
            $mainWebpData = ob_get_clean();

            ob_start();
            imagewebp($thumbImage, null, self::QUALITY);
            $thumbWebpData = ob_get_clean();

            Storage::disk('public')->put($mainPath, $mainWebpData);
            Storage::disk('public')->put($thumbPath, $thumbWebpData);

            imagedestroy($gdImage);
            imagedestroy($mainImage);
            if ($mainImage !== $thumbImage) {
                imagedestroy($thumbImage);
            }

            $newSize = strlen($mainWebpData);
            $reduction = $originalSize > 0 ? round((1 - $newSize / $originalSize) * 100) : 0;

            return [
                'url' => Storage::disk('public')->url($mainPath),
                'thumb_url' => Storage::disk('public')->url($thumbPath),
                'path' => $mainPath,
                'thumb_path' => $thumbPath,
                'original_size' => $originalSize,
                'optimized_size' => $newSize,
                'reduction_percent' => $reduction,
                'width' => imagesx($this->createGdImageFromData($mainWebpData) ?: $mainImage),
            ];
        } catch (\Throwable $e) {
            \Log::error('Image processing failed', [
                'error' => $e->getMessage(),
                'file'  => $e->getFile() . ':' . $e->getLine(),
            ]);
            return null;
        }
    }

    private function createGdImage(string $path, string $mimeType): \GdImage|false
    {
        // Use @ to suppress libpng/GD warnings (e.g. "iCCP: known incorrect sRGB profile")
        // that PHP converts to exceptions via the error handler, breaking image creation.
        // The image loads correctly despite the warning — it's a metadata issue, not corruption.
        return match ($mimeType) {
            'image/jpeg' => @imagecreatefromjpeg($path),
            'image/png'  => @imagecreatefrompng($path),
            'image/webp' => @imagecreatefromwebp($path),
            'image/gif'  => @imagecreatefromgif($path),
            default      => @imagecreatefromstring(@file_get_contents($path)),
        };
    }

    private function createGdImageFromData(string $data): \GdImage|false
    {
        return imagecreatefromstring($data);
    }

    private function resizeImage(\GdImage $source, int $origW, int $origH, int $maxW, int $maxH): \GdImage
    {
        if ($origW <= $maxW && $origH <= $maxH) {
            return $source;
        }

        $ratio = min($maxW / $origW, $maxH / $origH);
        $newW = (int) round($origW * $ratio);
        $newH = (int) round($origH * $ratio);

        $resized = imagecreatetruecolor($newW, $newH);

        // Preserve transparency for PNG/WebP
        imagealphablending($resized, false);
        imagesavealpha($resized, true);
        $transparent = imagecolorallocatealpha($resized, 0, 0, 0, 127);
        imagefilledrectangle($resized, 0, 0, $newW, $newH, $transparent);

        imagecopyresampled($resized, $source, 0, 0, 0, 0, $newW, $newH, $origW, $origH);

        return $resized;
    }
}
