<?php

namespace App\System\Module;

use App\System\Controller\NavController;
use App\System\Model\CurrencieModel;
use App\System\Model\CurrencyModel;
use App\System\Model\InvoiceItemModel;
use App\System\Model\InvoiceModel;
use App\System\Model\ModuleLogModel;
use App\System\Model\ProductAddonModulesModel;
use App\System\Model\ProductAddonTranslationsModel;
use App\System\Model\ProductModel;
use App\System\Model\ServerModel;
use App\System\Model\UserProductModel;
use App\System\Vendor\Auth;
use App\System\Vendor\Basic\beCookie;
use App\System\Vendor\beLanguage;

class hetznercloud {
    public $options = [
        "isneedserver" => true
    ];
    public $pages = [
        "/" => [
            "showmenu" => true,
            "name" => "Ana Sayfa",
            "icon" => "<i class=\"ri-home-line\"></i>"
        ]
    ];
    public function hetznercloud_info(){
        return [
            "name" => "Hetzner Cloud",
            "description" => "Hetzner ile gerekli bağlantıyı kurup Cloud sunucu için otomasyon sağlar",
            "version" => "1.0",
            "vercode" => 10,
            "type" => "server",
            "author" => "ITenGriTR"
        ];
    }
    public function hetznercloud_connection_test($params = []){
        $response = $this->beSendApiRequest([
            "apiurl" => $params["surl"],
            "method" => "checkuser",
            "data" => [
                "login_token" => $params["stoken"]
            ]
        ]);
        if(!$response["status"]){
            return ["status" => false,"message" => $response["message"]];
        }
        return ["status" => true];
    }
    public function hetznercloud_product_config($params = []){
        $server = ServerModel::beGetServer("hetznercloud");
        if(!$server){
            return ["status" => false,"message" => "Alan adı uzantıları için DomainNameAPI modülünün sunucu bilgileri girilmemiş."];
        }
        $response = $this->beSendApiRequest([
            "apiurl" => $server["surl"],
            "method" => "servertypes",
            "data" => [
                "login_token" => $server["stoken"]
            ]
        ]);
        if(!$response["status"]){
            return ["status" => false,"message" => $response["message"]];
        }
        $names = [];
        foreach($response["servertype"] as $servertype){
            $names[$servertype["name"]] = $servertype["description"]."(C:{$servertype['cores']},M:{$servertype['memory']}GB,D:{$servertype['disk']}GB)";
        }
        return [        
            "product" => [
                "name" => "Ürün",
                "description" => "Hetzner üzerinden müşteriye teslim edilecek hizmeti seçiniz",
                "type" => "select",
                "default" => "",
                "form-view" => [
                    "class" => "col-6 col-md-12" 
                ],
                "values" => $names
            ]
        ];
    }
    public function hetznercloud_addon_config($params = []){
        return [        
            "datacenter" => [
                "name" => "Veri Merkezi İsmi",
                "description" => "Veri merkezinin ismini giriniz. Bu alanı eklenti sistemindeki Hetzner Cloud eklentisi üzerinden öğrenebilirsiniz.",
                "type" => "string",
                "default" => "",
                "form-view" => [
                    "class" => "col-12" 
                ]
            ],
            "image" => [
                "name" => "İşletim Sistemi",
                "description" => "İşletim sisiteminin ismini giriniz. Bu alanı eklenti sistemindeki Hetzner Cloud eklentisi üzerinden öğrenebilirsiniz.",
                "type" => "string",
                "default" => "",
                "form-view" => [
                    "class" => "col-12" 
                ]
            ]
        ];
    }
    public function hetznercloud_create($params = []){
        $userproduct = $params["userproduct"];
        $updata = json_decode($userproduct["updata"],true);
        $productmodules = $params["productmodules"];
        $addonmodules = $params["addonmodules"];
        $siteshortname = strtolower(str_replace(" ","",beGetConfig("siteshortname")));
        $siteshortname = str_replace(["İ","Ü","Ö","Ğ","Ç","Ş","ı","ü","ö","ğ","ç","ş"],["I","U","O","G","C","S","i","u","o","g","c","s"],$siteshortname);
        $name = $siteshortname.$userproduct["upid"];
        $response = $this->beSendApiRequest([
            "apiurl" => $params["server"]["surl"],
            "method" => "datacenters",
            "data" => [
                "login_token" => $params["server"]["stoken"]
            ]
        ]);
        if(!$response["status"]){
            return ["status" => false,"message" => $response["message"]];
        }
        $datacenters = $response["datacenters"];
        $searchdatacenter = $addonmodules["datacenter"][0];
        $datacentername = "";
        foreach($datacenters as $datacenter){
            if($datacenter["location"]["name"] != $searchdatacenter){
                continue;
            }
            $datacentername = $datacenter["name"];
            break;
        }
        if(!$datacentername){
            ModuleLogModel::beCreateModuleLog($userproduct["upid"],"hetznercloud","Kurulum Hatası","Hiç bir veri merkezi seçilemedi belirtilen ürün için {$searchdatacenter} ülkesi için hiç veri merkezi bulunamıyor!");
            return ["status" => false,"message" => "Sunucu oluşturulurken bir şeyler ters gitti lütfen yönetici ile iletişime geçiniz!"];
        }
        $data = [
            "server_type" => $productmodules["product"],
            "name" => $name,
            "image" => $addonmodules["image"][0],
            "datacenter" => $datacentername
        ];
        $response = $this->beSendApiRequest([
            "apiurl" => $params["server"]["surl"],
            "method" => "servercreate",
            "data" => array_merge([
                "login_token" => $params["server"]["stoken"]
            ],$data)
        ]);
        if(!$response["status"]){
            ModuleLogModel::beCreateModuleLog($userproduct["upid"],"hetznercloud","Kurulum Hatası",$response["error"]["message"],[
                "data" => $data,
                "response" => $response
            ]);
            return ["status" => false,"message" => "Sunucu oluşturulurken bir şeyler ters gitti lütfen yönetici ile iletişime geçiniz!"];
        }
        $creation = $response["creation"];
        $password = $creation["root_password"];
        $server = $creation["server"];
        $serverid = $server["id"];
        $ipv4 = $server["public_net"]["ipv4"]["ip"];
        $ipv6 = $server["public_net"]["ipv6"]["ip"];
        $updatedata = [];
        $updatedata["uptag"] = $ipv4;
        $updata = [
            "name" => $name,
            "ipv4" => $ipv4,
            "ipv6" => $ipv6,
            "username" => "root",
            "password" => beEncryptData($password),
            "serverid" => $serverid
        ];
        $activisioninfo = "Sunucu IP: {$ipv4}<br>";
        $activisioninfo .= "Kullanıcı Adı: {$updata['username']}<br>";
        $activisioninfo .= "Şifre: {$response['password']}<br>";
        $updatedata["updata"] = json_encode($updata,JSON_UNESCAPED_UNICODE);
        UserProductModel::beUpdate($updatedata)->beWhere("upid",$userproduct["upid"])->beExecute();
        return [
            "status" => true,
            "message" => "Ürün yönetim paneline yönlendiliriliyorsunuz",
            "url" => beGetRoute("client.userproduct.userproduct.show",["upid" => $userproduct["upid"]]),
            "activisioninfo" => $activisioninfo
        ];
    }
    public function hetznercloud_manage($params = []){
        $userproduct = $params["userproduct"];
        beCookie::beCreateCookie("be_upid",$userproduct["upid"],true,true);
        return ["status" => true,"message" => "Ürün yönetim paneline yönlendiliriliyorsunuz","url" => beGetRoute("client.userproduct.userproduct.show",["upid" => $userproduct["upid"]])];
    }
    public function hetznercloud_suspend($params = []){
        $userproduct = $params["userproduct"];
        $updata = json_decode($userproduct["updata"],true);
        $response = $this->beSendApiRequest([
            "apiurl" => $params["server"]["surl"],
            "method" => "serverpower",
            "data" => [
                "login_token" => $params["server"]["stoken"],
                "serverid" => $updata["serverid"],
                "action" => "stop" 
            ]
        ]);
        if(!$response["status"]){
            return ["status" => false,"message" => $response["message"]];
        }
        return ["status" => true,"message" => "Başarılı bir şekilde sipariş modül üzerinde askıya alındı!"];
    }
    public function hetznercloud_unsuspend($params = []){
        $userproduct = $params["userproduct"];
        $updata = json_decode($userproduct["updata"],true);
        $response = $this->beSendApiRequest([
            "apiurl" => $params["server"]["surl"],
            "method" => "serverpower",
            "data" => [
                "login_token" => $params["server"]["stoken"],
                "serverid" => $updata["serverid"],
                "action" => "start" 
            ]
        ]);
        if(!$response["status"]){
            return ["status" => false,"message" => $response["message"]];
        }
        return ["status" => true,"message" => "Başarılı bir şekilde sipariş modül üzerinde askıdan çıkarıldı!"];
    }
    public function hetznercloud_terminate($params = []){
        $userproduct = $params["userproduct"];
        $updata = json_decode($userproduct["updata"],true);
        $response = $this->beSendApiRequest([
            "apiurl" => $params["server"]["surl"],
            "method" => "serverdelete",
            "data" => [
                "login_token" => $params["server"]["stoken"],
                "serverid" => $updata["serverid"],
            ]
        ]);
        if(!$response["status"]){
            return ["status" => false,"message" => $response["message"]];
        }
        return ["status" => true,"message" => "Başarılı bir şekilde sipariş modül üzerinde silindi!"];
    }
    public function hetznercloud_clientarea($params = []){
        $user = Auth::beGetUser();
        $userproduct = $params["userproduct"];
        $productmodules = $params["productmodules"];
        $updata = json_decode($userproduct["updata"],true);
        $url = $params["url"];
        $page = $params["page"];
        if($page == "konsol"){
            $response = $this->beSendApiRequest([
                "apiurl" => $params["server"]["surl"],
                "method" => "serverconsole",
                "data" => [
                    "login_token" => $params["server"]["stoken"],
                    "serverid" => $updata["serverid"],
                ]
            ]);
            if(!$response["status"]){
                beError("Sunucu Yönetimi",$response["message"]);
            }
            $wss_url = $response["wss_url"];
            $password = $response["password"];
            $content = beGetView("modules.hetznercloud.console",[
                "url" => $url,
                "userproduct" => $userproduct,
                "wss_url" => $wss_url,
                "password" => $password
            ]);
            echo $content;
            exit;
        }
        $productaddontranslation = ProductAddonTranslationsModel::beSelect("patid,paoptions")->beWhere("lid",$user["lid"])->beWhere("pacode","hetznercloud_image")->beGet();
        $images = json_decode($productaddontranslation["paoptions"],true);
        beLanguage::beReadLang("diyovm");
        $response = $this->beSendApiRequest([
            "apiurl" => $params["server"]["surl"],
            "method" => "serverget",
            "data" => [
                "login_token" => $params["server"]["stoken"],
                "serverid" => $updata["serverid"],
            ]
        ]);
        $server = $response["server"];
        $invoice = null;
        $invoiceitem = InvoiceItemModel::beSelect("iid")->beWhere("iiobjectid",$userproduct["upid"])->beWhere("iiobject","ExtendOrder")->beOrder("iiid","DESC")->beLimit(1)->beGet();
        if($invoiceitem){
            $invoice = InvoiceModel::beSelect("iid,cid,iname,iprice")->beWhere("iid",$invoiceitem["iid"])->beWhere("istatus","0")->beGet();
        }
        $upoptions = json_decode($userproduct["upoptions"],true);
        $currencie = CurrencyModel::beGetCurrencies("cicon",$userproduct["cid"]);
        $orderinfo = [
            "product" => $userproduct["pname"],
            "billingprice" => $upoptions["period"]["price"],
            "billingcycle" => ProductModel::beGetPeriods()[$upoptions["period"]["period"]],
            "regdate" => date("d.m.Y",$userproduct["upstime"]),
            "nextduedate" => date("d.m.Y",$userproduct["upntime"]),
            "amount" => $userproduct["upprice"],
            "currencie" => $currencie
        ];
        $updata["password"] = beDecryptData($updata["password"]);
        $content = beGetView("modules.hetznercloud.show",[
            "url" => $url,
            "userproduct" => $userproduct,
            "updata" => $updata,
            "orderinfo" => $orderinfo,
            "invoice" => $invoice,
            "server" => $server,
            "images" => $images
        ]);
        return [
            "status" => true,
            "title" => "Sunucuyu Yönetimi",
            "content" => $content,
            "menus" => []
        ];
    }
    public function hetznercloud_rescue_status($params){
        $userproduct = $params["userproduct"];
        $updata = json_decode($userproduct["updata"],true);
        $status = $_POST["status"];
        switch($status){
            case "enable" :
                $response = $this->beSendApiRequest([
                    "apiurl" => $params["server"]["surl"],
                    "method" => "serverrescue",
                    "data" => [
                        "login_token" => $params["server"]["stoken"],
                        "serverid" => $updata["serverid"],
                        "status" => "enable"
                    ]
                ]);
                if(!$response["status"]){
                    return beAjaxError(["message" => $response["message"]]);
                }
                $updata["rescue_password"] = $response["root_password"];
                UserProductModel::beUpdate([
                    "updata" => json_encode($updata,JSON_UNESCAPED_UNICODE)
                ])->beWhere("upid",$userproduct["upid"])->beExecute();
                return beAjaxSuccess(["message" => "Başarılı bir şekilde kurtarma modu açıldı","refresh" => 1]);
                break;
            case "disable" :
                $response = $this->beSendApiRequest([
                    "apiurl" => $params["server"]["surl"],
                    "method" => "serverrescue",
                    "data" => [
                        "login_token" => $params["server"]["stoken"],
                        "serverid" => $updata["serverid"],
                        "status" => "disable"
                    ]
                ]);
                if(!$response["status"]){
                    return beAjaxError(["message" => $response["message"]]);
                }
                return beAjaxSuccess(["message" => "Başarılı bir şekilde kurtarma modu kapatıldı","refresh" => 1]);
                break;
            default :
                return beAjaxError(["message" => "Belirtilen işlem sistem üzerinde bulunamadı!"]);
                break;
        }
    }
    public function hetznercloud_password_reset($params){
        $userproduct = $params["userproduct"];
        $updata = json_decode($userproduct["updata"],true);
        $response = $this->beSendApiRequest([
            "apiurl" => $params["server"]["surl"],
            "method" => "serverpasswordreset",
            "data" => [
                "login_token" => $params["server"]["stoken"],
                "serverid" => $updata["serverid"],
            ]
        ]);
        if(!$response["status"]){
            return beAjaxError(["message" => $response["message"]]);
        }
        $root_password = $response["root_password"];
        $updata["password"] = beEncryptData($root_password);
        UserProductModel::beUpdate([
            "updata" => json_encode($updata,JSON_UNESCAPED_UNICODE)
        ])->beWhere("upid",$userproduct["upid"])->beExecute();
        return beAjaxSuccess(["message" => "Başarılı bir şekilde sunucu şifresi sıfırlandı","refresh" => 1]);
    }
    public function hetznercloud_power_action($params){
        $userproduct = $params["userproduct"];
        $updata = json_decode($userproduct["updata"],true);
        $process = $_POST["process"];
        if(!in_array($process,["start","stop","restart"])){
            return beAjaxError(["message" => "Belirtilen işlem sistem tarafında bulunmamaktadır."]);
        }
        $response = $this->beSendApiRequest([
            "apiurl" => $params["server"]["surl"],
            "method" => "serverpower",
            "data" => [
                "login_token" => $params["server"]["stoken"],
                "serverid" => $updata["serverid"],
                "action" => $process
            ]
        ]);
        if(!$response["status"]){
            return beAjaxError(["message" => $response["message"]]);
        }
        return beAjaxSuccess(["message" => "Başarılı bir şekilde sunucu üzerinde işlem uygulandı","refresh" => 1]);
    }
    public function hetznercloud_format($params){
        if(!$_POST["approval"]){
            return beAjaxError(["message" => "Lütfen bilgilendirme mesajını okuyup onayladığınızı bildiren kutuyu tikleyiniz!"]);
        }
        $user = Auth::beGetUser();
        $userproduct = $params["userproduct"];
        $updata = json_decode($userproduct["updata"],true);
        $imageid = (int)$_POST["image"];
        $productaddontranslation = ProductAddonTranslationsModel::beSelect("patid,paoptions")->beWhere("lid",$user["lid"])->beWhere("pacode","hetznercloud_image")->beGet();
        $images = json_decode($productaddontranslation["paoptions"],true);
        if(!array_key_exists($imageid,$images)){
            return beAjaxError(["message" => "Belirtilen işletim sistemi bulunmamaktadır."]);
        }
        $image = ProductAddonModulesModel::beSelect("pamid,pavalue")->beWhere("patid",$productaddontranslation["patid"])->beWhere("pamodule","hetznercloud")->beWhere("pamodulekey","image")->beWhere("pakey",$imageid)->beGet();
        if(!$image){
            return beAjaxError(["message" => "Belirtilen işletim sistemi bulunmamaktadır."]);
        }
        $response = $this->beSendApiRequest([
            "apiurl" => $params["server"]["surl"],
            "method" => "serverrebuild",
            "data" => [
                "login_token" => $params["server"]["stoken"],
                "serverid" => $updata["serverid"],
                "image" => $image["pavalue"]
            ]
        ]);
        if(!$response["status"]){
            return beAjaxError(["message" => $response["message"]]);
        }
        return beAjaxSuccess(["message" => "Başarılı bir şekilde sunucuya format atıldı bu işlem yaklaşık bir dakika sürebilir lütfen konsol üzerinden takip ediniz"]);
    }
    public function beSendApiRequest($data = []){
        global $be;
        $settings = $be->settings;
        $data["data"] = array_merge($data["data"],[
            "cid" => $settings["system_id"],
            "ctoken" => $settings["system_token"],
            "secret" => $settings["system_secret"],
            "acces_token" => substr(md5($settings["system_id"].BE_TIME),0,8),
            "time" => BE_TIME
        ]);
        $ch = curl_init();
        curl_setopt($ch,CURLOPT_URL,"https://{$data['apiurl']}/api/hetznercloud/{$data['method']}");
        curl_setopt($ch,CURLOPT_POST,1);
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
        curl_setopt($ch,CURLOPT_POSTFIELDS,http_build_query($data["data"]));
        curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
        $response = curl_exec($ch);
        curl_close($ch);
        return json_decode($response,true);
    }
}