<?php
/**
 * Route for department self-serve condition rules
 */

namespace routes;

use classes\authentication;
use classes\response;
use objects\department_selfserve_conditions_o;
use objects\department_selfserve_condition_rules_o;
use objects\logs_o;
use traits\route_t;

class departmentSelfserveConditionRulesRoute
{
    use route_t;

    public function run(): void
    {
        /**
         * List department self-serve condition rules
         */
        $this->get('/department/selfserve/condition/rules', function () {
            global $response;
            $this->requirePermission('list_department_selfserve_condition_rules');
            $user = (new authentication())->get_user();
            if ($user) {
                (new logs_o())->add('department_selfserve_condition_rules', 'global', 1, $user->id, 'LIST_RULES', 'User listed department self-serve condition rules');
                
                $rules_o = new department_selfserve_condition_rules_o();
                
                // If an ID is provided, return that specific rule
                if (self::isParametersSet(['id'])) {
                    $rules_o->select((int)self::getParameter('id'));
                    if ($rules_o->exists()) {
                        // Check access via condition -> department
                        $condition_o = new department_selfserve_conditions_o();
                        $condition_o->select((int)$rules_o->condition_id->value());
                        $authorized_department_ids = $user->getGroup()->getDepartments();
                        if ($condition_o->exists()) {
                            if (!in_array((int)$condition_o->department->value(), $authorized_department_ids) && !$this->hasPermission('view_all_department_selfserve_condition_rules')) {
                                $response->error('You do not have access to this department', 403);
                            }
                        }
                        $response->success($rules_o->asArray());
                    } else {
                        $response->error('Rule not found', 404);
                    }
                }

                $filters = [];
                if (self::isParametersSet(['condition_id'])) {
                    $filters['condition_id'] = (int)self::getParameter('condition_id');
                    
                    // Verify access to this condition
                    $condition_o = new department_selfserve_conditions_o();
                    $condition_o->select($filters['condition_id']);
                    if ($condition_o->exists()) {
                        $authorized_department_ids = $user->getGroup()->getDepartments();
                        if (!in_array((int)$condition_o->department->value(), $authorized_department_ids) && !$this->hasPermission('view_all_department_selfserve_condition_rules')) {
                            $response->error('You do not have access to this department', 403);
                        }
                    }
                }

                if (self::isParametersSet(['type'])) {
                    $filters['type'] = (string)self::getParameter('type');
                }

                if (self::isParametersSet(['object_type'])) {
                    $filters['object_type'] = (string)self::getParameter('object_type');
                }

                if (self::isParametersSet(['object_id'])) {
                    $filters['object_id'] = (int)self::getParameter('object_id');
                }

                $response->success(
                    $rules_o->setSearchableFields(['id', 'condition_id', 'type', 'object_type', 'object_id', 'name', 'description', 'deleted_at'])
                        ->listObjectsWithPaginationIfSet(function ($rule) {
                            $r = new department_selfserve_condition_rules_o();
                            $r->select((int)$rule['id']);
                            return $r->asArray();
                        }, $rules_o->forceRestrictFilters($filters))
                );
            } else {
                $response->error('Invalid session', 400);
            }
        }, [
            'list_department_selfserve_condition_rules' => 'List all department self-serve condition rules',
            'view_all_department_selfserve_condition_rules' => 'View all department self-serve condition rules'
        ]);

        /**
         * Add a department self-serve condition rule
         */
        $this->post('/department/selfserve/condition/rules', function () {
            global $response;
            $this->requirePermission('add_department_selfserve_condition_rules');
            $user = (new authentication())->get_user();
            if ($user) {
                $condition_id = (int)$response->getRequestParameter('condition_id');
                $type = (string)$response->getRequestParameter('type');
                $object_type = (string)$response->getRequestParameter('object_type');
                $object_id = (int)$response->getRequestParameter('object_id');
                $name = (string)$response->getRequestParameter('name');
                $description = (string)$response->getRequestParameter('description');

                if (!$condition_id || !$type || !$object_type || !$object_id || !$name || !$description) {
                    $response->error('Missing required fields', 400);
                }

                // Verify access to this condition
                $condition_o = new department_selfserve_conditions_o();
                $condition_o->select($condition_id);
                if (!$condition_o->exists()) {
                    $response->error('Condition not found', 404);
                }
                $authorized_department_ids = $user->getGroup()->getDepartments();
                if (!in_array((int)$condition_o->department->value(), $authorized_department_ids)) {
                    $response->error('You do not have access to this department', 403);
                }

                try {
                    $rule_o = (new department_selfserve_condition_rules_o())->add(
                        $condition_id,
                        $type,
                        $object_type,
                        $object_id,
                        $name,
                        $description
                    );
                    (new logs_o())->add('department_selfserve_condition_rules', 'global', 1, $user->id, 'ADD_RULE', 'User added department self-serve condition rule ' . $rule_o->id);
                    $response->success($rule_o->asArray());
                } catch (\Exception $e) {
                    $response->error($e->getMessage(), 500);
                }
            } else {
                $response->error('Invalid session', 400);
            }
        }, [
            'add_department_selfserve_condition_rules' => 'Add a department self-serve condition rule'
        ]);

        /**
         * Update a department self-serve condition rule
         */
        $this->put('/department/selfserve/condition/rules', function () {
            global $response;
            $this->requirePermission('update_department_selfserve_condition_rules');
            $user = (new authentication())->get_user();
            if ($user) {
                $id = (int)$response->getRequestParameter('id');
                if (!$id) {
                    $response->error('Missing required fields', 400);
                }

                $rule_o = new department_selfserve_condition_rules_o();
                $rule_o->select($id);
                if (!$rule_o->exists()) {
                    $response->error('Rule not found', 404);
                }

                // Verify access via condition -> department
                $condition_o = new department_selfserve_conditions_o();
                $condition_o->select((int)$rule_o->condition_id->value());
                $authorized_department_ids = $user->getGroup()->getDepartments();
                if ($condition_o->exists() && !in_array((int)$condition_o->department->value(), $authorized_department_ids)) {
                    $response->error('You do not have access to this department', 403);
                }

                if ($response->isRequestParameterSet('condition_id')) {
                    $new_condition_id = (int)$response->getRequestParameter('condition_id');
                    $new_condition_o = new department_selfserve_conditions_o();
                    $new_condition_o->select($new_condition_id);
                    if (!$new_condition_o->exists()) {
                        $response->error('Target condition not found', 404);
                    }
                    if (!in_array((int)$new_condition_o->department->value(), $authorized_department_ids)) {
                        $response->error('You do not have access to the target department', 403);
                    }
                    $rule_o->condition_id->update($new_condition_id);
                }
                if ($response->isRequestParameterSet('type')) {
                    $rule_o->type->update((string)$response->getRequestParameter('type'));
                }
                if ($response->isRequestParameterSet('object_type')) {
                    $rule_o->object_type->update((string)$response->getRequestParameter('object_type'));
                }
                if ($response->isRequestParameterSet('object_id')) {
                    $rule_o->object_id->update((int)$response->getRequestParameter('object_id'));
                }
                if ($response->isRequestParameterSet('name')) {
                    $rule_o->name->update((string)$response->getRequestParameter('name'));
                }
                if ($response->isRequestParameterSet('description')) {
                    $rule_o->description->update((string)$response->getRequestParameter('description'));
                }

                (new logs_o())->add('department_selfserve_condition_rules', 'global', 1, $user->id, 'UPDATE_RULE', 'User updated department self-serve condition rule ' . $id);
                $response->success($rule_o->asArray());
            } else {
                $response->error('Invalid session', 400);
            }
        }, [
            'update_department_selfserve_condition_rules' => 'Update a department self-serve condition rule'
        ]);

        /**
         * Delete a department self-serve condition rule
         */
        $this->delete('/department/selfserve/condition/rules', function () {
            global $response;
            $this->requirePermission('delete_department_selfserve_condition_rules');
            $user = (new authentication())->get_user();
            if ($user) {
                $id = (int)$response->getRequestParameter('id');
                if (!$id) {
                    $response->error('Missing required fields', 400);
                }

                $rule_o = new department_selfserve_condition_rules_o();
                $rule_o->select($id);
                if (!$rule_o->exists()) {
                    $response->error('Rule not found', 404);
                }

                // Verify access via condition -> department
                $condition_o = new department_selfserve_conditions_o();
                $condition_o->select((int)$rule_o->condition_id->value());
                $authorized_department_ids = $user->getGroup()->getDepartments();
                if ($condition_o->exists() && !in_array((int)$condition_o->department->value(), $authorized_department_ids)) {
                    $response->error('You do not have access to this department', 403);
                }

                $rule_o->delete();
                (new logs_o())->add('department_selfserve_condition_rules', 'global', 1, $user->id, 'DELETE_RULE', 'User deleted department self-serve condition rule ' . $id);
                $response->success('Rule deleted');
            } else {
                $response->error('Invalid session', 400);
            }
        }, [
            'delete_department_selfserve_condition_rules' => 'Delete a department self-serve condition rule'
        ]);
    }
}
