<?php

/**
 *  Informatica Eindproject D4p
 *  6in3, Stedelijk Gymnasium Nijmegen
 *  Docent: Hans de Wolf
 *
 *  ==================
 *
 *  Daniel Boutros,
 *  Christiaan Goossens,
 *  Jelmer Hinssen
 */

namespace Inforbank\Application\API;

use \Slim\App;
use Inforbank\Application\Helper\Idob\Client;
use Inforbank\Application\Helper\Idob\Transactie;

class Handler
{
    public function __construct(App $app)
    {
        /**
         * Create the API route group
         */
        $app->group('/api', function () {
            /**
             * TransactionRequest API Endpoint
             *
             * Requires the following POST arguments:
             * - clientId
             * - transactionId
             * - amount
             * - description
             * - returnUrl
             * - sha1
             */
            $this->post('/transactionRequest', function ($request, $response, $args) {
                $parsedBody = $request->getParsedBody();

                if (isset($parsedBody['clientId']) && isset($parsedBody['transactionId']) && isset($parsedBody['amount']) && isset($parsedBody['description']) && isset($parsedBody['returnUrl']) && isset($parsedBody['hash'])) {
                    // Correct request
                    try {
                        $client = new Client($parsedBody['clientId']);
                        $clientSecret = $client->getClientSecret();

                        $sha = hash("sha256", $parsedBody['transactionId'] . $parsedBody['amount'] . $clientSecret);

                        if ($sha === $parsedBody['hash']) {
                            if ($parsedBody['returnUrl'] === $client->getClientRedirectURI()) {
                                // Voeg de transactie toe aan de lijst en stuur een response
                                try {
                                    $reference = $parsedBody['transactionId'];
                                    $amount = ((double) $parsedBody['amount']) / 100;
                                    $description = $parsedBody['description'];
                                    $clientId = $parsedBody['clientId'];

                                    $transactie = Transactie::createTransactie($reference, $clientId, $amount, $description);

                                    $uri = $request->getUri();

                                    $responseJSON = array(
                                        "success" => true,
                                        "redirect" => $uri->getBaseUrl() . "/idob/betalen?trxid=" . $transactie
                                    );
                                } catch (\Exception $e) {
                                    $response = $response->withStatus(500);
                                    $responseJSON = array(
                                        "success" => false,
                                        "error" => $e->getMessage()
                                    );
                                }
                            } else {
                                $response = $response->withStatus(400);
                                $responseJSON = array(
                                    "success" => false,
                                    "error" => "Unknown return URI."
                                );
                            }
                        } else {
                            $response = $response->withStatus(403);
                            $responseJSON = array(
                                "success" => false,
                                "error" => "Incorrect verification hash."
                            );
                        }
                    } catch (\Exception $e) {
                        $response = $response->withStatus(403);
                        $responseJSON = array(
                            "success" => false,
                            "error" => "Incorrect client id."
                        );
                    }
                } else {
                    $response = $response->withStatus(400);
                    $responseJSON = array(
                        "success" => false,
                        "error" => "Missing one of the following attributes: [clientId, transactionId, amount, description, returnUrl, hash]"
                    );
                }

                $body = $response->getBody();
                $body->write(json_encode($responseJSON));
                return $response->withBody($body);
            });

            /**
             * StatusRequest API Endpoint
             *
             * Requires the following POST arguments:
             * - clientId
             * - transactionId
             * - sha1
             */
            $this->post('/statusRequest', function ($request, $response, $args) {
                $parsedBody = $request->getParsedBody();

                if (isset($parsedBody['clientId']) && isset($parsedBody['transactionId']) && isset($parsedBody['hash'])) {
                    // Correct request
                    try {
                        $client = new Client($parsedBody['clientId']);
                        $clientSecret = $client->getClientSecret();

                        $sha = hash("sha256", $parsedBody['transactionId'] . $clientSecret);

                        if ($sha === $parsedBody['hash']) {
                            try {
                                $transactie = Transactie::getTransactie($parsedBody['transactionId']);

                                if ($transactie['clientId'] === $parsedBody['clientId']) {
                                    $responseJSON = array(
                                        "success" => true,
                                        "transaction" => array(
                                            "reference" => $transactie['reference'],
                                            "status" =>  $transactie['status']
                                        )
                                    );
                                } else {
                                    $response = $response->withStatus(500);
                                    $responseJSON = array(
                                        "success" => false,
                                        "error" => "Transaction not found."
                                    );
                                }
                            } catch (\Exception $e) {
                                $response = $response->withStatus(500);
                                $responseJSON = array(
                                    "success" => false,
                                    "error" => $e->getMessage()
                                );
                            }
                        } else {
                            $response = $response->withStatus(403);
                            $responseJSON = array(
                                "success" => false,
                                "error" => "Incorrect verification hash."
                            );
                        }
                    } catch (\Exception $e) {
                        $response = $response->withStatus(403);
                        $responseJSON = array(
                            "success" => false,
                            "error" => "Incorrect client id."
                        );
                    }
                } else {
                    $response = $response->withStatus(400);
                    $responseJSON = array(
                        "success" => false,
                        "error" => "Missing one of the following attributes: [clientId, transactionId, hash]"
                    );
                }

                $body = $response->getBody();
                $body->write(json_encode($responseJSON));
                return $response->withBody($body);
            });
        })->add(function ($request, $response, $next) {
            /**
             * Add the correct JSON headers to the responses
             */
            $response = $response->withHeader('Content-type', 'application/json');
            return $next($request, $response);
        });
    }
}
