<?php
/**
 * Modelo para la tabla sidcai_apor_alicuota
 */
class SidcaiAporAlicuota extends CActiveRecord
{
    // Definición de estatus
    const ESTATUS_ACTIVO = 1;
    const ESTATUS_RECHAZADO = 2;
    const ESTATUS_INACTIVO = 3;
    const ESTATUS_VERIFICANDO = 4;
     const ESTATUS_DECLARACION = 1001;
	public $alicuota_actual;

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return 'sidcai_apor_alicuota';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        return array(
            array('cod_aportante, alicuota, estatus', 'required'),
            array('apor_tipoempresa', 'required', 'message' => ''),

            array('cod_aportante, analista_id, estatus, apor_tipoempresa', 'numerical', 'integerOnly'=>true),
            array('alicuota', 'numerical'),
            array('estatus', 'in', 'range'=>array(1,2,3,4)),
			// Agrega esta nueva regla de validación
            array('estatus', 'validarUnicidadEstatus', 'on'=>'insert,update'),
            array('comentarios', 'safe'),
            // The following rule is used by search().
            array('cod_apor_alicuota, cod_aportante, alicuota, fecha_registro, analista_id, estatus, fecha_modificacion, comentarios', 'safe', 'on'=>'search'),
            array('apor_tipoempresa', 'numerical', 'integerOnly'=>true),
           
            array('apor_actividad_economica', 'required', 'message' => ''),

            array('apor_actividad_economica', 'validarActividadesEconomicas'),
            array('apor_actividad_economica, otras_actividades', 'length', 'max'=>255),
            array('apor_porcprivada, apor_porcpublico', 'numerical'),
            array('es_fidetel', 'boolean'),
            array('apor_tipoempresa, apor_actividad_economica, apor_porcprivada, apor_porcpublico, es_fidetel, otras_actividades', 'safe'),
            array('apor_tipoempresa, apor_actividad_economica, apor_porcprivada, apor_porcpublico, es_fidetel, otras_actividades', 'safe', 'on'=>'search'),
           // array('apor_porcprivada, apor_porcpublico', 'validarSumaPorcentajes'),
		   array('alicuota_actual', 'validarReduccionAlicuota', 'on'=>'update'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
        return array(
            'aportante' => array(self::BELONGS_TO, 'SidcaiAportante', 'cod_aportante'),
            'analista' => array(self::BELONGS_TO, 'SidcaiUsuario', 'analista_id'),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'cod_apor_alicuota' => 'ID Alicuota',
            'cod_aportante' => 'Aportante',
            'alicuota' => 'Alicuota',
            'fecha_registro' => 'Fecha de Registro',
            'analista_id' => 'Analista',
            'estatus' => 'Estatus',
            'fecha_modificacion' => 'Fecha de Modificación',
            'comentarios' => 'Comentarios',
            'apor_tipoempresa' => 'Tipo de Empresa',
            'apor_actividad_economica' => 'Actividad Económica',
            'apor_porcprivada' => 'Porcentaje Privado',
            'apor_porcpublico' => 'Porcentaje Público',
            'es_fidetel' => '¿Es aportante FIDETEL?',
            'otras_actividades' => 'Otras Actividades',
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     *
     * @return CActiveDataProvider the data provider that can return the models
     * based on the search/filter conditions.
     */
    public function search()
    {
        $criteria=new CDbCriteria;
        $criteria->compare('cod_apor_alicuota',$this->cod_apor_alicuota);
        $criteria->compare('cod_aportante',$this->cod_aportante);
        $criteria->compare('alicuota',$this->alicuota);
        $criteria->compare('fecha_registro',$this->fecha_registro,true);
        $criteria->compare('analista_id',$this->analista_id);
        $criteria->compare('estatus',$this->estatus);
        $criteria->compare('fecha_modificacion',$this->fecha_modificacion,true);
        $criteria->compare('comentarios',$this->comentarios,true);
        $criteria->compare('apor_tipoempresa', $this->apor_tipoempresa);
        $criteria->compare('apor_actividad_economica', $this->apor_actividad_economica, true);
        $criteria->compare('apor_porcprivada', $this->apor_porcprivada);
        $criteria->compare('apor_porcpublico', $this->apor_porcpublico);
        $criteria->compare('es_fidetel', $this->es_fidetel);
        $criteria->compare('otras_actividades', $this->otras_actividades, true);
        return new CActiveDataProvider($this, array(
            'criteria'=>$criteria,
            'sort'=>array(
                'defaultOrder'=>'fecha_registro DESC',
            ),
            'pagination'=>array(
                'pageSize'=>20,
            ),
        ));
    }

    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return SidcaiAporAlicuota the static model class
     */
    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }

    /**
     * Obtiene las opciones de estatus para dropdowns
     * @return array
     */
    public function getOpcionesEstatus()
    {
        return array(
            self::ESTATUS_ACTIVO => 'Activo',
            self::ESTATUS_RECHAZADO => 'Rechazado',
            self::ESTATUS_INACTIVO => 'Inactivo',
            self::ESTATUS_VERIFICANDO => 'Verificando',
        );
    }

    /**
     * Obtiene el texto del estatus
     * @return string
     */
    public function getTextoEstatus()
    {
        $opciones = $this->getOpcionesEstatus();
        return isset($opciones[$this->estatus]) ? $opciones[$this->estatus] : 'Desconocido';
    }

    /**
     * Before save operations
     */
    protected function beforeSave()
    {
        if(parent::beforeSave()) {
            if (in_array($this->apor_tipoempresa, array(1, 2))) {
                $this->alicuota = $this->calcularAlicuota();
            }
            if($this->isNewRecord) {
                // Asignar el usuario actual si no está definido
                if(empty($this->analista_id)) {
                    $this->analista_id = NULL;
                }
            }
            return true;
        }
        return false;
    }

    /**
     * Valida que la suma de porcentajes no exceda 100%
     */
    /*public function validarSumaPorcentajes($attribute, $params)
    {
        if ($this->apor_porcprivada + $this->apor_porcpublico > 100) {
            $this->addError('apor_porcprivada', 'La suma de porcentajes no puede exceder 100%');
            $this->addError('apor_porcpublico', 'La suma de porcentajes no puede exceder 100%');
        }
    }*/

    /**
     * Valida que los IDs de actividades económicas existan
     */
    public function validarActividadesEconomicas($attribute, $params) {
        if(empty($this->$attribute)) {
            return;
        }

        $ids = explode(',', $this->$attribute);
        $existentes = SidcaiActividadEconomica::model()->countByAttributes(array(
            'act_codigo_pk' => $ids
        ));

        if($existentes != count($ids)) {
            $this->addError($attribute, 'Una o más actividades económicas no existen');
        }
    }

    /**
     * Calcula la alícuota basada en el tipo de empresa
     */
    public function calcularAlicuota() {
        switch ($this->apor_tipoempresa) {
            case 1: // Casinos, bingos, etc.
                return 2.0;
                break;

            case 2: // Hidrocarburos y minería
                if ($this->apor_porcpublico >= 50) {
                    return 0.5;
                } else {
                    return 1.0;
                }
                break;

            case 3: // Otras empresas
                return $this->alicuota; // Mantiene el valor ingresado
                break;

            default:
                return 0;
        }
    }

	/**
     * Valida que no exista más de un registro con estatus 1 o 4 para el mismo aportante
     */
    public function validarUnicidadEstatus($attribute, $params)
    {
        // Solo aplica para estatus 1 (ACTIVO) y 4 (VERIFICANDO)
        if (in_array($this->estatus, array(self::ESTATUS_ACTIVO, self::ESTATUS_VERIFICANDO))) {
            $condition = 'cod_aportante = :cod_aportante AND estatus = :estatus';
            $params = array(
                ':cod_aportante' => $this->cod_aportante,
                ':estatus' => $this->estatus
            );
            
            // Si es una actualización, excluir el registro actual
            if (!$this->isNewRecord) {
                $condition .= ' AND cod_apor_alicuota != :id';
                $params[':id'] = $this->cod_apor_alicuota;
            }
            
            $existente = self::model()->count($condition, $params);
            
            if ($existente > 0) {
                $estatusText = ($this->estatus == self::ESTATUS_ACTIVO) ? 'Activo' : 'Verificando';
                $this->addError('estatus', "Ya existe un registro con estatus '$estatusText' para este aportante. Solo puede haber uno.");
            }
        }
    }

	/**
 * Valida que no se reduzca la alícuota sin confirmación
 */
public function validarReduccionAlicuota($attribute, $params)
{
    if (!$this->isNewRecord) {
        $alicuotaActual = self::model()->findByPk($this->cod_apor_alicuota)->alicuota;
        
        if ($this->alicuota < $alicuotaActual && $this->estatus != self::ESTATUS_VERIFICANDO) {
            $this->addError($attribute, 'Para reducir la alícuota debe cambiar el estatus a "Verificando"');
        }
    }
}

public function getAlicuotaActiva($codAportante)
{
    return $this->findByAttributes(array(
        'cod_aportante' => $codAportante,
        'estatus' => self::ESTATUS_ACTIVO
    ));
}

public function verificarAlicuotasDeclaracion($codAportante = null)
{
    Yii::log("Iniciando verificación para aportante: " . ($codAportante ?: 'TODOS'), 'info', 'alicuotas');
    
    $transaction = Yii::app()->db->beginTransaction();
    
    try {
        $condiciones = array('estatus' => 1);
        
        if ($codAportante !== null) {
            $condiciones['cod_aportante'] = $codAportante;
        }

        Yii::log("Buscando alícuota con condiciones: " . print_r($condiciones, true), 'info', 'alicuotas');
        
        $alicuotaActiva = $this->findByAttributes($condiciones);
        
        if (!$alicuotaActiva) {
            $transaction->commit();
            Yii::log("No se encontró alícuota activa", 'warning', 'alicuotas');
            return 0;
        }

        Yii::log("Alícuota encontrada: " . $alicuotaActiva->alicuota . " para aportante: " . $alicuotaActiva->cod_aportante, 'info', 'alicuotas');

      // SQL directo (sin parámetros)
            $sql = "
            UPDATE sidcai_declaracioncti 
            SET decl_alicuota = {$alicuotaActiva->alicuota},
                decl_montorequerido = decl_ingresosbrutos * ({$alicuotaActiva->alicuota} / 100)
            WHERE apor_codigo_fk = {$alicuotaActiva->cod_aportante}
            AND esta_codigo_fk = 1001
            AND (decl_alicuota IS NULL OR decl_alicuota != {$alicuotaActiva->alicuota})
            ";

          //  print_r($sql);die();

            // Ejecutar sin $params
            Yii::log("Ejecutando SQL directo: " . $sql, 'info', 'alicuotas');

            $actualizados = Yii::app()->db->createCommand($sql)->execute();


        $transaction->commit();
        
        Yii::log("Actualizados: $actualizados registros", 'info', 'alicuotas');
        
        return $actualizados;

    } catch (Exception $e) {
        $transaction->rollBack();
        Yii::log("Error: " . $e->getMessage(), 'error', 'alicuotas');
        throw $e;
    }
}

/**
 * Método público para usar desde otros lados
 */
public function verificarAlicuotasPorAportante($codAportante)
{
    return $this->verificarAlicuotasDeclaracion($codAportante);
}


// En SidcaiAporAlicuota.php
public function verificarAlicuotasTodos()
{
    $aportantes = SidcaiAportante::model()->findAll();

    $totalActualizados = 0;

    foreach ($aportantes as $aportante) {
        try {
            $resultado = $this->verificarAlicuotasPorAportante($aportante->apor_codigo_pk);
            Yii::log("Aportante {$aportante->apor_codigo_pk}: $resultado registros actualizados", 'info', 'alicuotas');
            $totalActualizados += $resultado;
        } catch (Exception $e) {
            Yii::log("Error con aportante {$aportante->apor_codigo_pk}: " . $e->getMessage(), 'error', 'alicuotas');
        }
    }

    return $totalActualizados;
}



}
