<?php
declare(strict_types=1);

use App\Core\Application;
use App\Core\Http\Request;
use App\Core\Http\Response;
use App\Modules\Auth\AuthController;
use App\Modules\Auth\AuthMiddleware;
use App\Modules\Cron\CronHandlerFactory;
use App\Modules\Cron\CronRepository;
use App\Modules\Orders\OrdersController;
use App\Modules\Orders\OrderImportRepository;
use App\Modules\Orders\OrderNotesService;
use App\Modules\Orders\OrdersRepository;
use App\Modules\Statistics\OrdersStatisticsController;
use App\Modules\Statistics\OrdersStatisticsRepository;
use App\Modules\Settings\AllegroApiClient;
use App\Modules\Settings\AllegroDeliveryMappingController;
use App\Modules\Settings\AllegroIntegrationController;
use App\Modules\Settings\AllegroIntegrationRepository;
use App\Modules\Settings\AllegroOAuthClient;
use App\Modules\Settings\AllegroOrderImportService;
use App\Modules\Settings\AllegroPullStatusMappingRepository;
use App\Modules\Settings\AllegroStatusDiscoveryService;
use App\Modules\Settings\AllegroStatusMappingController;
use App\Modules\Settings\AllegroTokenManager;
use App\Modules\Settings\AllegroStatusMappingRepository;
use App\Modules\Settings\OrderStatusRepository;
use App\Modules\Settings\ApaczkaApiClient;
use App\Modules\Settings\ApaczkaIntegrationController;
use App\Modules\Settings\ApaczkaIntegrationRepository;
use App\Modules\Settings\CarrierDeliveryMethodMappingRepository;
use App\Modules\Settings\FakturowniaApiClient;
use App\Modules\Settings\FakturowniaIntegrationController;
use App\Modules\Settings\FakturowniaIntegrationRepository;
use App\Modules\Settings\HostedSmsApiClient;
use App\Modules\Settings\HostedSmsIntegrationController;
use App\Modules\Settings\HostedSmsIntegrationRepository;
use App\Modules\Settings\InpostIntegrationController;
use App\Modules\Settings\InpostIntegrationRepository;
use App\Modules\Settings\IntegrationsHubController;
use App\Modules\Settings\IntegrationsRepository;
use App\Modules\Settings\PolkurierApiClient;
use App\Modules\Settings\PolkurierIntegrationController;
use App\Modules\Settings\PolkurierIntegrationRepository;
use App\Modules\Settings\SmsplanetApiClient;
use App\Modules\Settings\SmsplanetIntegrationController;
use App\Modules\Settings\SmsplanetIntegrationRepository;
use App\Modules\Settings\ShopproIntegrationsController;
use App\Modules\Settings\ShopproIntegrationsRepository;
use App\Modules\Settings\ShopproPullStatusMappingRepository;
use App\Modules\Settings\ShopproStatusMappingRepository;
use App\Modules\Settings\CompanySettingsController;
use App\Modules\Settings\CompanySettingsRepository;
use App\Modules\Settings\InvoiceConfigController;
use App\Modules\Settings\InvoiceConfigRepository;
use App\Modules\Settings\ReceiptConfigController;
use App\Modules\Settings\ReceiptConfigRepository;
use App\Modules\Settings\EmailMailboxController;
use App\Modules\Settings\EmailMailboxRepository;
use App\Modules\Settings\EmailTemplateController;
use App\Modules\Settings\EmailTemplateRepository;
use App\Modules\Settings\SmsTemplateController;
use App\Modules\Settings\IntegrationSecretCipher;
use App\Modules\Email\AttachmentGenerator;
use App\Modules\Email\EmailSendingService;
use App\Modules\Email\VariableResolver;
use App\Modules\Accounting\AccountingController;
use App\Core\Http\MfWhitelistApiClient;
use App\Modules\Accounting\InvoiceController;
use App\Modules\Accounting\InvoiceRepository;
use App\Modules\Accounting\InvoiceService;
use App\Modules\Accounting\ReceiptController;
use App\Modules\Accounting\ReceiptRepository;
use App\Modules\Accounting\ReceiptService;
use App\Modules\Automation\AutomationController;
use App\Modules\Automation\AutomationRepository;
use App\Modules\Automation\AutomationService;
use App\Modules\Automation\AutomationExecutionLogRepository;
use App\Modules\Automation\AutomationEmailOnceRepository;
use App\Modules\Settings\CronSettingsController;
use App\Modules\Settings\DeliveryStatusMappingController;
use App\Modules\Settings\DeliveryStatusesController;
use App\Modules\Settings\SettingsController;
use App\Modules\Shipments\ApaczkaShipmentService;
use App\Modules\Shipments\PolkurierShipmentService;
use App\Modules\Shipments\AllegroShipmentService;
use App\Modules\Shipments\InpostShipmentService;
use App\Modules\Shipments\ShipmentController;
use App\Modules\Shipments\ShipmentPackageRepository;
use App\Modules\Shipments\ShipmentPresetController;
use App\Modules\Shipments\DeliveryStatusMappingRepository;
use App\Modules\Shipments\DeliveryStatusRepository;
use App\Modules\Shipments\ShipmentPresetRepository;
use App\Modules\Shipments\ShipmentProviderRegistry;
use App\Modules\Printing\ApiKeyMiddleware;
use App\Modules\Printing\PrintApiController;
use App\Modules\Printing\PrintApiKeyRepository;
use App\Modules\Printing\PrintJobRepository;
use App\Modules\Settings\PrintSettingsController;
use App\Modules\Settings\ProjectMappingController;
use App\Modules\Settings\ProjectMappingRepository;
use App\Modules\Info\InfoController;
use App\Modules\Notifications\NotificationApiController;
use App\Modules\Notifications\NotificationController;
use App\Modules\Notifications\NotificationRepository;
use App\Modules\Sms\SmsConversationService;
use App\Modules\Sms\SmsMessageRepository;
use App\Modules\Sms\SmsTemplateRepository;
use App\Modules\Sms\SmsVariableResolver;
use App\Modules\Sms\SmsplanetWebhookController;
use App\Modules\Users\UsersController;

return static function (Application $app): void {
    $router = $app->router();
    $template = $app->template();
    $auth = $app->auth();
    $translator = $app->translator();

    $authController = new AuthController($template, $auth, $translator);
    $usersController = new UsersController($template, $translator, $auth, $app->users());
    $shipmentPackageRepositoryForOrders = new ShipmentPackageRepository($app->db());
    $receiptConfigRepository = new ReceiptConfigRepository($app->db());
    $receiptRepository = new ReceiptRepository($app->db());
    $settingsController = new SettingsController($template, $translator, $auth, $app->migrator(), $app->orderStatuses());
    $allegroIntegrationRepository = new AllegroIntegrationRepository(
        $app->db(),
        (string) $app->config('app.integrations.secret', '')
    );
    $allegroStatusMappingRepository = new AllegroStatusMappingRepository($app->db());
    $carrierDeliveryMappings = new CarrierDeliveryMethodMappingRepository($app->db());
    $allegroOAuthClient = new AllegroOAuthClient();
    $allegroTokenManager = new AllegroTokenManager($allegroIntegrationRepository, $allegroOAuthClient);
    $apaczkaApiClient = new ApaczkaApiClient();
    $cronRepository = new CronRepository($app->db());
    $apaczkaIntegrationRepository = new ApaczkaIntegrationRepository(
        $app->db(),
        (string) $app->config('app.integrations.secret', '')
    );
    $allegroPullStatusMappingRepository = new AllegroPullStatusMappingRepository($app->db());
    $allegroStatusDiscoveryService = new AllegroStatusDiscoveryService(
        $allegroTokenManager,
        new AllegroApiClient(),
        $allegroStatusMappingRepository,
        $allegroPullStatusMappingRepository
    );
    $allegroStatusMappingController = new AllegroStatusMappingController(
        $translator,
        $allegroStatusMappingRepository,
        $app->orderStatuses(),
        $allegroStatusDiscoveryService,
        $allegroPullStatusMappingRepository
    );
    $allegroDeliveryMappingController = new AllegroDeliveryMappingController(
        $translator,
        $allegroIntegrationRepository,
        $allegroOAuthClient,
        new AllegroApiClient(),
        $carrierDeliveryMappings,
        $apaczkaIntegrationRepository,
        $apaczkaApiClient
    );
    $apaczkaIntegrationController = new ApaczkaIntegrationController(
        $template,
        $translator,
        $auth,
        $apaczkaIntegrationRepository,
        $apaczkaApiClient
    );
    $inpostIntegrationRepository = new InpostIntegrationRepository(
        $app->db(),
        (string) $app->config('app.integrations.secret', '')
    );
    $inpostIntegrationController = new InpostIntegrationController(
        $template,
        $translator,
        $auth,
        $inpostIntegrationRepository
    );
    $shopproIntegrationsRepository = new ShopproIntegrationsRepository(
        $app->db(),
        (string) $app->config('app.integrations.secret', '')
    );
    $shopproIntegrationsController = new ShopproIntegrationsController(
        $template,
        $translator,
        $auth,
        $shopproIntegrationsRepository,
        new ShopproStatusMappingRepository($app->db()),
        new ShopproPullStatusMappingRepository($app->db()),
        $app->orderStatuses(),
        $cronRepository,
        $carrierDeliveryMappings,
        $allegroIntegrationRepository,
        $allegroOAuthClient,
        new AllegroApiClient(),
        $apaczkaIntegrationRepository,
        $apaczkaApiClient
    );
    $fakturowniaIntegrationRepository = new FakturowniaIntegrationRepository(
        $app->db(),
        (string) $app->config('app.integrations.secret', '')
    );
    $fakturowniaApiClient = new FakturowniaApiClient();
    $fakturowniaIntegrationController = new FakturowniaIntegrationController(
        $template,
        $translator,
        $auth,
        $fakturowniaIntegrationRepository,
        $fakturowniaApiClient,
        new IntegrationsRepository($app->db())
    );
    $hostedSmsIntegrationRepository = new HostedSmsIntegrationRepository(
        $app->db(),
        (string) $app->config('app.integrations.secret', '')
    );
    $hostedSmsIntegrationController = new HostedSmsIntegrationController(
        $template,
        $translator,
        $auth,
        $hostedSmsIntegrationRepository,
        new HostedSmsApiClient(),
        new IntegrationsRepository($app->db())
    );
    $polkurierIntegrationRepository = new PolkurierIntegrationRepository(
        $app->db(),
        (string) $app->config('app.integrations.secret', '')
    );
    $polkurierIntegrationController = new PolkurierIntegrationController(
        $template,
        $translator,
        $auth,
        $polkurierIntegrationRepository,
        new PolkurierApiClient(),
        new IntegrationsRepository($app->db())
    );
    $smsplanetIntegrationRepository = new SmsplanetIntegrationRepository(
        $app->db(),
        (string) $app->config('app.integrations.secret', '')
    );
    $smsplanetIntegrationController = new SmsplanetIntegrationController(
        $template,
        $translator,
        $auth,
        $smsplanetIntegrationRepository,
        new SmsplanetApiClient(),
        new IntegrationsRepository($app->db())
    );
    $notificationRepository = new NotificationRepository($app->db());
    $smsMessageRepository = new SmsMessageRepository($app->db());
    $smsConversationService = new SmsConversationService(
        $smsMessageRepository,
        $smsplanetIntegrationRepository,
        new SmsplanetApiClient(),
        $notificationRepository
    );
    $smsplanetWebhookController = new SmsplanetWebhookController($smsConversationService);
    $notificationController = new NotificationController($template, $translator, $auth, $notificationRepository);
    $notificationApiController = new NotificationApiController($notificationRepository);
    $integrationsHubController = new IntegrationsHubController(
        $template,
        $translator,
        $auth,
        new IntegrationsRepository($app->db()),
        $allegroIntegrationRepository,
        $apaczkaIntegrationRepository,
        $inpostIntegrationRepository,
        $shopproIntegrationsRepository,
        $fakturowniaIntegrationRepository,
        $hostedSmsIntegrationRepository,
        $smsplanetIntegrationRepository,
        $polkurierIntegrationRepository
    );
    $cronSettingsController = new CronSettingsController(
        $template,
        $translator,
        $auth,
        $cronRepository,
        (bool) $app->config('app.cron.run_on_web_default', false),
        (int) $app->config('app.cron.web_limit_default', 5)
    );
    $deliveryStatusMappingRepository = new DeliveryStatusMappingRepository($app->db());
    $deliveryStatusRepository = new DeliveryStatusRepository($app->db());
    \App\Modules\Shipments\DeliveryStatus::setRepository($deliveryStatusRepository);
    $deliveryStatusesController = new DeliveryStatusesController(
        $template,
        $translator,
        $auth,
        $deliveryStatusRepository,
        $deliveryStatusMappingRepository
    );
    $deliveryStatusMappingController = new DeliveryStatusMappingController(
        $template,
        $translator,
        $auth,
        $deliveryStatusMappingRepository,
        $deliveryStatusRepository
    );
    $companySettingsRepository = new CompanySettingsRepository($app->db());
    $companySettingsController = new CompanySettingsController(
        $template,
        $translator,
        $auth,
        $companySettingsRepository
    );
    $receiptConfigController = new ReceiptConfigController(
        $template,
        $translator,
        $auth,
        $receiptConfigRepository
    );
    $invoiceConfigRepository = new InvoiceConfigRepository($app->db(), $fakturowniaIntegrationRepository);
    $invoiceConfigController = new InvoiceConfigController(
        $template,
        $translator,
        $auth,
        $invoiceConfigRepository,
        $fakturowniaIntegrationRepository
    );
    $invoiceRepository = new InvoiceRepository($app->db());
    $emailMailboxRepository = new EmailMailboxRepository(
        $app->db(),
        new IntegrationSecretCipher((string) $app->config('app.integrations.secret', ''))
    );
    $emailMailboxController = new EmailMailboxController(
        $template,
        $translator,
        $auth,
        $emailMailboxRepository
    );
    $emailTemplateRepository = new EmailTemplateRepository($app->db());
    $emailTemplateController = new EmailTemplateController(
        $template,
        $translator,
        $auth,
        $emailTemplateRepository,
        $emailMailboxRepository
    );
    $smsTemplateRepository = new SmsTemplateRepository($app->db());
    $smsTemplateController = new SmsTemplateController(
        $template,
        $translator,
        $auth,
        $smsTemplateRepository
    );
    $automationRepository = new AutomationRepository($app->db());
    $automationExecutionLogRepository = new AutomationExecutionLogRepository($app->db());
    $automationController = new AutomationController(
        $template,
        $translator,
        $auth,
        $automationRepository,
        $automationExecutionLogRepository,
        $receiptConfigRepository
    );
    $smsVariableResolver = new SmsVariableResolver($shipmentPackageRepositoryForOrders);
    $variableResolver = new VariableResolver($shipmentPackageRepositoryForOrders, $smsVariableResolver);
    $attachmentGenerator = new AttachmentGenerator($receiptRepository, $receiptConfigRepository, $template);
    $emailSendingService = new EmailSendingService(
        $app->db(),
        $app->orders(),
        $emailTemplateRepository,
        $emailMailboxRepository,
        $variableResolver,
        $attachmentGenerator
    );
    $receiptService = new ReceiptService(
        $receiptRepository,
        $receiptConfigRepository,
        $companySettingsRepository,
        new OrdersRepository($app->db())
    );
    $invoiceService = new InvoiceService(
        $invoiceRepository,
        $invoiceConfigRepository,
        $companySettingsRepository,
        new OrdersRepository($app->db()),
        $fakturowniaIntegrationRepository,
        $fakturowniaApiClient
    );
    $automationService = new AutomationService(
        $automationRepository,
        $automationExecutionLogRepository,
        new AutomationEmailOnceRepository($app->db()),
        $emailSendingService,
        new OrdersRepository($app->db()),
        $companySettingsRepository,
        $receiptRepository,
        $receiptConfigRepository,
        $shipmentPackageRepositoryForOrders,
        $receiptService
    );
    $allegroIntegrationController = new AllegroIntegrationController(
        $template,
        $translator,
        $auth,
        $allegroIntegrationRepository,
        $allegroStatusMappingRepository,
        $allegroPullStatusMappingRepository,
        $app->orderStatuses(),
        $cronRepository,
        $allegroOAuthClient,
        new AllegroOrderImportService(
            $allegroIntegrationRepository,
            $allegroTokenManager,
            new AllegroApiClient(),
            new OrderImportRepository($app->db()),
            $allegroStatusMappingRepository,
            new OrdersRepository($app->db()),
            new AllegroPullStatusMappingRepository($app->db()),
            $automationService
        ),
        $allegroStatusDiscoveryService,
        (string) $app->config('app.url', ''),
        $allegroDeliveryMappingController
    );
    $printJobRepository = new PrintJobRepository($app->db());
    $orderNotesService = new OrderNotesService($app->db());
    $ordersController = new OrdersController($template, $translator, $auth, $app->orders(), $shipmentPackageRepositoryForOrders, $receiptRepository, $receiptConfigRepository, $emailSendingService, $emailTemplateRepository, $emailMailboxRepository, $app->basePath('storage'), $printJobRepository, $shopproIntegrationsRepository, $automationService, $invoiceRepository, $invoiceConfigRepository, $smsMessageRepository, $smsConversationService, $smsTemplateRepository, $smsVariableResolver, $companySettingsRepository, $orderNotesService);
    $ordersStatisticsController = new OrdersStatisticsController(
        $template,
        $translator,
        $auth,
        new OrdersStatisticsRepository($app->db())
    );
    $receiptController = new ReceiptController(
        $template,
        $translator,
        $auth,
        $receiptRepository,
        $receiptConfigRepository,
        $companySettingsRepository,
        new OrdersRepository($app->db()),
        $automationService,
        $receiptService
    );
    $accountingController = new AccountingController(
        $template,
        $translator,
        $auth,
        $receiptRepository,
        $receiptConfigRepository
    );
    $invoiceController = new InvoiceController(
        $template,
        $translator,
        $auth,
        $invoiceRepository,
        $invoiceConfigRepository,
        $companySettingsRepository,
        new OrdersRepository($app->db()),
        $invoiceService,
        new MfWhitelistApiClient()
    );
    $allegroApiClient = new AllegroApiClient();
    $shipmentPackageRepository = new ShipmentPackageRepository($app->db());
    $shipmentService = new AllegroShipmentService(
        $allegroTokenManager,
        $allegroApiClient,
        $shipmentPackageRepository,
        $companySettingsRepository,
        new OrdersRepository($app->db())
    );
    $apaczkaShipmentService = new ApaczkaShipmentService(
        $apaczkaIntegrationRepository,
        $apaczkaApiClient,
        $shipmentPackageRepository,
        $companySettingsRepository,
        new OrdersRepository($app->db())
    );
    $inpostShipmentService = new InpostShipmentService(
        $inpostIntegrationRepository,
        $shipmentPackageRepository,
        $companySettingsRepository,
        new OrdersRepository($app->db())
    );
    $polkurierShipmentService = new PolkurierShipmentService(
        $polkurierIntegrationRepository,
        new PolkurierApiClient(),
        $shipmentPackageRepository,
        $companySettingsRepository,
        new OrdersRepository($app->db())
    );
    $shipmentProviderRegistry = new ShipmentProviderRegistry([
        $shipmentService,
        $apaczkaShipmentService,
        $inpostShipmentService,
        $polkurierShipmentService,
    ]);
    $shipmentController = new ShipmentController(
        $template,
        $translator,
        $auth,
        $app->orders(),
        $companySettingsRepository,
        $shipmentProviderRegistry,
        $shipmentPackageRepository,
        $automationService,
        $app->basePath('storage'),
        $carrierDeliveryMappings,
        $printJobRepository
    );
    $authMiddleware = new AuthMiddleware($auth);

    $publicCronHandler = static function (Request $request) use ($app, $cronRepository): Response {
        $token = trim((string) $request->input('token', ''));
        if ($token === '') {
            $token = trim((string) $request->input('tokenValue', ''));
            if (str_starts_with($token, 'token=')) {
                $token = substr($token, 6);
            }
        }

        $expectedToken = trim((string) $app->config('app.cron.public_token', ''));
        if ($expectedToken === '' || $token === '' || !hash_equals($expectedToken, $token)) {
            return Response::json([
                'ok' => false,
                'message' => 'Unauthorized',
            ], 403);
        }

        try {
            $limit = $cronRepository->getIntSetting(
                'cron_web_limit',
                (int) $app->config('app.cron.web_limit_default', 5),
                1,
                100
            );

            $factory = new CronHandlerFactory(
                $app->db(),
                (string) $app->config('app.integrations.secret', ''),
                $app->basePath()
            );
            $runner = $factory->build($cronRepository, $app->logger());
            $runner->run($limit);

            return Response::json([
                'ok' => true,
                'message' => 'Cron executed',
                'limit' => $limit,
                'timestamp' => date(DATE_ATOM),
            ]);
        } catch (\Throwable $exception) {
            $app->logger()->error('Public cron endpoint failed', [
                'message' => $exception->getMessage(),
                'path' => $request->path(),
            ]);

            $debug = (bool) $app->config('app.debug', false);
            return Response::json([
                'ok' => false,
                'message' => 'Cron execution failed',
                'error' => $debug ? $exception->getMessage() : null,
            ], 500);
        }
    };

    $infoController = new InfoController($template);
    $router->get('/info', [$infoController, 'show']);

    $router->get('/health', static fn (Request $request): Response => Response::json([
        'status' => 'ok',
        'app' => (string) $app->config('app.name', 'orderPRO'),
        'timestamp' => date(DATE_ATOM),
    ]));
    $router->get('/cron', $publicCronHandler);
    $router->get('/cron/{tokenValue}', $publicCronHandler);
    $router->post('/webhooks/smsplanet/inbound', [$smsplanetWebhookController, 'inbound']);
    $router->get('/webhooks/smsplanet/inbound', [$smsplanetWebhookController, 'inbound']);

    $router->get('/', static function (Request $request) use ($auth): Response {
        return $auth->check()
            ? Response::redirect('/settings/users')
            : Response::redirect('/login');
    });

    $router->get('/login', [$authController, 'showLogin']);
    $router->post('/login', [$authController, 'login']);
    $router->post('/logout', [$authController, 'logout'], [$authMiddleware]);

    $router->get('/users', static fn (Request $request): Response => Response::redirect('/settings/users'), [$authMiddleware]);
    $router->get('/orders', static fn (Request $request): Response => Response::redirect('/orders/list'), [$authMiddleware]);
    $router->get('/orders/list', [$ordersController, 'index'], [$authMiddleware]);
    $router->get('/statistics/summary', [$ordersStatisticsController, 'summary'], [$authMiddleware]);
    $router->get('/statistics/orders', [$ordersStatisticsController, 'index'], [$authMiddleware]);
    $router->get('/notifications', [$notificationController, 'index'], [$authMiddleware]);
    $router->post('/notifications/mark-read', [$notificationController, 'markRead'], [$authMiddleware]);
    $router->get('/api/notifications/unread', [$notificationApiController, 'unread'], [$authMiddleware]);
    $router->post('/api/notifications/mark-read', [$notificationApiController, 'markRead'], [$authMiddleware]);
    $router->get('/orders/{id}', [$ordersController, 'show'], [$authMiddleware]);
    $router->post('/orders/{id}/status', [$ordersController, 'updateStatus'], [$authMiddleware]);
    $router->post('/orders/{id}/details/update', [$ordersController, 'updateDetails'], [$authMiddleware]);
    $router->post('/orders/{id}/sms/send', [$ordersController, 'sendSms'], [$authMiddleware]);
    $router->get('/orders/{id}/sms/template', [$ordersController, 'smsTemplate'], [$authMiddleware]);
    $router->post('/orders/{id}/send-email', [$ordersController, 'sendEmail'], [$authMiddleware]);
    $router->post('/orders/{id}/email-preview', [$ordersController, 'emailPreview'], [$authMiddleware]);
    $router->get('/api/orders/search', [$ordersController, 'quickSearch'], [$authMiddleware]);
    $router->get('/api/orders/{id}/preview', [$ordersController, 'preview'], [$authMiddleware]);
    $router->post('/orders/{id}/notes', [$ordersController, 'storeNote'], [$authMiddleware]);
    $router->post('/orders/{id}/notes/{noteId}/update', [$ordersController, 'updateNote'], [$authMiddleware]);
    $router->post('/orders/{id}/notes/{noteId}/delete', [$ordersController, 'deleteNote'], [$authMiddleware]);
    $router->post('/users', [$usersController, 'store'], [$authMiddleware]);
    $router->get('/settings/users', [$usersController, 'index'], [$authMiddleware]);
    $router->post('/settings/users', [$usersController, 'store'], [$authMiddleware]);
    $router->get('/settings', static fn (Request $request): Response => Response::redirect('/settings/users'), [$authMiddleware]);
    $router->get('/settings/database', [$settingsController, 'database'], [$authMiddleware]);
    $router->post('/settings/database/migrate', [$settingsController, 'migrate'], [$authMiddleware]);
    $router->get('/settings/statuses', [$settingsController, 'statuses'], [$authMiddleware]);
    $router->post('/settings/status-groups', [$settingsController, 'createStatusGroup'], [$authMiddleware]);
    $router->post('/settings/status-groups/update', [$settingsController, 'updateStatusGroup'], [$authMiddleware]);
    $router->post('/settings/status-groups/delete', [$settingsController, 'deleteStatusGroup'], [$authMiddleware]);
    $router->post('/settings/status-groups/reorder', [$settingsController, 'reorderStatusGroups'], [$authMiddleware]);
    $router->post('/settings/statuses/create', [$settingsController, 'createStatus'], [$authMiddleware]);
    $router->post('/settings/statuses/update', [$settingsController, 'updateStatus'], [$authMiddleware]);
    $router->post('/settings/statuses/delete', [$settingsController, 'deleteStatus'], [$authMiddleware]);
    $router->post('/settings/statuses/reorder', [$settingsController, 'reorderStatuses'], [$authMiddleware]);
    $router->get('/settings/cron', [$cronSettingsController, 'index'], [$authMiddleware]);
    $router->post('/settings/cron', [$cronSettingsController, 'save'], [$authMiddleware]);
    $router->get('/settings/integrations', [$integrationsHubController, 'index'], [$authMiddleware]);
    $router->get('/settings/integrations/allegro', [$allegroIntegrationController, 'index'], [$authMiddleware]);
    $router->post('/settings/integrations/allegro/save', [$allegroIntegrationController, 'save'], [$authMiddleware]);
    $router->post('/settings/integrations/allegro/settings/save', [$allegroIntegrationController, 'saveImportSettings'], [$authMiddleware]);
    $router->post('/settings/integrations/allegro/oauth/start', [$allegroIntegrationController, 'startOAuth'], [$authMiddleware]);
    $router->post('/settings/integrations/allegro/import-single', [$allegroIntegrationController, 'importSingleOrder'], [$authMiddleware]);
    $router->post('/settings/integrations/allegro/statuses/save', [$allegroStatusMappingController, 'saveStatusMapping'], [$authMiddleware]);
    $router->post('/settings/integrations/allegro/statuses/save-bulk', [$allegroStatusMappingController, 'saveStatusMappingsBulk'], [$authMiddleware]);
    $router->post('/settings/integrations/allegro/statuses/delete', [$allegroStatusMappingController, 'deleteStatusMapping'], [$authMiddleware]);
    $router->post('/settings/integrations/allegro/statuses/save-pull', [$allegroStatusMappingController, 'savePullStatusMappings'], [$authMiddleware]);
    $router->post('/settings/integrations/allegro/statuses/sync', [$allegroStatusMappingController, 'syncStatusesFromAllegro'], [$authMiddleware]);
    $router->post('/settings/integrations/allegro/delivery/save', [$allegroDeliveryMappingController, 'saveDeliveryMappings'], [$authMiddleware]);
    $router->get('/settings/integrations/allegro/oauth/callback', [$allegroIntegrationController, 'oauthCallback']);
    $router->get('/settings/integrations/apaczka', [$apaczkaIntegrationController, 'index'], [$authMiddleware]);
    $router->post('/settings/integrations/apaczka/save', [$apaczkaIntegrationController, 'save'], [$authMiddleware]);
    $router->post('/settings/integrations/apaczka/test', [$apaczkaIntegrationController, 'test'], [$authMiddleware]);
    $router->get('/settings/integrations/inpost', [$inpostIntegrationController, 'index'], [$authMiddleware]);
    $router->post('/settings/integrations/inpost/save', [$inpostIntegrationController, 'save'], [$authMiddleware]);
    $router->get('/settings/integrations/fakturownia', [$fakturowniaIntegrationController, 'index'], [$authMiddleware]);
    $router->get('/settings/integrations/fakturownia/new', [$fakturowniaIntegrationController, 'edit'], [$authMiddleware]);
    $router->get('/settings/integrations/fakturownia/edit', [$fakturowniaIntegrationController, 'edit'], [$authMiddleware]);
    $router->post('/settings/integrations/fakturownia/save', [$fakturowniaIntegrationController, 'save'], [$authMiddleware]);
    $router->post('/settings/integrations/fakturownia/test', [$fakturowniaIntegrationController, 'test'], [$authMiddleware]);
    $router->get('/settings/integrations/hostedsms', [$hostedSmsIntegrationController, 'index'], [$authMiddleware]);
    $router->post('/settings/integrations/hostedsms/save', [$hostedSmsIntegrationController, 'save'], [$authMiddleware]);
    $router->post('/settings/integrations/hostedsms/test', [$hostedSmsIntegrationController, 'test'], [$authMiddleware]);
    $router->get('/settings/integrations/polkurier', [$polkurierIntegrationController, 'index'], [$authMiddleware]);
    $router->post('/settings/integrations/polkurier/save', [$polkurierIntegrationController, 'save'], [$authMiddleware]);
    $router->post('/settings/integrations/polkurier/test', [$polkurierIntegrationController, 'test'], [$authMiddleware]);
    $router->get('/settings/integrations/smsplanet', [$smsplanetIntegrationController, 'index'], [$authMiddleware]);
    $router->post('/settings/integrations/smsplanet/save', [$smsplanetIntegrationController, 'save'], [$authMiddleware]);
    $router->post('/settings/integrations/smsplanet/test', [$smsplanetIntegrationController, 'test'], [$authMiddleware]);
    $router->get('/settings/integrations/shoppro', [$shopproIntegrationsController, 'index'], [$authMiddleware]);
    $router->post('/settings/integrations/shoppro/save', [$shopproIntegrationsController, 'save'], [$authMiddleware]);
    $router->post('/settings/integrations/shoppro/test', [$shopproIntegrationsController, 'test'], [$authMiddleware]);
    $router->post('/settings/integrations/shoppro/statuses/save', [$shopproIntegrationsController, 'saveStatusMappings'], [$authMiddleware]);
    $router->post('/settings/integrations/shoppro/statuses/save-pull', [$shopproIntegrationsController, 'savePullStatusMappings'], [$authMiddleware]);
    $router->post('/settings/integrations/shoppro/statuses/sync', [$shopproIntegrationsController, 'syncStatuses'], [$authMiddleware]);
    $router->post('/settings/integrations/shoppro/delivery/save', [$shopproIntegrationsController, 'saveDeliveryMappings'], [$authMiddleware]);
    $router->get('/settings/company', [$companySettingsController, 'index'], [$authMiddleware]);
    $router->post('/settings/company/save', [$companySettingsController, 'save'], [$authMiddleware]);
    $router->get('/settings/accounting', [$receiptConfigController, 'hub'], [$authMiddleware]);
    $router->get('/settings/accounting/receipts', [$receiptConfigController, 'list'], [$authMiddleware]);
    $router->get('/settings/accounting/receipts/new', [$receiptConfigController, 'edit'], [$authMiddleware]);
    $router->get('/settings/accounting/receipts/edit', [$receiptConfigController, 'edit'], [$authMiddleware]);
    $router->post('/settings/accounting/receipts/save', [$receiptConfigController, 'save'], [$authMiddleware]);
    $router->post('/settings/accounting/receipts/toggle', [$receiptConfigController, 'toggleStatus'], [$authMiddleware]);
    $router->post('/settings/accounting/receipts/delete', [$receiptConfigController, 'delete'], [$authMiddleware]);
    // Legacy aliases (backwards compatibility with bookmarks/form actions from before Phase 114-01)
    $router->post('/settings/accounting/save', [$receiptConfigController, 'save'], [$authMiddleware]);
    $router->post('/settings/accounting/toggle', [$receiptConfigController, 'toggleStatus'], [$authMiddleware]);
    $router->post('/settings/accounting/delete', [$receiptConfigController, 'delete'], [$authMiddleware]);
    // Invoices (Phase 114-01)
    $router->get('/settings/accounting/invoices', [$invoiceConfigController, 'index'], [$authMiddleware]);
    $router->get('/settings/accounting/invoices/new', [$invoiceConfigController, 'edit'], [$authMiddleware]);
    $router->get('/settings/accounting/invoices/edit', [$invoiceConfigController, 'edit'], [$authMiddleware]);
    $router->post('/settings/accounting/invoices/save', [$invoiceConfigController, 'save'], [$authMiddleware]);
    $router->post('/settings/accounting/invoices/toggle', [$invoiceConfigController, 'toggleStatus'], [$authMiddleware]);
    $router->post('/settings/accounting/invoices/delete', [$invoiceConfigController, 'delete'], [$authMiddleware]);
    $router->get('/settings/email-mailboxes', [$emailMailboxController, 'index'], [$authMiddleware]);
    $router->post('/settings/email-mailboxes/save', [$emailMailboxController, 'save'], [$authMiddleware]);
    $router->post('/settings/email-mailboxes/delete', [$emailMailboxController, 'delete'], [$authMiddleware]);
    $router->post('/settings/email-mailboxes/toggle', [$emailMailboxController, 'toggleStatus'], [$authMiddleware]);
    $router->post('/settings/email-mailboxes/test', [$emailMailboxController, 'testConnection'], [$authMiddleware]);
    $router->get('/settings/email-templates', [$emailTemplateController, 'index'], [$authMiddleware]);
    $router->get('/settings/email-templates/create', [$emailTemplateController, 'create'], [$authMiddleware]);
    $router->get('/settings/email-templates/edit', [$emailTemplateController, 'edit'], [$authMiddleware]);
    $router->post('/settings/email-templates/save', [$emailTemplateController, 'save'], [$authMiddleware]);
    $router->post('/settings/email-templates/delete', [$emailTemplateController, 'delete'], [$authMiddleware]);
    $router->post('/settings/email-templates/duplicate', [$emailTemplateController, 'duplicate'], [$authMiddleware]);
    $router->post('/settings/email-templates/toggle', [$emailTemplateController, 'toggleStatus'], [$authMiddleware]);
    $router->post('/settings/email-templates/preview', [$emailTemplateController, 'preview'], [$authMiddleware]);
    $router->get('/settings/email-templates/variables', [$emailTemplateController, 'getVariables'], [$authMiddleware]);
    $router->get('/settings/sms-templates', [$smsTemplateController, 'index'], [$authMiddleware]);
    $router->get('/settings/sms-templates/create', [$smsTemplateController, 'create'], [$authMiddleware]);
    $router->get('/settings/sms-templates/edit', [$smsTemplateController, 'edit'], [$authMiddleware]);
    $router->post('/settings/sms-templates/save', [$smsTemplateController, 'save'], [$authMiddleware]);
    $router->post('/settings/sms-templates/delete', [$smsTemplateController, 'delete'], [$authMiddleware]);
    $router->post('/settings/sms-templates/toggle', [$smsTemplateController, 'toggleStatus'], [$authMiddleware]);
    $router->get('/settings/sms-templates/variables', [$smsTemplateController, 'getVariables'], [$authMiddleware]);
    $router->get('/settings/automation', [$automationController, 'index'], [$authMiddleware]);
    $router->get('/settings/automation/create', [$automationController, 'create'], [$authMiddleware]);
    $router->post('/settings/automation/store', [$automationController, 'store'], [$authMiddleware]);
    $router->get('/settings/automation/edit', [$automationController, 'edit'], [$authMiddleware]);
    $router->post('/settings/automation/update', [$automationController, 'update'], [$authMiddleware]);
    $router->post('/settings/automation/delete', [$automationController, 'destroy'], [$authMiddleware]);
    $router->post('/settings/automation/duplicate', [$automationController, 'duplicate'], [$authMiddleware]);
    $router->post('/settings/automation/toggle', [$automationController, 'toggleStatus'], [$authMiddleware]);
    $router->get('/settings/delivery-status-mappings', [$deliveryStatusMappingController, 'index'], [$authMiddleware]);
    $router->post('/settings/delivery-status-mappings/save', [$deliveryStatusMappingController, 'save'], [$authMiddleware]);
    $router->post('/settings/delivery-status-mappings/save-bulk', [$deliveryStatusMappingController, 'saveBulk'], [$authMiddleware]);
    $router->post('/settings/delivery-status-mappings/reset', [$deliveryStatusMappingController, 'reset'], [$authMiddleware]);
    $router->post('/settings/delivery-status-mappings/reset-all', [$deliveryStatusMappingController, 'resetAll'], [$authMiddleware]);
    $router->get('/settings/delivery-statuses', [$deliveryStatusesController, 'index'], [$authMiddleware]);
    $router->get('/settings/delivery-statuses/new', [$deliveryStatusesController, 'create'], [$authMiddleware]);
    $router->get('/settings/delivery-statuses/{id}/edit', [$deliveryStatusesController, 'edit'], [$authMiddleware]);
    $router->post('/settings/delivery-statuses', [$deliveryStatusesController, 'store'], [$authMiddleware]);
    $router->post('/settings/delivery-statuses/{id}/update', [$deliveryStatusesController, 'update'], [$authMiddleware]);
    $router->post('/settings/delivery-statuses/{id}/delete', [$deliveryStatusesController, 'destroy'], [$authMiddleware]);
    $router->get('/accounting', [$accountingController, 'index'], [$authMiddleware]);
    $router->post('/accounting/export', [$accountingController, 'export'], [$authMiddleware]);
    $router->get('/orders/{id}/receipt/create', [$receiptController, 'create'], [$authMiddleware]);
    $router->post('/orders/{id}/receipt/store', [$receiptController, 'store'], [$authMiddleware]);
    $router->get('/orders/{id}/receipt/{receiptId}', [$receiptController, 'show'], [$authMiddleware]);
    $router->get('/orders/{id}/receipt/{receiptId}/print', [$receiptController, 'printView'], [$authMiddleware]);
    $router->get('/orders/{id}/receipt/{receiptId}/pdf', [$receiptController, 'pdf'], [$authMiddleware]);
    // Invoices from order (Phase 115-01)
    $router->post('/orders/{id}/invoice-requested/toggle', [$ordersController, 'toggleInvoiceRequested'], [$authMiddleware]);
    $router->get('/orders/{id}/invoice/create', [$invoiceController, 'create'], [$authMiddleware]);
    $router->post('/orders/{id}/invoice/store', [$invoiceController, 'store'], [$authMiddleware]);
    $router->get('/orders/{id}/invoice/{invoiceId}', [$invoiceController, 'show'], [$authMiddleware]);
    $router->get('/orders/{id}/invoice/{invoiceId}/pdf', [$invoiceController, 'pdf'], [$authMiddleware]);
    $router->get('/settings/accounting/invoices/issued', [$invoiceController, 'issuedList'], [$authMiddleware]);
    $router->get('/api/nip/lookup', [$invoiceController, 'nipLookup'], [$authMiddleware]);
    $router->get('/orders/{id}/shipment/prepare', [$shipmentController, 'prepare'], [$authMiddleware]);
    $router->post('/orders/{id}/shipment/create', [$shipmentController, 'create'], [$authMiddleware]);
    $router->get('/orders/{id}/shipment/{packageId}/status', [$shipmentController, 'checkStatus'], [$authMiddleware]);
    $router->post('/orders/{id}/shipment/{packageId}/label', [$shipmentController, 'label'], [$authMiddleware]);
    $router->post('/orders/{id}/shipment/manual', [$shipmentController, 'createManual'], [$authMiddleware]);
    $router->post('/orders/{id}/shipment/{packageId}/delete', [$shipmentController, 'delete'], [$authMiddleware]);
    $router->post('/orders/{id}/payment/add', [$ordersController, 'addPayment'], [$authMiddleware]);

    // --- Printing module ---
    $printApiKeyRepository = new PrintApiKeyRepository($app->db());
    $apiKeyMiddleware = new ApiKeyMiddleware($printApiKeyRepository);
    $printApiController = new PrintApiController(
        $printJobRepository,
        $shipmentPackageRepository,
        $auth,
        $app->basePath('storage'),
        $shipmentProviderRegistry
    );
    $printSettingsController = new PrintSettingsController($template, $translator, $auth, $printApiKeyRepository, $printJobRepository);
    $projectMappingRepository = new ProjectMappingRepository($app->db());
    $projectMappingController = new ProjectMappingController(
        $template,
        $translator,
        $auth,
        $projectMappingRepository,
        $app->basePath()
    );

    // Print API — session auth (from orderPRO UI)
    $router->post('/api/print/jobs', [$printApiController, 'createJob'], [$authMiddleware]);
    $router->get('/api/print/jobs/status', [$printApiController, 'status'], [$authMiddleware]);

    // Print API — API key auth (from Windows client)
    $router->get('/api/print/jobs/pending', [$printApiController, 'listPending'], [$apiKeyMiddleware]);
    $router->get('/api/print/jobs/{id}/download', [$printApiController, 'downloadLabel'], [$apiKeyMiddleware]);
    $router->post('/api/print/jobs/{id}/complete', [$printApiController, 'markComplete'], [$apiKeyMiddleware]);

    // Print settings
    $router->get('/settings/printing', [$printSettingsController, 'index'], [$authMiddleware]);
    $router->post('/settings/printing/keys/create', [$printSettingsController, 'createKey'], [$authMiddleware]);
    $router->post('/settings/printing/keys/{id}/delete', [$printSettingsController, 'deleteKey'], [$authMiddleware]);
    $router->post('/settings/printing/jobs/delete', [$printSettingsController, 'deleteJob'], [$authMiddleware]);

    // Project mappings
    $router->get('/settings/project-mappings', [$projectMappingController, 'index'], [$authMiddleware]);
    $router->post('/settings/project-mappings', [$projectMappingController, 'store'], [$authMiddleware]);
    $router->post('/settings/project-mappings/{id}/update', [$projectMappingController, 'update'], [$authMiddleware]);
    $router->post('/settings/project-mappings/{id}/delete', [$projectMappingController, 'delete'], [$authMiddleware]);
    $router->post('/settings/project-mappings/{id}/toggle', [$projectMappingController, 'toggleActive'], [$authMiddleware]);

    // Shipment presets API
    $presetRepository = new ShipmentPresetRepository($app->db());
    $presetController = new ShipmentPresetController($presetRepository);

    $router->get('/api/shipment-presets', [$presetController, 'list'], [$authMiddleware]);
    $router->post('/api/shipment-presets', [$presetController, 'store'], [$authMiddleware]);
    $router->post('/api/shipment-presets/update', [$presetController, 'update'], [$authMiddleware]);
    $router->post('/api/shipment-presets/delete', [$presetController, 'destroy'], [$authMiddleware]);
};
