<?php

namespace App\Http\Controllers;

use App\Models\Producto;
use App\Support\CatalogDeletionGuard;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Symfony\Component\HttpFoundation\Response;

class ProductoController extends Controller
{
    /**
     * Listado de productos y servicios (catálogo unificado).
     */
    public function index(): JsonResponse
    {
        // C7/D4: este módulo legacy ("productos") debe exponer solo productos físicos (stock).
        // Los servicios se gestionan en el módulo de servicios/TIBU y NO deben mezclarse aquí.
        $productos = Producto::query()
            ->where('es_servicio', false)
            ->orderBy('nombre')
            ->get(['id', 'nombre', 'descripcion', 'precio', 'stock', 'es_servicio', 'tipo_cobro']);

        return response()->json(['data' => $productos], JsonResponse::HTTP_OK);
    }

    /**
     * Detalle de un producto/servicio.
     */
    public function show(Producto $producto): JsonResponse
    {
        return response()->json(['data' => $producto], JsonResponse::HTTP_OK);
    }

    /**
     * Crear producto o servicio. Si es servicio, tipo_cobro (peso|pieza) es requerido. Si es producto, se maneja stock.
     *
     * C7: con `lavanderia.productos_legacy_frozen` no se permiten altas (ventas nuevas vía TIBU).
     */
    public function store(Request $request): JsonResponse
    {
        $legacyFrozen = (bool) config('lavanderia.productos_legacy_frozen', true);
        $esServicioInput = $request->input('es_servicio', false);
        $esServicio = filter_var($esServicioInput, FILTER_VALIDATE_BOOLEAN);

        // C7: si el catálogo legacy está congelado, solo se bloquean altas de SERVICIOS.
        // Los PRODUCTOS (stock) siguen permitidos para ajustes/altas puntuales.
        if ($legacyFrozen && $esServicio) {
            return response()->json([
                'message' => 'Las altas en el catálogo legacy (tabla productos) están deshabilitadas. Las ventas nuevas usan servicio y tipos de prenda en el POS (TIBU).',
                'errors' => [
                    'es_servicio' => ['Altas de servicios legacy congeladas (C7).'],
                ],
            ], Response::HTTP_FORBIDDEN);
        }

        $rules = [
            'nombre' => ['required', 'string', 'max:255'],
            'descripcion' => ['nullable', 'string'],
            // Productos físicos (inventario legacy) no usan precio.
            // Servicios legacy sí requieren precio para el POS.
            'precio' => ['nullable', 'numeric', 'min:0'],
            'stock' => ['nullable', 'integer', 'min:0'],
            'es_servicio' => ['boolean'],
        ];
        $data = $request->all();
        if (! empty($data['es_servicio'])) {
            $rules['tipo_cobro'] = ['required', 'in:peso,pieza'];
            $rules['precio'] = ['required', 'numeric', 'min:0'];
        } else {
            $rules['stock'] = ['required', 'integer', 'min:0'];
            $rules['tipo_cobro'] = ['nullable', 'in:peso,pieza'];
        }

        $validator = Validator::make($request->all(), $rules);
        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], JsonResponse::HTTP_UNPROCESSABLE_ENTITY);
        }

        $payload = $validator->validated();
        $payload['es_servicio'] = (bool) ($payload['es_servicio'] ?? false);
        $payload['stock'] = isset($payload['stock']) ? (int) $payload['stock'] : 0;
        // Mantener compatibilidad con la estructura DB: para productos físicos el precio es 0.
        $payload['precio'] = isset($payload['precio']) ? (float) $payload['precio'] : 0.0;
        $payload['tipo_cobro'] = $payload['tipo_cobro'] ?? null;

        $producto = Producto::create($payload);

        return response()->json(['data' => $producto], JsonResponse::HTTP_CREATED);
    }

    /**
     * Actualizar producto o servicio.
     */
    public function update(Request $request, Producto $producto): JsonResponse
    {
        $rules = [
            'nombre' => ['sometimes', 'string', 'max:255'],
            'descripcion' => ['nullable', 'string'],
            'precio' => ['sometimes', 'numeric', 'min:0'],
            'stock' => ['nullable', 'integer', 'min:0'],
            'es_servicio' => ['boolean'],
        ];
        $data = $request->all();
        if (array_key_exists('es_servicio', $data) && ! empty($data['es_servicio'])) {
            $rules['tipo_cobro'] = ['required', 'in:peso,pieza'];
        } else {
            $rules['tipo_cobro'] = ['nullable', 'in:peso,pieza'];
        }

        $validator = Validator::make($request->all(), $rules);
        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], JsonResponse::HTTP_UNPROCESSABLE_ENTITY);
        }

        $producto->update($validator->validated());

        return response()->json(['data' => $producto->fresh()], JsonResponse::HTTP_OK);
    }

    /**
     * Eliminar producto/servicio. No se permite si tiene detalles de órdenes (opcional: verificar).
     */
    public function destroy(Producto $producto): JsonResponse
    {
        $block = CatalogDeletionGuard::productoLegacy($producto);
        if ($block !== null) {
            return response()->json([
                'message' => $block,
            ], JsonResponse::HTTP_UNPROCESSABLE_ENTITY);
        }
        $producto->delete();

        return response()->json(['message' => 'Eliminado correctamente.'], JsonResponse::HTTP_OK);
    }
}
