<?php
namespace App\Controllers;

use App\Models\CajaModel;

class CajaController extends BaseController
{
    public function index()
    {
        $cajaModel = new CajaModel();
        $role = session()->get('role');
        $openCaja = $cajaModel->getOpenCaja();

        if ($openCaja) {
            $caja = $cajaModel->getCajaWithMovements($openCaja['id_caja']);
            $data['caja'] = $caja;
            $data['title'] = 'Caja - Sesión Abierta';
            return view('caja/current', $data);
        }

        $todayCajas = $cajaModel->getTodayCajas();
        $data['todayCajas'] = $todayCajas;

        $lastClosed = $cajaModel->getLastClosedCaja();
        if ($lastClosed) {
            $data['lastCaja'] = $cajaModel->getCajaWithMovements($lastClosed['id_caja']);
        } else {
            $data['lastCaja'] = null;
        }

        $data['title'] = 'Caja';
        return view('caja/open', $data);
    }

    public function open()
    {
        if ($this->request->getMethod() !== 'POST') {
            return redirect()->to('/cash');
        }

        $cajaModel = new CajaModel();
        $userId = session()->get('user_id');

        $lastClosed = $cajaModel->getLastClosedCaja();
        $montoInicial = 0;
        if ($lastClosed) {
            $lastData = $cajaModel->getCajaWithMovements($lastClosed['id_caja']);
            $montoInicial = $lastData['monto_inicial'] + ($lastData['total_chica_ingresos'] ?? 0) - ($lastData['total_chica_gastos'] ?? 0);
        }
        $fondoChica = (float) $this->request->getPost('fondo_chica');
        if ($fondoChica < 0) {
            return redirect()->back()->with('error', 'El monto no puede ser negativo.');
        }

        $cajaModel->save([
            'id_usuario'        => $userId,
            'monto_inicial'     => $montoInicial,
            'monto_esperado'    => $montoInicial,
            'fondo_chica'       => $fondoChica,
            'saldo_chica_actual'=> $fondoChica,
            'fecha_apertura'    => date('Y-m-d H:i:s'),
            'estado'            => 'abierto'
        ]);

        return redirect()->to('/cash')->with('success', 'Caja chica abierta con S/ ' . number_format($fondoChica, 2) . ' | General hereda S/ ' . number_format($montoInicial, 2));
    }

    public function addMovement()
    {
        if ($this->request->getMethod() !== 'POST') {
            return redirect()->to('/cash');
        }

        $cajaModel = new CajaModel();
        $userId = session()->get('user_id');
        $caja = $cajaModel->getOpenCaja();

        if (!$caja) {
            return redirect()->to('/cash')->with('error', 'No hay una caja abierta.');
        }

        $validation = \Config\Services::validation();
        $validation->setRules([
            'tipo'     => 'required|in_list[ingreso,egreso]',
            'concepto' => 'required|min_length[3]',
            'monto'    => 'required|numeric|greater_than[0]'
        ]);

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

        $cajaModel->addMovement([
            'id_caja'   => $caja['id_caja'],
            'id_usuario'=> $userId,
            'tipo'      => $this->request->getPost('tipo'),
            'concepto'  => $this->request->getPost('concepto'),
            'monto'     => (float) $this->request->getPost('monto'),
            'id_venta'  => null
        ]);

        return redirect()->to('/cash')->with('success', 'Movimiento registrado correctamente.');
    }

    public function addChicaMovement()
    {
        if ($this->request->getMethod() !== 'POST') {
            return redirect()->to('/cash');
        }

        $cajaModel = new CajaModel();
        $userId = session()->get('user_id');
        $caja = $cajaModel->getOpenCaja();

        if (!$caja) {
            return redirect()->to('/cash')->with('error', 'No hay una caja abierta.');
        }

        $validation = \Config\Services::validation();
        $validation->setRules([
            'tipo'     => 'required|in_list[gasto,reposicion,ingreso]',
            'concepto' => 'required|min_length[3]',
            'monto'    => 'required|numeric|greater_than[0]'
        ]);

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

        $tipo = $this->request->getPost('tipo');
        $monto = (float) $this->request->getPost('monto');

        if ($tipo == 'gasto' && $monto > $caja['saldo_chica_actual']) {
            return redirect()->back()->with('error', 'Saldo insuficiente en caja chica. Saldo actual: S/ ' . number_format($caja['saldo_chica_actual'], 2));
        }

        $cajaModel->addChicaMovement([
            'id_caja'   => $caja['id_caja'],
            'id_usuario'=> $userId,
            'tipo'      => $tipo,
            'concepto'  => $this->request->getPost('concepto'),
            'monto'     => $monto
        ]);

        $label = $tipo == 'gasto' ? 'Gasto registrado' : 'Reposición registrada';
        return redirect()->to('/cash')->with('success', $label . ' correctamente.');
    }

    public function close()
    {
        if ($this->request->getMethod() !== 'POST') {
            return redirect()->to('/cash');
        }

        $cajaModel = new CajaModel();
        $caja = $cajaModel->getOpenCaja();

        if (!$caja) {
            return redirect()->to('/cash')->with('error', 'No hay una caja abierta.');
        }

        $cajaModel->closeCaja($caja['id_caja']);

        $updatedCaja = $cajaModel->find($caja['id_caja']);
        $generalReal = $updatedCaja['monto_real_cierre'];
        $chicaFinal = $caja['fondo_chica'];
        $msg = 'Caja cerrada. Ventas sumadas a General: S/ ' . number_format($generalReal, 2) . ' | Chica reinicia a: S/ ' . number_format($chicaFinal, 2);

        return redirect()->to('/cash')->with('success', $msg);
    }

    public function history()
    {
        $cajaModel = new CajaModel();
        $desde = $this->request->getGet('desde');
        $hasta = $this->request->getGet('hasta');
        $data['cajas'] = $cajaModel->getHistory(200, $desde, $hasta);
        $data['desde'] = $desde;
        $data['hasta'] = $hasta;
        $data['title'] = 'Historial de Caja';
        return view('caja/history', $data);
    }

    public function detail($id)
    {
        $cajaModel = new CajaModel();
        $caja = $cajaModel->getCajaWithMovements($id);
        if (!$caja) {
            return redirect()->to('/cash/history')->with('error', 'Caja no encontrada.');
        }
        $data['caja'] = $caja;
        $data['title'] = 'Detalle de Caja #' . $id;
        return view('caja/detail', $data);
    }
}
