<?php

namespace App\System\Module;

use App\System\Basic\beModel;
use App\System\Basic\beRouter;
use App\System\Model\CurrencyModel;
use App\System\Model\PaymentModel;
use App\System\Model\SettingModel;
use App\System\Model\UserInfoModel;
use App\System\Vendor\Auth;

class iyzico {
    public function iyzico_info(){
        return [
            "name" => "İyzico",
            "description" => "İyzico ile ödeme alın",
            "version" => "1.2",
            "vercode" => 12,
            "author" => "ITenGriTR",
        ];
    }
    public function iyzico_is_activated(){
        $settings = SettingModel::beGetSettings("iyzico_status");
        return $settings["iyzico_status"] == 1 ? true:false;
    }
    public function iyzico_currency(){
        return 1;
    }
    public function iyzico_template($params = []){
        $settings = SettingModel::beGetSettings("iyzico_methodfee");
        $price = $params["total"];
        $currency = $params["currency"];
        $newprice = $price*(100+$settings["iyzico_methodfee"])/100;
        return beGetView("global.iyzico.frontpanel",["price" => round($newprice,2),"currency" => $currency]);
    }
    public function iyzico_create_payment($invoice){
        $settings = SettingModel::beGetSettings("iyzico_methodfee");
        $user = Auth::beGetUser($invoice["uid"]);
        $userinfo = UserInfoModel::beWhere("uid",$user["uid"])->beGet();
        $useridentity = beModel::beTable("be_user_identity")->beSelect("uid,uitcno")->beWhere("uid",$user["uid"])->beGet();
        if(strlen($useridentity["uitcno"]) != 11){
            $useridentity["uitcno"] = "18512566150";
        }
        $cardid = $_POST["cardid"];
        $invoice["itotal"] = round($invoice["itotal"]*(100+$settings["iyzico_methodfee"])/100,2);
        $data = [
            "locale" => "tr",
            "conversationId" => strval($invoice["oid"]),
            "price" => number_format($invoice["itotal"],1,".",""),
            "paidPrice" => number_format($invoice["itotal"],1,".",""),
            "installment" => "1",
            "paymentChannel" => "WEB",
            "paymentGroup" => "PRODUCT"
        ];
        if($cardid){
            $userdata = beModel::beTable("be_iyzico_card_user")->beSelect("icusertoken")->beWhere("uid",$user["uid"])->beGet();
            $usercarddata = beModel::beTable("be_iyzico_card_storage")->beSelect("iccardtoken")->beWhere("icid",$cardid)->beWhere("uid",$user["uid"])->beGet();
            $data["paymentCard"] = [
                "cardToken" => $usercarddata["iccardtoken"],
                "cardUserKey" => $userdata["icusertoken"],
            ];
        }
        else{
            $cardnumber = preg_replace("/[^0-9]/","",str_replace(" ","",$_POST["cardNumer"]));
            if(strlen($cardnumber) != 16){
                return ["status" => false,"message" => "Kart numarası doğrulanamadı lütfen kontrol edin!"];
            }
            $securitycode = preg_replace("/[^0-9]/","",$_POST["cardCvc"]);
            if(strlen($securitycode) != 3){
                return ["status" => false,"message" => "Kart güvenlik numarası(CVC) doğrulanamadı lütfen kontrol edin!"];
            }
            $cardvalidate = explode("/",str_replace(" ","",$_POST["cardValidate"]));
            $expiramm = preg_replace("/[^0-9]/","",$cardvalidate[0]);
            if((int)$expiramm < 0 || (int)$expiramm > 12){
                return ["status" => false,"message" => "Kart son kullanım doğrulanamadı lütfen kontrol edin!"];
            }
            $expirayy = preg_replace("/[^0-9]/","",$cardvalidate[1]);
            if((int)$expirayy < 23 || (int)$expirayy > 40){
                return ["status" => false,"message" => "Kart son kullanım doğrulanamadı lütfen kontrol edin!"];
            }
            $savecard = $_POST["savecard"];
            if($savecard && $userinfo["acid"] == 218){
                $alias =  $_POST["alias"];
                if(empty($alias)){
                    $alias = "Kayıtlı Kartım #".substr(md5(BE_TIME),0,3);
                }
                $carduser = beModel::beTable("be_iyzico_card_user")->beWhere("uid",$user["uid"])->beGet();
                $siteshortname = strtolower(str_replace(" ","",beGetConfig("siteshortname")));
                $cardid = $siteshortname.substr(md5($user["uid"].BE_TIME),0,8);
                if(!$carduser){
                    $response = $this->beSendRequest("cardstorage/card",[
                        "locale" => "tr",
                        "conversationId" => $cardid,
                        "externalId" => $cardid,
                        "email" => $user["email"],
                        "card" => [
                            "cardAlias" => $alias,    
                            "cardNumber" => $cardnumber,
                            "expireYear" => "20".strval($expirayy),
                            "expireMonth" => strval($expiramm),
                            "cardHolderName" => $user["name"]." ".$user["surname"],
                        ]
                    ]);
                }
                else{
                    $response = $this->beSendRequest("cardstorage/card",[
                        "locale" => "tr",
                        "conversationId" => $cardid,
                        "cardUserKey" => $carduser["icusertoken"],
                        "email" => $user["email"],
                        "card" => [
                            "cardAlias" => $alias,    
                            "cardNumber" => $cardnumber,
                            "expireYear" => "20".strval($expirayy),
                            "expireMonth" => strval($expiramm),
                            "cardHolderName" => $user["name"]." ".$user["surname"],
                        ]
                    ]);
                }
                if($response["status"] != "success"){
                    return ["status" => false,"message" => $response["errorMessage"]];
                }
                if(!$carduser){
                    beModel::beInsert([
                        "uid" => $user["uid"],
                        "icusertoken" => $response["cardUserKey"],
                        "icdateline" => BE_TIME
                    ],"be_iyzico_card_user");
                }
                beModel::beInsert([
                    "uid" => $user["uid"],
                    "iccardid" => $cardid,
                    "iccardtoken" => $response["cardToken"],
                    "icbinnumber" => $response["binNumber"],
                    "iclastfour" => $response["lastFourDigits"],
                    "icname" => $alias,
                    "ictype" => $response["cardType"],
                    "icassociation" => $response["cardAssociation"],
                    "icfamily" => $response["cardFamily"],
                    "icbankname" => $response["cardBankName"],
                    "icdateline" => BE_TIME
                ],"be_iyzico_card_storage");
            }
            $data["paymentCard"] = [
                "cardHolderName" => $user["name"]." ".$user["surname"],
                "cardNumber" => $cardnumber,
                "expireYear" => "20".strval($expirayy),
                "expireMonth" => strval($expiramm),
                "cvc" => strval($securitycode),
                "registerCard" => 0
            ];
            beModel::beInsert([
                "uid" => $user["uid"],
                "iid" => $invoice["iid"],
                "iccardnumber" => $cardnumber,
                "iccardexpire" => $expiramm."/20".$expirayy,
                "icipaddress" => beRouter::$beUserIP,
                "icdateline" => BE_TIME
            ],"be_iyzico_cards");
        }
        if(!$userinfo["uiaddress"]){
            $userinfo["uiaddress"] = "Adres Bilinmiyor - Doğru Değil";
        }
        $data["buyer"] = [
            "id" => $user["uid"],
            "name" => $user["name"],
            "surname" => $user["surname"],
            "identityNumber" => $useridentity["uitcno"],
            "email" => $user["email"],
            "gsmNumber" => "+".$userinfo["uidial"].$userinfo["uiphone"],
            "registrationAddress" => $userinfo["uiaddress"],
            "city" => "Tekirdağ",
            "country" => "Turkey",
            "ip" => beRouter::$beUserIP
        ];
        $data["billingAddress"] = [
            "address" => $userinfo["uiaddress"],
            "contactName" => $user["name"]." ".$user["surname"],
            "city" => "Tekirdag",
            "country" => "Turkey"
        ];
        $data["basketItems"][] = [
            "id" => "1",
            "price" => number_format($invoice["itotal"],1,".",""),
            "name" => $invoice["iname"],
            "category1" => "Hizmet",
            "category2" => "Hizmet2",
            "itemType" => "VIRTUAL"
        ];
        $data["currency"] = "TRY";
        $data["callbackUrl"] = beGetRoute("invoice.payment.callback")."?module=iyzico";
        $response = $this->beSendRequest("payment/3dsecure/initialize",$data);
        if($response["status"] != "success"){
            beModel::beInsert([
                "uid" => $user["uid"],
                "sltitle" => "Ödeme Yöntemi Hatası - Iyzico",
                "slcontent" => "Ödeme işlemi oluşturulmaya çalışılırken bir hata oluştu!",
                "sldata" => json_encode($response,JSON_UNESCAPED_UNICODE),
                "sldateline" => BE_TIME
            ],"be_system_logs");
            return ["status" => false,"message" => "Ödeme işlemi oluşturulurken bir sorun oluştu kart bilgileriniz hatalı olabilir!"];
        }
        $htmldata = base64_decode($response["threeDSHtmlContent"]);
        $htmldata .= "<script>document.forms['autosubmit'].submit();</script>";
        return ["status" => true,"message" => "Başarılı bir şekilde ödeme oluşturuldu!","data" => $htmldata];
    }
    public function iyzico_delete_card($data = []){
        $response = $this->beSendRequest("cardstorage/card",[
            "locale" => "tr",
            "conversationId" => "123",
            "cardUserKey" => $data["carduser_key"],
            "cardToken" => $data["card_token"]
        ],"DELETE");
        if($response["status"] != "success"){
            return ["status" => false,"message" => $response["errorMessage"]];
        }
        return ["status" => true];
    }
    public function iyzico_pay_page($invoice){
        $settings = SettingModel::beGetSettings("iyzico_methodfee,iyzico_store_card");
        $user = Auth::beGetUser($invoice["uid"]);
        $currencies = CurrencyModel::beGetCurrencies("cid,cname,cicon");
        $comussion = round($invoice["itotal"]*$settings["iyzico_methodfee"]/100,2);
        $invoice["itotal"] += $comussion;
        $usercards = beModel::beTable("be_iyzico_card_storage")->beWhere("uid",$user["uid"])->beGetAll();
        return ["status" => true,"template" => beGetView("global.iyzico.form",["invoice" => $invoice,"usercards" => $usercards,"currencies" => $currencies,"settings" => $settings])];
    }
    public function iyzico_pay_notification(){
        return ["status" => false,"message" => "Bu ödeme yöntemi için bildirim sistemi kullanılmamaktadır."];
    }
    public function iyzico_pay_callback(){
        $list = [
            -1 => "3-D Secure imzası geçersiz veya doğrulama.",    
            0 => "3-D Secure imzası geçersiz veya doğrulama.",    
            2 => "Kart sahibi veya bankası sisteme kayıtlı değil.",  
            3 => "Kartın bankası sisteme kayıtlı değil.",  
            4 => "Doğrulama denemesi, kart sahibi sisteme daha sonra kayıt olmayı seçmiş.",  
            5 => "Doğrulama yapılamıyor.",  
            6 => "3-D Secure hatası.",  
            7 => "Sistem Hatası",  
            8 => "Bilinmeyen kart no."
        ];
        if($_POST["status"] != "success"){
            beError("Ödeme Hatası",$list[$_POST["mdStatus"]]);
        }
        $paymentId = $_POST["paymentId"];
        $conversationData = $_POST["conversationData"];
        $conversationId = $_POST["conversationId"];
        $response = $this->beSendRequest("/payment/3dsecure/auth",[
            "locale" => "tr",
            "conversationId" => $conversationId,
            "paymentId" => $paymentId,
            "conversationData" => $conversationData
        ]);
        if($response["status"] != "success"){
            beError("Ödeme Hatası","Ödeme işleminiz bankanız tarafından reddedildi.");
        }
        $payment = PaymentModel::beSelect("pid,cid,uid,iid,ptotal,pstatus")->beWhere("pid",$conversationId)->beGet();
        if(!$payment){
            return ["status" => false,"message" => "Belirtilen ödeme bulunamadı!"];
        }
        if($payment["pstatus"] != 0){
            PaymentModel::beUpdate(["pstatus" => "-1"])->beWhere("pid",$payment["pid"])->beExecute();
            return ["status" => false,"message" => "OK"];
        }
        if($_POST["status"] != "success"){
            PaymentModel::beUpdate(["pstatus" => "-1"])->beWhere("pid",$payment["pid"])->beExecute();
            return ["status" => false,"message" => "OK"];
        }
        PaymentModel::beUpdate(["pstatus" => "1"])->beWhere("pid",$payment["pid"])->beExecute();
        return ["status" => true,"payment" => $payment,"add_accounting" => true,"message" => "OK","url" => beGetRoute("client.userproduct.userproducts")];
    }
    private function beSendRequest($endpoint,$data,$type = "POST"){
        $settings = SettingModel::beGetSettings("iyzico_status,iyzico_merchant_id,iyzico_merchant_key,iyzico_merchant_secret,iyzico_methodfee");
        $tokendata = $this->beGetToken($settings["iyzico_merchant_key"],$settings["iyzico_merchant_secret"],$data);
        $ch = curl_init();
        curl_setopt($ch,CURLOPT_URL,"https://api.iyzipay.com/{$endpoint}");
        if($data){
            curl_setopt($ch,CURLOPT_CUSTOMREQUEST,$type);
            curl_setopt($ch,CURLOPT_POSTFIELDS,json_encode($data,JSON_UNESCAPED_UNICODE));
        }
        curl_setopt($ch,CURLOPT_HTTPHEADER,[
            "Accept: application/json",
            "Content-Type: application/json",
            "Authorization:".$tokendata["authorization"],
            "x-iyzi-rnd:".$tokendata["rand"],
        ]);
        curl_setopt($ch,CURLOPT_TIMEOUT,30);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
        $response = curl_exec($ch);
        curl_close($ch);
        return json_decode($response,true);
    }
    private function beGetToken($apikey,$apisecret,$data){
        $rand = rand(1000,9999);
        $hash = base64_encode(sha1($apikey.$rand.$apisecret.$this->beCreateDataPKI($data),true));
        return [
            "authorization" => "IYZWS ".$apikey.":".$hash,
            "rand" => $rand
        ];
    }
    private function beCreateDataPKI($data){
        $text = "[";
        foreach($data as $key => $val){
            if(is_array($val)){
                if(!is_numeric($key)){
                    $text .= $key."=";
                }
                $text .= "[";
                foreach($val as $keyalt => $valalt){
                    if(is_array($valalt)){
                        if(!is_numeric($keyalt)){
                            $text .= $keyalt."=";
                        }
                        $text .= "[";
                        foreach($valalt as $keyalt2 => $valalt2){
                            $text .= $keyalt2."=".$valalt2.",";
                        }
                        $text = substr($text,0,-1);
                        $text .= "],";
                    }
                    else{
                        if(!is_numeric($keyalt)){
                            $text .= $keyalt."=";
                        }
                        $text .= $valalt.",";
                    }
                }
                $text = substr($text,0,-1);
                $text .= "],";
            }
            else{
                $text .= $key."=".$val.",";
            }
        }
        $text = substr($text,0,-1);
        $text .= "]";
        return $text;
    }
}
?>