<?php
error_reporting(0);

//Opencart2.0v
class ControllerPaymentPaywithiyzico extends Controller {

    private $module_version = "1.0.0";
    private $module_product_name = "eleven";

    public function index()
    {
       if (VERSION >= '2.2.0.0'){
           $template_url = 'payment/paywithiyzico_form.tpl';
       }
       else{
           $template_url = 'default/template/payment/paywithiyzico_form.tpl';
       }

        $this->checkAndSetCookieSameSite();

        $this->load->language('payment/paywithiyzico');
        $this->load->model('checkout/order');
        $this->load->model('setting/setting');
        $this->load->model('payment/paywithiyzico');

        $order_id                              = (int) $this->session->data['order_id'];
        $user_id                               = (int) isset($this->session->data['user_id']) ? $this->session->data['user_id'] : 0;
        $order_info                            = $this->model_checkout_order->getOrder($order_id);
        $products                              = $this->cart->getProducts();
        $api_key                               = $this->config->get('iyzico_checkout_form_api_id_live');
        $secret_key                            = $this->config->get('iyzico_checkout_form_secret_key_live');
        $payment_source                        = "OPENCART-".VERSION.'|'.$this->module_version."-".$this->module_product_name."|PWI";

        $user_create_date                      = $this->model_payment_paywithiyzico->getUserCreateDate($user_id);

        $this->session->data['conversation_id'] = $order_id;

        $order_info['payment_address']         = $order_info['payment_address_1']." ".$order_info['payment_address_2'];
        $order_info['shipping_address']        = $order_info['shipping_address_1']." ".$order_info['shipping_address_2'];

        /* Order Detail */
        $paywithiyzico = new stdClass;
        $paywithiyzico->locale                       = $this->language->get('code');
        $paywithiyzico->conversationId               = $order_id;
        $paywithiyzico->price                        = $this->priceParser($this->itemPriceSubTotal($products) * $order_info['currency_value']);
        $paywithiyzico->paidPrice                    = $this->priceParser($order_info['total'] * $order_info['currency_value']);
        $paywithiyzico->currency                     = $order_info['currency_code'];
        $paywithiyzico->basketId                     = $order_id;
        $paywithiyzico->paymentGroup                 = "PRODUCT";
        $paywithiyzico->callbackUrl                  = $this->url->link('payment/paywithiyzico/getcallback', '', true);
        $paywithiyzico->cancelUrl                    = $this->config->get('config_url');
        $paywithiyzico->paymentSource                = $payment_source;

        $paywithiyzico->buyer = new stdClass;
        $paywithiyzico->buyer->id                          = $order_info['customer_id'];
        $paywithiyzico->buyer->name                        = $this->dataCheck($order_info['firstname']);
        $paywithiyzico->buyer->surname                     = $this->dataCheck($order_info['lastname']);
        $paywithiyzico->buyer->identityNumber              = '11111111111';
        $paywithiyzico->buyer->email                       = $this->dataCheck($order_info['email']);
        $paywithiyzico->buyer->gsmNumber                   = $this->dataCheck($order_info['telephone']);
        $paywithiyzico->buyer->registrationDate            = $user_create_date;
        $paywithiyzico->buyer->lastLoginDate               = date('Y-m-d H:i:s');
        $paywithiyzico->buyer->registrationAddress         = $this->dataCheck($order_info['payment_address']);
        $paywithiyzico->buyer->city                        = $this->dataCheck($order_info['payment_zone']);
        $paywithiyzico->buyer->country                     = $this->dataCheck($order_info['payment_country']);
        $paywithiyzico->buyer->zipCode                     = $this->dataCheck($order_info['payment_postcode']);
        $paywithiyzico->buyer->ip                          = $this->dataCheck($this->getIpAdress());

        $paywithiyzico->shippingAddress = new stdClass;
        $paywithiyzico->shippingAddress->address          = $this->dataCheck($order_info['shipping_address']);
        $paywithiyzico->shippingAddress->zipCode          = $this->dataCheck($order_info['shipping_postcode']);
        $paywithiyzico->shippingAddress->contactName      = $this->dataCheck($order_info['shipping_firstname']);
        $paywithiyzico->shippingAddress->city             = $this->dataCheck($order_info['shipping_zone']);
        $paywithiyzico->shippingAddress->country          = $this->dataCheck($order_info['shipping_country']);


        $paywithiyzico->billingAddress = new stdClass;
        $paywithiyzico->billingAddress->address          = $this->dataCheck($order_info['payment_address']);
        $paywithiyzico->billingAddress->zipCode          = $this->dataCheck($order_info['payment_postcode']);
        $paywithiyzico->billingAddress->contactName      = $this->dataCheck($order_info['payment_firstname']);
        $paywithiyzico->billingAddress->city             = $this->dataCheck($order_info['payment_zone']);
        $paywithiyzico->billingAddress->country          = $this->dataCheck($order_info['payment_country']);

        $count = 0;
        foreach ($products as $product) {
            $price = $product['total'] * $order_info['currency_value'];
            if($price) {
                $paywithiyzico->basketItems[$count] = new stdClass;

                $paywithiyzico->basketItems[$count]->id                = $product['model'];
                $paywithiyzico->basketItems[$count]->price             = $this->priceParser($price);
                $paywithiyzico->basketItems[$count]->name              = $product['name'];
                $paywithiyzico->basketItems[$count]->category1         = $this->model_payment_paywithiyzico->getCategoryName($product['product_id']);
                $paywithiyzico->basketItems[$count]->itemType          = "PHYSICAL";

                $count++;
            }
        }

        $shipping = $this->shippingInfo();

        if(!empty($shipping) && $shipping['cost'] && $shipping['cost'] != '0.00') {

            $shippigKey = count($paywithiyzico->basketItems);

            $paywithiyzico->basketItems[$shippigKey] = new stdClass();

            $paywithiyzico->basketItems[$shippigKey]->id            = 'Kargo';
            $paywithiyzico->basketItems[$shippigKey]->price         = $this->priceParser($shipping['cost'] * $order_info['currency_value']);
            $paywithiyzico->basketItems[$shippigKey]->name          = $shipping['title'];
            $paywithiyzico->basketItems[$shippigKey]->category1     = "Kargo";
            $paywithiyzico->basketItems[$shippigKey]->itemType      = "VIRTUAL";
        }

        $rand_value             = rand(100000,99999999);
        $order_object           = $this->model_payment_paywithiyzico->createFormInitializObjectSort($paywithiyzico);
        $pki_generate           = $this->model_payment_paywithiyzico->pkiStringGenerate($order_object);
        $authorization_data     = $this->model_payment_paywithiyzico->authorizationGenerate($pki_generate,$api_key,$secret_key,$rand_value);

        $paywithiyzico_json = json_encode($paywithiyzico,JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE);

        $form_response = $this->model_payment_paywithiyzico->createFormInitializeRequest($paywithiyzico_json,$authorization_data);

        $data['pwi_redirect'] = $form_response->payWithIyzicoPageUrl;



        return $this->load->view($template_url,$data);

    }

    public function getCallBack()
    {

        try{

            $this->load->language('payment/paywithiyzico');

            if(!isset($this->request->post['token']) || empty($this->request->post['token'])) {

                $errorMessage = 'invalid token';
                throw new \Exception($errorMessage);

            }

            $this->load->model('checkout/order');
            $this->load->model('payment/paywithiyzico');

            $api_key                               = $this->config->get('iyzico_checkout_form_api_id_live');
            $secret_key                            = $this->config->get('iyzico_checkout_form_secret_key_live');

            $conversation_id                       = (int) $this->session->data['conversation_id'];
            $order_id                              = (int) $this->session->data['order_id'];
            $customer_id                           = isset($this->session->data['customer_id']) ? (int) $this->session->data['customer_id'] : 0;

            $detail_object = new stdClass();

            $detail_object->locale         = $this->language->get('code');
            $detail_object->conversationId = $conversation_id;
            $detail_object->token          = $this->db->escape($this->request->post['token']);

            $rand_value             = rand(100000,99999999);
            $pki_generate           = $this->model_payment_paywithiyzico->pkiStringGenerate($detail_object);
            $authorization_data     = $this->model_payment_paywithiyzico->authorizationGenerate($pki_generate,$api_key,$secret_key,$rand_value);

            $paywithiyzico_json = json_encode($detail_object);
            $request_response = $this->model_payment_paywithiyzico->createFormInitializeDetailRequest($paywithiyzico_json,$authorization_data);

            $paywithiyzico_local_order = new stdClass;
            $paywithiyzico_local_order->payment_id         = !empty($request_response->paymentId) ? (int) $request_response->paymentId : '';
            $paywithiyzico_local_order->order_id           = (int) $this->session->data['order_id'];
            $paywithiyzico_local_order->total_amount       = !empty($request_response->paidPrice) ? (float) $request_response->paidPrice : '';
            $paywithiyzico_local_order->status             = $request_response->paymentStatus;

            $paywithiyzico_order_insert  = $this->model_payment_paywithiyzico->insertIyzicoOrder($paywithiyzico_local_order);


            if($request_response->paymentStatus != 'SUCCESS' || $request_response->status != 'success' || $order_id != $request_response->basketId ) {

                /* Redirect Error */
                $errorMessage = isset($request_response->errorMessage) ? $request_response->errorMessage : $this->language->get('payment_failed');
                throw new \Exception($errorMessage);
            }

            $payment_id            = $this->db->escape($request_response->paymentId);

            $payment_field_desc    = $this->language->get('payment_field_desc');
            if (!empty($payment_id)) {
                $message = $payment_field_desc.$payment_id . "\n";
            }

            $installment = $request_response->installment;

            if ($installment > 1) {
                $installement_count = $this->language->get('installement_count');
                $this->model_payment_paywithiyzico->orderUpdateByInstallement($paywithiyzico_local_order->order_id,$request_response->paidPrice);
                $this->model_checkout_order->addOrderHistory($paywithiyzico_local_order->order_id, $this->config->get('paywithiyzico_order_status_id'), $message, false);
                $messageInstallement = $request_response->cardFamily . ' - ' . $request_response->installment . $installement_count;
                $this->model_checkout_order->addOrderHistory($paywithiyzico_local_order->order_id, $this->config->get('paywithiyzico_order_status_id'), $messageInstallement, false);
            } else {
                $this->model_checkout_order->addOrderHistory($paywithiyzico_local_order->order_id, $this->config->get('paywithiyzico_order_status_id'), $message, false);
            }

            return $this->response->redirect($this->url->link('checkout/success', '', 'SSL'));
        }
        catch (Exception $e){
            $errorMessage = isset($request_response->errorMessage) ? $request_response->errorMessage : $e->getMessage();

            $this->session->data['paywithiyzico_error_message'] = $errorMessage;

            return $this->response->redirect($this->url->link('payment/paywithiyzico/errorpage'));
        }

    }

    public function errorPage()
    {
        if (VERSION >= '2.2.0.0'){
            $template_url = 'payment/paywithiyzico_error.tpl';
        }
        else{
            $template_url = 'default/template/payment/paywithiyzico_error.tpl';
        }

        $data['continue'] = $this->url->link('common/home');
        $data['column_left'] = $this->load->controller('common/column_left');
        $data['column_right'] = $this->load->controller('common/column_right');
        $data['content_top'] = $this->load->controller('common/content_top');
        $data['content_bottom'] = $this->load->controller('common/content_bottom');
        $data['footer'] = $this->load->controller('common/footer');
        $data['header'] = $this->load->controller('common/header');
        $data['error_title']    = 'Ödemeniz Alınamadı.';
        $data['error_message']  = isset($this->session->data['paywithiyzico_error_message']) ? $this->session->data['paywithiyzico_error_message'] : 'PWI ERROR' ;
        $data['error_icon']     = 'catalog/view/theme/default/image/payment/paywithiyzico_error_icon.png';

        return $this->response->setOutput($this->load->view($template_url, $data));

    }

    private function dataCheck($data) {

        if(!$data || $data == ' ') {

            $data = "NOT PROVIDED";
        }

        return $data;

    }

    private function shippingInfo() {

        if(isset($this->session->data['shipping_method'])) {

            $shipping_info      = $this->session->data['shipping_method'];

        } else {

            $shipping_info = false;
        }

        if($shipping_info) {

            if ($shipping_info['tax_class_id']) {

                $shipping_info['tax'] = $this->tax->getRates($shipping_info['cost'], $shipping_info['tax_class_id']);

            } else {

                $shipping_info['tax'] = false;
            }

        }

        return $shipping_info;
    }

    private function itemPriceSubTotal($products) {

        $price = 0;

        foreach ($products as $key => $product) {

            $price+= (float) $product['total'];
        }


        $shippingInfo = $this->shippingInfo();

        if(is_object($shippingInfo) || is_array($shippingInfo)) {

            $price+= (float) $shippingInfo['cost'];

        }

        return $price;

    }

    private function priceParser($price) {

        if (strpos($price, ".") === false) {
            return $price . ".0";
        }
        $subStrIndex = 0;
        $priceReversed = strrev($price);
        for ($i = 0; $i < strlen($priceReversed); $i++) {
            if (strcmp($priceReversed[$i], "0") == 0) {
                $subStrIndex = $i + 1;
            } else if (strcmp($priceReversed[$i], ".") == 0) {
                $priceReversed = "0" . $priceReversed;
                break;
            } else {
                break;
            }
        }

        return strrev(substr($priceReversed, $subStrIndex));
    }

    private function getIpAdress() {

        $ip_address = $_SERVER['REMOTE_ADDR'];

        return $ip_address;
    }

    private function checkAndSetCookieSameSite(){

        $checkCookieNames = array('PHPSESSID','OCSESSID','default','PrestaShop-','wp_woocommerce_session_');

        foreach ($_COOKIE as $cookieName => $value) {
            foreach ($checkCookieNames as $checkCookieName){
                if (stripos($cookieName,$checkCookieName) === 0) {
                    $this->setcookieSameSite($cookieName,$_COOKIE[$cookieName], time() + 86400, "/", $_SERVER['SERVER_NAME'],true, true);
                }
            }
        }
    }

    private function setcookieSameSite($name, $value, $expire, $path, $domain, $secure, $httponly) {

        if (PHP_VERSION_ID < 70300) {

            setcookie($name, $value, $expire, "$path; samesite=None", $domain, $secure, $httponly);
        }
        else {
            setcookie($name, $value, [
                'expires' => $expire,
                'path' => $path,
                'domain' => $domain,
                'samesite' => 'None',
                'secure' => $secure,
                'httponly' => $httponly
            ]);


        }
    }
}