<?php

namespace routes;

use classes\authentication;
use objects\logs_o;
use objects\product_options_o;
use traits\route_t;

class productOptionsRoute
{
    use route_t;

    public function run(): void
    {
        $this->get('/product/options', function () {

            // Require the user to be logged in
            global $response;
            $this->requirePermission('list_product_options');
            // Get the user object
            $user = (new authentication())->get_user();
            // Check if the request was successful
            if ($user) {
                // Log the incident
                (new logs_o())->add('product_options', 'global', 1, $user->id, 'LIST_PRODUCT_OPTIONS', 'User listed product options');
                // Return the list of departments
                $response->success(
                    (new product_options_o())
                        ->setSearchableFields([
                            // The fields that can be searched. This would otherwise make it possible to get secret information from the database, simply by searching for it and getting the result count back
                            'id',
                            'product_id',
                            'option_id',
                            'name',
                            'min',
                            'max',
                            'created_at',
                            'updated_at'
                        ])
                        ->listObjectsWithPaginationIfSet(
                            function ($option) use ($user) {
                                // Return the object as an array
                                return [
                                    'id' => (int)$option['id'],
                                    'product_id' => (int)$option['product_id'],
                                    'option_id' => (int)$option['option_id'],
                                    'name' => (string)$option['name'],
                                    'min' => $option['min'] === null ? null : (int)$option['min'],
                                    'max' => $option['max'] === null ? null : (int)$option['max'],
                                    'created_at' => (string)$option['created_at'],
                                    'updated_at' => (string)$option['updated_at'],
                                ];
                            }
                        )
                );
            } else {
                // Log the incident
                (new logs_o())->add('product_options', 'global', 1, 0, 'LIST_PRODUCT_OPTIONS', 'User tried to list product options without being logged in');
                // Return an error
                $response->error('Invalid session', 400);
            }
        },
            [
                'list_product_options' => 'List all product options'
            ]
        );

        $this->post('/product/options', function () {
            // Require the user to be logged in
            global $response;
            $this->requirePermission('add_product_option');
            // Get the user object
            $user = (new authentication())->get_user();
            // Check if the request was successful
            if ($user) {
                // Check if the required parameters are set
                self::requireParameters(['product_id', 'option_id']);
                // Check if the parameters are of the correct type
                self::requireType(self::getParameter('product_id'), self::TYPE_INT());
                self::requireType(self::getParameter('option_id'), self::TYPE_INT());
                // Create the object
                $product_options = new product_options_o();
                // Add the object
                $product_options->add(
                    self::getParameter('product_id'),
                    self::getParameter('option_id')
                );
                // Log the incident
                (new logs_o())->add('product_options', 'global', 1, $user->id, 'ADD_PRODUCT_OPTION', 'User added a product option');
                // Return the object
                $response->success(
                    $product_options->__toString()
                );
            } else {
                // Log the incident
                (new logs_o())->add('product_options', 'global', 1, 0, 'ADD_PRODUCT_OPTION', 'User tried to add a product option without being logged in');
                // Return an error
                $response->error('Invalid session', 400);
            }
        },
            [
                'add_product_option' => 'Add a product option'
            ]
        );

        $this->put('/product/options', function () {
            // Require the user to be logged in
            global $response;
            $this->requirePermission('edit_product_option');
            // Get the user object
            $user = (new authentication())->get_user();
            // Check if the request was successful
            if ($user) {
                // Check if the required parameters are set
                self::requireParameters(['id']);
                // Check if the parameters are of the correct type
                self::requireType(self::getParameter('id'), self::TYPE_INT());
                // Create the object
                $product_options = new product_options_o();
                // Select the object
                $product_options->select(self::getParameter('id'));
                // Check what the user wants to edit

                // Option name
                if (self::isParametersSet(['name'])) {
                    // Check if the parameters are of the correct type
                    self::requireType(self::getParameter('name'), self::TYPE_STRING());
                    // Set the name
                    $product_options->set_name(self::getParameter('name'));
                }
                // Option min
                if (self::isParametersSet(['min'])) {
                    // Check if the parameters are of the correct type (Or NULL)
                    self::requireTypeIn(self::getParameter('min'), [self::TYPE_INT(), self::TYPE_NULL()]);
                    // Set the min value
                    $product_options->set_min(self::getParameter('min'));
                }
                // Option max
                if (self::isParametersSet(['max'])) {
                    // Check if the parameters are of the correct type
                    self::requireType(self::getParameter('max'), self::TYPE_INT());
                    // Set the max value
                    $product_options->set_max(self::getParameter('max'));
                }

                // Log the incident
                (new logs_o())->add('product_options', 'global', 1, $user->id, 'EDIT_PRODUCT_OPTION', 'User edited a product option');
                // Return the object
                $response->success(
                    $product_options->__toString()
                );
            } else {
                // Log the incident
                (new logs_o())->add('product_options', 'global', 1, 0, 'EDIT_PRODUCT_OPTION', 'User tried to edit a product option without being logged in');
                // Return an error
                $response->error('Invalid session', 400);
            }
        },
            [
                'edit_product_option' => 'Edit a product option'
            ]
        );

        $this->delete('/product/options', function () {
            // Require the user to be logged in
            global $response;
            $this->requirePermission('delete_product_option');
            // Get the user object
            $user = (new authentication())->get_user();
            // Check if the request was successful
            if ($user) {
                // Check if the required parameters are set
                self::requireParameters(['id']);
                // Check if the parameters are of the correct type
                self::requireType((int)self::getParameter('id'), self::TYPE_INT());
                // Require the minimum value to be above 0
                self::requireMinValue((int)self::getParameter('id'), 1);
                // Create the object
                $product_options = new product_options_o();
                // Select the object
                $product_options->select((int)self::getParameter('id'));
                // Delete the object
                $product_options->delete();
                // Log the incident
                (new logs_o())->add('product_options', 'global', 1, $user->id, 'DELETE_PRODUCT_OPTION', 'User deleted a product option');
                // Return the object
                $response->success(
                    'Product option deleted'
                );
            } else {
                // Log the incident
                (new logs_o())->add('product_options', 'global', 1, 0, 'DELETE_PRODUCT_OPTION', 'User tried to delete a product option without being logged in');
                // Return an error
                $response->error('Invalid session', 400);
            }
        },
            [
                'delete_product_option' => 'Delete a product option'
            ]
        );
    }
}