<?php

// Require the autoloader for the PayNL SDK.
require_once(dirname(__FILE__) . '/vendor/autoload.php');

class paynl extends Payment_Provider_Base
{
    protected const PAYMENT_METHOD_ID = 0;

    function __construct()
    {
        $this->loadConfiguration();

        // Load parent constructor
        parent::__construct();

        // Load configuration
        $this->loadConf();
    }

    protected function loadConfiguration()
    {
        $this->conf['PaymentDirectory'] = 'paynl';
        $this->conf['PaymentMethod'] = 'other';
    }

    protected function setTokens()
    {
        \Paynl\Config::setTokenCode($this->conf['ExtraID']);
        \Paynl\Config::setApiToken($this->conf['Password']);
        \Paynl\Config::setServiceId($this->conf['MerchantID']);
    }

    public static function getBackofficeSettings()
    {
        $settings = array();

        $settings['InternalName'] = 'Pay.nl';

        $settings['MerchantID']['Title'] = "Service id (SL)";
        $settings['MerchantID']['Value'] = "SL-####-####";

        $settings['ExtraID']['Title'] = "Token code (AT)";
        $settings['ExtraID']['Value'] = "AT-####-####";

        $settings['Password']['Title'] = "API token";
        $settings['Password']['Value'] = "";

        $settings['Advanced']['Title'] = "Betaal met Pay.nl";
        $settings['Advanced']['Image'] = "paynl.png";
        $settings['Advanced']['Extra'] = "Kies uw betaalmethode: ";

        $settings['Hint'] = "Registreer eerst een account op <a  target='_blank' href='https://www.pay.nl/direct-registreren'>pay.nl/direct-registreren</a>, gebruik partnercode &quot;HostFact&quot; om een gratis account als hostingbedrijf aan te kunnen maken.<br />Ga na het inloggen naar <a target='_blank' href='https://my.pay.nl/programs/programs'>Instellingen</a> en klik op het icon voor &quot;gegevens&quot; bij de verkooplocatie.";

        return $settings;
    }

    public function choosePaymentMethod()
    {
        try {
            $this->setTokens();

            $payment_methods = \Paynl\Paymentmethods::getList();

            $html = "<select name=\"paynl_payment_method\">";
            $html .= "<option value=\"\" selected=\"selected\">Kies uw betaalmethode</option>";
            foreach ($payment_methods as $method) {
                $html .= "<option value=\"".$method['id']."\">".$method['visibleName']."</option>";
            }
            $html .= "</select>";
            return $html;
        } catch(Exception $e){
            // Return error message for consumer
            $this->paymentStatusUnknown($e->getMessage());
            exit;
        }
    }

    public function validateChosenPaymentMethod()
    {
        if (!empty($_POST['paynl_payment_method'])) {
            $_SESSION['paynl']['payment_method'] = $_POST['paynl_payment_method'];
            return true;
        } else if (!isset($_POST['paynl_payment_method']) && !empty($_SESSION['paynl']['payment_method'])) {
            return true;
        }

        $this->Error = 'U heeft nog geen betaalmethode geselecteerd.';
        return false;
    }

    public function startTransaction()
    {
        if ($this->Type == 'invoice') {
            $orderID = $this->InvoiceCode;
            $description = __('description prefix invoice') . ' ' . $this->InvoiceCode;
            $lines = $this->getInvoiceLines($this->InvoiceCode);
        } else {
            $orderID = $this->OrderCode;
            $description = __('description prefix order') . ' ' . $this->OrderCode;
            $lines = $this->getOrderLines($this->OrderCode);
        }

        try {
            $this->setTokens();
            $customer_data = $this->getCustomerData();

            // Split address into street name and street number.
            if ( preg_match('/([^\d]+)\s?(.+)/i', $customer_data->Address, $result) ){
                $streetName = $result[1];
                $streetNumber = $result[2];
            } else {
                $streetName = $customer_data->Address;
                $streetNumber = '';
            }

            $transactionConfig = array(
                'amount' => round($this->Amount, 2),
                'currency' => CURRENCY_CODE,
                'returnUrl' => IDEAL_EMAIL . $this->conf['PaymentDirectory'] . "/return.php?id=" . urlencode(base64_encode(passcrypt('paynl' . $orderID))),
                'exchangeUrl' => IDEAL_EMAIL . $this->conf['PaymentDirectory'] . '/notify.php',
                'description' => $description,
                'extra1' => $orderID,
                'ipaddress' => \Paynl\Helper::getIp(),
                'testmode' => 0,
                'statsData' => 'HostFact|202412|PHP' . phpversion(),
                'enduser' => array(
                    'initials' => $customer_data->Initials,
                    'lastName' => $customer_data->SurName,
                    'emailAddress' => getFirstMailAddress($customer_data->EmailAddress),
                    'address' => array(
                        'streetName' => $streetName,
                        'streetNumber' => $streetNumber,
                        'zipCode' => $customer_data->ZipCode,
                        'city' => $customer_data->City,
                        'countryCode' => $customer_data->Country
                    ),
                    'invoiceAddress' => array(
                        'initials' => $customer_data->Initials,
                        'lastName' => $customer_data->SurName,
                        'streetName' => $streetName,
                        'streetNumber' => $streetNumber,
                        'zipCode' => $customer_data->ZipCode,
                        'city' => $customer_data->City,
                        'countryCode' => $customer_data->Country
                    ),
                ),
                'saleData' => array(
                    'orderData' => array_map(function($line) {
                        return array(
                            'productId' => $line->ProductCode,
                            'description' => $line->Description,
                            'price' => round($line->PriceExcl * 100),
                            'quantity' => $line->Number,
                            'vatPercentage' => $line->TaxPercentage * 100
                        );
                    }, $lines)
                )
            );

            // Company details for IN3-zakelijk payment method.
            if (!empty($customer_data->CompanyName) && !empty($customer_data->TaxNumber)) {
                $transactionConfig['enduser']['company'] = array(
                    'name' => $customer_data->CompanyName,
                    'vatNumber' => $customer_data->TaxNumber
                );
            }

            // Specify the payment method and bank for non-generic PayNL payments.
            if ($this::PAYMENT_METHOD_ID > 0) {
                $transactionConfig['paymentMethod'] = $this::PAYMENT_METHOD_ID;
                if (isset($_SESSION['paynl']['bank'])) {
                    $transactionConfig['bank'] = $_SESSION['paynl']['bank'];
                }
            } else if (!empty($_SESSION['paynl']['payment_method'])) {
                $transactionConfig['paymentMethod'] = $_SESSION['paynl']['payment_method'];
            }

            // Start transaction
            $transaction = \Paynl\Transaction::start($transactionConfig);

            $this->updateTransactionID($transaction->getTransactionId());
            $_SESSION['paynl']['transaction_id'] = $transaction->getTransactionId();

            header("Location: " . $transaction->getRedirectUrl());
            exit;
        } catch(Exception $e){
            // Return error message for consumer
            $this->paymentStatusUnknown($e->getMessage());
            exit;
        }
    }

    public function validateTransaction($transactionID)
    {
        try {
            $this->setTokens();

            $transaction = \Paynl\Transaction::status($transactionID);
        } catch(Exception $e){
            if ($this->isNotificationScript !== true) {
                $this->paymentStatusUnknown();
                header("Location: " . IDEAL_EMAIL);
            } else {
                // Return a 503 http code.
                header('HTTP/1.1 503 Service Temporarily Unavailable');
            }
            exit;
        }

        if ($this->isNotificationScript === true) {
            if ($transaction->isPaid()) {
                echo 'TRUE| Paid';
                $this->paymentProcessed($transactionID);
                exit();
            } else if ($transaction->isCanceled()) {
                echo 'TRUE| Canceled';
                $this->paymentFailed($transactionID);
                exit();
            } else {
                exit('TRUE| Not updated');
            }
        } else {
            if ($this->getType($transactionID) && $this->Paid > 0) {
                if ($this->Type == 'invoice') {
                    $_SESSION['payment']['type'] = 'invoice';
                    $_SESSION['payment']['id'] = $this->InvoiceID;
                } elseif ($this->Type == 'order') {
                    $_SESSION['payment']['type'] = 'order';
                    $_SESSION['payment']['id'] = $this->OrderID;
                }
            }

            if ($transaction->isPending()) {
                $_SESSION['payment']['status'] = 'pending';
                $_SESSION['payment']['paymentmethod'] = $this->conf['PaymentMethod'];
                $_SESSION['payment']['transactionid'] = $transactionID;
                $_SESSION['payment']['date'] = date('Y-m-d H:i:s');
            } elseif ($transaction->isPaid() || $this->Paid > 0) {
                // Because type is found, we know it is paid
                $_SESSION['payment']['status'] = 'paid';
                $_SESSION['payment']['paymentmethod'] = $this->conf['PaymentMethod'];
                $_SESSION['payment']['transactionid'] = $transactionID;
                $_SESSION['payment']['date'] = date('Y-m-d H:i:s');
            } else {
                $_SESSION['payment']['status'] = 'failed';
                $_SESSION['payment']['paymentmethod'] = $this->conf['PaymentMethod'];
                $_SESSION['payment']['transactionid'] = $transactionID;
                $_SESSION['payment']['date'] = date('Y-m-d H:i:s');
            }

            header("Location: " . IDEAL_EMAIL);
            exit;
        }
    }
}