<?php

namespace App\Http\Controllers;

use App\Models\TransaccionCaja;
use App\Models\Caja;
use App\Models\Concepto;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Barryvdh\DomPDF\Facade\Pdf;
use App\Models\Instituto;
use App\Models\AnulacionTransaccion;
use Illuminate\Support\Facades\Auth;
class TransaccionCajaController extends Controller
{
    // Listar todas las transacciones
    public function index()
    {
        $transacciones = TransaccionCaja::with(['caja', 'concepto'])
            ->orderBy('fecha', 'desc')
            ->get();

        $conceptos = Concepto::where('activo', 1)->orderBy('nombre')->get(); // Lista de conceptos activos
       $cajas = Caja::whereNull('fecha_cierre')
             ->orderBy('fecha_apertura', 'desc')
             ->get();


        return view('transacciones.index', compact('transacciones', 'conceptos', 'cajas'));
    }


    // Mostrar formulario para crear una transacción
    public function create($cajaId)
    {
        $caja = Caja::findOrFail($cajaId);
        $conceptos = Concepto::where('activo', 1)->get();

        return view('transacciones.create', compact('caja', 'conceptos'));
    }

    // Guardar una nueva transacción
    public function store(Request $request)
{
    $request->validate([
        'caja_id'     => 'required|exists:caja,id_caja',
        'tipo'        => 'required|in:ingreso,egreso',
        'monto'       => 'required|numeric|min:0.01',
        'fecha'       => 'required|date',
        'concepto_id' => 'nullable|exists:conceptos,id_concepto',
        'observacion' => 'nullable|string',
        'dni'         => 'nullable|string|max:30',
        'nombres'     => 'nullable|string|max:30',
        'apellidos'   => 'nullable|string|max:30',
    ]);

    try {
        DB::beginTransaction();

        // Crear la transacción
        $transaccion = TransaccionCaja::create([
            'caja_id'     => $request->caja_id,
            'tipo'        => $request->tipo,
            'monto'       => $request->monto,
            'fecha'       => $request->fecha,
            'concepto_id' => $request->concepto_id,
            'observacion' => $request->observacion,
            'estado'      => 'aceptado',
            'dni'         => $request->dni,
            'nombres'     => $request->nombres,
            'apellidos'   => $request->apellidos,
        ]);

        // Actualizar saldo de la caja
        $caja = Caja::findOrFail($request->caja_id);

        if ($request->tipo === 'ingreso') {
            $caja->increment('saldo', $request->monto);
        } else {
            $nuevoSaldo = $caja->saldo - $request->monto;
            if ($nuevoSaldo < 0) {
                throw new \Exception("El saldo de la caja no puede ser negativo.");
            }
            $caja->decrement('saldo', $request->monto);
        }

        DB::commit();

        return response()->json(['success' => true]);
    } catch (\Exception $e) {
        DB::rollBack();
        return response()->json([
            'success' => false,
            'message' => 'Error al registrar transacción: ' . $e->getMessage()
        ]);
    }
}


    // Ver detalle de una transacción
    public function show($id)
    {
        $transaccion = TransaccionCaja::with('caja', 'concepto')->findOrFail($id);
        return view('transacciones.show', compact('transaccion'));
    }

    // Mostrar formulario para editar una transacción
    public function edit($id)
    {
        $transaccion = TransaccionCaja::findOrFail($id);
        $conceptos = Concepto::where('activo', 1)->get();

        return view('transacciones.edit', compact('transaccion', 'conceptos'));
    }

    // Actualizar la transacción
    public function update(Request $request, $id)
    {
        $transaccion = TransaccionCaja::findOrFail($id);

        $request->validate([
            'concepto_id' => 'nullable|exists:conceptos,id_concepto',
            'observacion' => 'nullable|string',
        ]);

        $transaccion->update($request->only(['concepto_id', 'observacion']));

        return redirect()->route('transacciones.index')->with('success', 'Transacción actualizada.');
    }

    // Eliminar o anular transacción (opcional)
    public function destroy($id)
    {
        $transaccion = TransaccionCaja::findOrFail($id);

        if ($transaccion->estado === 'anulado') {
            return back()->with('info', 'La transacción ya fue anulada.');
        }

        // Revertir saldo
        $caja = $transaccion->caja;
        $transaccion->tipo === 'ingreso'
            ? $caja->decrement('saldo', $transaccion->monto)
            : $caja->increment('saldo', $transaccion->monto);

        $transaccion->update(['estado' => 'anulado']);

        return back()->with('success', 'Transacción anulada correctamente.');
    }

    public function generarPdf($id)
{
    $transaccion = TransaccionCaja::with('caja', 'concepto')->findOrFail($id);
    $instituto = Instituto::first(); // Suponemos que hay un solo registro

    $pdf = Pdf::loadView('transacciones.ticket', compact('transaccion', 'instituto'))
              ->setPaper([0, 0, 226.77, 300], 'portrait'); // 80mm de ancho

    return $pdf->stream("ticket_transaccion_{$id}.pdf");
}

public function anular(Request $request, $id)
{
    $request->validate([
        'motivo' => 'required|string'
    ]);

    DB::beginTransaction();

    try {
        $transaccion = TransaccionCaja::findOrFail($id);

        if ($transaccion->estado === 'anulado') {
            return response()->json(['success' => false, 'message' => 'Esta transacción ya está anulada.']);
        }

        // Revertir saldo
        $caja = $transaccion->caja;

        if ($transaccion->tipo === 'ingreso') {
            $caja->decrement('saldo', $transaccion->monto);
        } else {
            $caja->increment('saldo', $transaccion->monto);
        }

        // Actualizar estado de transacción
        $transaccion->estado = 'anulado';
        $transaccion->save();

        // Registrar motivo de anulación
        AnulacionTransaccion::create([
            'id_transaccion' => $transaccion->id_transaccion,
            'usuario_id' => Auth::id(),
            'motivo' => $request->motivo,
            'fecha_anulacion' => now(),
        ]);

        DB::commit();
        return response()->json(['success' => true, 'message' => 'Transacción anulada correctamente.']);
    } catch (\Exception $e) {
        DB::rollBack();
        return response()->json(['success' => false, 'message' => 'Error al anular: ' . $e->getMessage()]);
    }
}

public function ingresos()
{
    $cajas = Caja::whereNull('fecha_cierre')->orWhereNotNull('fecha_cierre')->orderByDesc('fecha_apertura')->get();
    return view('reportes.ingresos', compact('cajas'));
}

public function buscarIngresos(Request $request)
{
    $query = TransaccionCaja::with(['caja', 'concepto'])
        ->where('tipo', 'ingreso')
        ->where('estado', 'aceptado');

    if ($request->filled('fecha_inicio')) {
        $query->whereDate('fecha', '>=', $request->fecha_inicio);
    }

    if ($request->filled('fecha_fin')) {
        $query->whereDate('fecha', '<=', $request->fecha_fin);
    }

    if ($request->filled('caja_id')) {
        $query->where('caja_id', $request->caja_id);
    }

    $transacciones = $query->orderBy('fecha')->get();

    $total = $transacciones->sum('monto');

    return response()->json([
        'html' => view('reportes.partials.ingresos_resultado', compact('transacciones', 'total'))->render()
    ]);
}

public function ingresosPdf(Request $request)
{
    $query = TransaccionCaja::with('caja', 'concepto')
                ->where('tipo', 'ingreso')
                ->where('estado', 'aceptado');

    if ($request->filled('desde')) {
        $query->whereDate('fecha', '>=', $request->desde);
    }

    if ($request->filled('hasta')) {
        $query->whereDate('fecha', '<=', $request->hasta);
    }

    if ($request->filled('caja_id')) {
        $query->where('caja_id', $request->caja_id);
    }

    $ingresos = $query->orderBy('fecha', 'desc')->get();
    $instituto = Instituto::first();

    $pdf = Pdf::loadView('reportes.pdf.ingresos', compact('ingresos', 'instituto'))
              ->setPaper('A4', 'portrait');

    return $pdf->stream('reporte_ingresos.pdf');
}

//egresos

public function egresos()
{
    $cajas = Caja::whereNull('fecha_cierre')->orWhereNotNull('fecha_cierre')->orderByDesc('fecha_apertura')->get();
    return view('reportes.egresos', compact('cajas'));
}

public function buscarEgresos(Request $request)
{
    $query = TransaccionCaja::with(['caja', 'concepto'])
        ->where('tipo', 'egreso')
        ->where('estado', 'aceptado');

    if ($request->filled('fecha_inicio')) {
        $query->whereDate('fecha', '>=', $request->fecha_inicio);
    }

    if ($request->filled('fecha_fin')) {
        $query->whereDate('fecha', '<=', $request->fecha_fin);
    }

    if ($request->filled('caja_id')) {
        $query->where('caja_id', $request->caja_id);
    }

    $transacciones = $query->orderBy('fecha')->get();

    $total = $transacciones->sum('monto');

    return response()->json([
        'html' => view('reportes.partials.egresos_resultado', compact('transacciones', 'total'))->render()
    ]);
}

public function egresosPdf(Request $request)
{
    $query = TransaccionCaja::with('caja', 'concepto')
                ->where('tipo', 'egreso')
                ->where('estado', 'aceptado');

    if ($request->filled('desde')) {
        $query->whereDate('fecha', '>=', $request->desde);
    }

    if ($request->filled('hasta')) {
        $query->whereDate('fecha', '<=', $request->hasta);
    }

    if ($request->filled('caja_id')) {
        $query->where('caja_id', $request->caja_id);
    }

    $ingresos = $query->orderBy('fecha', 'desc')->get();
    $instituto = Instituto::first();

    $pdf = Pdf::loadView('reportes.pdf.egresos', compact('ingresos', 'instituto'))
              ->setPaper('A4', 'portrait');

    return $pdf->stream('reporte_egresos.pdf');
}

//anulaciones

public function anulaciones()
{
    $cajas = Caja::whereNull('fecha_cierre')->orWhereNotNull('fecha_cierre')->orderByDesc('fecha_apertura')->get();
    return view('reportes.anulaciones', compact('cajas'));
}

public function buscarAnulaciones(Request $request)
{
    $query = TransaccionCaja::with(['caja', 'concepto'])
         ->where('estado', 'anulado');

    if ($request->filled('fecha_inicio')) {
        $query->whereDate('fecha', '>=', $request->fecha_inicio);
    }

    if ($request->filled('fecha_fin')) {
        $query->whereDate('fecha', '<=', $request->fecha_fin);
    }

    if ($request->filled('caja_id')) {
        $query->where('caja_id', $request->caja_id);
    }

    $transacciones = $query->orderBy('fecha')->get();

    $total = $transacciones->sum('monto');

    return response()->json([
        'html' => view('reportes.partials.anulaciones_resultado', compact('transacciones', 'total'))->render()
    ]);
}

public function anulacionesPdf(Request $request)
{
    $query = TransaccionCaja::with('caja', 'concepto')
                ->where('estado', 'anulado');

    if ($request->filled('desde')) {
        $query->whereDate('fecha', '>=', $request->desde);
    }

    if ($request->filled('hasta')) {
        $query->whereDate('fecha', '<=', $request->hasta);
    }

    if ($request->filled('caja_id')) {
        $query->where('caja_id', $request->caja_id);
    }

    $ingresos = $query->orderBy('fecha', 'desc')->get();
    $instituto = Instituto::first();

    $pdf = Pdf::loadView('reportes.pdf.anulaciones', compact('ingresos', 'instituto'))
              ->setPaper('A4', 'portrait');

    return $pdf->stream('reporte_anulaciones.pdf');
}

}
