<?php

namespace api\user;
require_once __DIR__ . "/../utils/routesInterface.php";
require_once "userData.php";

use api\utils\routesInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\App;

class userRoutes implements routesInterface
{
    private userData $user;

    /**
     * constructor used to instantiate a base user routes, to be used in the index.php file.
     * @param App $app - the slim app used to create the routes
     */
    public function __construct(App $app)
    {
        $this->user = new userData();
        $this->createRoutes($app);
    }

    /**
     * creates the routes for the user
     * @param App $app - the slim app used to create the routes
     * @return void - returns nothing
     */
    public function createRoutes(App $app): void
    {
        $app->post("/user/login", function (Request $request, Response $response)
        {
            // get request data
            $data = $request->getParsedBody();

            if (empty($data["username"]) || empty($data["password"]))
            {
                // uh oh user sent empty data
                return $response->withStatus(400);
            }

            if ($this->user->checkUser($data["username"], $data["password"]))
            {
                // yay, user is logged in
                $_SESSION["token"] = $this->user->createToken($data["username"]);
                $_SESSION["username"] = $data["username"];

                $inactive = 60 * 60 * 48; // 2 days
                $_SESSION["timeout"] = time() + $inactive;

                $response->getBody()->write(json_encode(array("token" => $_SESSION["token"])));
                return $response;
            }
            $response->getBody()->write(json_encode(array("error" => "Unauthorised")));
            return $response->withStatus(401);
        });

        $app->get("/user/logout", function (Request $request, Response $response)
        {
            session_unset();
            return $response;
        });

        $app->get("/user/isLoggedIn", function (Request $request, Response $response)
        {
            if (empty($_SESSION["token"]) && empty($_SESSION["username"]))
            {
                // uh oh user not logged in
                return $response->withStatus(401);
            }

            $inactive = 60 * 60 * 48; // 2 days
            $sessionLife = time() - $_SESSION["timeout"];
            if ($sessionLife > $inactive)
            {
                // uh oh user session expired
                session_destroy();
                return $response->withStatus(401);
            }

            if (empty($_SESSION["token"]))
            {
                // user is logged in but no token was created
                $_SESSION["token"] = $this->user->createToken($_SESSION["username"]);
                return $response->withStatus(201);
            }

            $response->getBody()->write(json_encode(array("token" => $_SESSION["token"])));
            return $response;

        });

        $app->get("/user/checkResetEmail/{email}", function (Request $request, Response $response, array $args)
        {
            if (empty($args["email"]))
            {
                // uh oh sent empty data
                return $response->withStatus(400);
            }

            if ($this->user->checkEmail($args["email"]))
            {
                // yay email does exist
                $_SESSION["resetToken"] = $this->user->sendResetEmail($args["email"]);
                $_SESSION["resetEmail"] = $args["email"];
                return $response;
            }
            return $response->withStatus(404);
        });

        $app->get("/user/resendEmail", function (Request $request, Response $response)
        {
            if (empty($_SESSION["resetToken"]))
            {
                // uh oh not authorized to resend email
                return $response->withStatus(401);
            }

            $_SESSION["resetToken"] = $this->user->sendResetEmail($_SESSION["resetEmail"]);
            return $response;
        });

        $app->get("/user/checkResetCode/{code}", function (Request $request, Response $response, array $args)
        {
            if (empty($args["code"]))
            {
                // uh oh sent empty data
                return $response->withStatus(400);
            }

            if ($_SESSION["resetToken"] === $args["code"])
            {
                // yay, code code matches
                return $response;
            }

            return $response->withStatus(401);
        });

        $app->post("/user/changePassword", function (Request $request, Response $response)
        {
            if (empty($_SESSION["resetToken"]) && empty($_SESSION["resetEmail"]))
            {
                // uh oh not authorized to change password
                return $response->withStatus(401);
            }

            $data = $request->getParsedBody();
            if (empty($data["password"]))
            {
                // uh oh sent empty data
                return $response->withStatus(400);
            }

            if ($this->user->changePassword($_SESSION["resetEmail"], $data["password"]))
            {
                // yay, password changed
                unset($_SESSION["resetToken"]);
                unset($_SESSION["resetEmail"]);
                return $response->withStatus(201);
            }

            return $response->withStatus(500);
        });
    }
}