<?php

namespace App\Http\Controllers\Features;

use App\Http\Controllers\Controller;
use App\Models\Features\Feature;
use App\Services\Features\FeatureImageService;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Storage;
use App\Support\LimiteDeSubida;
use Illuminate\Support\Facades\Validator;

class ImageUploadController extends Controller
{
    /**
     * Maneja la subida de imágenes desde el editor Jodit
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function upload(Request $request): JsonResponse
    {
        // Validar que se haya enviado una imagen.
        //
        // El SVG NO se admite, y no es un olvido: un SVG es XML y puede llevar
        // <script> dentro. Estos ficheros se guardan en el disco público y se sirven
        // desde el MISMO origen que el panel, así que un SVG con script no ejecuta
        // nada dentro de un <img>, pero sí al abrirlo por su URL directa, con la
        // sesión de quien lo abra. Es una vía de un rol de contenido hacia la sesión
        // de un Admin. Ver known-issues MGR-020.
        //
        // Si algún día hace falta vectorial (diagramas), se reintroduce con saneado
        // específico al subir, como ticket propio. No relajar esta lista sin eso.
        $validator = Validator::make($request->all(), [
            // **El tope se calcula, no se escribe.** Ver `LimiteDeSubida`: el 5120 de
            // antes era el límite de la última de cuatro capas, y el aviso lo
            // anunciaba como si fuera el único (PRODSECU-156).
            'image' => ['required', 'file', 'mimes:jpeg,jpg,png,webp', 'max:' . LimiteDeSubida::enKb()],
            'feature_id' => 'nullable|exists:features,id',
            'product_id' => 'nullable|exists:products,id',
            'feature_version_id' => 'nullable|exists:feature_versions,id',
        ], [
            'image.mimes' => 'Formato no admitido. Se aceptan PNG, JPG y WebP. El SVG no se admite por seguridad: puede contener código ejecutable.',
            'image.max' => 'La imagen no puede superar los ' . LimiteDeSubida::comoTexto()
                . (LimiteDeSubida::loRecortaElServidor()
                    ? '. Ese tope lo impone la configuración del servidor, no el panel.'
                    : '.'),
            'image.required' => 'No se ha recibido ninguna imagen.',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'files' => [],
                'path' => '',
                'baseurl' => '',
                'error' => 1,
                'msg' => $validator->errors()->first(),
            ], 400);
        }

        try {
            $imageService = app(FeatureImageService::class);
            $featureId = $request->input('feature_id');
            $productId = $request->input('product_id');
            $featureVersionId = $request->input('feature_version_id');

            // Si hay feature_id, usar la feature existente
            if ($featureId) {
                $feature = Feature::with('featureVersion')->findOrFail($featureId);
                
                // Verificar que la feature pertenezca al producto (a través de featureVersion)
                if ($feature->featureVersion && $productId && $feature->featureVersion->product_id != $productId) {
                    return response()->json([
                        'files' => [],
                        'path' => '',
                        'baseurl' => '',
                        'error' => 1,
                        'msg' => 'La feature no pertenece a este producto',
                    ], 400);
                }
                
                // Verificar feature_version_id si se proporciona
                if ($featureVersionId && $feature->feature_version_id != $featureVersionId) {
                    return response()->json([
                        'files' => [],
                        'path' => '',
                        'baseurl' => '',
                        'error' => 1,
                        'msg' => 'La feature no pertenece a esta versión',
                    ], 400);
                }

                // Modo edición: guardar en un directorio temporal asociado a la feature
                $tempPath = "features/temp/feature/{$feature->id}";
                $filename = $imageService->generateUniqueFilename($request->file('image'), 'editor');
                Storage::disk('public')->putFileAs($tempPath, $request->file('image'), $filename);
                $relativePath = $tempPath . '/' . $filename;
            } else {
                // Si no hay feature_id (modo Create), usar product_id o feature_version_id
                if ($featureVersionId) {
                    // Usar feature_version_id si está disponible
                    $tempPath = "features/temp/version/{$featureVersionId}";
                } elseif ($productId) {
                    // Fallback a product_id para compatibilidad
                    $tempPath = "features/temp/{$productId}";
                } else {
                    return response()->json([
                        'files' => [],
                        'path' => '',
                        'baseurl' => '',
                        'error' => 1,
                        'msg' => 'Se requiere product_id o feature_version_id',
                    ], 400);
                }
                
                $filename = $imageService->generateUniqueFilename($request->file('image'), 'temp');
                $relativePath = $tempPath . '/' . $filename;
                
                Storage::disk('public')->putFileAs($tempPath, $request->file('image'), $filename);
            }

            // Respuesta en formato estándar de Jodit: { files, path, baseurl, error, msg }
            $storageBase = rtrim(Storage::disk('public')->url('/'), '/'); // p.ej. https://.../storage

            return response()->json([
                'files' => [$relativePath],
                'path' => $relativePath,
                'baseurl' => $storageBase . '/',
                'error' => 0,
                'msg' => '',
            ]);
        } catch (\Exception $e) {
            // El mensaje de la excepción NO se devuelve al cliente: un error de disco
            // o de BD filtraría rutas del servidor o estructura de tablas. El detalle
            // va al log. Misma familia que known-issues MGR-007.
            report($e);

            return response()->json([
                'files' => [],
                'path' => '',
                'baseurl' => '',
                'error' => 1,
                'msg' => 'No se ha podido guardar la imagen. Inténtalo de nuevo o avisa a soporte.',
            ], 500);
        }
    }
}

