<?php

namespace App\Http\Controllers;

use App\Models\Ajustador;
use App\Models\Caso;
use App\Models\Tenant;
use Illuminate\Http\Request;
use Inertia\Inertia;

class FacturacionController extends Controller
{
    public function index(Request $request)
    {
        $aseguradoras = Tenant::all();

        $query = Caso::with(['aseguradora', 'cliente', 'vehiculo'])
            ->where('estado_actual', 'facturacion');

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

        $casos = $query->get();

        $alertas = [];
        $hoy = now()->day;
        foreach ($aseguradoras as $aseguradora) {
            if ($aseguradora->corte_facturacion_dia) {
                if (abs($hoy - $aseguradora->corte_facturacion_dia) <= 3) {
                    $alertas[] = [
                        'tipo' => 'corte',
                        'mensaje' => "Corte de facturación próximo para {$aseguradora->nombre} (Día {$aseguradora->corte_facturacion_dia})",
                        'aseguradora_id' => $aseguradora->id,
                    ];
                }
            }
            if ($aseguradora->cruce_facturacion_dia) {
                if (abs($hoy - $aseguradora->cruce_facturacion_dia) <= 3) {
                    $alertas[] = [
                        'tipo' => 'cruce',
                        'mensaje' => "Fecha de cruce/pago próxima para {$aseguradora->nombre} (Día {$aseguradora->cruce_facturacion_dia})",
                        'aseguradora_id' => $aseguradora->id,
                    ];
                }
            }
        }

        return Inertia::render('Facturacion/Index', [
            'title' => 'Cruce de Facturación',
            'casos' => $casos,
            'aseguradoras' => $aseguradoras,
            'alertas' => $alertas,
            'filters' => $request->only(['aseguradora_id']),
            'resultados_cruce' => session('resultados_cruce'),
            'resumen_cruce' => session('resumen_cruce'),
        ]);
    }

    public function cargar(Request $request)
    {
        $request->validate([
            'archivo_excel' => 'required|file',
            'aseguradora_id' => 'required|exists:tenants,id',
        ]);

        $file = $request->file('archivo_excel');
        $path = $file->getRealPath();

        $cruce = [];
        $resumen = [
            'coincide' => 0,
            'diferencia' => 0,
            'no_encontrado' => 0,
            'total' => 0,
        ];
        $processedCaseIds = [];

        if (($handle = fopen($path, 'r')) !== false) {
            // Saltamos la cabecera si existe (asumimos: reclamo/placa/caso, valor)
            $header = fgetcsv($handle, 1000, ',');

            while (($data = fgetcsv($handle, 1000, ',')) !== false) {
                $identificador = trim($data[0] ?? '');
                $valorExterno = floatval($data[1] ?? 0);

                if (empty($identificador)) {
                    continue;
                }

                $resumen['total']++;

                // Slide 17: Cruce por reclamo, caso o placa
                $caso = Caso::where('aseguradora_id', $request->aseguradora_id)
                    ->where(function ($q) use ($identificador) {
                        $q->where('numero_reclamo', 'like', $identificador)
                            ->orWhere('numero_caso_sias', 'like', $identificador)
                            ->orWhereHas('vehiculo', function ($v) use ($identificador) {
                                $v->where('placa', 'like', $identificador);
                            });
                    })
                    ->first();

                if ($caso) {
                    $valorSistema = floatval($caso->honorario_perito ?? 0); // Use honorario_perito calculated in M3/M8
                    if ($valorSistema == 0) {
                        $valorSistema = floatval($caso->tarifa_ajuste) + floatval($caso->valor_kilometraje);
                    }

                    $diferencia = round($valorSistema - $valorExterno, 2);
                    $estadoCruce = abs($diferencia) < 0.1 ? 'coincide' : 'diferencia';

                    $resultado = [
                        'numero_reclamo' => $caso->numero_reclamo,
                        'numero_caso_sias' => $caso->numero_caso_sias,
                        'placa' => $caso->vehiculo?->placa,
                        'cobertura' => $caso->cobertura,
                        'valor_ajuste' => floatval($caso->tarifa_ajuste),
                        'valor_kilometraje' => floatval($caso->valor_kilometraje),
                        'valor_sistema' => $valorSistema,
                        'valor_externo' => $valorExterno,
                        'diferencia' => $diferencia,
                        'estado' => $estadoCruce,
                    ];

                    // Actualizar estado de pago en BD (M1 PPTX)
                    if ($estadoCruce === 'coincide') {
                        $caso->update(['pago_estado' => 'pagado']);
                        $resumen['coincide']++;
                    } else {
                        $caso->update(['pago_estado' => 'pendiente_validacion']);
                        $resumen['diferencia']++;
                    }
                } else {
                    $resultado = [
                        'numero_reclamo' => $identificador,
                        'numero_caso_sias' => 'N/A',
                        'placa' => 'N/A',
                        'cobertura' => 'N/A',
                        'valor_sistema' => 0,
                        'valor_externo' => $valorExterno,
                        'diferencia' => -$valorExterno,
                        'estado' => 'no_encontrado',
                    ];
                    $resumen['no_encontrado']++;
                }

                $cruce[] = $resultado;
                $processedCaseIds[] = $caso ? $caso->id : null;
            }
            fclose($handle);

            // Mark cases in 'facturacion' that were NOT in the Excel as 'no_registra' (M1 PPTX)
            $processedCaseIds = array_filter($processedCaseIds);
            Caso::where('estado_actual', 'facturacion')
                ->where('aseguradora_id', $request->aseguradora_id)
                ->whereNotIn('id', $processedCaseIds)
                ->update(['pago_estado' => 'no_registra']);
        }

        session(['resultados_cruce' => $cruce]);
        session(['resumen_cruce' => $resumen]);

        return back()->with('message', "Cruce completado: {$resumen['coincide']} coincidencias, {$resumen['diferencia']} diferencias, {$resumen['no_encontrado']} no encontrados.");
    }

    public function generar(Request $request)
    {
        $resultados = session('resultados_cruce');

        if (! $resultados) {
            return back()->withErrors(['message' => 'No hay resultados de cruce para exportar. Realice un cruce primero.']);
        }

        $headers = [
            'Content-Type' => 'text/csv',
            'Content-Disposition' => 'attachment; filename="reporte_conciliacion_'.date('Y-m-d_H-i-s').'.csv"',
        ];

        $callback = function () use ($resultados) {
            $file = fopen('php://output', 'w');
            fputcsv($file, ['Reclamo', 'SIAS', 'Placa', 'Cobertura', 'Valor Ajuste', 'Valor Kilometraje', 'Valor Sistema', 'Valor Excel', 'Diferencia', 'Estado']);

            foreach ($resultados as $row) {
                fputcsv($file, [
                    $row['numero_reclamo'],
                    $row['numero_caso_sias'],
                    $row['placa'] ?? 'N/A',
                    $row['cobertura'] ?? 'N/A',
                    $row['valor_ajuste'] ?? 0,
                    $row['valor_kilometraje'] ?? 0,
                    $row['valor_sistema'],
                    $row['valor_externo'],
                    $row['diferencia'],
                    strtoupper($row['estado']),
                ]);
            }

            fclose($file);
        };

        return response()->stream($callback, 200, $headers);
    }

    public function reporteAjustadores(Request $request)
    {
        $query = Caso::with(['ajustador', 'cliente', 'vehiculo'])
            ->whereNotNull('honorario_perito');

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

        if ($request->estado_pago) {
            $query->where('pago_estado', $request->estado_pago);
        }

        $casos = $query->orderBy('created_at', 'desc')->get();

        if ($request->export) {
            $headers = [
                'Content-Type' => 'text/csv',
                'Content-Disposition' => 'attachment; filename="reporte_honorarios_'.date('Y-m-d').'.csv"',
            ];

            $callback = function () use ($casos) {
                $file = fopen('php://output', 'w');
                fputcsv($file, ['Ajustador', 'Aseguradora', 'No. Caso', 'Tarifa', 'Tipo Ajuste', 'Kilometraje', 'Total', 'Estado Pago']);

                foreach ($casos as $c) {
                    fputcsv($file, [
                        $c->ajustador?->nombre,
                        $c->aseguradora?->nombre,
                        $c->numero_reclamo,
                        $c->tarifa_ajustador_valor,
                        $c->tipo_ajuste,
                        $c->kilometros,
                        $c->honorario_perito,
                        strtoupper($c->pago_estado),
                    ]);
                }
                fclose($file);
            };

            return response()->stream($callback, 200, $headers);
        }

        return Inertia::render('Facturacion/ReporteAjustadores', [
            'title' => 'Reporte de Honorarios de Ajustadores',
            'casos' => $casos,
            'ajustadores' => Ajustador::all(),
            'filters' => $request->only(['ajustador_id', 'estado_pago']),
        ]);
    }
}
