<?php
namespace App\Controllers;

use App\Models\ProductModel;

class ProductController extends BaseController
{
    public function index()
    {
        $productModel = new ProductModel();
        $search = $this->request->getGet('q');
        $stockBajo = $this->request->getGet('stock_bajo');
        if ($stockBajo) {
            $products = $productModel->getLowStockProducts();
        } elseif ($search) {
            $products = $productModel->searchProducts($search);
        } else {
            $products = $productModel->getProductsWithCategory();
        }

        $grouped = [];
        foreach ($products as $p) {
            $cat = $p['categoria_nombre'] ?? 'Sin categoria';
            $grouped[$cat][] = $p;
        }

        $data['groupedProducts'] = $grouped;
        $data['search'] = $search;
        $data['stockBajo'] = $stockBajo;
        $data['title'] = 'Lista de Productos';
        return view('products/index', $data);
    }

    public function create()
    {
        $productModel = new ProductModel();
        $data['categories'] = $productModel->getCategories();
        $data['title'] = 'Registrar Producto';
        return view('products/create', $data);
    }

    public function store()
    {
        $validation = \Config\Services::validation();
        $validation->setRules([
            'nombre'        => 'required',
            'codigo_unico'  => 'required|is_unique[productos.codigo_unico]',
            'precio_compra' => 'required|numeric|greater_than[0]',
            'precio_venta'  => 'required|numeric|greater_than[0]',
            'id_categoria'  => 'required|numeric',
            'stock_actual'  => 'required|integer|greater_than_equal_to[0]',
            'unidad_medida' => 'required'
        ]);

        if (!$validation->withRequest($this->request)->run()) {
            return redirect()->back()->withInput()->with('errors', $validation->getErrors());
        }

        $productModel = new ProductModel();
        $data = [
            'nombre'        => $this->request->getPost('nombre'),
            'codigo_unico'  => $this->request->getPost('codigo_unico'),
            'precio_compra' => $this->request->getPost('precio_compra'),
            'precio_venta'  => $this->request->getPost('precio_venta'),
            'id_categoria'  => $this->request->getPost('id_categoria'),
            'stock_actual'  => $this->request->getPost('stock_actual'),
            'unidad_medida' => $this->request->getPost('unidad_medida')
        ];

        $file = $this->request->getFile('imagen');
        if ($file && $file->isValid() && !$file->hasMoved()) {
            $newName = $file->getRandomName();
            $file->move('uploads/products', $newName);
            $data['imagen'] = $newName;
        }

        try {
            if ($productModel->save($data)) {
                return redirect()->to('/products')->with('success', 'Producto registrado correctamente');
            }
        } catch (\Exception $e) {
            return redirect()->back()->withInput()->with('error', 'Error: ' . $e->getMessage());
        }
        return redirect()->back()->withInput()->with('error', 'Error al registrar producto');
    }

    public function edit($id)
    {
        $productModel = new ProductModel();
        $data['product'] = $productModel->find($id);
        if (!$data['product']) {
            return redirect()->to('/products')->with('error', 'Producto no encontrado');
        }
        $data['categories'] = $productModel->getCategories();
        $data['title'] = 'Editar Producto';
        return view('products/edit', $data);
    }

    public function update($id)
    {
        $productModel = new ProductModel();
        $product = $productModel->find($id);
        if (!$product) {
            return redirect()->to('/products')->with('error', 'Producto no encontrado');
        }

        $validation = \Config\Services::validation();
        $validation->setRules([
            'nombre'        => 'required',
            'codigo_unico'  => "required|is_unique[productos.codigo_unico,id_producto,$id]",
            'precio_compra' => 'required|numeric|greater_than[0]',
            'precio_venta'  => 'required|numeric|greater_than[0]',
            'id_categoria'  => 'required|numeric',
            'stock_actual'  => 'required|integer|greater_than_equal_to[0]',
            'unidad_medida' => 'required'
        ]);

        if (!$validation->withRequest($this->request)->run()) {
            return redirect()->back()->withInput()->with('errors', $validation->getErrors());
        }

        $data = [
            'nombre'        => $this->request->getPost('nombre'),
            'codigo_unico'  => $this->request->getPost('codigo_unico'),
            'precio_compra' => $this->request->getPost('precio_compra'),
            'precio_venta'  => $this->request->getPost('precio_venta'),
            'id_categoria'  => $this->request->getPost('id_categoria'),
            'stock_actual'  => $this->request->getPost('stock_actual'),
            'unidad_medida' => $this->request->getPost('unidad_medida')
        ];

        $file = $this->request->getFile('imagen');
        if ($file && $file->isValid() && !$file->hasMoved()) {
            if (!empty($product['imagen']) && file_exists('uploads/products/' . $product['imagen'])) {
                unlink('uploads/products/' . $product['imagen']);
            }
            $newName = $file->getRandomName();
            $file->move('uploads/products', $newName);
            $data['imagen'] = $newName;
        }

        try {
            if ($productModel->update($id, $data)) {
                return redirect()->to('/products')->with('success', 'Producto actualizado correctamente');
            }
        } catch (\Exception $e) {
            return redirect()->back()->withInput()->with('error', 'Error: ' . $e->getMessage());
        }
        return redirect()->back()->withInput()->with('error', 'Error al actualizar producto');
    }

    public function saveCategory()
    {
        $name = $this->request->getPost('nombre');
        if (!$name || trim($name) === '') {
            if ($this->request->hasHeader('HX-Request')) {
                return $this->response->setHeader('HX-Trigger', json_encode([
                    'categoryError' => 'Nombre requerido'
                ]));
            }
            return $this->response->setJSON(['success' => false, 'message' => 'Nombre requerido']);
        }

        $db = \Config\Database::connect();
        $db->table('categorias')->insert(['nombre' => trim($name)]);
        $id = $db->insertID();

        if ($this->request->hasHeader('HX-Request')) {
            return $this->response->setHeader('HX-Trigger', json_encode([
                'categorySaved' => ['id' => $id, 'nombre' => trim($name)]
            ]));
        }

        return $this->response->setJSON(['success' => true, 'id' => $id, 'nombre' => trim($name)]);
    }

    public function delete($id)
    {
        $productModel = new ProductModel();
        $product = $productModel->find($id);
        if (!$product) {
            return redirect()->to('/products')->with('error', 'Producto no encontrado');
        }

        if (!empty($product['imagen']) && file_exists('uploads/products/' . $product['imagen'])) {
            unlink('uploads/products/' . $product['imagen']);
        }

        try {
            if ($productModel->delete($id)) {
                return redirect()->to('/products')->with('success', 'Producto eliminado correctamente');
            }
        } catch (\Exception $e) {
            return redirect()->back()->with('error', 'No se puede eliminar el producto porque tiene registros asociados en ventas o movimientos de stock.');
        }

        return redirect()->back()->with('error', 'Error al eliminar producto');
    }
}
