<?php
// app/api/accounts/generate

    header("Content-Type:application/json");
    include("../../../settings/dbconn.php");
    include("../../../settings/utils.php");
    
    // parametros obligatorios
    $parmsob = array("sessionid","currencies");
    if (!parametrosValidos($_GET, $parmsob)){
        badEnd("400", array("msg"=>"Parametros obligatorios " . implode(",", $parmsob)));
    }
    
    //Definicion de variables e inicializacion
    $out= new stdClass();
    $sessionid = $_GET["sessionid"];
    $currencies = $_GET["currencies"];
    $generateFailed = false;
    $currenciesFailed = [];
    
    //Validamos la session
    $userid = isSessionValid($db, $sessionid);
    
    // Obtenemos el lenguaje del usuario
    $lang = updateLang($db,$sessionid);
    
    //Validamos el si el usuario puede crear cuentas
    isLevelValid($db, $userid);
    
    //Consultamos los datos del usuarios para la insercion/validacion
    $sql = "SELECT * from users WHERE sessionid = '".$sessionid."'";
    if (!$rs=$db->query($sql))
        badEnd("500", array("msg"=>determinateDBError($db)));
        
    $userdata = $rs->fetch_assoc();
    
    //Partimos la cadena con las monedas separadas por -
    $currenciesid = explode('-',$currencies);
    
    //Recorremos cada moneda
    foreach($currenciesid as $currencyid){
        $record = new stdClass();
        
        //consultamos las monedas disponibles para las cuentas AFX
        $sql = "SELECT currencies FROM paymentmethods WHERE id = -1";
        if (!$rs=$db->query($sql))
            badEnd("500", array("msg"=>determinateDBError($db)));
        
        $allowedcurrencies = $rs->fetch_assoc();
    
        //Validamos que la moneda enviada sea valida
        $allowedcurrenciesarr = explode(",",$allowedcurrencies["currencies"]);
        $isValid = false;
    
        foreach($allowedcurrenciesarr as $allowedcurrency){
            if($allowedcurrency == $currencyid){
                $isValid = true;
            }
        }
    
        //Si la moneda no es valida retornamos error
        if(!$isValid){
            badEnd("400", array("msg"=>"La moneda es invalida ".$currencyid,'test'=>$allowedcurrenciesarr,'currency'=>$currencyid));
        }
    
        //Consultamos si ya posee una cuenta de AFX
        $sql = "SELECT COUNT(id) AS qty FROM accounts".
        "       WHERE userid = ".$userid.
        "       AND paymentmethodid = -1 ".
        "       AND entityusrid = -1 ".
        "       AND currencyid = ".$currencyid;
        if (!$rs=$db->query($sql))
            badEnd("500", array("msg"=>determinateDBError($db)));
        
        $row = $rs->fetch_assoc();
    
        if(intval($row["qty"]) > 0){
            badEnd("409", array("msg"=>"Registro Duplicado"));
        }
    
        //Consultamos los datos de la moneda
        $sql = "SELECT name, symbol, interface, decimals, status FROM currencies ".
        "       WHERE id = ".$currencyid;
        if (!$rs=$db->query($sql))
            badEnd("500", array("msg"=>determinateDBError($db)));
        
        $row = $rs->fetch_assoc();
        if(intval($row["status"]) == 0){
            badEnd("400", array("msg"=>"Moneda inactiva"));
        }
        //Validamos si es una criptomoneda o fiat
        $isCripto = false;
        $isFiat = false;
        
        // Guardamos el nombre de la moneda para la auditoria
        $currencynameaudit = $row['name'];
        
        /*
        1 = BS
        2 = Internacional
        3 = Saldos
        4 = BTC
        5 = PTR
        */
        if(intval($row['interface']) == 1 || intval($row['interface']) == 3 || intval($row['interface']) == 2){
            $isFiat = true;
        }else if(intval($row['interface']) == 4 || intval($row['interface']) == 5 || intval($row['interface']) == 6 || intval($row['interface']) == 7){
            $isCripto = true;
        }

        //Retornamos los datos de la moneda
        $record->symbol = $row['symbol'];

        $db->autocommit(FALSE);

        $walletid = "";
        $apiKeySecret = "";

        if($isCripto && !$isFiat){
            $apiKeySecret = '';
            $txidWallet = '';
            // Si es 5 Consultmos la api de TCV, si no es de prueba
            if(intval($row['interface']) == 5){
                // PETRO
                $rsp = queryPrivate('deposit_address', $TCV_JWT, $TCV_URL, $VERSION_API, false, ['currency' => $row['symbol']]);
                
                // Si la direccion es null y la respuesta es distinta a 201, hubo un error
                if($rsp['address'] == NULL || $rsp['httpres'] != 201){
                    $generateFailed = true;
                    array_push($currenciesFailed, $row['symbol']);
                    continue;
                    //badEnd("402", array("msg"=>'Error al obtener direccion: '.$rsp['httpres']." - ".$rsp['error']->message));
                } 

                $walletid = $rsp['address'];
                $apiKeySecret = randomString(8);
                
            }else if(intval($row['interface']) == 4){
                // BTC
                $parms = array("label"=>"afxaddr");
                $request = array('method'=>'getnewaddress','parms' => $parms);
                $rsp = json_decode(queryServicesBTC($BTC_URL, $request), true);
    
                // Validamos que el error no sea nulo para mandar el mensaje
                if($rsp['error'] != null){
                    $generateFailed = true;
                    array_push($currenciesFailed, $row['symbol']);
                    continue;
                    //badEnd('500',array("msg"=>$rest['error']['message']));
                }
                
                if($rsp['result'] == null){
                    $generateFailed = true;
                    array_push($currenciesFailed, $row['symbol']);
                    continue;
                    //badEnd('402',array("msg"=>"Error al obtener direccion: ", 'msg2'=>$rsp));
                }
                    
                $walletid = $rsp['result'];
                $apiKeySecret = randomString(8);
                
                
            }else if(intval($row['interface']) == 6){
                $sqlPref =  "SELECT * FROM cmspreferences WHERE id = 1";
                if (!$rsPref=$db->query($sqlPref))
                    badEnd("500", array("msg"=>determinateDBError($db)));
                
                $rowPref = $rsPref->fetch_assoc();
                $newwalletFee = (($rowPref["newwalletfeeUsdt"])*1);
                if($newwalletFee == 0 || $newwalletFee >= ($rowPref["limitfeeUsdt"]*1)){
                    $generateFailed = true;
                    array_push($currenciesFailed, $row['symbol']);                    
                    continue;
                }else{
                    //Con este servicio consultaremos los depositos que estan pendientes buscandolos en la API(DINAMICO)
                    $request = array('method'=>'getBalances', "address" => $USDT_CENTRAL_WALLET);
                    $rest = json_decode(queryServicesUSDT($USDT_URL, $request), true);
                    
                    // Si es mayor al requerido cómo preferencia + 5TRX en el saldo de la wallet central podemos generar la billetera nueva con saldo para la aprobación
                    if(formattedTrxAmount($rest['TRX']) >= ($newwalletFee+5)){               
                        //TETHER
                        $request = array('method'=>'createAddress', "trx" => $newwalletFee);//No hace falta convertir el fee se envía la cantidad de TRX
                        $rest = json_decode(queryServicesUSDT($USDT_URL, $request), true);

                        if($rest['newaddress']['address_base58'] == null){
                            $generateFailed = true;
                            array_push($currenciesFailed, $row['symbol']);                        
                            continue; //Esto interrumpe el proceso y pasa al siguiente objeto del ciclo
                        }else{
                            $walletid = $rest['newaddress']['address_base58'];
                            $apiKeySecret = $rest['newaddress']['private_key'];

                            $txidWallet = $rest['transaction']['txid'];
                        }
                    }else{
                        $generateFailed = true;
                        array_push($currenciesFailed, $row['symbol']);                    
                        continue;
                    }
                }
            }else if (intval($row['interface']) == 7){ 
                // DASH
                $parms = array("label"=>"afxaddr");
                $request = array('method'=>'getnewaddress','parms' => $parms);
                $rsp = json_decode(queryServicesDash($DASH_URL, $request),true);
    
                // Validamos que el error no sea nulo para mandar el mensaje
                if($rsp['error'] != null){
                    $generateFailed = true;
                    array_push($currenciesFailed, $row['symbol']);
                    continue;
                    //badEnd('500',array("msg"=>$rest['error']['message']));
                }
                    
                if($rsp['result'] == null){
                    $generateFailed = true;
                    array_push($currenciesFailed, $row['symbol']);                    
                    continue;
                   //badEnd('402',array("msg"=>"Error al obtener direccion: ".$rsp['error']['message']));
                }
                    
                $walletid = $rsp['result'];
                $apiKeySecret = randomString(8);
                
            } else {
                $walletid = randomString(30);
                $apiKeySecret = randomString(8);
            }
            
            //Insertamos la nueva cuenta
            $sql = "INSERT INTO accounts".
            "       (".
            "       paymentmethodid, ".
            "       userid, ".
            "       currencyid, ".
            "       details1, ".
            "       entityusrid, ".
            "       status ".
            "       )".
            "       VALUES(".
            "       -1, ".
            "       ".$userdata["id"].", ".
            "       ".$currencyid.", ".
            "       '".$walletid."', ".
            "       -1,".
            "       1 ".
            "       )";

            if (!$db->query($sql)){
                $error = determinateDBError($db);
                $db->rollback();
                $db->close();
                badEnd("500", array("msg"=>$error));
            }
            
            // Retornamos el id que fue insertado
            $record->id = (int)$db->insert_id;
        
            if($walletid!=""){
                //Al ser una cripto, creamos una wallet
                $sql = "INSERT INTO wallets".
                "       (".
                "       wallet, ".
                "       secretKey, ".
                "       accountid, ".
                "       txid, ".
                "       expirationDate".
                "       )".
                "       VALUES(".
                "       '".$walletid."', ".
                "       '".$apiKeySecret."', ".
                "       ".$record->id.", ".
                "       ".(($txidWallet == '' || $txidWallet == NULL) ? 'NULL' : "'".$txidWallet."'").", ".
                "       ".(($txidWallet == ''|| $txidWallet == NULL) ? '(DATE_ADD(NOW(), INTERVAL 1 YEAR))' : "(DATE_ADD(NOW(), INTERVAL 3 YEAR))")." ".
                "       )";
                if (!$db->query($sql)){
                    $error = determinateDBError($db);
                    $db->rollback();
                    $db->close();
                    badEnd("500", array("msg"=>$error));
                }
            }
        
        }else if($isFiat && !$isCripto){
            //Insertamos la nueva cuenta
            $sql = "INSERT INTO accounts".
            "       (".
            "       paymentmethodid, ".
            "       userid, ".
            "       currencyid, ".
            "       entityusrid, ".
            "       status".
            "       )".
            "       VALUES(".
            "       -1, ".
            "       ".$userdata["id"].", ".
            "       ".$currencyid.", ".
            "       -1, ".
            "       1".
            "       )";
            if (!$db->query($sql)){
                $error = determinateDBError($db);
                $db->rollback();
                $db->close();
                badEnd("500", array("msg"=>$error));
            }
            
            // Retornamos el id que fue insertado
            $record->id = (int)$db->insert_id;
        }else{
            $db->rollback();
            $db->close();
            badEnd("500", array("msg"=>"No se logro determinar el tipo de moneda, avise para verificar el interface de la moneda"));
        }
        
        //retornamos el id de la moneda
        $record->currid = (int)$currencyid;
        
        $records [] = $record;
        
        // Obtenemos el nombre del usuario
        $sql = "SELECT IF(userpersons.fname IS NULL, usercompanies.name, CONCAT(userpersons.fname,' ',userpersons.flastname)) AS name ".
        "       FROM users ".
        "       LEFT JOIN userpersons ON userpersons.usrid = users.id ".
        "       LEFT JOIN usercompanies ON usercompanies.usrid = users.id ".
        "       WHERE sessionid = '".$sessionid."'";
        if (!$res=$db->query($sql)){
            $error = determinateDBError($db);
            $db->rollback();
            $db->close();
            badEnd("500", array("msg"=>$error));
        }
        
        $userdataaudit = $res->fetch_assoc();
    
        //auditoria
        setAudit($db, "F. DE PAGO", $sessionid, "APP", "Se creo una cuenta de ".$currencynameaudit."(".$currencyid.") para el usuario ".$userdataaudit['name']);
        $db->commit();
        
        $db->autocommit(TRUE);
    }
    
    // Retornamos los records
    $out = $records;
    
    //Cerramos la conexion
    $db->close();
    
    if ($generateFailed) {
        header("HTTP/1.1 502");
        echo (json_encode(array("msg"=>determinateMsgFail(array(
            "esp"=>'Cuenta'.(count($currenciesFailed) > 1 ? 's' : '').' en ' .implode(",",$currenciesFailed). " no creada".(count($currenciesFailed) > 1 ? 's' : '')." por falla de conexión",
            "eng"=>"Account".(count($currenciesFailed) > 1 ? 's' : '')." in ".implode(",",$currenciesFailed)." not created due to connection failure"), $lang, 'Cuenta'.(count($currenciesFailed) > 1 ? 's' : '').' en ' .implode(",",$currenciesFailed). " no creada".(count($currenciesFailed) > 1 ? 's' : '')." por falla de conexión"))));
        die();
    } else {
        header("HTTP/1.1 200");
        echo (json_encode($out));
        die();
    }

    function formattedTrxAmount($value){
        return ((($value*1) > 0)?(($value*1)/1000000):0);
    }
    
?>
