<?php

namespace api\classes;

use api\classes\API;
use JetBrains\PhpStorm\NoReturn;

require_once 'API.php';

class API_usergroups extends API
{
    public function getUsergroup($returnBoolean = false)
    {
        list($query, $types, $params) = $this->buildDynamicQuery('system_user_groups');

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

        return $items;
    }

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

        if ($this->getUsergroup(true)) {
            $this->apiOutput(409, ['error' => 'Usergroup already exists.']);
        }
        $this->baseQuery = ''; # reset the base query set $_GET['builder']

        $this->data['user_group_weight'] = $this->get_next_available_user_group_weight($this->data['user_group_weight']);

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

        $query = "INSERT INTO system_user_groups (user_group_uuid, user_group_name, user_group_slugify, user_group_weight, user_group_type, user_group_create_timestamp) VALUES (UUID(), ?, ?, ?, ?, ?)";
        $stmt = $this->prepareStatement($query);
        $timestamp = time();
        $stmt->bind_param("ssisi", $this->data['user_group_name'], $this->data['user_group_slugify'], $this->data['user_group_weight'], $this->data['user_group_type'], $timestamp);
        $this->executeStatement($stmt);
        $_GET['builder'] = [1 => ['where' => [0 => 'user_group_slugify', 1 => $this->data['user_group_slugify']]]];
        $user_group = $this->getUsergroup();
        $user_group_uuid = $user_group[0]['user_group_uuid'];


        # Get all the permission from the database and create the permission for the user group.
        $stmt = $this->conn->query("SELECT permission_uuid FROM system_permissions");
        while ($row = $stmt->fetch_assoc()) {
            $permission_uuids[] = $row['permission_uuid'];
        }


        $values = [];
        foreach ($permission_uuids as $permission_uuid) {
            $permission_uuid_safe = $GLOBALS['conn']->real_escape_string($permission_uuid);
            $values[] = "('$permission_uuid_safe', '$user_group_uuid')";
        }

        if (!empty($values)) {
            $values_sql = implode(", ", $values);

            $query = "INSERT INTO system_user_group_permissions (permission_uuid, user_group_uuid) VALUES $values_sql";

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

            $this->apiOutput(200, ['success' => 'User group created successfully']);
        } else {
            $this->apiOutput(500, ['error' => 'Something went wrong creating the user-group.'], 'error_contact_support');
        }
    }

    #[NoReturn]
    public function deleteUsergroup()
    {
        # check if the user group exists
        $_GET['builder'] = [1 => ['where' => [0 => 'user_group_uuid', 1 => $this->data['user_group_uuid']]]];
        $user_group = $this->getUsergroup();

        # superuser cannot be deleted
        if ($user_group[0]['user_group_slugify'] === 'superuser') {
            $this->apiOutput(400, ['error' => 'superuser cannot be deleted.']);
        }

        if ($user_group[0]['user_group_weight'] < $_SESSION['user']['user_group_weight']) {
            $this->apiOutput(400, ['error' => 'groups with an lower weight cannot be deleted.']);
        }

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

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

    private function get_next_available_user_group_weight($weight)
    {
        # checks what the next avail weight is if the weight is taken by another item
        $sql = "SELECT user_group_weight FROM system_user_groups ORDER BY user_group_weight ASC";
        $result = $this->conn->query($sql);

        // Store all existing weights in an array
        $existing_weights = [];
        while ($row = $result->fetch_assoc()) {
            $existing_weights[] = (int)$row['user_group_weight'];
        }

        // If weight already exists, find the next available integer
        while (in_array($weight, $existing_weights)) {
            $weight++;
        }

        return $weight;
    }

    #[NoReturn]
    public function updateUserGroup()
    {
        # check if the user group exists
        $_GET['builder'] = [1 => ['where' => [0 => 'user_group_uuid', 1 => $this->data['user_group_uuid']]]];
        $user_group = $this->getUsergroup();

        # superuser cannot be modified
        if ($user_group[0]['user_group_slugify'] === 'superuser') {
            $this->apiOutput(500, ['error' => 'superuser cannot be modified']);
        }

        if ($user_group[0]['user_group_weight'] != $this->data['user_group_weight']) {
            $this->data['user_group_weight'] = $this->get_next_available_user_group_weight($this->data['user_group_weight']);
        }

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

        $query = "UPDATE system_user_groups SET user_group_name = ?, user_group_weight = ?, user_group_modified_timestamp = ? WHERE user_group_uuid = ?";
        $stmt = $this->prepareStatement($query);
        $stmt->bind_param("siis", $this->data['user_group_name'], $this->data['user_group_weight'], time(), $this->data['user_group_uuid']);
        $this->executeStatement($stmt);

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