<?php

class SituacionFinancieraFechaQuery
{
    use AttributeAccess;

    protected $attributes;

    public function __construct($attributes)
    {
        $this->attributes = $attributes;
    }

    public function run()
    {
        if (!empty($this->fecha_desde) || !empty($this->fecha_hasta)) {            
            return [[], true, 'Debe seleccionar una rango de fechas a consultar.'];
        }

        if ($this->nivel != null) {
            $where_nivel = " AND nivel <= {$this->nivel} ";
        }

        if ($this->excluir_movimiento_cierre) {
            $movimiento_cierre = 'AND (id_tipo_comprobante=1 OR id_tipo_comprobante=2)';
        } else {
            $movimiento_cierre = 'AND (id_tipo_comprobante=1 OR id_tipo_comprobante=2 OR id_tipo_comprobante=3)';
        }

        if ($this->fecha_desde != null && $this->fecha_hasta != null) {
            $where_fecha = " AND fecha_comprobante BETWEEN '{$this->fecha_desde}' AND '{$this->fecha_hasta}' ";
        }

        if ($this->fecha_desde != null) {
            $where_fecha_ant = " AND fecha_comprobante <= '{$this->fecha_desde}' ";
        }

        $fecha_ant = $where_fecha_ant;

        $cuentas = CuentasConsolidada::model()->findAll([
            'condition' => "blnborrado = FALSE
                            AND SUBSTRING(cuenta from 1 for 1) IN ('1','2','3')
                            {$where_nivel}",
            'order' => 'cuenta ASC',
        ]);

        $conf_contable = ConfContable::model()->find('id=4');
        $ejercicio = EjerciciosContables::model()->find('activo=1');
        $config_contable = ['0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 5, '5' => 7, '6' => 9, '7' => 11];
        // $config_contable = [
        //     '0' => 0,
        //     '1' => 3,
        //     '2' => 5,
        //     '3' => 7,
        //     '4' => 9,
        //     '5' => 11,
        //     '6' => 13,
        //     '7' => 15,
        // ];

        $acum_total_anterior = 0;
        $acum_total_actual = 0;
        $acum_variacion = 0;

        $acum_activos_anterior = 0;
        $acum_activos_actual = 0;
        $acum_activos_variacion = 0;

        $acum_pasivos_anterior = 0;
        $acum_pasivos_actual = 0;
        $acum_pasivos_variacion = 0;

        $acum_patrimonio_anterior = 0;
        $acum_patrimonio_actual = 0;
        $acum_patrimonio_variacion = 0;

        $datos = [];
        $datos['detalle'] = [];
        $datos['attributes'] = $this->attributes;

        foreach ($cuentas as $cuenta) {
            $ingresoactual = DetalleAnalitico::model()->find([
                'select' => 'COALESCE(sum(monto_debe), 0) - COALESCE(sum(monto_haber), 0) as total_monto_actual',
                'condition' => "SUBSTRING('400000000' from 1 for 1 ) = SUBSTRING(cuenta from 1 for 1 )
                                AND estatus_contab=1
                                AND activo=1
                                AND clvejercicio={$ejercicio->id}
                                AND blnborrado = FALSE
                                {$movimiento_cierre}
                                {$where_fecha}",
            ]);

            $ingresoanterior = DetalleAnalitico::model()->find([
                'select' => 'COALESCE(sum(monto_debe), 0) - COALESCE(sum(monto_haber), 0) as total_monto_anterior',
                'condition' => "SUBSTRING('400000000' from 1 for 1 ) = SUBSTRING(cuenta from 1 for 1 )
                                AND estatus_contab=1
                                AND activo=1
                                AND clvejercicio={$ejercicio->id}
                                AND blnborrado = FALSE
                                {$movimiento_cierre}
                                {$fecha_ant}",
            ]);

            // condicion para las cuentas de excedente y patrimonio
            $condicion = $this->isPatrimonyAccount($cuenta->id);

            // Trimestre anterior
            if ($condicion && $ingresoanterior->total_monto_anterior != null) {
                $model_total_anterior = DetalleAnalitico::model()->find([
                    'select' => "COALESCE(sum(monto_debe), 0) - COALESCE(sum(monto_haber), 0) +
                                (
                                    SELECT COALESCE(sum(monto_debe), 0) - COALESCE(sum(monto_haber), 0) as total_monto_actual
                                    FROM contable.vsw_detalle_analitico
                                    WHERE SUBSTRING('400000000' from 1 for 1) = SUBSTRING(cuenta from 1 for 1)
                                        AND estatus_contab=1
                                        AND activo=1
                                        AND clvejercicio={$ejercicio->id}
                                        AND blnborrado = FALSE
                                        {$movimiento_cierre}
                                        {$fecha_ant}
                                    LIMIT 1
                                ) +
                                (
                                    SELECT COALESCE(sum(monto_debe), 0) - COALESCE(sum(monto_haber), 0) as total_monto_actual
                                    FROM contable.vsw_detalle_analitico
                                    WHERE SUBSTRING('500000000' from 1 for 1) = SUBSTRING(cuenta from 1 for 1)
                                        AND estatus_contab=1
                                        AND activo=1
                                        AND clvejercicio={$ejercicio->id}
                                        AND blnborrado = FALSE
                                        {$movimiento_cierre}
                                        {$fecha_ant}
                                    LIMIT 1
                                ) as total_monto_anterior ",
                    'condition' => "SUBSTRING('{$cuenta->cuenta}' from 1 for {$config_contable[$cuenta->nivel]})=SUBSTRING(cuenta from 1 for {$config_contable[$cuenta->nivel]})
                                    AND estatus_contab=1
                                    AND activo=1
                                    AND clvejercicio={$ejercicio->id}
                                    AND blnborrado = FALSE
                                    {$movimiento_cierre}
                                    {$fecha_ant}",
                ]);

                if ($cuenta->id == $conf_contable->atributo) {
                    $model_total_anterior = DetalleAnalitico::model()->find([
                        'select' => "(
                                        SELECT COALESCE(sum(monto_debe), 0) - COALESCE(sum(monto_haber), 0) as total_monto_actual
                                        FROM contable.vsw_detalle_analitico
                                        WHERE SUBSTRING('400000000' from 1 for 1 ) = SUBSTRING(cuenta from 1 for 1)
                                            AND estatus_contab=1
                                            AND activo=1
                                            AND clvejercicio={$ejercicio->id}
                                            AND blnborrado = FALSE
                                            {$movimiento_cierre}
                                            {$fecha_ant}
                                        LIMIT 1
                                    ) +
                                    (
                                        SELECT COALESCE(sum(monto_debe), 0) - COALESCE(sum(monto_haber), 0) as total_monto_actual
                                        FROM contable.vsw_detalle_analitico
                                        WHERE SUBSTRING('500000000' from 1 for 1) = SUBSTRING(cuenta from 1 for 1)
                                            AND estatus_contab=1
                                            AND activo=1
                                            AND clvejercicio={$ejercicio->id}
                                            AND blnborrado = FALSE
                                            {$movimiento_cierre}
                                            {$fecha_ant}
                                        LIMIT 1
                                    ) as total_monto_anterior",
                        'condition' => "SUBSTRING('341010000' from 1 for 1) = SUBSTRING(cuenta from 1 for 1) ",
                    ]);
                }
            } else {
                $model_total_anterior = DetalleAnalitico::model()->find([
                    'select' => 'COALESCE(sum(monto_debe), 0) - COALESCE(sum(monto_haber), 0) as total_monto_anterior ',
                    'condition' => "SUBSTRING('{$cuenta->cuenta}' from 1 for {$config_contable[$cuenta->nivel]})=SUBSTRING(cuenta from 1 for {$config_contable[$cuenta->nivel]})
                                    AND estatus_contab=1
                                    AND activo=1
                                    AND clvejercicio={$ejercicio->id}
                                    AND blnborrado = FALSE
                                    {$movimiento_cierre}
                                    {$fecha_ant}",
                ]);
            }

            // Trimestre actual
            if ($condicion && $ingresoanterior->total_monto_anterior != null) {
                $model_total = DetalleAnalitico::model()->find([
                    'select' => "COALESCE(sum(monto_debe), 0) - COALESCE(sum(monto_haber), 0) +
                                (
                                    select COALESCE(sum(monto_debe), 0) - COALESCE(sum(monto_haber), 0)
                                    FROM contable.vsw_detalle_analitico
                                    where SUBSTRING('{$cuenta->cuenta}' from 1 for {$config_contable[$cuenta->nivel]}) = SUBSTRING(cuenta from 1 for {$config_contable[$cuenta->nivel]})
                                        AND estatus_contab=1
                                        AND activo=1
                                        AND clvejercicio={$ejercicio->id}
                                        AND blnborrado = FALSE
                                        {$movimiento_cierre}
                                        {$fecha_ant}
                                    LIMIT 1
                                ) +
                                (
                                    SELECT COALESCE(sum(monto_debe), 0) - COALESCE(sum(monto_haber), 0)
                                    FROM contable.vsw_detalle_analitico
                                    WHERE SUBSTRING('400000000' from 1 for 1) = SUBSTRING(cuenta from 1 for 1)
                                        AND estatus_contab=1
                                        AND activo=1
                                        AND clvejercicio={$ejercicio->id}
                                        AND blnborrado = FALSE
                                        {$movimiento_cierre}
                                        {$where_fecha}
                                    LIMIT 1
                                ) +
                                (
                                    SELECT COALESCE(sum(monto_debe), 0) - COALESCE(sum(monto_haber), 0)
                                    FROM contable.vsw_detalle_analitico
                                    WHERE SUBSTRING('500000000' from 1 for 1) = SUBSTRING(cuenta from 1 for 1)
                                        AND estatus_contab=1
                                        AND activo=1
                                        AND clvejercicio={$ejercicio->id}
                                        AND blnborrado = FALSE
                                        {$movimiento_cierre}
                                        {$where_fecha}
                                    LIMIT 1
                                ) +
                                (
                                    SELECT COALESCE(sum(monto_debe), 0) - COALESCE(sum(monto_haber), 0)
                                    FROM contable.vsw_detalle_analitico
                                    WHERE SUBSTRING('400000000' from 1 for 1) = SUBSTRING(cuenta from 1 for 1)
                                        AND estatus_contab=1
                                        AND activo=1
                                        AND clvejercicio={$ejercicio->id}
                                        AND blnborrado = FALSE
                                        {$movimiento_cierre}
                                        {$fecha_ant}
                                    LIMIT 1
                                ) +
                                (
                                    SELECT COALESCE(sum(monto_debe), 0) - COALESCE(sum(monto_haber), 0)
                                    FROM contable.vsw_detalle_analitico
                                    WHERE SUBSTRING('500000000' from 1 for 1) = SUBSTRING(cuenta from 1 for 1)
                                        AND estatus_contab=1
                                        AND activo=1
                                        AND clvejercicio={$ejercicio->id}
                                        AND blnborrado = FALSE
                                        {$movimiento_cierre}
                                        {$fecha_ant}
                                    LIMIT 1
                                ) as total_monto_actual",
                    'condition' => "SUBSTRING('{$cuenta->cuenta}' from 1 for {$config_contable[$cuenta->nivel]})=SUBSTRING(cuenta from 1 for {$config_contable[$cuenta->nivel]})
                                    AND estatus_contab=1
                                    AND activo=1
                                    AND clvejercicio={$ejercicio->id}
                                    AND blnborrado = FALSE
                                    {$movimiento_cierre}
                                    {$where_fecha}",
                ]);

                if ($cuenta->id == $conf_contable->atributo && $ingresoactual->total_monto_actual != null) {
                    $model_total = DetalleAnalitico::model()->find([
                        'select' => "(
                                        SELECT COALESCE(sum(monto_debe), 0) - COALESCE(sum(monto_haber), 0) as total_monto_actual
                                        FROM contable.vsw_detalle_analitico
                                        WHERE SUBSTRING('400000000' from 1 for 1) = SUBSTRING(cuenta from 1 for 1)
                                            AND estatus_contab=1
                                            AND activo=1
                                            AND clvejercicio={$ejercicio->id}
                                            AND blnborrado = FALSE
                                            {$movimiento_cierre}
                                            {$where_fecha}
                                        LIMIT 1
                                    ) +
                                    (
                                        SELECT COALESCE(sum(monto_debe), 0) - COALESCE(sum(monto_haber), 0) as total_monto_actual
                                        FROM contable.vsw_detalle_analitico
                                        WHERE SUBSTRING('500000000' from 1 for 1) = SUBSTRING(cuenta from 1 for 1)
                                            AND estatus_contab=1
                                            AND activo=1
                                            AND clvejercicio={$ejercicio->id}
                                            AND blnborrado = FALSE
                                            {$movimiento_cierre}
                                            {$where_fecha}
                                        LIMIT 1
                                    ) +
                                    (
                                        SELECT COALESCE(sum(monto_debe), 0) - COALESCE(sum(monto_haber), 0) as total_monto_actual
                                        FROM contable.vsw_detalle_analitico
                                        WHERE SUBSTRING('400000000' from 1 for 1) = SUBSTRING(cuenta from 1 for 1)
                                            AND estatus_contab=1
                                            AND activo=1
                                            AND clvejercicio={$ejercicio->id}
                                            AND blnborrado = FALSE
                                            {$movimiento_cierre}
                                            {$fecha_ant}
                                        LIMIT 1
                                    ) +
                                    (
                                        SELECT COALESCE(sum(monto_debe), 0) - COALESCE(sum(monto_haber), 0) as total_monto_actual
                                        FROM contable.vsw_detalle_analitico
                                        WHERE SUBSTRING('500000000' from 1 for 1) = SUBSTRING(cuenta from 1 for 1)
                                            AND estatus_contab=1
                                            AND activo=1
                                            AND clvejercicio={$ejercicio->id}
                                            AND blnborrado = FALSE
                                            {$movimiento_cierre}
                                            {$fecha_ant}
                                        LIMIT 1
                                    ) as total_monto_actual",
                        'condition' => "SUBSTRING('341010000' from 1 for 1) = SUBSTRING(cuenta from 1 for 1 )",
                    ]);
                }
            } else {
                $model_total = DetalleAnalitico::model()->find([
                    'select' => 'COALESCE(sum(monto_debe), 0) - COALESCE(sum(monto_haber), 0) as total_monto_actual',
                    'condition' => "SUBSTRING('{$cuenta->cuenta}' from 1 for {$config_contable[$cuenta->nivel]})=SUBSTRING(cuenta from 1 for {$config_contable[$cuenta->nivel]})
                                    AND estatus_contab=1
                                    AND activo=1
                                    AND clvejercicio={$ejercicio->id}
                                    AND blnborrado = FALSE
                                    {$movimiento_cierre}
                                    {$where_fecha}",
                ]);
            }

            $monto_anterior = ($model_total_anterior->total_monto_anterior) ? $model_total_anterior->total_monto_anterior : 0;
            $monto_actual = ($model_total->total_monto_actual) ? $model_total->total_monto_actual : 0;

            /*
             * Se aplica para las cuentas de patrimonio y excendente tambien para cuando se consulta el primer periodo.
             * (el calculo del trimestre esta basado en el las fechas desde y hasta)
             */
            if (($condicion && $ingresoactual->total_monto_actual != null) || (new Periodo($this->fecha_desde, $this->fecha_hasta))->getTrimestre() == 1) {
                // formula: (debe - haber)
                $monto_actual = $monto_actual;
            } else {
                // formula: (debe - haber) + saldo_anterior
                $monto_actual = $monto_actual + $monto_anterior;
            }

            $monto_variacion = $monto_actual - $monto_anterior;

            //Verificamos si a la cuenta se le hacen movimientos
            $cta_mov = DetalleComprobante::model()->findByAttributes(['id_cuenta' => $cuenta->id]);

            // Si es una cuenta de movimiento si sumo para el total del balance
            if ($cta_mov != null) {
                $acum_total_anterior += $monto_anterior;
                $acum_total_actual += $monto_actual;
                $acum_variacion += $monto_variacion;
            }

            //total de los activos
            if (trim($cuenta->cuenta[0]) == '1' && $cuenta->nivel == 1) {
                $acum_activos_anterior += $monto_anterior;
                $acum_activos_actual += $monto_actual;
                $acum_activos_variacion += $monto_variacion;
            }

            //total de los pasivos
            if (trim($cuenta->cuenta[0]) == '2' && $cuenta->nivel == 1) {
                $acum_pasivos_anterior += $monto_anterior;
                $acum_pasivos_actual += $monto_actual;
                $acum_pasivos_variacion += $monto_variacion;
            }
            //total de patrimonio
            if (trim($cuenta->cuenta[0]) == '3' && $cuenta->nivel == 1) {
                $acum_patrimonio_anterior += $monto_anterior;
                $acum_patrimonio_actual += $monto_actual;
                $acum_patrimonio_variacion += $monto_variacion;
            }

            //Si son los 3 primeros niveles la presentacion debe ser en mayusculas y negrita
            if (in_array($cuenta->nivel, [1, 2, 3])) {
                $clase_cuenta = 'cuenta_alto_nivel';
                $cuenta->cuenta = strtoupper($cuenta->cuenta);
            } else {
                $clase_cuenta = '';
            }

            if ($this->sin_ceros && array_sum([$monto_actual, $monto_anterior, $monto_variacion]) == 0) {
                $mostrar = false;
            } else {
                $mostrar = true;
            }

            //Obtenemos el patrimonio:
            $total_patrimonio_anterior = (-$acum_activos_anterior - $acum_pasivos_anterior);
            $total_patrimonio_actual = (-$acum_activos_actual - $acum_pasivos_actual);
            $total_patrimonio_variacion = ($total_patrimonio_actual - $total_patrimonio_anterior);

            if ($mostrar) {
                $datos['detalle'][$cuenta->id] = [
                    'clase' => $clase_cuenta,
                    'cuenta_titulo' => $cuenta->titulo_mov == 1,
                    'cuenta' => $cuenta->cuenta,
                    'descripcion' => $cuenta->descripcion,
                    'anterior' => $monto_anterior,
                    'actual' => $monto_actual,
                    'variacion' => $monto_variacion,
                ];
            }
        }

        $datos['totales'] = [
            'activo' => [
                'anterior' => $acum_activos_anterior,
                'actual' => $acum_activos_actual,
                'variacion' => $acum_activos_variacion,
            ],
            'pasivo' => [
                'anterior' => $acum_pasivos_anterior,
                'actual' => $acum_pasivos_actual,
                'variacion' => $acum_pasivos_variacion,
            ],
            'patrimonio' => [
                'anterior' => $total_patrimonio_anterior,
                'actual' => $total_patrimonio_actual,
                'variacion' => $total_patrimonio_variacion,
            ],
            'pasivo_patrimonio' => [
                'anterior' => $total_patrimonio_anterior + $acum_pasivos_anterior,
                'actual' => $total_patrimonio_actual + $acum_pasivos_actual,
                'variacion' => $total_patrimonio_variacion + $acum_pasivos_variacion,
            ],
        ];

        return [$datos, false, ''];
    }

    protected function isPatrimonyAccount($account)
    {
        $ctas = Yii::app()->getDb()->createCommand("
            SELECT id
            FROM contable.cuentas_consolidada
            WHERE codigo_cuenta ILIKE '%341.%'
                AND blnborrado=false
                AND titulo_mov=1
        ")->queryColumn();

        $conf_contable = ConfContable::model()->find('id=4');

        return in_array($account, array_merge($ctas, [
            'patrimonio' => 477,
            'excedente' => 498,
            'utilidad_retenida_ejercicio' => $conf_contable->atributo,
        ]));
    }
}
