<?php

namespace App\Http\Controllers;

use App\Models\Producto;
use App\Models\Venta;
use App\Models\Orden;
use App\Models\Marca;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use App\Exports\ProductosExport;
use Maatwebsite\Excel\Facades\Excel;

class ProductoController extends Controller
{
    public function index(Request $request)
    {
        $query = Producto::query();

        if ($request->has('search') && $request->search != '') {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('nombre', 'like', "%{$search}%")
                    ->orWhere('codigo', 'like', "%{$search}%")
                    ->orWhere('marca', 'like', "%{$search}%");
            });
        }

        // Aumentamos el número de productos por página a 20
        $productos = $query->paginate(20);

        return view('productos.index', compact('productos'));
    }

    public function create()
    {
        return view('productos.create');
    }


    public function store(Request $request)
    {
        $rules = [
            'nombre' => 'required|string|max:255',
            'marca' => 'nullable|string|max:100',
            'cantidad' => 'required|integer|min:0',
            'precio' => 'required|numeric|min:0',
            'descripcion' => 'nullable|string',
            'imagen' => 'nullable|image|max:2048',
            'codigo' => 'required|string|max:255|unique:productos,codigo',
            'minimo' => 'required|integer|min:0',
            'maximo' => 'required|integer|min:0|gte:minimo',
        ];

        if (auth()->check() && auth()->user()->role === 'administrador') {
            $rules['costo'] = 'nullable|numeric|min:0';
        }

        $request->validate($rules, [
            'codigo.unique' => 'El código de producto ya existe. Por favor ingresa uno diferente.',
            'maximo.gte' => 'El stock máximo debe ser mayor o igual al mínimo.',
        ]);

        $data = $request->only(['nombre', 'marca', 'cantidad', 'precio', 'descripcion', 'codigo', 'minimo', 'maximo']);

        if (auth()->check() && auth()->user()->role === 'administrador') {
            $data['costo'] = $request->input('costo');
        }

        if ($request->hasFile('imagen')) {
            $data['imagen'] = $request->file('imagen')->store('productos', 'public');
        }

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

        if ($producto->cantidad <= $producto->minimo) {
            $this->crearOrdenSiNoExiste($producto);
        }

        return redirect()->route('productos.index')->with('success', 'Producto creado correctamente.');
    }

    public function show(Producto $producto)
    {
        return view('productos.show', compact('producto'));
    }

    public function edit(Producto $producto)
    {
        return view('productos.edit', compact('producto'));
    }

    public function update(Request $request, Producto $producto)
    {
        $rules = [
            'nombre' => 'required|string|max:255',
            'marca' => 'nullable|string|max:100',
            'cantidad' => 'required|integer|min:0',
            'precio' => 'required|numeric|min:0',
            'descripcion' => 'nullable|string',
            'imagen' => 'nullable|image|max:2048',
            'codigo' => 'required|string|max:255|unique:productos,codigo,' . $producto->id,
            'minimo' => 'required|integer|min:0',
            'maximo' => 'required|integer|min:0|gte:minimo',
        ];

        if (auth()->check() && auth()->user()->role === 'administrador') {
            $rules['costo'] = 'nullable|numeric|min:0';
        }

        $request->validate($rules, [
            'codigo.unique' => 'El código de producto ya existe. Por favor ingresa uno diferente.',
            'maximo.gte' => 'El stock máximo debe ser mayor o igual al mínimo.',
        ]);

        $data = $request->only(['nombre', 'marca', 'cantidad', 'precio', 'descripcion', 'codigo', 'minimo', 'maximo']);

        if (auth()->check() && auth()->user()->role === 'administrador') {
            $data['costo'] = $request->input('costo');
        }

        if ($request->hasFile('imagen')) {
            if ($producto->imagen) {
                Storage::disk('public')->delete($producto->imagen);
            }
            $data['imagen'] = $request->file('imagen')->store('productos', 'public');
        }

        $producto->update($data);

        if ($producto->cantidad <= $producto->minimo) {
            $this->crearOrdenSiNoExiste($producto);
        }

        return redirect()->route('productos.index')->with('success', 'Producto actualizado correctamente.');
    }

    public function destroy(Producto $producto)
    {
        if ($producto->imagen) {
            Storage::disk('public')->delete($producto->imagen);
        }

        $producto->delete();

        Orden::where('producto_id', $producto->id)->delete();

        return redirect()->route('productos.index')->with('success', 'Producto eliminado correctamente.');
    }

    public function venta(Request $request, Producto $producto)
    {
        if ($producto->cantidad > 0) {
            $producto->cantidad -= 1;
            $producto->save();

            Venta::create([
                'producto_id' => $producto->id,
                'user_id' => auth()->id(),
                'cantidad' => 1,
                'precio_unitario' => $producto->precio,
            ]);

            if ($producto->cantidad <= $producto->minimo) {
                $this->crearOrdenSiNoExiste($producto);
            }

            return redirect()->route('productos.index')->with('success', 'Venta realizada correctamente. Stock actualizado.');
        }

        return redirect()->route('productos.index')->with('error', 'No hay stock disponible para este producto.');
    }

    private function crearOrdenSiNoExiste($producto)
    {
        $ordenExistente = Orden::where('producto_id', $producto->id)->first();

        if (!$ordenExistente) {
            Orden::create([
                'producto_id' => $producto->id,
                'nombre' => $producto->nombre,
                'marca' => $producto->marca,
                'cantidad' => $producto->cantidad,
                'precio' => $producto->precio,
                'descripcion' => $producto->descripcion,
                'codigo' => $producto->codigo,
                'minimo' => $producto->minimo,
                'maximo' => $producto->maximo,
                'imagen' => $producto->imagen,
            ]);
        }
    }
    
    /**
     * Exporta los productos a un archivo de Excel.
     *
     * @return \Illuminate\Http\Response
     */
    public function exportarExcel()
    {
        return Excel::download(new ProductosExport, 'productos.xlsx');
    }
}