<?php

namespace routes;

use classes\authentication;
use classes\response;
use objects\logs_o;
use objects\orders_o;
use traits\route_t;

class orderRoute
{
    use route_t;

    public function run(): void
    {
        $this->get('/order', function () {
            // Require the user to be logged in
            global /** @var response $response */
            $response;
            $this->requirePermission('fetch_order');
            // Get the user object
            $user = (new authentication())->get_user();
            // Check if the request was successful
            if ($user) {
                // Make sure the order id is set
                if (!(int)$this->getParameter('id')) {
                    $response->error('Order id is required', 400);
                }
                $orders_o = new orders_o();
                $orders_o->select((int)$this->getParameter('id'));
                // Make sure the order exists
                if (!$orders_o->exists()) {
                    $response->error('Order not found', 400);
                }
                // Log the incident
                (new logs_o())->add('orders', 'global', 1, $user->id, 'FETCH_ORDER', 'Successfully fetched order');
                // Check if the user has access to the department the order is in
                self::requireDepartmentAccess($orders_o->department_id->value());
                // Return the list of departments
                $response->success(
                    $orders_o->includeIncludes()->asArray()
                );
            } else {
                // Log the incident
                (new logs_o())->add('orders', 'global', 1, 0, 'FETCH_ORDER', 'No user found, or invalid session');
                // Return an error
                $response->error('Invalid session', 400);
            }
        },
            [
                'fetch_order' => 'Fetch any order, provided the user has access to the department the order is in',
                'department_access_:id' => 'Access to the department the order is in'
            ]
        );

        $this->post('/order/wash-certificate', function () {
            // Require the user to be logged in and have permission
            global /** @var response $response */
            $response;
            $this->requirePermission('complete_bookings');
            // Get the user
            $user = (new authentication())->get_user();
            if (!$user) {
                (new logs_o())->add('orders', 'global', 1, 0, 'GENERATE_ORDER_WASH_CERTIFICATE', 'No user found, or invalid session');
                $response->error('Invalid session', 400);
            }

            // Parse request body
            $data = json_decode(file_get_contents('php://input'), true);
            if (!is_array($data)) {
                $data = [];
            }
            if (!isset($data['id']) || !(int)$data['id']) {
                $response->error('Order id is required', 400);
            }

            $orders_o = new orders_o();
            $orders_o->select((int)$data['id']);
            if (!$orders_o->exists()) {
                $response->error('Order not found', 400);
            }

            // Check department access
            self::requireDepartmentAccess($orders_o->department_id->value());

            // Collect optional params
            $safety_seal = null;
            if (isset($data['safety_seal']) && $data['safety_seal'] !== '') {
                $safety_seal = (int)$data['safety_seal'];
            }
            $operator = isset($data['operator']) && $data['operator'] !== '' ? (string)$data['operator'] : (string)$user->display_name->value();
            // Set the date to the creation date of the order if not provided
            if (isset($data['date']) && $data['date'] !== '') {
                $date = date('Y-m-d H:i:s', strtotime($data['date']));
            } else {
                $date = date('Y-m-d H:i:s', strtotime($orders_o->created_at->value()));
            }
            // Determine if already exists
            $already_exists = $orders_o->hasWashCertificateAttached();
            // Generate (no-op if already exists)
            $orders_o->generateWashCertificate($safety_seal, $operator, $date);
            $now_exists = $orders_o->hasWashCertificateAttached();
            // If a booking is associated, send the wash certificate email to the customer
            if ($orders_o->booking_id->value()) {
                $order_booking = $orders_o->getOrderBooking();
                $order_booking?->sendWashCertificateToCustomer();
            }

            (new logs_o())->add('orders', $orders_o->department_id->value(), 1, $user->id, 'GENERATE_ORDER_WASH_CERTIFICATE', 'Wash certificate ' . ($already_exists ? 'already existed' : 'generated'));

            $response->success([
                'order_id' => (int)$orders_o->id,
                'created' => !$already_exists && $now_exists,
                'already_existed' => $already_exists,
            ]);
        }, [
            'complete_bookings' => 'Generate and attach a wash certificate PDF to an order',
            'department_access_:id' => 'Access to the department the order is in'
        ]);

        /**
         * $this->put('/order', function () {
         *
         * // Require the user to be logged in
         * global $response;
         * $this->requirePermission('update_order');
         * // Get the user object
         * $user = (new authentication())->get_user();
         * // Check if the request was successful
         * if ($user) {
         * // Get the post data
         * $data = json_decode(file_get_contents('php://input'), true);
         * // Require the id to be set, and to be a valid integer
         * if (!isset($data['id']) || !(int)$data['id']) {
         * $response->error('Order id is required', 400);
         * }
         * // Get the orders_o objects' properties
         * $order = (new orders_o())->getOrderById($data['id']);
         * // Check if the order exists
         * if (!$order->exists()) {
         * $response->error('Order not found', 400);
         * }
         * // Update the order
         * $order->updateRequest();
         *
         * // Log the incident
         * (new logs_o())->add('orders', $order->department_id->value(), 1, $user->id, 'UPDATE_ORDER', 'Successfully updated order');
         * // Return a success message
         * $response->success(['message' => 'Order updated successfully']);
         * } else {
         * // Log the incident
         * (new logs_o())->add('orders', 'global', 1, 0, 'UPDATE_ORDER', 'No user found, or invalid session');
         * // Return an error
         * $response->error('Invalid session', 400);
         * }
         * },
         * [
         * 'update_order' => 'Update order'
         * ]
         * );
         * }
 */
    }
}