<?php

/*
 * PuzzleApp
 * Webemyos
 * Jérôme Oliva
 * GNU Licence
 */

namespace Apps\Api;

use Apps\Admin\Module\DashBoard\DashBoardController;
use Core\Core\Core;
use Core\Core\Request;
use Apps\Base\Base;
use Core\Security\Authentication;
use Core\Entity\User\User;
use Core\Utility\File\File;
use Apps\Swcf\Swcf;
use Core\Utility\Date\Date;

class Api extends Base {

    /**
     * Constructeur
     * */
    function __construct() {
        
        $this->Core = Core::getInstance();
        parent::__construct($this->Core, "Api");

    /*    header('Access-Control-Allow-Origin: http://lo*');  //I have also tried the * wildcard and get the same response
        header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
        header('Access-Control-Max-Age: 1000');
        header('Access-Control-Allow-Headers: Access-Control-Allow-Origin, Content-Type, Content-Range, Content-Disposition, Content-Description');
*/
        $token = str_replace("DealegitToken", "", base64_decode($_POST["token"]));
        $this->UserId = $token;
    }

    /**
     * Définie les routes publiques
     */
    function GetRoute($routes = "") {
        parent::GetRoute(array("Auth", "SendPush", "GetAppStore"));
        return $this->Route;
    }

    /**
     * Execute spécifique action
     */
    function Execute($action, $params ="") {
        
        $url = explode("/", $_SERVER["REQUEST_URI"]);
        $arg = $url[4];

        //TODO VERIFIER LES ROUTES PUBLIC
        //TODO AJOUTER LES APP Chargé
              //If user have the app 
        if(\Apps\EeApp\Helper\AppHelper::HaveApp($this->Core, $action)){
            $path = "\\Apps\\".$action ."\\".$action;
            $app = new $path($this->Core);

            $ap = new $app($this->Core);
            return $ap->$params($arg, $this->UserId);
        }
        
        //If user have the plugin
        if(\Apps\EeApp\Helper\AppHelper::HavePlugin($this->Core, $action)){
            $path = "\\Plugins\\".$action ."\\".$action;
            $app = new $path($this->Core);

            $ap = new $app($this->Core);
            return $ap->$params($arg, $this->UserId);
        }
        
        
        if (in_array($action, array("u","IsDispo", "Auth", "Register", "SendFile", "SetGoogleToken", "SendPush", "GetDepartement", "GetAppStore"))) {
            return $this->$action($params);
        } 
        else if(in_array($action, array("GetInfoDataBase","GetDataTable" ,"UpdateRow", "DeleteRow", "DetailRow", "PlayRequest"))){
            
            if ( $this->isValid()) {
                 return $this->$action($params);
            } else {
                return json_encode(array("statut" => "Error", "message" => "InvalidToken"));
            }
        }
        else {
            
            //Vérification du token afin de ne pas autoriser l'acces à n'importe qui
            if(in_array($action, array("GetLastModelAndArticle", "getDetailProduct", "searchProductApi", "GetDetailUserApi" , "GetMoreArticle", "GetCategories"))) {
                $swcfApi = new Swcf($this->Core);
                return $swcfApi->$action($params, $this->UserId);
            }
            
            if ( $this->isValid()) {
                $swcfApi = new Swcf($this->Core);
                return $swcfApi->$action($params, $this->UserId);
            } else {
                return json_encode(array("statut" => "Error", "message" => "InvalidTokend"));
            }
        }
    }

    /***
     * Update de site
     */
    function u(){
        
        $contentFile = "../Contents/content.json";
        
        //Import du contenu si on l'a chnagé
        if(file_exists($contentFile)){
            $content = file_get_contents("../Contents/content.json");
            
            $path = "\Apps\Cms\Cms";
            $app = new $path($this->Core);
            $app->ImportContent($content);
        }

            //On selectionne le templates
            $deploy = json_decode(file_get_contents("../Contents/deploy.json"));
            
            $templateName = $deploy->template;
            $template = new  \Apps\EeApp\Entity\EeAppTemplate($this->Core);
            $existTemplate = $template->GetByCode($templateName);
            
            //Suppresssion des templates actifs
            $request = "Update EeAppTemplate set actif = null where id > 0";
            $this->Core->Db->Execute($request);
            
            if ($existTemplate == null){
                $newTemplate = new \Apps\EeApp\Entity\EeAppTemplate($this->Core);
                $newTemplate->Code->Value = $templateName;
                $newTemplate->Name->Value = $templateName;
                $newTemplate->Description->Value = $templateName;
                $newTemplate->Actif->Value = 1;
                $newTemplate->Save();
            } else {
                
                
                $existTemplate->Actif->Value = 1;
                $existTemplate->Save();
            }   
            
            //Deploiement des applications et leurs plugins
            foreach($deploy->Apps as $app){
                
                $appName = $app->Name;
                
                //Installation 
                $existApp = new \Apps\EeApp\Entity\EeAppApp($this->Core);
                $existApp = $existApp->Find("Name='" . $appName . "'");
                
                
                if(count($existApp) ==  0){
                   $request = File::GetFileContent("../Apps/" . $appName . "/Db/install.sql");
                    $this->Core->Db->ExecuteMulti($request);

                    //Ajout dans la base de donnée
                    $AppApp = new \Apps\EeApp\Entity\EeAppApp($this->Core);
                    $AppApp->Name->Value = $appName;
                    $AppApp->CategoryId->Value = 1;
                    $AppApp->Save();

                    $App = \Core\Dashboard\DashBoardManager::GetApp($appName, $this->Core);
                    $App->PostInstall();
                    
                    //Passage des langues francais et anglais
                    $langFile = "../Apps/$appName/Lang/langFr.json";
                    \Apps\EeApp\Helper\UploadHelper::DoUploadLanguage("", "", $langFile);

                    $langFile = "../Apps/$appName/Lang/langEn.json";
                    \Apps\EeApp\Helper\UploadHelper::DoUploadLanguage("", "", $langFile);
                    
                    $appId = $this->Core->Db->GetInsertedId();
                    
                } else {
                    
                    $request = File::GetFileContent("../Apps/" . $appName . "/Db/update.sql");
                    $this->Core->Db->ExecuteMulti($request);
 
                    $appId = $existApp[0]->IdEntite;
                }
                
                //Ajout des plugins
                foreach($app->Plugin as $pluginName){
                     $Plugin = new \Apps\EeApp\Entity\EeAppPlugin($this->Core);
                     $PluginExist = $Plugin->Find("Name='" .$pluginName."'");

                     if(count($PluginExist) == 0){
                        $Plugin = new \Apps\EeApp\Entity\EeAppPlugin($this->Core);
                        $Plugin->Name->Value = $pluginName;
                        $Plugin->Code->Value = $pluginName;
                        $Plugin->Description->Value = $pluginName;
                        $Plugin->Save();
                        $pluginId = $this->Core->Db->GetInsertedId();
                     } else{
                         $pluginId = $PluginExist[0]->IdEntite;
                     }

                     $pluginAdd = new \Apps\EeApp\Entity\EeAppPluginApp($this->Core);

                     $pluginApp = $pluginAdd->Find("AppId=" . $appId . " AND PluginId= " .$pluginId);

                     if(count($pluginApp) == 0){
                        $pluginAdd = new \Apps\EeApp\Entity\EeAppPluginApp($this->Core);
                        $pluginAdd->AppId->Value = $appId;
                        $pluginAdd->PluginId->Value = $pluginId;
                        $pluginAdd->Save();
                     }
                }
            }
    }
    
    /**
     * Telecharge le document
     */
    function SendFile() {
        echo "FILE SEND";
        var_dump($_FILES);

        echo $tmpFileName = $_FILES['file']['tmp_name'];
        echo $fileName = $_FILES['file']['name'];

        echo $directory = "Data/Apps/Rex/" . $this->UserId;

        File::CreateDirectory($directory);

        move_uploaded_file($tmpFileName, $directory . "/" . $fileName);
    }

    /**
     * Vérification du token
     */
    function isValid() {
        if ($_POST["token"] == "") {
            return false;
        }

        $token = str_replace("DealegitToken", "", base64_decode($_POST["token"]));

        $user = new User($this->Core);
        $user->GetById($this->UserId);

        if ($user->IdEntite != "") {
            return true;
        }

        return false;
    }

    /**
     * Send Ok
     * Web service can Verify if the Serveur is Disponible
     */
    function IsDispo() {
        return "OK";
    }

    /**
     * Authentifie l'utilisateur 
     * Retourne une token
     */
     function Auth($params) {
        $result = Authentication::Connect(Request::GetPost("login"), Request::GetPost("password"));
        if ($result === true) {
           
            $this->Core->User->DateConnect->Value = Date::Now(true); 
            $this->Core->User->Save();
            
            return json_encode(array("statut" => "success",
                "token" => base64_encode("DealegitToken" . $this->Core->User->IdEntite)
            ));
        } else {
            return json_encode(array("statut" => "error", "message" => $result));
        }
    }

    /**
     * Vérification et création du compte utilisateur
     */
    function Register() {
        
        ///$core, $email, $pass, $verify, $name ="" , $firstName ="" ,  $birtDate ="", $experience = "", $cookGroup="", $department ="",
        //                              $webSite ="", $other = "", $identityCard = "", $tagCard ="",
        //                              $contactMethod ="", $messenger ="", $tel ="",$whatsApp ="",$contactEmail ="", $discord ="",  $intern ="", $departement = ""
        $contactMethode =Request::GetPost("contactMethode");
        
        $result = Authentication::CreateUser($this->Core,
                        Request::GetPost("email"),
                
                        Request::GetPost("password"),
                        Request::GetPost("repeatPassWord"),
                        Request::GetPost("name"),
                        Request::GetPost("firstName"),
                        Request::GetPost("birthDate"),
                        Request::GetPost("experience"),
                        "",
                       Request::GetPost("department"),
                        "",
                        "",
                        "",
                        "",
                       $contactMethode,
                       Request::GetPost("messenger"),
                       Request::GetPost("tel"),
                       Request::GetPost("whatsapp"),
                       Request::GetPost("emailContact"),
                       Request::GetPost("discord"),
                );

        Authentication::Connect(Request::GetPost("login"), Request::GetPost("password"));
        if ($result === "OK") {
            return json_encode(array("statut" => "success",
                "token" => base64_encode("DealegitToken" . $this->Core->User->IdEntite),
            ));
        } else {
            return json_encode(array("statut" => "ko", "message" => $result));
        }
    }

    /*     * *
     * Enregisttre le token Google pour l'utilisateur
     */

    function SetGoogleToken() {
        $token = str_replace("DealegitToken", "", base64_decode($_POST["token"]));
 
        
        $user = new User($this->Core);
        $user->GetById($this->UserId);
        $user->GoogleToken->Value = $_POST["GoogleToken"];
        $user->Save();

        echo "OK";
    }

    /*     * *
     * Envoi des notifications Push
     */

    function SendPush() {
        $html = "Send Push";

        $request = "Select * from ee_user where GoogleToken is not null";
        $result = $this->Core->Db->GetArray($request);

        foreach ($result as $user) {
              $this->Push($user["GoogleToken"]);
        }
        echo $html;
    }

    /**
     * Envoi de la notification via le serveru Google
     * @param type $registrationId
     */
    function Push($registrationId, $title, $message) {
  
        $notification = array('title' => $title, 'body' => $message, 'sound' => 'default', 'badge' => '1');
        $arrayToSend = array('to' => $registrationId, 'notification' => $notification, 'priority' => 'high');

        // $server_key = 'AAAAO85vcwk:APA91bFRLrZHCYivhxUmjp-OGDpW5saC3rPJnwi1gqXwJQnwgWWU_-TtEmo230H_osVGOr7od3KtEwqAlIFC1jnQ5ZXXlh0-5WoC_557PY1IV0mu2yjBsrNNcjoyzbAoZaGwCLsv72ul';
        $server_key = 'AAAArf8dV6Y:APA91bF4UFVivE9LxfLcdGJfEhFmXHdsXZF3JY95Y_Chu5pm_w1o4p6dK6acNmGkQHcHiQt4IhvfCbS2NZIrctHHap-G4euKOxEBDsvPKejR1a_SVg8SK7NuL1l4B3uoIHvLRHQDQDCc';
        
        $headers = array(
            'Content-Type:application/json',
            'Authorization:key=' . $server_key
        );

        $url = 'https://fcm.googleapis.com/fcm/send';
        //CURL request to route notification to FCM connection server (provided by Google)
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($arrayToSend));
        $result = curl_exec($ch);

        if ($result === FALSE) {
            die('Oops! FCM Send Error: ' . curl_error($ch));
        }
        curl_close($ch);
    }
    
     /*     * *
     * Obtient les info de la base de données
     */

    public function GetInfoDataBase() {
        $request = "show tables";

        $result = $this->Core->Db->GetArray($request);
        $tables = array();

        foreach ($result as $key => $value) {

            $keys = array_keys($value);
            $tables[] = $value[$keys[0]];
        }

        return json_encode($tables);
    }
    
    /***
     * Obtient les données d'une table
     */
    public function GetDataTable(){

        $table = Request::GetPost("table");
        $where = Request::GetPost("where");
        $select = Request::GetPost("select");
        
        if($select == ""){
            $select = "*";
        }
        
        
        $request = "select $select from ".$table;
        
        if($where != ""){
            $request .= " where " . $where;
        }
        $result = $this->Core->Db->GetArray($request);
        
        return json_encode($result);
    }
   
    /***
     * Met à jour les info d'une ligne
     */
    public function UpdateRow(){
        
        $data = Request::GetPosts();
        $table = $data["table"];
        $id =  $data["Id"];
        
        $row = json_decode($data["row"]);
        $property = "";
        
        foreach($row as $key => $value ){
            
            if(!in_array($key,array("Id", "Class", "Methode", "App", "row", 'table', 'serveurId'))) {
                
                if($property != ""){
                    $property .= ",";
                }
                
                $property .= $key ."='" .$value ."'";
            }
        }
        
        //Request update simple
        $request = " UPDATE " . $table . " SET " .  $property  . " WHERE Id = " . $row->Id;
        $this->Core->Db->Execute($request);
    }
    
    /***
     * Supprime une ligne 
     */
    public function DeleteRow(){
        $data = Request::GetPosts();
        $table = $data["table"];
        $id =  $data["id"];
        
        //Request update simple
        $request = " DELETE FROM  " . $table . "  WHERE Id = " . $id;
        return $this->Core->Db->Execute($request);
    }
    
    /***
     * Détail d'une entité 
     */
    public function DetailRow(){
       
        $data = Request::GetPosts();
        $table = $data["table"];
        $id =  $data["id"];
       
        $entities = array("FavorisFavoris" =>  "Apps\Favoris\Entity\FavorisFavoris",
                          "DiscussDiscuss"    => "Apps\Discuss\Entity\DiscussDiscuss",
                          "Product"        => "Apps\Swcf\Entity\Product",
                          "Proposition"    => "Apps\Swcf\Entity\Proposition",
                          "Evaluate"    => "Apps\Swcf\Entity\Evaluate"
            );
        
        $entityPath = $entities[$table];
                
        $entity = new $entityPath($this->Core);
        $entity->GetById($id);
        
        return json_encode($entity->ToEntityArray());
    }
    
    /***
     * Execute une requete et retourne le resultat
     */
    public function PlayRequest(){
        $data = Request::GetPosts();
        $request = $data["request"];
        
        $result = $this->Core->Db->GetArray($request);
        
        return json_encode($result);
    }

    /***
     * Return the Store
     */
    public function GetAppStore(){
        return  json_encode(\Apps\PuzzleApp\Helper\VersionningHelper::GetAppStore($this->Core));
    }

}
