<?php

namespace App\Support;

use App\Models\Credit;
use App\Models\Installment;
use Exception;

class CreditRules
{
    /**
     * Determina si el crédito tiene pagos de cualquier tipo (interés o capital).
     */
    public static function hasPayments(Credit $credit): bool
    {
        // 1) Pagos EFECTIVOS: no anulados y que no sean reversas. Anular un pago deja
        //    su fila con `voided=1` MÁS una fila compensatoria `payment_method='reversal'`;
        //    ninguno representa dinero recibido. Contarlos dejaba el crédito en SOLO
        //    LECTURA aun después de anular su único pago para poder editarlo (#387) —
        //    bloqueando `CreditPolicy::update/delete/clone/extend/cancel` y los campos
        //    del `CreditForm`. El capital realmente amortizado lo cubre el punto 2.
        if ($credit->payments()->collections()->exists()) {
            return true;
        }

        // 2) Cuotas con abonos parciales o pagadas
        return $credit->installments()
            ->where(function ($q) {
                $q->where('amount_paid', '>', 0)
                    ->orWhere('status', Installment::STATUS_PAID)
                    ->orWhere('status', Installment::STATUS_PARTIAL_PAID);
            })
            ->exists();
    }

    /**
     * Detecta si existe algún pago que amortice capital.
     * amount_paid > interest_amount → pagó principal.
     */
    public static function hasCapitalPayments(Credit $credit): bool
    {
        if (! $credit->hasPayments()) {
            return false;
        }

        // Los pagos se aplican interés-primero: una cuota amortiza capital cuando
        // lo abonado supera su porción de interés (#96). Detecta también los abonos
        // parciales que exceden el interés, no solo las cuotas 100% saldadas.
        return $credit->installments()
            ->whereColumn('amount_paid', '>', 'interest_amount')
            ->exists();
    }

    /**
     * POLÍTICA A PRO REVISADA:
     * - Si TIENE pagos de capital → PROHIBIDO operar.
     * - Si solo tiene pagos de intereses → PERMITIDO operar.
     */
    public static function ensureNoCapitalPaid(Credit $credit): void
    {
        if (self::hasCapitalPayments($credit)) {
            throw new Exception(
                'Este crédito tiene pagos de capital y está en modo SOLO LECTURA (POLÍTICA A PRO). '.
                'No se permite extender, cancelar, duplicar ni editar.'
            );
        }
    }
}
