<?php

class EstadoResultadoAnualQuery
{
    use AttributeAccess;

    protected $attributes;

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

    public function run()
    {
        $where_total_cuenta = '';
        if ($this->cuenta_desde != null && $this->cuenta_hasta != null) {
            $where_cuenta = " AND cuenta BETWEEN '{$this->cuenta_desde}' AND '{$this->cuenta_hasta}'
                              AND titulo_mov = 2 
                              OR (titulo_mov = 1 AND cuenta BETWEEN '1' AND '{$this->cuenta_hasta}')";
            $where_total_cuenta = " AND cuenta BETWEEN '{$this->cuenta_desde}' AND '{$this->cuenta_hasta}' ";
        }

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

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

        //Vamos a buscar los dias primero y ultimo de dicho rango (trimestre)
        if ($this->trimestre == 1) {
            $this->trimestre_ant = 4; //trimestre anterior
            $this->anyo_ant = $this->anyo - 1; //año del trimestre anterior
        } else {
            $this->trimestre_ant = $this->trimestre - 1;
            $this->anyo_ant = $this->anyo;
        }

        $mes_ultimo_trimestre = $this->trimestre * 3;
        $mes_primero_trimestre = ($mes_ultimo_trimestre - 3) + 1;

        $mes_ultimo_trimestre_ant = $this->trimestre_ant * 3;
        $mes_primero_trimestre_ant = ($mes_ultimo_trimestre_ant - 3) + 1;

        $fecha_hasta_trimestre = date('Y-m-t', strtotime($this->anyo.'-'.$mes_ultimo_trimestre.'-01'));
        $fecha_desde_trimestre = $this->anyo.'-'.$mes_primero_trimestre.'-01';

        $fecha_hasta_trimestre_ant = date('Y-m-t', strtotime($this->anyo_ant.'-'.$mes_ultimo_trimestre_ant.'-01'));
        $fecha_desde_trimestre_ant = $this->anyo_ant.'-'.$mes_primero_trimestre_ant.'-01';

        if ($this->trimestre == 5) {
            $fecha_desde_trimestre = $this->anyo.'-01-01';
            $fecha_hasta_trimestre = date('Y-m-d', strtotime($this->anyo.'-12-31'));
            $fecha_hasta_trimestre_ant = date('Y-m-d', strtotime($this->anyo_ant.'-01-01'));
            $fecha_desde_trimestre_ant = $this->anyo_ant.'-12-31';
        }

        if ($fecha_desde_trimestre_ant != null && $fecha_hasta_trimestre_ant != null) {
            $where_fecha_ant = " AND fecha_comprobante BETWEEN '${fecha_desde_trimestre_ant}' AND '${fecha_hasta_trimestre_ant}' ";
        }

        if ($fecha_desde_trimestre != null && $fecha_hasta_trimestre != null) {
            $where_fecha = " AND fecha_comprobante BETWEEN '{$fecha_desde_trimestre}' AND '{$fecha_hasta_trimestre}' ";
        }

        $config_contable = ['0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 5, '5' => 7, '6' => 9, '7' => 11];

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

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

        $acum_ingresos_anterior = 0;
        $acum_ingresos_actual = 0;
        $acum_ingresos_variacion = 0;

        $acum_egresos_anterior = 0;
        $acum_egresos_actual = 0;
        $acum_egresos_variacion = 0;

        $datos = [];
        $datos['attributes'] = $this->attributes;
        $datos['attributes']['fecha_hasta'] = date('d-m-Y', strtotime($fecha_hasta_trimestre));

        $ejercicio = EjerciciosContables::model()->find('activo=1');
        foreach ($cuentas as $cuenta) {
            if ($this->trimestre == 1) {
                //El detalle del trimestre anterior
                $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
                                    AND id_tipo_comprobante=2
                                    {$where_total_cuenta}",
                ]);
            } else {
                //El detalle del trimestre anterior
                $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}
                                    {$where_total_cuenta}
                                    {$where_fecha_ant}",
                ]);
            }

            // El detalle del trimestre actual
            $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_total_cuenta}
                                {$where_fecha}",
            ]);

            //Vamos a  buscar el saldo total sumandolo a la apertura
            $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;
            $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]) == '4' && $cuenta->nivel == 1) {
                $acum_ingresos_anterior += $monto_anterior;
                $acum_ingresos_actual += $monto_actual;
                $acum_ingresos_variacion += $monto_variacion;
            }

            //total de los pasivos
            if (trim($cuenta->cuenta[0]) == '5' && $cuenta->nivel == 1) {
                $acum_egresos_anterior += $monto_anterior;
                $acum_egresos_actual += $monto_actual;
                $acum_egresos_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_anterior, $monto_actual]) == 0) {
                $mostrar = false;
            } else {
                $mostrar = true;
            }

            $total_utilidad_anterior = $acum_ingresos_anterior - $acum_egresos_anterior * -1;
            $total_utilidad_actual = $acum_ingresos_actual - $acum_egresos_actual * -1;
            $total_utilidad_variacion = -$total_utilidad_anterior - $total_utilidad_actual * -1;

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

        $datos['totales'] = [
            'ingresos' => [
                'actual' => $acum_ingresos_actual,
            ],
            'egresos' => [
                'actual' => $acum_egresos_actual,
            ],
            'utilidad' => [
                'actual' => $total_utilidad_actual,
            ],
        ];

        return $datos;
    }
}
