<?php

namespace routes;

use classes\authentication;
use objects\customer_default_department_o;
use objects\departments_o;
use objects\logs_o;
use objects\users_o;
use traits\route_t;

class customerDefaultDepartmentRoute
{
    use route_t;

    public function run(): void
    {
        $this->get('/customer/department/default', function () {
            // Require the user to be logged in
            global $response;
            self::requirePermission('get_customer_default_department');
            $user = (new authentication())->get_user();
            if (!$user) {
                (new logs_o())->add('customer_default_department', 'global', 0, $user->id, 'CUSTOMER_GET_DEFAULT_DEPARTMENT', 'User not logged in');
                $response->error('Invalid session', 400);
            }
            // Require the customer number parameter
            $customer_number = (int)$this->getCustomerNumberFromParameterOrUser($user);
            // Check if the customer is its own customer number
            if ($customer_number !== (int)$user->customer_number->value()) {
                self::requirePermission('get_customer_default_department_other');
            }
            // Check if the customer number exists
            $customer = (new users_o())->getUserByCustomerNumber((int)$customer_number);
            if (!$customer->exists()) {
                (new logs_o())->add('customer_default_department', 'global', 0, $user->id, 'CUSTOMER_GET_DEFAULT_DEPARTMENT', 'Customer not found');
                $response->error('Customer not found', 400);
            }
            // Get the default department for the customer
            $customer_default_department_o = new customer_default_department_o();
            $default_department_object_id = $customer_default_department_o->getIdByCustomerNumber((int)$customer_number);
            if (empty($default_department_object_id)) {
                // Return "Not found"
                $response->error('This customer does not have a default department', 400);
            }
            // Select the object
            $customer_default_department_o->select((int)$default_department_object_id);
            // Log the action
            (new logs_o())->add('customer_default_department', 'global', 0, $user->id, 'CUSTOMER_GET_DEFAULT_DEPARTMENT', 'Default department retrieved');
            // Return success
            $response->success($customer_default_department_o->asArray());
        },
            [
                'get_customer_default_department' => 'Get the default department for a customer (for its both own and other customers, depending on the get_customer_default_department_other permission)',
                'get_customer_default_department_other' => 'Get the default department for other customers',
            ]
        );

        $this->post('/customer/department/default', function () {
            // Require the user to be logged in
            global $response;
            self::requirePermission('add_customer_default_department');
            $user = (new authentication())->get_user();
            if (!$user) {
                (new logs_o())->add('customer_default_department', 'global', 0, $user->id, 'CUSTOMER_ADD_DEFAULT_DEPARTMENT', 'User not logged in');
                $response->error('Invalid session', 400);
            }
            // Require the customer number and department parameters
            self::requireParameters(['department']);
            // Require the customer number parameter
            $customer_number = $this->getCustomerNumberFromParameterOrUser($user);
            // Check if the customer is its own customer number
            if ($customer_number !== (int)$user->customer_number->value()) {
                self::requirePermission('add_customer_default_department_other');
            }
            // Check if the department is valid
            $department = (int)self::getParameter('department');
            self::requireMinLength('department', 1);
            self::requireMaxLength('department', 255);
            self::requireType($department, self::type_int());
            self::requireMinValue($department, 1);
            // Check if the department actually exists
            $departments_o = new departments_o();
            $department_object = $departments_o->selectId((int)$department);
            if (!$department_object->exists()) {
                (new logs_o())->add('customer_default_department', 'global', 0, $user->id, 'CUSTOMER_ADD_DEFAULT_DEPARTMENT', 'Department not found');
                $response->error('Department not found', 400);
            }
            // Check if the customer number exists
            $customer = (new users_o())->getUserByCustomerNumber((int)$customer_number);
            if (!$customer->exists()) {
                (new logs_o())->add('customer_default_department', 'global', 0, $user->id, 'CUSTOMER_ADD_DEFAULT_DEPARTMENT', 'Customer not found');
                $response->error('Customer not found', 400);
            }
            // Check if the customer already has a default department
            $customer_default_department_o = new customer_default_department_o();
            $default_department_object_id = $customer_default_department_o->getIdByCustomerNumber((int)$customer_number);
            if (!empty($default_department_object_id)) {
                // Return "Already exists"
                $response->error('This customer already has a default department', 400);
            }
            // Add the default department
            $customer_default_department_o->add((int)$customer_number, (int)$department);
            // Log the action
            (new logs_o())->add('customer_default_department', 'global', 0, $user->id, 'CUSTOMER_ADD_DEFAULT_DEPARTMENT', 'Default department added');
            // Return success
            $response->success($customer_default_department_o->asArray());
        },
            [
                'add_customer_default_department' => 'Add a default department for a customer (for its both own and other customers, depending on the add_customer_default_department_other permission)',
                'add_customer_default_department_other' => 'Add a default department for other customers',
            ]
        );

        $this->delete('/customer/department/default', function () {
            // Require the user to be logged in
            global $response;
            self::requirePermission('delete_customer_default_department');
            $user = (new authentication())->get_user();
            if (!$user) {
                (new logs_o())->add('customer_default_department', 'global', 0, $user->id, 'CUSTOMER_DELETE_DEFAULT_DEPARTMENT', 'User not logged in');
                $response->error('Invalid session', 400);
            }
            // Require the customer number parameter
            $customer_number = $this->getCustomerNumberFromParameterOrUser($user);
            // Check if the customer is its own customer number
            if ($customer_number !== (int)$user->customer_number->value()) {
                self::requirePermission('delete_customer_default_department_other');
            }
            // Check if the customer number exists
            $customer = (new users_o())->getUserByCustomerNumber((int)$customer_number);
            if (!$customer->exists()) {
                (new logs_o())->add('customer_default_department', 'global', 0, $user->id, 'CUSTOMER_DELETE_DEFAULT_DEPARTMENT', 'Customer not found');
                $response->error('Customer not found', 400);
            }
            // Check if the customer already has a default department
            $customer_default_department_o = new customer_default_department_o();
            $default_department_object_id = $customer_default_department_o->getIdByCustomerNumber((int)$customer_number);
            if (empty($default_department_object_id)) {
                // Return "Not found"
                $response->error('This customer does not have a default department', 400);
            }
            // Delete the default department
            $customer_default_department_o->select((int)$default_department_object_id);
            $customer_default_department_o->delete();
            // Log the action
            (new logs_o())->add('customer_default_department', 'global', 0, $user->id, 'CUSTOMER_DELETE_DEFAULT_DEPARTMENT', 'Default department deleted');
            // Return success
            $response->success('Default department deleted');
        },
            [
                'delete_customer_default_department' => 'Delete a default department for a customer (for its both own and other customers, depending on the delete_customer_default_department_other permission)',
                'delete_customer_default_department_other' => 'Delete a default department for other customers',
            ]
        );

    }

    /**
     * @param users_o|false $user
     * @return int
     */
    private function getCustomerNumberFromParameterOrUser(users_o|false $user): int
    {
        if (self::isParametersSet(['customer_number'])) {
            self::requireParameters(['customer_number']);
            // Check if the customer number is valid
            $customer_number = (int)self::getParameter('customer_number');
            self::requireMinLength('customer_number', 1);
            self::requireMaxLength('customer_number', 255);
            self::requireType($customer_number, self::type_int());
        } else {
            // If the customer number is not set, use the user's customer number
            $customer_number = (int)$user->customer_number->value();
            // Make sure the customer number is valid
        }
        self::requireMinValue($customer_number, 1);
        return $customer_number;
    }
}