<?php

include ROOT . '/class/Paginacion/Paginacion.php';
include ROOT . '/class/Paginacion/Tradicional.php';

class EntityRepository {
    
    private $id;
    private $lastInsertId = null;
    
    protected $_options = array();

    public function setId($id) {
        $this->id = $id;
    }

    public function getId() {
        return $this->id;
    }
    
    public function delete($id,$table){
        $select = "DELETE  FROM $table WHERE id = $id";
        $result = $this->query($select);
        
        if($result){
            return true;
        }        
        return null;
    }

    public function save(array $data, $table) {
        $select = "INSERT INTO $table";
        $fields = "";
        $values = "";
        foreach ($data as $key => $value) {           
            if(!is_array($value)){
                $fields .= "$key,";
                $value = mysqli_real_escape_string(DataBase::getInstance(),$value);
                
                if($value == '_NULL' || is_null($value) || trim($value)==''){
                    $values .= "NULL,";
                }else{
                    $values .= "'$value',";
                }
            }else{         
                $fields .= "{$value['key']},";
                $value['value'] = mysqli_real_escape_string(DataBase::getInstance(),$value['value']);
                
                if($value['value'] == '_NULL' || is_null($value['value']) || trim($value['value'])==''){
                    $values .= "NULL,";
                }else{
                    $values .= "'{$value['value']}',";
                }
            }            
            
        }
        $fields = substr($fields, 0, strlen($fields) - 1);
        $values = substr($values, 0, strlen($values) - 1);

        $select = $select . "(" . $fields . ") VALUES (" . $values . ")";
               
        return $this->query($select);        
    }
    
    public function getInsertId(){
        return DataBase::getInsertId();
    }
    
    public function setLastInsertId($id){
        $this->lastInsertId = $id;
    }
    
    public function getLastInsertId(){
        return $this->lastInsertId;
    }

    public function update($id, $fields, $table) {
        //var_dump($fields);
        $select = "UPDATE $table SET ";
        foreach ($fields as $key => $value) {
            if(!is_array($value)){
                $value = mysqli_real_escape_string(DataBase::getInstance(),$value);
                if($value == '_NULL' || is_null($value) || trim($value)==''){
                    $select .= "$key = NULL,";
                }else{
                    $select .= "$key = '$value',";
                }  
            
            }else{                
                $value['value'] = mysqli_real_escape_string(DataBase::getInstance(),$value['value']);
                if($value['value'] == '_NULL' || is_null($value['value']) || trim($value['value'])==''){
                    $select .= "$key = NULL,";
                }else{
                    $select .= "$key = '{$value['value']}',";
                }              
            }            
        }

        $select = substr($select, 0, strlen($select) - 1);
        $select .= " WHERE id = $id";
        //echo $select;exit;
        return  $this->query($select);
    }
    
    public function updateString($fields,$where,$table) {
        $select = "UPDATE $table SET ";
        foreach ($fields as $key => $value) {
            $select .= "$key = '$value',";
        }

        $select = substr($select, 0, strlen($select) - 1);
        $select .= " WHERE ".$where;
        //echo $select;
        return  $this->query($select);
    }

    public function getById($id, $table,$selectAux = null) {
        $select = "SELECT * ";
        if($selectAux){$select .= ",$selectAux";}
        
        $select = "$select FROM $table WHERE id = '$id'";
        $result = $this->query($select);

        if ($result->num_rows>0) {
            $set = $this->resultToArray($result);
            return $set[0];
        }

        return null;
    }
    
    public function isUsedInRecord($id,array $buscarEn, $andWhere = null){
        foreach($buscarEn as $key => $value){
            $select = "SELECT id FROM $key WHERE $value = '$id' $andWhere limit 1";
            $result = $this->query($select);
            if($result->num_rows > 0){
                $result = $result->fetch_object();
                return array('id'=>$result->id,'table'=>$key);
            }
        }
        
        return null;
    }
    
    public function query($query){ 
        $result = DataBase::getInstance()->execute($query);
        return $result;
    }
    
    public function resultToArray($result){
        for ($set = array(); $row = $result->fetch_assoc(); $set[] = $row);
  
        return $set;
    }
    
    public function startTransaction(){
        return $this->query('START TRANSACTION');
    }
    
    public function commit(){
        return $this->query('COMMIT');
    }
    
    public function rollback(){
        return $this->query('ROLLBACK');
    }
    
    public function setBackButton($controller){
        $url = "/Controller/$controller.php?".$this->getQueryVarsFromGET();
        $_SESSION['back_button'] = "<a href='$url' class='btn btn-default btn-sm' style='float:left;margin-right: 10px'><span class='fa fa-arrow-circle-left'></span> Back</a>";
    }
    
    public function getBackButton(){
        return $_SESSION['back_button'];
    }
    
    public function getQueryVarsFromGET($noReturn = array()){
        $queryVars='';
        foreach ($_GET as $clave => $valor){
          if(!in_array($clave,$noReturn)){
          $queryVars .= $clave . "=" . $valor . "&amp;";
        }
      }
        return $queryVars;
    } 
    
    /*******************************************/
    /*********** IMPORT FROM EXCEL *************/
    /*******************************************/
    
    public function import(Importable $data) { 
        try {
            if (!$data->isUploaded()) {
                $data->upload();
            }
            $data->setEntity($this);
            if (!$data->save($this)) {
                throw new Exception($data->getFeedbackMsg());
            }
            return true;
        } catch (Exception $exc) {
            $this->flashmessenger->addMessage(array(
                'danger' => $exc->getMessage(),
            ));
            return false;
        }            
    }
    
    public function insert($data) {
        try {
//            TODO: Need to talk with Carlos to move this code to another place, looks like it is tied to a specific entity type;
//            $dataTemp = $data[0];
//            $query = "DELETE FROM {$this->getTableName()} WHERE YEAR = {$dataTemp['YEAR']} AND MONTH  = {$dataTemp['MONTH']}";
//            $this->query($query);

            foreach ($data as $row) {
                if (!is_array($row)) {
                    $this->save($data,$this->getTableName());
                    break;
                }
               $this->save($row,$this->getTableName());
            }
            return true;
        } catch(Exception $exc) {
            throw new Exception("There was a problem trying to import the data: <strong>{$exc->getMessage()}</strong>");
        } catch (Exception $exc) {
            throw $exc;
        }
    }

    protected function camelize($option) {
        return 'set' . str_replace(' ', null, ucwords(str_replace('_', ' ', strtolower($option))));
    }

    public function setOptionsAssoc($optionsAssoc) {
        foreach($optionsAssoc as $key => $value) {
            $this->setOption($key, $value);
        }
    }

    public function setOptions($options) {
        for ($i = 0, $keys = array_keys($this->_options), $size = count($this->_options);
             $i < $size;
             $this->setOption($keys[$i], $options[$i]));
    }

    public function setOption($option, $value) {
        $camelized = $this->camelize($option);
        if (method_exists($this, $this->camelize($option))) {
            $this->$camelized($value);

            return $this;
        }

        if (key_exists($option, $this->_options)) {
            $this->_options[$option] = $value;
        }

        return $this;
    }

    public function __set($name, $value) {
        $this->setOption($name, $value);
    }
    
    public function __get($name) {
        if (isset($this->_options[$name])) {
            return $this->_options[$name];
        }

        return null;
    }
}