<?php
namespace App\Http\Controllers;

use App\Models\Contrato;
use App\Models\Cliente;
use App\Models\Clientetmp;
use App\Models\Lote;
use App\Models\Urbanizacion;
use App\Models\Distrito;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Helpers\FechaHelper;
use App\Helpers\SeguimientoHelper;
use Carbon\Carbon;

class ContratoController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
    }

    // ── Listado con búsqueda ─────────────────────────────────────────────────
public function index(Request $request)
{
    $buscar  = $request->input('buscar', '');
    $tipoBusca = $request->input('tipo_busca', '1'); // 1=contrato, 2=cliente, 3=lote

    $query = Contrato::with(['cliente', 'urbanizacionRel', 'distritoRel'])
        ->orderBy('id', 'desc');

    if ($buscar !== '') {
        match($tipoBusca) {
            // Buscar por ID exacto del contrato
            '1' => $query->where('id', $buscar),

            // Buscar por nombre del cliente (usando relación)
            '2' => $query->whereHas('cliente', function($q) use ($buscar) {
                $q->where('nombre', 'like', "%$buscar%");
            }),

            // Buscar por el nombre/número del lote (usando relación)
            '3' => $query->whereHas('loteRel', function($q) use ($buscar) {
                $q->where('nombre', 'like', "%$buscar%");
            }),

            default => null,
        };
    }

    $contratos = $query->paginate(50)->withQueryString();

    return view('contratos.index', compact('contratos', 'buscar', 'tipoBusca'));
}
    // ── Ver detalle ──────────────────────────────────────────────────────────
  public function show($id)
{
    $contrato = Contrato::with([
        'cliente', 'loteRel', 'urbanizacionRel',
        'distritoRel', 'vendedor',
    ])->findOrFail($id);

    // Codeudores
    $codeudores = DB::table('codeudores')
        ->join('clientes', 'codeudores.idcliente', '=', 'clientes.id')
        ->where('codeudores.idcontrato', $id)
        ->select('clientes.id', 'clientes.nombre', 'clientes.ci')
        ->get();

    // Extractos del contrato
    $extractos = DB::table('extractos')
        ->where('idcontrato', $id)
        ->orderBy('numcuo')
        ->get();

    // --- CÁLCULOS PARA LAS CARDS ---
    
    // 1. Sumamos todos los pagos reales que ha hecho el cliente (Abonos)
    // Filtramos que no sean extractos anulados si tienes ese campo
    $totalPagado = $extractos->where('anulado', 0)->sum('abono');

    // 2. El saldo es lo que falta por pagar del TOTAL del contrato
    $saldo = $contrato->total - $totalPagado;

    return view('contratos.show', compact(
        'contrato', 
        'codeudores', 
        'extractos', 
        'saldo', 
        'totalPagado' // <--- Enviamos esta nueva variable
    ));
}

    // ── Formulario nuevo ─────────────────────────────────────────────────────
public function create(Request $request)
{
    $this->soloAdminOTecnico();

    $idgrupo = $request->input('idgrupo');
    $vendedores = DB::table('vendedores')->orderBy('id')->get();
    $urbanizaciones = Urbanizacion::orderBy('nombre')->get();
    $nuevoId = (Contrato::max('id') ?? 0) + 1;
    $hoy = \App\Helpers\FechaHelper::hoy();

    // Solo limpiar temporales si es un contrato nuevo sin clientes previos
    if (!$idgrupo) {
        $nuevoGrupo = (Clientetmp::max('idgrupo') ?? 0) + 1;
        $clientesTmp = collect(); // vacío
    } else {
        $nuevoGrupo = $idgrupo;
        // ✅ Cargar los clientes que ya se guardaron en confirmarGrupo
        $clientesTmp = Clientetmp::where('idgrupo', $idgrupo)->get();
    }

    return view('contratos.create', compact(
        'vendedores', 'urbanizaciones', 'nuevoId', 'hoy',
        'nuevoGrupo', 'clientesTmp'
    ));
}


    // public function create(Request $request)
    // {
    //     $this->soloAdminOTecnico();

    //     $idgrupo  = $request->input('idgrupo');
    //     $vendedores = DB::table('vendedores')->orderBy('id')->get();
    //     $urbanizaciones = Urbanizacion::orderBy('nombre')->get();
    //     $nuevoId  = (Contrato::max('id') ?? 0) + 1;
    //     $hoy      = FechaHelper::hoy();

    //     // Clientes del grupo temporal
    //     $clientesTmp = [];
    //     if ($idgrupo) {
    //         $clientesTmp = Clientetmp::where('idgrupo', $idgrupo)->get();
    //     }

    //     return view('contratos.create', compact(
    //         'vendedores', 'urbanizaciones', 'nuevoId', 'hoy', 'idgrupo', 'clientesTmp'
    //     ));
    // }

    // ── Guardar nuevo contrato ───────────────────────────────────────────────
    public function store(Request $request)
    {
        $this->soloAdminOTecnico();

        $request->validate([
            'id'            => 'required|integer|unique:contratos,id',
            'fecha'         => 'required|string',
            'select1'       => 'required|integer|not_in:0',
            'select2'       => 'required|integer|not_in:0',
            'select3'       => 'required|integer|not_in:0',
            'total'         => 'required|numeric|min:0',
            'pagos'         => 'required|in:credito,contado,otros',
            'cboVendedores' => 'required|integer|not_in:0',
        ], [
            'id.unique'            => 'Este número de contrato ya existe.',
            'select1.not_in'       => 'Debe seleccionar urbanización.',
            'select2.not_in'       => 'Debe seleccionar distrito.',
            'select3.not_in'       => 'Debe seleccionar lote.',
            'cboVendedores.not_in' => 'Debe seleccionar un vendedor.',
        ]);

        $idgrupo  = $request->idgrupo;
        $idLote   = $request->select3;
        $pagos    = $request->pagos;
        $fecha    = FechaHelper::localToBd($request->fecha);
        $hoy      = now('America/La_Paz')->format('Y-m-d');

        // Obtener datos del lote
        $lote = Lote::findOrFail($idLote);

        // Calcular cuotas según tipo de pago
        [$inicial, $ncuotas, $mensual] = $this->calcularCuotas($request, $pagos);

        // Obtener titular del grupo
        $titular = Clientetmp::where('idgrupo', $idgrupo)
                              ->where('tipo', 'Titular')
                              ->firstOrFail();

        // Verificar si hay codeudores
        $tieneCod = Clientetmp::where('idgrupo', $idgrupo)
                               ->where('tipo', 'Codeudor')
                               ->exists();

        // tipo: 1=crédito, 2=contado, 3=C.E. — campo INT, nunca string vacío
        $tipoPago = match($pagos) {
            'credito' => 1,
            'contado' => 2,
            'otros'   => 3,
            default   => 1,
        };

        // ── Insertar contrato ────────────────────────────────────────────────
        // Obtener CI del titular
        $titularCliente = \App\Models\Cliente::find($titular->id);
        $ciTitular = $titularCliente ? $titularCliente->ci : ($titular->ci ?? '');

        Contrato::create([
            'id'           => (int) $request->id,
            'fecha'        => $fecha,                  // Y-m-d desde FechaHelper::localToBd()
            'urbanizacion' => (int) $request->select1,
            'distrito'     => (int) $request->select2,
            'idlote'       => (int) $idLote,
            'manzano'      => $lote->manzano,
            'lote'         => $lote->nombre,
            'superficie'   => (float) ($request->select4 ?? $lote->superf),
            'total'        => (float) $request->total,
            'subtotal'     => (float) ($request->subtotal ?? 0),
            'numcuotas'    => (int) $ncuotas,
            'cuotainicial' => (float) $inicial,
            'cuotamensual' => (float) $mensual,
            'idcliente'    => (int) $titular->id,
            'cicliente'    => $ciTitular,              // VARCHAR — string ok
            'idvendedor'   => (int) $request->cboVendedores,
            'observaciones'=> $request->observaciones ?? '',
            'cli'          => $tieneCod ? 1 : 0,       // INT
            'anul'         => 0,                       // INT
            'movnum'       => 0,                       // INT — no string vacío
            'numman'       => 0,                       // INT — no string vacío
            'tipo'         => $tipoPago,                // INT: 1=crédito, 2=contado, 3=C.E.
            'respons'      => session('nombre', ''),   // VARCHAR — nombre del usuario
            'actudat'      => '0000-00-00',            // DATE — no string vacío
            'fechacomp'    => '0000-00-00',            // DATE — no string vacío
            'obsanul'      => '',                      // VARCHAR — ok
        ]);

        SeguimientoHelper::altaContrato($request->id);

        // ── Generar extractos según tipo de pago ─────────────────────────────
        $this->generarExtractos(
            $request->id, $titular->id, $pagos, $fecha, $hoy,
            $request->total, $inicial, $ncuotas, $mensual,
            $request->cboVendedores
        );

        // ── Actualizar estado del lote ───────────────────────────────────────
        $estadoLote = ($pagos === 'otros') ? 4 : 3; // 4=Vendido, 3=En Proceso
        DB::table('lotes')->where('id', $idLote)->update(['iteest' => $estadoLote]);

        // ── Mover clientes de tmp → clientes y registrar codeudores ─────────
        $this->procesarClientesTmp($idgrupo, $request->id, $hoy);

        return redirect()->route('contratos.show', $request->id)
                         ->with('success', 'Contrato guardado correctamente.');
    }

    // ── AJAX: lotes disponibles por distrito ─────────────────────────────────
    public function getLotesDisponibles($idDistrito)
    {
        $lotes = Lote::where('relacion', $idDistrito)
                     ->where('iteest', 1) // Solo disponibles
                     ->orderBy('manzano')
                     ->orderBy('nombre')
                     ->get(['id', 'manzano', 'nombre', 'superf']);

        return response()->json($lotes);
    }

    // ── AJAX: datos del lote seleccionado (superficie + subtotal) ────────────
    public function getDatosLote($idLote)
    {
        $lote = Lote::with('distrito')->findOrFail($idLote);

        $precio = match((int)$lote->itetip) {
            1 => $lote->distrito->Calle    ?? 0,
            2 => $lote->distrito->Avenida  ?? 0,
            3 => $lote->distrito->AreaVerde ?? 0,
            default => 0,
        };

        $subtotal = round($lote->superf * $precio, 2);

        return response()->json([
            'superf'     => $lote->superf,
            'subtotal'   => $subtotal,
            'alcanta'    => $lote->alcanta,
            'luz'        => $lote->luz,
            'agua'       => $lote->agua,
            'telef'      => $lote->telef,
            'transpor'   => $lote->transpor,
            'cordon'     => $lote->cordon,
            'acera'      => $lote->acera,
            'muralla'    => $lote->muralla,
        ]);
    }

    // ── AJAX: buscar clientes para autocomplete ──────────────────────────────
    public function buscarCliente(Request $request)
    {
        $q = $request->input('q', '');
        $clientes = Cliente::where('tipo', 1)
            ->where(function ($query) use ($q) {
                $query->where('id',     'like', "$q%")
                      ->orWhere('nombre', 'like', "%$q%")
                      ->orWhere('ci',     'like', "$q%");
            })
            ->limit(15)
            ->get(['id', 'nombre', 'ci']);

        return response()->json($clientes);
    }

    // ── Helpers privados ─────────────────────────────────────────────────────

    private function soloAdminOTecnico(): void
    {
        if (!in_array(auth()->user()->tipo, [1, 4]))
            abort(403, 'Privilegio de acceso denegado.');
    }

    private function calcularCuotas(Request $request, string $pagos): array
    {
        return match($pagos) {
            'credito' => [
                (float) $request->inicial,
                (int)   $request->ncuotas,
                (float) $request->mensual,
            ],
            'contado' => [
                (float) $request->inicial2,
                1,
                0,
            ],
            'otros' => [
                0,
                1,
                0,
            ],
            default => [0, 0, 0],
        };
    }

    private function generarExtractos(
        int $idContrato, int $idCliente, string $pagos,
        string $fecha, string $hoy,
        float $total, float $inicial, int $ncuotas, float $mensual,
        int $idVendedor
    ): void {
        $idExtracto = DB::table('extractos')->max('id') ?? 0;

        if ($pagos === 'credito') {
            // Cuota inicial
            $idExtracto++;
            DB::table('extractos')->insert([
                'id'           => $idExtracto,
                'fecha'        => $hoy,
                'numman'       => 0,
                'numcuo'       => 1,
                'tipmov'       => 1,
                'numrec'       => 0,
                'tiprec'       => 0,
                'numaju'       => 0,
                'tipo'         => 1,
                'tipmon'       => 2,
                'idcontrato'   => $idContrato,
                'idcliente'    => $idCliente,
                'fechaven'     => $hoy,
                'cargo'        => $inicial,
                'abono'        => 0,
                'abono2'       => 0,
                'abono3'       => 0,
                'saldo'        => 0,
                'tipocambio'   => 7.04,
                'anulado'      => 0,
                'titulo'       => "Cuota inicial según contrato No: $idContrato en fecha $hoy",
                'montosus'     => 0,
                'montobs'      => 0,
                'fechaanulado' => '0000-00-00',
                'idcobrador'   => 0,
                'idvendedor'   => $idVendedor,
                'respons'      => 'Sistema',
                'flag'         => 0,
                'numcomp'      => 0,
                'fechcomp'     => '0000-00-00',
                'clascomp'     => 0,
            ]);

            // Cuotas mensuales
            $fechaVen = Carbon::parse($hoy);
            for ($n = 2; $n <= $ncuotas + 1; $n++) {
                $fechaVen = $fechaVen->addDays(30);
                $idExtracto++;
                DB::table('extractos')->insert([
                    'id'           => $idExtracto,
                    'fecha'        => $hoy,
                    'numman'       => 0,
                    'numcuo'       => $n,
                    'tipmov'       => 1,
                    'numrec'       => 0,
                    'tiprec'       => 0,
                    'numaju'       => 0,
                    'tipo'         => 1,
                    'tipmon'       => 2,
                    'idcontrato'   => $idContrato,
                    'idcliente'    => $idCliente,
                    'fechaven'     => $fechaVen->format('Y-m-d'),
                    'cargo'        => $mensual,
                    'abono'        => 0,
                    'abono2'       => 0,
                    'abono3'       => 0,
                    'saldo'        => 0,
                    'tipocambio'   => 7.04,
                    'anulado'      => 0,
                    'titulo'       => "Cuota mes $n según Contrato No: $idContrato",
                    'montosus'     => 0,
                    'montobs'      => 0,
                    'fechaanulado' => '0000-00-00',
                    'idcobrador'   => 0,
                    'idvendedor'   => $idVendedor,
                    'respons'      => 'Sistema',
                    'flag'         => 0,
                    'numcomp'      => 0,
                    'fechcomp'     => '0000-00-00',
                    'clascomp'     => 0,
                ]);
            }

        } elseif ($pagos === 'contado') {
            // Una sola cuota igual al total
            $idExtracto++;
            DB::table('extractos')->insert([
                'id'           => $idExtracto,
                'fecha'        => $hoy,
                'numman'       => 0,
                'numcuo'       => 1,
                'tipmov'       => 1,
                'numrec'       => 0,
                'tiprec'       => 0,
                'numaju'       => 0,
                'tipo'         => 1,
                'tipmon'       => 2,
                'idcontrato'   => $idContrato,
                'idcliente'    => $idCliente,
                'fechaven'     => $hoy,
                'cargo'        => $inicial,
                'abono'        => 0,
                'abono2'       => 0,
                'abono3'       => 0,
                'saldo'        => 0,
                'tipocambio'   => 7.04,
                'anulado'      => 0,
                'titulo'       => "Pago al contado Contrato No: $idContrato",
                'montosus'     => 0,
                'montobs'      => 0,
                'fechaanulado' => '0000-00-00',
                'idcobrador'   => 0,
                'idvendedor'   => $idVendedor,
                'respons'      => 'Sistema',
                'flag'         => 0,
                'numcomp'      => 0,
                'fechcomp'     => '0000-00-00',
                'clascomp'     => 0,
            ]);

        } elseif ($pagos === 'otros') {
            // C.E. — extracto con cargo 0
            $idExtracto++;
            DB::table('extractos')->insert([
                'id'           => $idExtracto,
                'fecha'        => $hoy,
                'numman'       => 0,
                'numcuo'       => 1,
                'tipmov'       => 1,
                'numrec'       => 0,
                'tiprec'       => 0,
                'numaju'       => 0,
                'tipo'         => 1,
                'tipmon'       => 2,
                'idcontrato'   => $idContrato,
                'idcliente'    => $idCliente,
                'fechaven'     => $hoy,
                'cargo'        => 0,
                'abono'        => 0,
                'abono2'       => 0,
                'abono3'       => 0,
                'saldo'        => 0,
                'tipocambio'   => 7.04,
                'anulado'      => 0,
                'titulo'       => "Contrato especial No: $idContrato",
                'montosus'     => 0,
                'montobs'      => 0,
                'fechaanulado' => '0000-00-00',
                'idcobrador'   => 0,
                'idvendedor'   => $idVendedor,
                'respons'      => 'Sistema',
                'flag'         => 0,
                'numcomp'      => 0,
                'fechcomp'     => '0000-00-00',
                'clascomp'     => 0,
            ]);
        }
    }

    private function procesarClientesTmp(int $idgrupo, int $idContrato, string $hoy): void
    {
        $lineas = Clientetmp::where('idgrupo', $idgrupo)->get();

        foreach ($lineas as $tmp) {
            // Solo insertar los clientes nuevos (temporal=0)
            if ($tmp->temporal == 0 && !Cliente::find($tmp->id)) {
                Cliente::create([
                    'id'            => $tmp->id,
                    'fecha'         => $hoy,
                    'nombre'        => $tmp->nombre,
                    'ci'            => $tmp->ci,
                    'direccion'     => $tmp->direccion,
                    'ciudad'        => $tmp->ciudad,
                    'telefono'      => $tmp->telefono,
                    'celular'       => $tmp->celular,
                    'fax'           => $tmp->fax ?? '',
                    'email'         => $tmp->email ?? '',
                    'casilla'       => $tmp->casilla ?? '',
                    'respons'       => '',
                    'observaciones' => $tmp->observaciones ?? '',
                    'sexo'          => $tmp->sexo,
                    'estadocivil'   => $tmp->estadocivil,
                    'tipo'          => $tmp->tipo === 'Titular' ? 1 : 2,
                    'idgrupo'       => $tmp->idgrupo,
                    'temporal'      => 0,
                ]);
                SeguimientoHelper::altaCliente($tmp->id);
            }

            // Registrar codeudores
            if ($tmp->tipo === 'Codeudor') {
                DB::table('codeudores')->insert([
                    'idcliente'  => $tmp->id,
                    'idcontrato' => $idContrato,
                    'flag'       => 0,
                ]);
            }
        }

        // Limpiar temporales
        Clientetmp::where('idgrupo', $idgrupo)->delete();
    }
}