<?php
/**
 * Route for department self-serve vehicle conditions
 */

namespace routes;

use classes\authentication;
use classes\response;
use classes\selfserve;
use objects\department_selfserve_vehicle_conditions_o;
use objects\customer_vehicles_o;
use objects\logs_o;
use traits\route_t;

class departmentSelfserveVehicleConditionsRoute
{
    use route_t;

    public function run(): void
    {
        /**
         * List department self-serve vehicle conditions
         */
        $this->get('/department/selfserve/vehicle/conditions', function () {
            global $response;
            $user = (new authentication())->get_user();
            if (!$user) {
                $response->error('Invalid session', 400);
            }

            $has_global = $user->hasPermission('list_department_selfserve_vehicle_conditions');
            $has_own = $user->hasPermission('list_own_department_selfserve_vehicle_conditions');

            if (!$has_global && !$has_own) {
                $response->error('Permission denied', 403);
            }

            (new logs_o())->add('department_selfserve_vehicle_conditions', 'global', 1, $user->id, 'LIST_VEHICLE_CONDITIONS', 'User listed department self-serve vehicle conditions');
            
            $conditions_o = new department_selfserve_vehicle_conditions_o();
            $customer_number = (int)$user->customer_number->value();
            
            // If an ID is provided, return that specific condition
            if (self::isParametersSet(['id'])) {
                $conditions_o->select((int)self::getParameter('id'));
                if ($conditions_o->exists()) {
                    if ($has_global) {
                        $authorized_department_ids = $user->getGroup()->getDepartments();
                        if (!in_array((int)$conditions_o->department->value(), $authorized_department_ids)) {
                            $response->error('You do not have access to this department', 403);
                        }
                    } else {
                        // Own permission only
                        if ((int)$conditions_o->customer_id->value() !== $customer_number) {
                            $response->error('You do not have access to this condition', 403);
                        }
                    }
                    $response->success($conditions_o->asArray());
                } else {
                    $response->error('Condition not found', 404);
                }
            }

            $filters = [];
            if ($has_global) {
                $authorized_department_ids = $user->getGroup()->getDepartments();
                if (self::isParametersSet(['department'])) {
                    $requested_department = (int)self::getParameter('department');
                    if (!in_array($requested_department, $authorized_department_ids)) {
                        $response->error('You do not have access to this department', 403);
                    }
                    $filters['department'] = $requested_department;
                } else {
                    $filters['department'] = $authorized_department_ids;
                }

                if (self::isParametersSet(['customer_id'])) {
                    $filters['customer_id'] = (int)self::getParameter('customer_id');
                }
            } else {
                // Own permission only
                $filters['customer_id'] = $customer_number;
                if (self::isParametersSet(['department'])) {
                    $filters['department'] = (int)self::getParameter('department');
                }
            }

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

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

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

                $response->success(
                    $conditions_o->setSearchableFields(['id', 'department', 'lane', 'customer_id', 'reg', 'question', 'value', 'created_at', 'updated_at', 'deleted_at'])
                        ->listObjectsWithPaginationIfSet(function ($condition) {
                            $c = new department_selfserve_vehicle_conditions_o();
                            $c->select((int)$condition['id']);
                            return $c->asArray();
                        }, $conditions_o->forceRestrictFilters($filters))
                );
        }, [
            'list_department_selfserve_vehicle_conditions' => 'List all department self-serve vehicle conditions',
            'list_own_department_selfserve_vehicle_conditions' => 'List own department self-serve vehicle conditions'
        ]);

        /**
         * Add a department self-serve vehicle condition
         */
        $this->post('/department/selfserve/vehicle/conditions', function () {
            global $response;
            $user = (new authentication())->get_user();
            if (!$user) {
                $response->error('Invalid session', 400);
            }

            $has_global = $user->hasPermission('add_department_selfserve_vehicle_conditions');
            $has_own = $user->hasPermission('add_own_department_selfserve_vehicle_conditions');

            if (!$has_global && !$has_own) {
                $response->error('Permission denied', 403);
            }

            $department = (int)$response->getRequestParameter('department');
            $lane = (int)$response->getRequestParameter('lane');
            $reg = (string)$response->getRequestParameter('reg');
            $question = (int)$response->getRequestParameter('question');
            $value = (bool)$response->getRequestParameter('value');

            if (!$department || !$lane || !$reg || !$question) {
                $response->error('Missing required fields', 400);
            }

            if ($has_global) {
                $customer_id = $response->isRequestParameterSet('customer_id') ? (int)$response->getRequestParameter('customer_id') : null;
                $authorized_department_ids = $user->getGroup()->getDepartments();
                if (!in_array($department, $authorized_department_ids)) {
                    $response->error('You do not have access to this department', 403);
                }
            } else {
                // Own permission only
                $customer_id = (int)$user->customer_number->value();
                // Verify vehicle ownership
                $vehicle_o = (new customer_vehicles_o())->selectByPlate($reg);
                if (!$vehicle_o->exists() || (int)$vehicle_o->customer_id->value() !== $customer_id) {
                    $response->error('You do not own this vehicle', 403);
                }
            }

            try {
                $condition_o = new department_selfserve_vehicle_conditions_o();
                $condition_o->add($department, $lane, $reg, $question, $value, $customer_id);
                (new logs_o())->add('department_selfserve_vehicle_conditions', 'global', 1, $user->id, 'ADD_VEHICLE_CONDITION', 'User added department self-serve vehicle condition ' . $condition_o->id);
                $response->success($condition_o->asArray());
            } catch (\Exception $e) {
                $response->error($e->getMessage(), 500);
            }
        }, [
            'add_department_selfserve_vehicle_conditions' => 'Add a department self-serve vehicle condition',
            'add_own_department_selfserve_vehicle_conditions' => 'Add own department self-serve vehicle condition'
        ]);

        /**
         * Update a department self-serve vehicle condition
         */
        $this->put('/department/selfserve/vehicle/conditions', function () {
            global $response;
            $user = (new authentication())->get_user();
            if (!$user) {
                $response->error('Invalid session', 400);
            }

            $has_global = $user->hasPermission('update_department_selfserve_vehicle_conditions');
            $has_own = $user->hasPermission('update_own_department_selfserve_vehicle_conditions');

            if (!$has_global && !$has_own) {
                $response->error('Permission denied', 403);
            }

            $id = (int)$response->getRequestParameter('id');
            if (!$id) {
                $response->error('Missing required fields', 400);
            }

            $condition_o = new department_selfserve_vehicle_conditions_o();
            $condition_o->select($id);
            if (!$condition_o->exists()) {
                $response->error('Condition not found', 404);
            }

            $customer_number = (int)$user->customer_number->value();

            if ($has_global) {
                $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);
                }
            } else {
                // Own permission only
                if ((int)$condition_o->customer_id->value() !== $customer_number) {
                    $response->error('You do not have access to this condition', 403);
                }
            }

            if ($response->isRequestParameterSet('department')) {
                $new_department = (int)$response->getRequestParameter('department');
                if ($has_global) {
                    $authorized_department_ids = $user->getGroup()->getDepartments();
                    if (!in_array($new_department, $authorized_department_ids)) {
                        $response->error('You do not have access to the target department', 403);
                    }
                }
                $condition_o->department->update($new_department);
            }
            if ($response->isRequestParameterSet('lane')) {
                $condition_o->lane->update((int)$response->getRequestParameter('lane'));
            }
            if ($response->isRequestParameterSet('reg')) {
                $new_reg = selfserve::standardize_registration((string)$response->getRequestParameter('reg'));
                if (!$has_global && $has_own) {
                    // Verify ownership of the new reg
                    $vehicle_o = (new customer_vehicles_o())->selectByPlate($new_reg);
                    if (!$vehicle_o->exists() || (int)$vehicle_o->customer_id->value() !== $customer_number) {
                        $response->error('You do not own this vehicle', 403);
                    }
                }
                $condition_o->reg->update($new_reg);
            }
            if ($response->isRequestParameterSet('question')) {
                $condition_o->question->update((int)$response->getRequestParameter('question'));
            }
            if ($response->isRequestParameterSet('value')) {
                $condition_o->value->update((bool)$response->getRequestParameter('value'));
            }
            if ($response->isRequestParameterSet('customer_id')) {
                $new_customer_id = (int)$response->getRequestParameter('customer_id');
                if (!$has_global && $has_own && $new_customer_id !== $customer_number) {
                    $response->error('You cannot change the customer ID to another customer', 403);
                }
                $condition_o->customer_id->update($new_customer_id);
            }

            (new logs_o())->add('department_selfserve_vehicle_conditions', 'global', 1, $user->id, 'UPDATE_VEHICLE_CONDITION', 'User updated department self-serve vehicle condition ' . $id);
            $response->success($condition_o->asArray());
        }, [
            'update_department_selfserve_vehicle_conditions' => 'Update a department self-serve vehicle condition',
            'update_own_department_selfserve_vehicle_conditions' => 'Update own department self-serve vehicle condition'
        ]);

        /**
         * Delete a department self-serve vehicle condition
         */
        $this->delete('/department/selfserve/vehicle/conditions', function () {
            global $response;
            $user = (new authentication())->get_user();
            if (!$user) {
                $response->error('Invalid session', 400);
            }

            $has_global = $user->hasPermission('delete_department_selfserve_vehicle_conditions');
            $has_own = $user->hasPermission('delete_own_department_selfserve_vehicle_conditions');

            if (!$has_global && !$has_own) {
                $response->error('Permission denied', 403);
            }

            $id = (int)$response->getRequestParameter('id');
            if (!$id) {
                $response->error('Missing required fields', 400);
            }

            $condition_o = new department_selfserve_vehicle_conditions_o();
            $condition_o->select($id);
            if (!$condition_o->exists()) {
                $response->error('Condition not found', 404);
            }

            if ($has_global) {
                $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);
                }
            } else {
                // Own permission only
                if ((int)$condition_o->customer_id->value() !== (int)$user->customer_number->value()) {
                    $response->error('You do not have access to this condition', 403);
                }
            }

            $condition_o->delete();
            (new logs_o())->add('department_selfserve_vehicle_conditions', 'global', 1, $user->id, 'DELETE_VEHICLE_CONDITION', 'User deleted department self-serve vehicle condition ' . $id);
            $response->success('Condition deleted');
        }, [
            'delete_department_selfserve_vehicle_conditions' => 'Delete a department self-serve vehicle condition',
            'delete_own_department_selfserve_vehicle_conditions' => 'Delete own department self-serve vehicle condition'
        ]);
    }
}
