<?php

namespace App\Http\Controllers;

use App\Models\Restaurante;
use App\Models\Producto;
use App\Models\Categoria;
use App\Models\ZonaProduccion;
use App\Models\Ingrediente;
use App\Models\Receta;
use App\Services\PaginatorService;
use App\Services\UuidService;
use App\Exceptions\GenericException;
use App\Exceptions\ModelNotFoundException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Ramsey\Uuid\Uuid;

class ProductosController extends Controller {

    /**
     * Obtiene de forma paginada los productos registrados en el backend
     */
    public function all(Request $request, $restaurante_id) {
        app(UuidService::class)->validOrFail($restaurante_id);
        $restaurante = Restaurante::findOrFail($restaurante_id);

        $productos = $restaurante->productos();

        $paginate = app(PaginatorService::class)->paginate(
            perPage: $request->input('per_page', 15),
            page: $request->input('page', 1),
            total: $productos->count(),
            route: 'restaurant.all',
            data: ['restaurante_id' => $restaurante_id]
        );

        $data = $productos->get()
                          ->skip($paginate['from'] - 1)
                          ->take($paginate['per_page'])
                          ->all();

        return response()->json([
            'pagination' => $paginate,
            'data' => $data
        ]);
    }

    /**
     * Obtiene un producto por su id
     */
    public function get(Request $request, $restaurante_id, $id) {
        app(UuidService::class)->validOrFail($restaurante_id);
        app(UuidService::class)->validOrFail($id);

        $restaurante = Restaurante::findOrFail($restaurante_id);
        $producto = Producto::findOrFail($id);

        if($producto->restaurante != $restaurante) {
            throw new ModelNotFoundException("producto", $id);
        }

        return response()->json($producto);
    }

    /**
     * Crea un nuevo producto 
     */
    public function create(Request $request, $restaurante_id) {
        $this->validate($request, [
            'nombre' => 'required',
            'precio_venta' => 'required|numeric',
            'categoria_id' => 'required|exists:categorias,id',
            'zona_produccion_id' => 'required|exists:zonas_produccion,id',
        ]);

        app(UuidService::class)->validOrFail($restaurante_id);
        app(UuidService::class)->validOrFail($request->input('categoria_id'));
        app(UuidService::class)->validOrFail($request->input('zona_produccion_id'));

        $restaurante = Restaurante::findOrFail($restaurante_id);
        $categoria = Categoria::findOrFail($request->input('categoria_id'));
        $zonaProduccion = ZonaProduccion::findOrFail($request->input('zona_produccion_id'));

        if($categoria->restaurante != $restaurante) {
            throw new ModelNotFoundException("categoria", $id);
        }

        if($zonaProduccion->restaurante != $restaurante) {
            throw new ModelNotFoundException("zona_produccion", $id);
        }

        $producto = Producto::create([
            'id' => Uuid::uuid4(),
            'nombre' => $request->input('nombre'),
            'precio_venta' => $request->input('precio_venta'),
            'categoria_id' => $categoria->id,
            'zona_produccion_id' => $zonaProduccion->id,
            'restaurante_id' => $restaurante->id
        ]);

        return response()->json($producto, 201);
    }

    /**
     * Actualiza un producto
     */
    public function update(Request $request, $restaurante_id, $id) {
        $this->validate($request, [
            'nombre' => 'required',
            'precio_venta' => 'required|numeric',
            'categoria_id' => 'required|exists:categorias,id',
            'zona_produccion_id' => 'required|exists:zonas_produccion,id',
        ]);

        app(UuidService::class)->validOrFail($restaurante_id);
        app(UuidService::class)->validOrFail($request->input('categoria_id'));
        app(UuidService::class)->validOrFail($request->input('zona_produccion_id'));
        app(UuidService::class)->validOrFail($id);

        $restaurante = Restaurante::findOrFail($restaurante_id);
        $categoria = Categoria::findOrFail($request->input('categoria_id'));
        $zonaProduccion = ZonaProduccion::findOrFail($request->input('zona_produccion_id'));
        $producto = Producto::findOrFail($id);

        if($categoria->restaurante != $restaurante) {
            throw new ModelNotFoundException("categoria", $id);
        }

        if($zonaProduccion->restaurante != $restaurante) {
            throw new ModelNotFoundException("zona_produccion", $id);
        }

        if($producto->restaurante != $restaurante) {
            throw new ModelNotFoundException("ingrediente", $id);
        }

        $producto->nombre = $request->input('nombre');
        $producto->precio_venta = $request->input('precio_venta');
        $producto->categoria_id = $categoria->id;
        $producto->zona_produccion_id = $zonaProduccion->id;

        $producto->save();

        return response()->json($producto);
    }

    /**
     * Elimina un producto
     */
    public function delete(Request $request, $restaurante_id, $id) {
        app(UuidService::class)->validOrFail($restaurante_id);
        app(UuidService::class)->validOrFail($id);

        $restaurante = Restaurante::findOrFail($restaurante_id);
        $producto = Producto::findOrFail($id);

        if($producto->restaurante != $restaurante) {
            throw new ModelNotFoundException("producto", $id);
        }

        $producto->delete();

        return response()->json([], 204);
    }
}
