<?php

defined('BASEPATH') OR exit('No direct script access allowed');

class Sincronizacion extends MX_Controller
{
    
    public $path_js;
    protected $_permisos;
    
    public function __construct()
    {
        parent::__construct();
        if ($this->session->userdata('COD_TIPOPERFIL') !== 1 && $this->session->userdata('COD_TIPOPERFIL') !== 2) {
            echo "<h3>No tiene permisos para acceder a esta sección.</h3>";
            exit;
        }
        $this->load->model(['Sincronizacion_model', 'Sincronizacion_model_log', 'candidatos/Candidato', 'log_ingresos/Log_ingreso', 'participantes/Participante']);
        $this->path_js = 'sincronizacion/scripts_dev.js';
        $this->_permisos = $this->session->userdata('permisos'); 
    }
    
    public function index()
    {
        $data_view['titulo']  = 'Sincronización Remota de votaciones';
        $data_view['permisos']  = $this->_permisos;
        $data_view['load_js'] = $this->path_js;
        $this->load->view('index', $data_view);
    }
    
    public function generar()
    {
        $this->load->library('encryption');
        $this->load->library('excel');
        $nombre_archivo = 'archivo_sincronizacion_'.date('Y-m-d-H:i:s').'_'.time().'.csv';  
        $registros = $this->Sincronizacion_model->consultar_registros();
        
        $verifica_generacion = $this->Sincronizacion_model->consulta_generacion();
        $texto_generacion = 'No se ha generado un archivo previamente.';
        
        if($verifica_generacion){
            $texto_generacion = "La última genereración se realizó el ".$verifica_generacion->FEC_GENARCHIV.' por el usuario '.$verifica_generacion->TEX_USUARIO.'. Con un total 
            de '.$verifica_generacion->NUM_REGIST.' registros.';
        }
        
        if(!sizeof($registros)){
            $this->session->set_flashdata('error', 'No hay registros de votación. '.$texto_generacion );
            redirect('sincronizacion');
        }
        
        $total_registros = count($registros);
        $data_generacion = [
            'NUM_REGIST' => $total_registros,
            'FEC_GENARCHIV' => date('Y-m-d H:i:s'),
            'COD_SINUSU' => $this->session->userdata('COD_USUARIO'),
            
        ];
        $this->Sincronizacion_model->insert_generacion($data_generacion);
        
        $objPHPExcel = new PHPExcel();
        
        $this->encryption->initialize(
            array(
                'cipher' => 'aes-256',
                'mode'   => 'cbc',
                'key'    => $this->config->item('encryption_key')
                )
            );
            $i=1; //starting from row 2 bcz row 1 set to header
            foreach($registros as $data) {
                //Cédula
                $objPHPExcel->getActiveSheet()->setCellValue('A'.$i, $this->encryption->encrypt($data->NUM_IDETER));
                //Inicio de sesion
                $objPHPExcel->getActiveSheet()->setCellValue('B'.$i, $this->encryption->encrypt($data->BOL_INISES));
                 //Agencia participante
                $objPHPExcel->getActiveSheet()->setCellValue('C'.$i, $this->encryption->encrypt($data->COD_AGENCIA));
                //Id Candidato
                $objPHPExcel->getActiveSheet()->setCellValue('D'.$i, $this->encryption->encrypt($data->ID_CANDID));
                //Instancia
                $objPHPExcel->getActiveSheet()->setCellValue('E'.$i, $this->encryption->encrypt($data->ID_INSTAN));
                //Fecha voto
                $objPHPExcel->getActiveSheet()->setCellValue('F'.$i, $this->encryption->encrypt($data->FEC_PROVOT));
                //IP origen
                $objPHPExcel->getActiveSheet()->setCellValue('G'.$i, $this->encryption->encrypt($data->TEX_IPORIG));
                $i++;
            }
            // Redirect output to a client’s web browser (Excel5)
            header('Content-type: text/csv');
            header('Content-Disposition: attachment;filename="'.$nombre_archivo.'"');
            header('Cache-Control: max-age=0');
            
            $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'CSV');
            
            $objWriter->save('php://output');
            exit;  
        }
        
        public function cargar()
        { 
            
            if (!$this->input->post()) {
                $data_view['titulo'] = 'Cargar archivo para pre sincronizar';
                $data_view['load_js'] = $this->path_js;
                $this->load->view('cargar', $data_view);
                return false;
            }
            
        }
        /**
        * Descifrado de campos en el CSV.
        */
        public function descifrado()
        {
            $this->load->library('encryption');
            $this->encryption->initialize(
                array(
                    'cipher' => 'aes-256',
                    'mode'   => 'cbc',
                    'key'    => $this->config->item('encryption_key')
                    )
                );
            }
            /**
            * [Proceso para registrar los votos que se importan]
            * @return [type] [description]
            */
            public function ejecutar()
            {
                $csv = $_FILES['archivo']['tmp_name'];
                
                if(!$csv){
                    $this->session->set_flashdata('error', 'No ha seleccionado un Archivo o Archivo invalido, verifique e intente de nuevo');
                    redirect("sincronizacion/cargar");  
                }
                
                if(!empty($csv)){   
                    $this->descifrado();
                    $handle = fopen($csv,"r");
                    $votos_registrados = 0;
                    $votos_no_registrados = 0;
                    $votos_totales = 0;
                    $arr_log = [];
                    
                    // Inicio de la transaccion.
                    $this->db->trans_start();
                    while (($row = fgetcsv($handle, 10000, ",")) != FALSE) 
                    {
                        if (count($row) < 7) {
                            $this->session->set_flashdata('error', 'Archivo invalido, verifique e intente de nuevo');
                            redirect("sincronizacion/cargar");  
                            exit;
                        }

                        $votos_totales++;
                        $num_ideter = $this->encryption->decrypt($row[0]);
                        $ini_session = $this->encryption->decrypt($row[1]);
                        $cod_agencia = $this->encryption->decrypt($row[2]);
                        $id_candidato = $this->encryption->decrypt($row[3]);
                        $instancia = $this->encryption->decrypt($row[4]);
                        $fecha_voto = $this->encryption->decrypt($row[5]);
                        $ip_origen = $this->encryption->decrypt($row[6]);
                        
                        $arr_save = [
                            'ID_INSTAN'  => $instancia,
                            'ID_CANDID'  => $id_candidato,
                            'NUM_IDETER' => $num_ideter,
                            'COD_AGENCIA' => $cod_agencia,
                            'FEC_PROVOT' => $fecha_voto,
                            'TEX_IPORIG' => $ip_origen
                        ];
                        
                        $arr_log[] = $arr_save;
                        
                    } // End while
                    
                    //Se guarda la sincronizacion
                    $insert_sincro = $this->Sincronizacion_model->insert([
                        'STATUS' => 0,
                        'FEC_EJECUTA' =>  date('Y-m-d H:i:s'),
                        'COD_AGENCIA' =>  $this->session->userdata('COD_AGENCIA'),
                        'COD_EJEUSU' =>   $this->session->userdata('COD_USUARIO'),
                        'TEX_EJENOTA' =>  $this->input->ip_address()
                        ]);
                        // Se guarda el log de sincronizacion
                        if(is_int($insert_sincro)){
                            foreach ($arr_log as $key => $log) {
                                $this->Sincronizacion_model->insert_log(
                                    [
                                        'COD_PROCESO'  => $insert_sincro,
                                        'ID_INSTAN'  => $log['ID_INSTAN'],
                                        'ID_CANDID'  => $log['ID_CANDID'],
                                        'NUM_IDETER' => $log['NUM_IDETER'],
                                        'COD_AGENCIA' => $log['COD_AGENCIA'],
                                        'FEC_PROVOT' => $log['FEC_PROVOT'],
                                        'TEX_IPORIG' => $log['TEX_IPORIG'],
                                        'FEC_CREACION' => date('Y-m-d H:i:s')
                                        ]
                                    );
                                }
                            }
                            $this->db->trans_complete();
                            if ($this->db->trans_status() === FALSE) {
                                echo 'Error en la transaccion';
                                return false;
                            }
                            $this->session->set_flashdata('success', 'El archivo fue carga exitosamente, este es el detalle de votos a sincronizar');
                            $data_view['titulo'] = 'Cargar archivo para pre sincronizar';
                            $data_view['cod_proceso'] = $insert_sincro;
                            $data_view['total_registros'] = $votos_totales;
                            $data_view['total_registrados'] = $votos_registrados;
                            $data_view['total_no_registrados'] = $votos_no_registrados;
                            $data_view['arr_log'] = $arr_log;
                            $data_view['load_js'] = $this->path_js;
                            
                            $this->load->view('cargar', $data_view);
                            
                            //echo 'Votos totales: '.$votos_totales.'<br>';
                            //echo 'Votos registrados: '.$votos_registrados.'<br>';
                            //echo 'Votos no registrados: '.$votos_no_registrados.'<br>';
                        }
                    }
                    
                    /**
                    * Proceso de sincronizacion de votos
                    * @return [type] [description]
                    */
                    public function sincronizar($cod_proceso)
                    {
                        
                        if(!$cod_proceso){
                            $this->session->set_flashdata('error', 'El codigo del proceso es requerido');
                            redirect('sincronizacion');
                        }
                        
                        $registros = $this->Sincronizacion_model->get_registros_sincronizacion($cod_proceso);
                        
                        $votos_registrados = 0; 
                        $votos_no_registrados = 0; 
                        $this->db->trans_start();
                        foreach ($registros as $key => $registro) {
                            $instancia = $registro->ID_INSTAN;
                            $id_candidato = $registro->ID_CANDID;
                            $num_ideter = $registro->NUM_IDETER;
                            $fecha_voto = $registro->FEC_PROVOT;
                            $ip_origen = $registro->TEX_IPORIG;
                            
                            $validacion_voto = $this->_valida_voto($instancia, $id_candidato, $num_ideter);
                            
                            $arr_save = [
                                'ID_INSTAN'  => $instancia,
                                'ID_CANDID'  => $id_candidato,
                                'NUM_IDETER' => $num_ideter,
                                'FEC_PROVOT' => $fecha_voto,
                                'TEX_IPORIG' => $ip_origen
                            ];
                            // Si no esta registrada la votacion
                            if(!$validacion_voto){
                                $votos_registrados++;
                                //Inserción de log y suma de voto al candidato.
                                $this->Candidato->insert_log_voto($arr_save, $id_candidato);
                                $this->Log_ingreso->insert([
                                    'NUM_IDETER' => $num_ideter, 
                                    'FEC_INISES' => $fecha_voto, 
                                    'FEC_FINSES' => $fecha_voto, 
                                    'BOL_USADO' => 1,
                                    'TEX_IPORIG' => $ip_origen, 
                                    'FEC_CREACION' => date('Y-m-d H:i:s'), 
                                    ]);  
                                    //Inicio de sesion registro
                                    $this->Participante->edit($num_ideter, ['BOL_INISES' => 1]);
                                    
                                    $arr_save['BOL_REGIS'] = 1;
                                    $this->Sincronizacion_model_log->edit($registro->COD_LOGPROCESO, ['BOL_REGIS' => 1]);
                                    $arr_log[] = $arr_save; 
                                } else {
                                    $votos_no_registrados++;
                                    $arr_save['BOL_REGIS'] = 0;
                                    $arr_log[] = $arr_save; 
                                }// End validacion voto
                            }
                            $this->Sincronizacion_model->edit($cod_proceso, ['STATUS'=> 1]);
                            $this->db->trans_complete();
                            if ($this->db->trans_status() === FALSE) {
                                echo 'Error en la transaccion. no se pudo realizar la sincronización';
                                return false;
                            }
                            $this->session->set_flashdata('success', 'La sincronización se realizó con éxito. Este es el detalle del proceso');
                            $data_view['titulo'] = 'Resultados sincronización';
                            $data_view['cod_proceso'] = $cod_proceso;
                            $data_view['total_registros'] = count($registros);
                            $data_view['total_registrados'] = $votos_registrados;
                            $data_view['total_no_registrados'] = $votos_no_registrados;
                            $data_view['arr_log'] = $arr_log;
                            $data_view['load_js'] = $this->path_js;
                            
                            $this->load->view('resultados_sincronizacion', $data_view);
                            
                            
                        }
                        
                        /**
                        * Valida que no se haya hecho una votación previa.
                        * 
                        * @param type $instancia
                        * @param type $candidato
                        * @param type $participante
                        * @return boolean
                        */
                        private function _valida_voto($instancia, $candidato, $participante)
                        {
                            $consulta = $this->Participante->get_exits_voto($instancia, $participante, $candidato);
                            if ($consulta) {
                                return true;
                            }
                            else {
                                return false;
                            }
                        }
                        
                        public function historico()
                        {
                            $data_view['titulo'] = 'Histórico de sincronizaciones';
                            $data_view['load_js'] = $this->path_js;
                            $this->load->view('historico', $data_view);   
                        }
                        
                        /**
                        * Lista asociados desde Datatables.
                        */
                        public function get_historico()
                        {
                            $list = $this->Sincronizacion_model->get_datatables();
                            $data = array();
                            $no   = $this->input->post('start ');
                            
                            foreach ($list as $datos) {
                                $no++;
                                $row    = array();
                                $total_no_registrados = $datos->total_registros- $datos->total_registrados;
                                
                                $detalle = "<a href='sincronizacion/log/$datos->COD_PROCESO' class='btn btn-success'>Ver log</a>";
                                
                                $row[]  = $datos->COD_PROCESO;
                                $row[]  = ($datos->STATUS)?'Sincronizado':'No sincronizado por el usuario';
                                $row[]  = $datos->FEC_EJECUTA;
                                $row[]  = $datos->total_registros;
                                $row[]  = $datos->total_registrados;
                                $row[]  = $total_no_registrados;
                                $row[]  = $datos->agencia;
                                $row[]  = $datos->usuario;
                                $row[]  = $datos->TEX_EJENOTA;
                                $row[]  = "$detalle";
                                $data[] = $row;
                            }
                            $output = array(
                                "draw"            => $this->input->post('draw'),
                                "recordsTotal"    => $this->Sincronizacion_model->count_all(),
                                "recordsFiltered" => $this->Sincronizacion_model->count_filtered(),
                                "data"            => $data,
                            );
                            echo json_encode($output);
                        }  
                        
                        public function log($cod_proceso=null)
                        {
                            if($cod_proceso){
                                $data_view['titulo'] = 'Log registros de votación proceso '.$cod_proceso;
                                $data_view['load_js'] = $this->path_js;
                                $data_view['cod_proceso'] = $cod_proceso;
                                $this->load->view('log', $data_view); 
                            }
                        }
                        
                        public function get_log($cod_proceso)
                        {
                            $list = $this->Sincronizacion_model_log->get_datatables($cod_proceso);
                            $data = array();
                            $no   = $this->input->post('start ');
                            foreach ($list as $datos) {
                                $no++;
                                $row    = array();
                                $row[]  = $datos->ID_INSTAN;
                                $row[]  = $datos->ID_CANDID;
                                $row[]  = $datos->NUM_IDETER;
                                $row[]  = $datos->nombre_participante;
                                $row[]  = $datos->agencia;
                                $row[]  = $datos->FEC_PROVOT;
                                $row[]  = $datos->TEX_IPORIG;
                                $row[]  = ($datos->BOL_REGIS)?'<b class="text-success">Registrado</b>':'<b class="text-danger">No registrado, el participante ya ha votado en agencia principal</b>';
                                $data[] = $row;
                            }
                            $output = array(
                                "draw"            => $this->input->post('draw'),
                                "recordsTotal"    => $this->Sincronizacion_model_log->count_all(),
                                "recordsFiltered" => $this->Sincronizacion_model_log->count_filtered(),
                                "data"            => $data,
                            );
                            echo json_encode($output);     
                        } 
                    }
                    
                    
                    
