<?php

namespace api\classes;

use api\classes\API;
use api\classes\API_usergroups;
use bin\php\Classes\mailBuilder;
use JetBrains\PhpStorm\NoReturn;

require_once 'API.php';
require_once "{$_SERVER['DOCUMENT_ROOT']}/bin/php/Classes/mailBuilder.php";

class API_users extends API
{
    public function getUser($returnBoolean = false)
    {
        list($query, $types, $params) = $this->buildDynamicQuery('system_users');

        $items = $this->generalGetFunction($query, $types, $params, $returnBoolean, 'User');

        return $items;
    }

    #[NoReturn]
    public function createUser()
    {
        # check if the user already exists
        $_GET['builder'] = [1 => ['where' => [0 => 'user_email', 1 => $this->data['user_email']]]];

        if ($this->getUser(true)) {
            $this->apiOutput(409, ['error' => 'user already exists.']);
        }


        if ($this->getUserGroupWeight() < $_SESSION['user']['user_group_weight']) {
            $this->apiOutput(400, ['error' => 'You cannot make an user with an lower weight then yourself!']);
        }

        $query = "INSERT INTO system_users (
            user_uuid, user_group_uuid, user_email, user_first_name, user_last_name, user_full_name, 
            user_phone_number, user_password, user_password_reset_token, user_password_reset_expires, 
            user_two_factor_enabled, user_two_factor_secret, user_status, 
            user_verified_email, user_verified_phone, user_create_timestamp, user_modified_timestamp, 
            user_last_login_timestamp, user_login_attempts, user_pref_language, user_stompable
        ) VALUES (
            UUID(), ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, NULL, ?, 0, 0, ?, NULL, NULL, 0, ?, 0
        )";

        $stmt = $this->prepareStatement($query);

        $stmt->bind_param("ssssssssisis",
            $this->data['user_group_uuid'],
            $this->data['user_email'],
            $this->data['user_first_name'],
            $this->data['user_last_name'],
            $this->data['user_full_name'],
            $this->data['user_phone_number'],
            $this->data['user_password'],
            $this->data['user_password_reset_token'],
            $this->data['user_password_reset_expires'],
            $this->data['user_status'],
            time(),
            $this->data['user_pref_language'],
        );

        # Sending an email to the user
        $host = $_SERVER['HTTP_HOST'];
        $verifyLink = "https://{$host}/login/verifyEmail.php?token={$this->data['user_password_reset_token']}";


        $this->executeStatement($stmt);

        $mail = new mailBuilder();
        $mail->subject = "Hello " . $this->data['user_first_name'] . ", your Sentri account is ready — set your password";
        $mail->addAddress($this->data['user_email'], $this->data['user_first_name']);
        $mail->mailText = '
Hello ' . $this->data['user_first_name'] . ',<br><br>
An account has been created for you in Sentri.<br>
To activate your account, please verify your email address and set your password by clicking the link below:<br>
<a href="' . $verifyLink . '" class="btn btn-primary">Activate My Account</a><br><br>
Or copy and paste the following link into your browser: <br>' . $verifyLink . '<br><br>

This link is valid for 24 hours.<br>
After that, you’ll need to request a new activation link.<br><br>

If you weren’t expecting this email or believe it was sent by mistake, you can safely ignore it.<br><br>

Best regards,<br><br>
The Sentri gnomes';
        $mail->sendMail();

        $this->apiOutput(200, ['success' => 'User created successfully. mail has been sent']);
    }

    public function getUserGroupWeight($user_group_uuid = false)
    {
        require_once 'API_usergroups.php';

        $API_usergroups = new API_usergroups();

        $uuid = $user_group_uuid ?: $this->data['user_group_uuid'];
        $_GET['builder'] = [1 => ['where' => [0 => 'user_group_uuid', 1 => $uuid]]];

        return $API_usergroups->getUserGroup()[0]['user_group_weight'];
    }

    #[NoReturn]
    public function updateUser()
    {
        # check if the user exists
        $_GET['builder'] = [1 => ['where' => [0 => 'user_uuid', 1 => $this->data['user_uuid']]]];
        $this->getUser();

        if (!isset($this->postedData['user_profile_change']) && $this->getUserGroupWeight() < $_SESSION['user']['user_group_weight']) {
            $this->apiOutput(400, ['error' => 'You cannot edit a user with a lower weight than yourself!']);
        }

        $data = $this->data;

        $userUuid = $data['user_uuid'];
        unset($data['user_uuid']);

        # always set timestamp
        $data['user_modified_timestamp'] = time();

        $set = [];
        foreach ($data as $key => $value) {
            $set[] = "$key = :$key";
        }

        $sql = sprintf("UPDATE system_users SET %s WHERE user_uuid = :user_uuid", implode(', ', $set));
        $stmt = $GLOBALS['pdo']->prepare($sql);
        $data['user_uuid'] = $userUuid;
        $stmt->execute($data);

        $this->apiOutput(200, ['success' => 'User successfully updated.']);
    }

    #[NoReturn]
    public function deleteUser()
    {
        # delete an user

        # check if the user exists
        $_GET['builder'] = [1 => ['where' => [0 => 'user_uuid', 1 => $this->data['user_uuid']]]];
        $user_data = $this->getUser()[0];


        $this->data['user_group_uuid'] = $user_data['user_group_uuid'];

        # check group weight
        if ($this->getUserGroupWeight() < $_SESSION['user']['user_group_weight']) {
            $this->apiOutput(400, ['error' => 'You cannot delete a user with an lower weight then yourself!']);
        }

        if ($user_data['user_uuid'] == $_SESSION['user']['user_uuid']) {
            $this->apiOutput(400, ['error' => 'You cannot delete yourself, maybe some rope will do.']);
        }


        $query = "DELETE FROM system_users WHERE user_uuid = ?";
        $stmt = $this->prepareStatement($query);
        $stmt->bind_param('s', $this->data['user_uuid']);

        $this->executeStatement($stmt);

        $this->apiOutput(200, ['success' => 'User successfully deleted']);
    }
}