<?php

class AbonoPrestamo extends Utilidades implements Agrupable
{
    private $abono;
    public $escenario = 4; // prestamo
    private $tipo_unidad = 1;
    private $escenario_aporte_voluntario = 6;
    public $tipo_parametro_rebaja_prestamos = 3;
    private $titulo_proceso_abono_prestamo = 12;

    public function __construct($abono)
    {
        $this->abono = $abono;
        Yii::import('application.modules.contable.models.*', true);
        Yii::import('application.modules.contable.models.comprobantes.*', true);
    }

    public function contabilizar()
    {
        // Escenario abono a prestamos
        if (! ParamEscenarios::conectado(5)) {
            return;
        }

        ////////////////////////////////// COMPROBANTE /////////////////////////////////
        $comprobante = $this->comprobante();

        $this->seguimientoComprobante(
            $comprobante->id,
            $this->abono->id,
            null,
            $this->titulo_proceso_abono_prestamo
        );
        ////////////////////////// MOVIMIENTOS DEL COMPROBANTE /////////////////////////
        $this->movimientos($comprobante);
    }

    public function groupScenario()
    {
        return $this->tipo_parametro_rebaja_prestamos;
    }

    public function groupData()
    {
        return $this->prestamos();
    }

    private function movimientos($comprobante)
    {
        $movimiento = new Movimiento(
            $comprobante,
            $this->abono->fecha_referencia
        );

        $monto_aporte = $this->getMontos();

        $movimiento->crear(
            $this->abono->bancoCuentaContable(),
            $monto_aporte['cta_banco_abono']
        );

        $datosAgrupados = OrderByCuentaContable::comprobante($this)
            ->clave('cta_plazo_prestamo')
            ->groupBy('cta_prestamo_abono');

        if (count($datosAgrupados) > 0) {
            foreach ($datosAgrupados as $prestamo) {
                $movimiento->crear(
                    $prestamo['cuenta_contable'],
                    0,
                    $prestamo['monto']
                );
            }
        }

        $remanenteAbono = $this->abono->remanenteAbono();
        if ($remanenteAbono && $this->abono->destino_remanente == 1) { // Capitalizar
            $movimiento->crear(
                Parametros::getCuentaContable([
                    'clave' => 'cta_aporte_voluntario',
                    'escenario' => $this->escenario_aporte_voluntario,
                    'tipo_parametro' => $this->tipo_unidad,
                    'proceso' => $this->abono->idAsociado->idunidad,
                ]),
                0,
                $monto_aporte['cta_aporte_voluntario_abono']
            );
        }

        if ($remanenteAbono && $this->abono->destino_remanente == 2) { // Orden de pago
            $movimiento->crear(
                Parametros::getCuentaContable([
                    'clave' => 'cta_x_pagar_abono',
                    'escenario' => null,
                    'tipo_parametro' => null,
                    'proceso' => null,
                ]),
                0,
                $monto_aporte['cta_x_pagar_abono']
            );
        }
    }

    private function getMontos()
    {
        $debe = [
            'cta_banco_abono' => $this->abono->getMontoPrestamo(),
        ];

        $haber = array_filter($this->array_flatten([
            $this->getMontoRebajaPrestamo(),
            $this->getRemanente(),
        ]));

        // $this->debug($debe, $haber);

        $this->validate($debe, $haber);

        return array_merge([], $debe, $haber);
    }

    private function comprobante()
    {
        $this->setProceso($this->abono);

        $comprobante = new Comprobante();
        $comprobante->fecha_comprobante = $this->fechaComprobante();
        $comprobante->descripcion = $this->abono->idAsociado->nombreCompleto();
        $comprobante->status = 1;
        $comprobante->nro_documento = $this->abono->numero_referencia;
        if (! $comprobante->save()) {
            throw new Exception('Error al generar comprobante contable.', $this->codigo_error);
        }

        return $comprobante;
    }

    private function getMontoRebajaPrestamo()
    {
        $datos = $this->prestamos();

        return (new Warp($datos))->flatMap(function ($prestamo) {
            return [
                "cta_prestamo_abono_{$prestamo->id_credito}" => $prestamo->monto,
            ];
        });
    }

    private function getRemanente()
    {
        if (! $this->abono->remanenteAbono()) {
            return null;
        }

        // Capitalizar
        if ($this->abono->destino_remanente == 1) {
            return ['cta_aporte_voluntario_abono' => $this->abono->remanente_abono];
        }

        // Orden de pago
        if ($this->abono->destino_remanente == 2) {
            return ['cta_x_pagar_abono' => $this->abono->remanente_abono];
        }
    }

    private function prestamos()
    {
        $prestamos = (new Warp(json_decode($this->abono->prestamos_seleccionados)))->map(function ($prestamo) {
            return (object) [
                'id_credito' => $prestamo->id_credito,
                'id_tipo_credito' => $prestamo->id_tipo_credito,
                'monto_deuda' => $prestamo->monto_deuda,
                'monto' => $prestamo->monto_abonar,
            ];
        });

        return (new Warp($prestamos))->filter(function ($prestamo) {
            return $prestamo->monto > 0;
        });
    }
}
