<?php

namespace routes;

use classes\authentication;
use classes\redis;
use classes\response;
use classes\stripe;
use classes\xlvask;
use objects\collected_order_invoices_o;
use objects\departments_o;
use objects\economic_module_orders;
use objects\logs_o;
use objects\orders_o;
use objects\stripe_module_orders_o;
use objects\stripe_payment_intents_o;
use objects\users_o;
use objects\xlvask_usage_logs_o;
use traits\route_t;

class xlvaskUsageLogsRoute
{
    use route_t;

    public function run(): void
    {
        $this->get('/modules/xlvask/services/usage/orders', function () {
            // Define the permissions:
            $permission_list_own = 'list_xlvask_usage_orders_own'; // Permission to list own orders (Without department filter)
            $permission_list_all = 'list_xlvask_usage_orders_all'; // Permission to list all orders (With department filter)
            $response_includes_items = false; // Whether to include items in the response (This would increase the memory usage significantly)
            $response_includes_items_link = true; // Whether to include a cached direct link to fetch the order with items (This is used to avoid memory issues when the items are not needed)
            // Require the user to be logged in
            global $response;
            self::requirePermission($permission_list_own);
            // Check if the user has permission to list all entries
            if (self::hasPermission($permission_list_all)) {
                $this->requirePermission($permission_list_all);
            } else {
                $this->requirePermission($permission_list_own);
            }
            // Get the user object
            $user = (new authentication())->get_user();
            // Check if the request was successful
            if ($user) {
                // Log the incident
                (new logs_o())->add('xlvask_usage_orders', 'global', 1, $user->id, 'LIST_XLVASK_USAGE_ORDERS', 'User accessed the list of xlvask usage orders');
                $xlvask_usage_logs = new xlvask_usage_logs_o();
                $xlvask = new xlvask();
                $xlvask->new($xlvask->helpers->xlvask_usage_log)->getDepartment();
                $orders_o = new orders_o();
                $xlvask_usage_log = $xlvask->new($xlvask->helpers->xlvask_usage_log);
                // Increase the memory limit to 512MB (Provided it's currently less than that)
                if (ini_get('memory_limit') < '5120M') {
                    ini_set('memory_limit', '5120M');
                }
                // Set debug php
                error_reporting(E_ALL);
                ini_set('display_errors', '1');
                // Return the list of usage logs
                $result = $xlvask_usage_logs
                    // Make sure the Customer is not in the default customers list
                    ->setAdditionalWhereClause("`Customer` NOT IN ('" . implode("', '", $xlvask_usage_log::$default_customers) . "')")
                    ->listObjectsWithPaginationIfSet(
                        function ($log) use ($response_includes_items_link, $response_includes_items, $xlvask_usage_logs, $user, $xlvask) {
                            // Remove the 'id' field from the log
                            $id = (int)$log['id'];
                            unset($log['id']);
                            // Convert the 'WashItems' field from JSON to an array
                            $log['WashItems'] = json_decode($log['WashItems'], true);
                            // Create a new xlvask usage log object
                            $tmp = $xlvask->new($xlvask->helpers->xlvask_usage_log);
                            // Set the properties of the temporary object
                            $tmp->setProperties($log);
                            // Define the result structure
                            $isEligibleForAutomaticContinuance = $tmp->isEligibleForAutomaticContinuance(true);
                            // Generate a fast link key for the order, used to retrieve the order with items later.
                            if ($response_includes_items_link && $isEligibleForAutomaticContinuance) {
                                // Add a link to the order with items
                                $fast_link_key = redis->generateTemporaryCacheKey();
                                redis->set(
                                    $fast_link_key,
                                    json_encode($tmp->toArray(), JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
                                );
                                redis->expire($fast_link_key, 3600); // Set the link to expire in 1 hour
                            }
                            // Return the result
                            $tmp_res = ($isEligibleForAutomaticContinuance ? (new orders_o())->simulateOrderFromXLVask($tmp, $response_includes_items) : []);
                            $tmp_res['order']['customer_name'] = $tmp->Customer; // Add the customer name to the order
                            // Clear memory
                            unset($tmp);
                            unset($log);
                            // Return the result
                            return [
                                'id' => $id, // Return the ID of the log
                                'fast_link_key' => $fast_link_key ?? null, // Return the fast link key if it was generated
                                ...$tmp_res['order'], // Return the simulated order from XLVask (with or without items)
                                ];
                        },
                        $xlvask_usage_logs->forceRestrictFilters(
                            [
                                // This makes sure that the user can only see department logs that belong to their departments
                                'HallId' => $user->getGroup()->getDepartmentsScannersHallIds(),
                                'FinishStatus' => ['1'], // Only show finished logs
                            ]
                        )
                    );
                // Return the response
                $response->success($result);
            } else {
                // Log the incident
                (new logs_o())->add('xlvask_usage_orders', 'global', 1, 0, 'LIST_XLVASK_USAGE_ORDERS', 'No user found, or invalid session');
                // Return an error
                $response->error('Invalid session', 400);
            }
        },
            [
                'list_xlvask_usage_orders_own' => 'List own xlvask usage orders (Without department filter)',
                'list_xlvask_usage_orders_all' => 'List all xlvask usage orders (With department filter)',
            ]
        );

        $this->get('/modules/xlvask/services/usage/orders/fast-link', function () {
            global $response;
            self::requireParameters([
                'fast_link_key', // Example: 'temporary_cache_6878cf0603d77'
            ]);
            // Get the fast link key from the request
            $fast_link_key = (string)self::getParameter('fast_link_key');
            self::requireType($fast_link_key, self::type_string());
            self::requireMinLength('fast_link_key', 20); // Minimum length of the fast link key
            self::requireMaxLength('fast_link_key', 50); // Maximum length of the fast link key
            // Check if the fast link key is valid
            // First, check if the key has the correct format
            if (preg_match('/^temporary_cache_[a-z0-9]{12,32}$/', $fast_link_key)) {
                // Get the cached data from Redis
                $cached_data = redis->get($fast_link_key);
                // Check if the cached data is valid
                if ($cached_data) {
                    // Decode the cached data
                    $data = json_decode($cached_data, true);
                    // Check if the data is valid
                    if (is_array($data)) {
                        // Delete the cached data from Redis
                        redis->delete($fast_link_key);
                        // Return the data
                        $xlvask = new xlvask();
                        $order_arr = (new orders_o())->simulateOrderFromXLVask($xlvask->new($xlvask->helpers->xlvask_usage_log)->setProperties($data), true); //  ['order' => $order_arr, 'order_items' => $items_arr]
                        $tmp_order_obj = (object)[];
                        $tmp_order_arr = $order_arr['order'] ?? [];
                        /**
                         * "id": -1,
                         * "customer_id": 39159000,
                         * "cashier_id": 2285,
                         * "reference": "Simulated Order from XL Vask",
                         * "notes": "This is a simulated order generated from an XL Vask usage log",
                         * "department_id": 1,
                         * "reg_1": "DE55248",
                         * "reg_2": "",
                         * "reg_3": "",
                         * "completed_at": null,
                         * "created_at": "2025-07-16 13:04:54",
                         * "deleted_at": null,
                         * "total_net_amount": 683,
                         * "invoice_collection_id": 0,
                         * "booking_id": 0,
                         * "wash_id": "b24728ea-e22b-4dce-8cd3-a0998f7fdc5e",
                         * "lane": 1,
                         * "closed_at": null
                         */
                        $tmp_order_obj->customer_id = $tmp_order_arr['customer_id'] ?? 0;
                        $tmp_order_obj->department_id = $tmp_order_arr['department_id'] ?? 0;
                        $tmp_order_obj->reg_1 = $tmp_order_arr['reg_1'] ?? '';
                        $tmp_order_obj->reg_2 = $tmp_order_arr['reg_2'] ?? '';
                        $tmp_order_obj->reg_3 = $tmp_order_arr['reg_3'] ?? '';
                        $tmp_order_obj->created_at = $tmp_order_arr['created_at'] ?? '';
                        $tmp_order_obj->wash_id = $tmp_order_arr['wash_id'] ?? '';
                        $tmp_order_obj->lane = $tmp_order_arr['lane'] ?? 0;
                        $response->success([
                            ...$order_arr,
                            'potential_duplicates' => (new orders_o())->getOrderPotentialDuplicatesIfFound(
                                $tmp_order_obj->reg_1,
                                $tmp_order_obj->reg_2,
                                $tmp_order_obj->reg_3,
                                $tmp_order_obj->department_id,
                                $tmp_order_obj->created_at,
                            ),
                        ]);
                    } else {
                        // Return an error if the data is not valid
                        $response->error('Invalid cached data', 400);
                    }
                } else {
                    // Return an error if the fast link key does not exist in Redis
                    $response->error('Fast link key not found', 404);
                }
            } else {
                // Return an error if the fast link key is invalid
                $response->error('Invalid fast link key format', 400);
            }
        },
            [
                'fast_link_key' => 'string', // Example: 'temporary_cache_6878cf0603d77'
            ]
        );
    }
}