<?php

namespace ProxiumWXfrm\Proxium;

use ProxiumWXfrm\Http\Response;
use ProxiumWXfrm\Proxium\PeticionWS;

function limpiaSaltos($cadena){
    return str_replace('\r\n','',$cadena);
    //return $cadena;
}

class Error {

    public string $respuesta;

    public function __construct($clave,$error){
        $respuesta=array(
            'valor'=>0,
            'data'=>'',
            'errores'=>array('clave'=>$clave,'valor'=>$error)
        );
        $this->respuesta=json_encode($respuesta);
    }

}

class RespuestaStandard {

    public $valor=0;
    public $data='';
    public $errores=array();

    public function setValor(int $valor):self {
        $this->valor=$valor;
        return $this;
    }

    public function setData($data):self {
        $this->data=$data;
        $this->errores=''; //forzamos un cambio de tipo, para que no devuelva un array vacio
        return $this;
    }

    public function setErrores($errores):self {
        //$temp=array();
        //$this->data=json_encode($temp); //forzamos un cambio de tipo, para que no devuelva un string vacio
        $this->errores[]=$errores;
        return $this;
    }

    
    public static function error($clave,$error):self {
        return (new self)
        ->setValor(0)
        ->setErrores(array('clave'=>$clave,'valor'=>$error));
    }

    public static function data($data):self {
        return (new self)
        ->setValor(1)
        ->setData($data);
    }

    public function getRespuesta(){
        return json_encode($this);
    }

}

class Login {

    protected string $dispositivo_id;
    protected string $empresa;
    protected string $usuario;
    protected string $clave;
    protected string $matricula;
    protected string $tokenLogin;

    public function __construct($dispositivo_id,$empresa,$usuario,$clave,$matricula,$tokenLogin){

        $this->dispositivo_id=$dispositivo_id;
        $this->empresa=$empresa;
        $this->usuario=$usuario;
        $this->clave=$clave;
        $this->matricula=$matricula;
        $this->tokenLogin=$tokenLogin;
        
    }
        
    
    public function login(){

        $urlLlamada='/login';
        
        $parametrosLlamada=json_encode(
            array(
                'id'=>$this->dispositivo_id,
                'empresa'=>$this->empresa,
                'usuario'=>$this->usuario,
                'clave'=>$this->clave,
                'matricula'=>$this->matricula
            )
        );
        
        $peticion=new PeticionWS($urlLlamada,$parametrosLlamada);

        //print_r($peticion);
        
        $resultadoLogin=$peticion->lanzaPostRaw(false);

        return $resultadoLogin;

    }

    public function refreshTokenLogin(){

        $urlLlamada='/refreshTokenLogin';
        
        $parametrosLlamada=json_encode(
            array(
                'id'=>$this->dispositivo_id,
                'empresa'=>$this->empresa,
                'usuario'=>$this->usuario,
                'matricula'=>$this->matricula,
                'tokenLogin'=>$this->tokenLogin
            )
        );
        
        $peticion=new PeticionWS($urlLlamada,$parametrosLlamada);

        //print_r($peticion);
        
        $resultadoLogout=$peticion->lanzaPostRaw(false);

        return $resultadoLogout;

    }

    public function logout(){

        $urlLlamada='/logout';
        
        $parametrosLlamada=json_encode(
            array(
                'id'=>$this->dispositivo_id,
                'empresa'=>$this->empresa,
                'usuario'=>$this->usuario,
                'matricula'=>$this->matricula,
                'tokenLogin'=>$this->tokenLogin
            )
        );
        
        $peticion=new PeticionWS($urlLlamada,$parametrosLlamada);

        //print_r($peticion);
        
        $resultadoLogout=$peticion->lanzaPostRaw(false);

        return $resultadoLogout;

    }
}

class versionApp {

    public string $fechaHora;
    public string $nombre;
    protected string $archivo;
    public string $archivoBase64;
    public array $archivoPost;

    public function __construct(){

        
        global $conexionBdd;

        $this->fechaHora='';
        $this->nombre='';
        $this->archivo='';
        $this->archivoBase64='';

        $consulta='SELECT * FROM proxiumapi_version ORDER BY FechaHora DESC LIMIT 1';
        
        try {

            $temp=$conexionBdd->query($consulta);
            
            if($temp->rowCount()>0) {

                $resultado=$temp->fetch();
            
                $this->fechaHora=$resultado['FechaHora'];
                $this->nombre=$resultado['Nombre'];
                $this->archivo=$resultado['Archivo'];
            }

        } catch (PDOException $e) {
                
            echo 'error';
        }
            

    }

    public function nuevaVersion(){

        global $conexionBdd;

        $nombreArchivo=bin2hex(random_bytes(16));

        $this->archivo='..'.$configProxy['dir_data'].'/'.$nombreArchivo;

        /*
        $archivo = fopen($this->archivo,'wb');
        fwrite($archivo,base64_decode($this->archivoBase64));
        fclose($archivo);
        */

        
        $temporal=$this->archivoPost['tmp_name'];
        $nombre=$this->archivoPost['name'];

        if(move_uploaded_file($temporal,$this->archivo)) $subidaOk=true;
        else $subidaOk=false;

        if($subidaOk) {

            ///////////// AQUI CONTROLAR QUE NO EXISTA OTRA VERSION CON EL MISMO NOMBRE (ES EL ID)
            
            $consulta='SELECT * FROM proxiumapi_version WHERE Nombre=?';
            $parametros=array($this->nombre);

            try {

                $temp=$conexionBdd->prepare($consulta);
                $temp->execute($parametros);

                if($temp->rowCount()==0) {

                    $consulta='INSERT INTO proxiumapi_version (FechaHora,Nombre,Archivo) VALUES (now(),?,?)';
                    $parametros=array($this->nombre,$this->archivo);

                    try {

                        $temp=$conexionBdd->prepare($consulta);
                        $temp->execute($parametros);

                        $resultadoJson=array('nuevaVersionSubida'=>$this->nombre);
                        $response=Response::text(RespuestaStandard::data($resultadoJson)->getRespuesta());

                    } catch (PDOException $e) {
                        unlink($this->archivo);
                        $response=Response::text(RespuestaStandard::error(200,"Error al insertar registro en BDD.")->getRespuesta());
                    }

                }
                else {
                    unlink($this->archivo);
                    $response=Response::text(RespuestaStandard::error(201,"Error: Ya existe una versión con ese nombre.")->getRespuesta());
                }

            } catch (PDOException $e) {
                unlink($this->archivo);
                $response=Response::text(RespuestaStandard::error(202,"Error en peticion contra la BDD.")->getRespuesta());
            }

        }
        else $response=Response::text(RespuestaStandard::error(203,"Error: No ha podido subirse el archivo.")->getRespuesta());

        return $response;
            
    }
    

}

class versionAppDownload {

    protected string $dispositivo_id;
    protected string $dispositivo_ip;
    protected string $idInstalacionDispositivo;
    public string $version;
    public string $nombreArchivo;
    public string $url;
    public string $duracion;

    public function __construct(){

        $this->dispositivo_id='';
        $this->dispositivo_ip='';
        $this->idInstalacionDispositivo='';
        $this->version='';
        $this->nombreArchivo='';
        $this->url='';
        $this->duracion='';
       
    }

    public function creaEnlace($dispositivo_id,$dispositivo_ip,$version,$idInstalacionDispositivo){

        
        global $rutaPublicacion;
        global $configProxy;

        global $conexionBdd;

        
        if($dispositivo_id) $this->dispositivo_id=$dispositivo_id;
        if($dispositivo_ip) $this->dispositivo_ip=$dispositivo_ip;
        if($idInstalacionDispositivo) $this->idInstalacionDispositivo=$idInstalacionDispositivo;

        $this->version=$version->nombre;
        $this->duracion=$configProxy['duracionDescargaVersion'];
        
        //$this->nombreArchivo=bin2hex(random_bytes(8)).'.apk';
        $this->nombreArchivo=bin2hex(random_bytes(8));
        $this->url=$rutaPublicacion.'/descarga?archivo='.$this->nombreArchivo;

        
        $consulta='INSERT INTO proxiumapi_version_downloads (Dispositivo_id,Dispositivo_ip,IdInstalacionDispositivo,Version,NombreArchivo,Url,Cuando,Duracion) VALUES (?,?,?,?,?,?,now(),?)';
        $parametros=array($this->dispositivo_id,$this->dispositivo_ip,$this->idInstalacionDispositivo,$this->version,$this->nombreArchivo,$this->url,$this->duracion);

        try {

            $temp=$conexionBdd->prepare($consulta);
            $temp->execute($parametros);

        } catch (PDOException $e) {
                
            echo 'Error';
        }
           
        
        
    }

    public function descarga(){

    }

}

class Registro {

    protected string $dispositivo_id;
    protected string $empresa;
    protected string $api_key;
    protected string $token; //token de instalacion
    protected string $instalacion; //id de instalacion, llega en el correo


    public function __construct($dispositivo_id,$empresa,$api_key,$token,$instalacion){

        $this->dispositivo_id=$dispositivo_id;
        $this->empresa=$empresa;
        $this->api_key=$api_key;
        $this->token=$token;
        $this->instalacion=$instalacion;
        
    }
    

    public function getToken() {

        /*
        Peticion a caché para validación de intento de instalación y devuelve token para registro final
        Se le pasará:
        -   $this->dispositivo_id;
        -   $this->empresa;
        -   $this->token_instalacion;
        Devolverá un nuevo token para solicitar finalmente el registro.
        */

        $this->token='aaaabbbcccddd';

        return true;

    } 

    public function solicitarRegistro(){

        
        $urlLlamada='/registerDevice';
        $parametrosLlamada=json_encode(
            array(
                'id'=>$this->dispositivo_id,
                'empresa'=>$this->empresa,
                'apiKey'=>$this->api_key,
                'tokenInstalacion'=>$this->token,
                'instalacion'=>$this->instalacion
            )
        );
        
        $peticion=new PeticionWS($urlLlamada,$parametrosLlamada);
        
        

        $resultado=$peticion->lanzaPostRaw(false);
        $resultado=limpiaSaltos($resultado);

        //print_r($resultado);

        //$resultado=json_decode($resultado);
        //print_r($resultado);
        //echo $resultado->empresa;
        /*
        try {
            echo '---'.$resultado.'---';;
        }
        catch(exception $e) {
            echo $e;
        }
        finally{
            echo 'kk';
        }
        */
        //$resultado='{"Logo":"asdfasdfas"}';
        /*
        $buscar='"Logo":"';
        $posicion=strpos($resultado,$buscar);
        $temp2=substr($resultado,$posicion+strlen($buscar),1024-2);
        echo $temp2;
        */
        
        //$response=Response::text($resultado);
        ///return $response;

        return $resultado;

    }
    

}

class Integracion {

    public string $tipoWeb;
    public string $tipoProceso;
    public string $empresa;
    public string $cliente;
    public string $usuario;

    public string $UUID;
    public string $id;
    public string $idProceso;
    public string $cuando;
    public string $estado;
    public string $datos;

    public function __construct($tipoWeb,$tipoProceso,$empresa,$cliente,$usuario,$UUID='',$id='',$idProceso=''){

        $this->tipoWeb=$tipoWeb;
        $this->tipoProceso=$tipoProceso;
        $this->empresa=$empresa;
        $this->cliente=$cliente;
        $this->usuario=$usuario;

        $this->UUID=$UUID;
        $this->id=$id;
        $this->idProceso=$idProceso;

        global $conexionBdd;
        
        $consulta ='CREATE TABLE IF NOT EXISTS integracion_status (
            idIntegracion INTEGER PRIMARY KEY AUTOINCREMENT,
            UUID VARCHAR(255),
            id VARCHAR(255),
            idProceso VARCHAR(255),
            cuando DATETIME,
            estado VARCHAR(255),
            datos TEXT,
            tipoWeb VARCHAR(100),
            tipoProceso VARCHAR(100),
            empresa VARCHAR(50),
            cliente INTEGER,
            usuario VARCHAR(255)
          )';
        
        try {
            $conexionBdd->query($consulta);
        } catch (PDOException $e) {
            echo $e->getMessage();
        }

        $consulta ='CREATE INDEX IF NOT EXISTS indice ON integracion_status (UUID,id,idProceso)';
        
        try {
            $conexionBdd->query($consulta);
        } catch (PDOException $e) {
            echo $e->getMessage();
        }

    }

    public function registra($UUID,$id,$idProceso,$estado,$datos=''){

        $this->UUID=$UUID;
        $this->id=$id;
        $this->idProceso=$idProceso;
        $this->estado=$estado;
        $this->datos=$datos;

        //grabaLog($this);

        global $conexionBdd;
        
        $consulta ='INSERT INTO integracion_status (tipoWeb,tipoProceso,empresa,cliente,usuario,UUID,id,idProceso,cuando,estado,datos) VALUES (?,?,?,?,?,?,?,?,?,?,?)';
        $parametros=array( $this->tipoWeb, $this->tipoProceso, $this->empresa, $this->cliente, $this->usuario, $this->UUID, $this->id, $this->idProceso, date('Y-m-d h:i:s'), $this->estado, $this->datos);
        
        if($this->estado=='CREACION') {
            grabaLog($consulta);
            grabaLog($parametros);
        }
        

        try {
            
            $temp=$conexionBdd->prepare($consulta);
            $temp->execute($parametros);

            $response=Response::text(RespuestaStandard::data('Ok')->getRespuesta());

            if($this->estado=='CREACION') grabaLog('ok');

        } catch (PDOException $e) {

            $response=Response::text(RespuestaStandard::error(900,$e->getMessage())->getRespuesta());

            if($this->estado=='CREACION') grabaLog('ERROR: '.$e->getMessage());

        }

        return $response;

    }

    public function estado(){

        global $conexionBdd;
        
        $consulta ='SELECT * FROM integracion_status
            WHERE UUID=? AND id=? AND idProceso=?
            ORDER BY cuando DESC
            LIMIT 1
            ';
        $parametros=array($this->UUID,$this->id,$this->idProceso);
        
        try {
            $temp=$conexionBdd->prepare($consulta);
            $temp->execute($parametros);
        } catch (PDOException $e) {
            echo $e->getMessage();
        }

        
        $resultado=$temp->fetch();

        if(!$resultado) $resultado='';

        return $resultado;

    }

}

?>