"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = require("express");
const AuthMiddleware_1 = require("../../Application/Services/AuthMiddleware");
const DIContainer_1 = require("../../Application/Services/DIContainer");
const Generalsearch_1 = require("../../Application/Search/Generalsearch");
const Logger_1 = require("../../Application/Services/Logger");
const deckRouter = (0, express_1.Router)();
// Create search service that isn't in the container yet
const searchService = new Generalsearch_1.GeneralSearchService(DIContainer_1.container.userRepository, DIContainer_1.container.organizationRepository, DIContainer_1.container.deckRepository);
// Authenticated routes - Get decks with pagination (RECOMMENDED)
deckRouter.get('/page/:from/:to', AuthMiddleware_1.authRequired, async (req, res) => {
    try {
        const userId = req.user.userId;
        const userOrgId = req.user.orgId;
        const isAdmin = req.user.authLevel === 1;
        const from = parseInt(req.params.from);
        const to = parseInt(req.params.to);
        if (isNaN(from) || isNaN(to) || from < 0 || to < from) {
            return res.status(400).json({ error: 'Invalid page parameters. "from" and "to" must be valid numbers with to >= from >= 0' });
        }
        (0, Logger_1.logRequest)('Get decks by page endpoint accessed', req, res, {
            userId,
            userOrgId,
            isAdmin,
            from,
            to
        });
        // Use paginated query handler for memory efficiency
        const result = await DIContainer_1.container.getDecksByPageQueryHandler.execute({
            userId,
            userOrgId,
            isAdmin,
            from,
            to
        });
        (0, Logger_1.logRequest)('Get decks page completed successfully', req, res, {
            userId,
            from,
            to,
            returnedCount: result.decks.length,
            totalCount: result.totalCount
        });
        res.json(result);
    }
    catch (error) {
        (0, Logger_1.logError)('Get decks by page endpoint error', error, req, res);
        res.status(500).json({ error: 'Internal server error' });
    }
});
deckRouter.post('/', AuthMiddleware_1.authRequired, async (req, res) => {
    try {
        const userId = req.user.userId;
        (0, Logger_1.logRequest)('Create deck endpoint accessed', req, res, { name: req.body.name, userId });
        const result = await DIContainer_1.container.createDeckCommandHandler.execute(req.body);
        (0, Logger_1.logRequest)('Deck created successfully', req, res, { deckId: result.id, name: req.body.name, userId });
        res.json(result);
    }
    catch (error) {
        (0, Logger_1.logError)('Create deck endpoint error', error, req, res);
        if (error instanceof Error && (error.message.includes('duplicate') || error.message.includes('unique constraint'))) {
            return res.status(409).json({ error: 'Deck with this name already exists' });
        }
        if (error instanceof Error && error.message.includes('validation')) {
            return res.status(400).json({ error: 'Invalid input data', details: error.message });
        }
        res.status(500).json({ error: 'Internal server error' });
    }
});
deckRouter.get('/search', AuthMiddleware_1.authRequired, async (req, res) => {
    try {
        const { q: query, limit, offset } = req.query;
        (0, Logger_1.logRequest)('Search decks endpoint accessed', req, res, { query, limit, offset });
        if (!query || typeof query !== 'string') {
            (0, Logger_1.logWarning)('Deck search attempted without query', { query, hasQuery: !!query }, req, res);
            return res.status(400).json({ error: 'Search query is required' });
        }
        const searchQuery = {
            query: query.trim(),
            limit: limit ? parseInt(limit) : 20,
            offset: offset ? parseInt(offset) : 0
        };
        // Validate pagination parameters
        if (searchQuery.limit < 1 || searchQuery.limit > 100) {
            (0, Logger_1.logWarning)('Invalid deck search limit parameter', { limit: searchQuery.limit }, req, res);
            return res.status(400).json({ error: 'Limit must be between 1 and 100' });
        }
        if (searchQuery.offset < 0) {
            (0, Logger_1.logWarning)('Invalid deck search offset parameter', { offset: searchQuery.offset }, req, res);
            return res.status(400).json({ error: 'Offset must be non-negative' });
        }
        const result = await searchService.searchFromUrl(req.originalUrl, searchQuery);
        (0, Logger_1.logRequest)('Deck search completed successfully', req, res, {
            query: searchQuery.query,
            resultCount: Array.isArray(result) ? result.length : 0
        });
        res.json(result);
    }
    catch (error) {
        (0, Logger_1.logError)('Search decks endpoint error', error, req, res);
        res.status(500).json({ error: 'Internal server error' });
    }
});
deckRouter.get('/:id', AuthMiddleware_1.authRequired, async (req, res) => {
    try {
        const deckId = req.params.id;
        (0, Logger_1.logRequest)('Get deck by id endpoint accessed', req, res, { deckId });
        const result = await DIContainer_1.container.getDeckByIdQueryHandler.execute({ id: deckId });
        if (!result) {
            (0, Logger_1.logWarning)('Deck not found', { deckId }, req, res);
            return res.status(404).json({ error: 'Deck not found' });
        }
        (0, Logger_1.logRequest)('Deck retrieved successfully', req, res, { deckId });
        res.json(result);
    }
    catch (error) {
        (0, Logger_1.logError)('Get deck by id endpoint error', error, req, res);
        res.status(500).json({ error: 'Internal server error' });
    }
});
deckRouter.put('/:id', AuthMiddleware_1.authRequired, async (req, res) => {
    try {
        const deckId = req.params.id;
        const userId = req.user.userId;
        (0, Logger_1.logRequest)('Update deck endpoint accessed', req, res, { deckId, userId, updateFields: Object.keys(req.body) });
        const result = await DIContainer_1.container.updateDeckCommandHandler.execute({ id: deckId, ...req.body });
        (0, Logger_1.logRequest)('Deck updated successfully', req, res, { deckId, userId });
        res.json(result);
    }
    catch (error) {
        (0, Logger_1.logError)('Update deck endpoint error', error, req, res);
        if (error instanceof Error && error.message.includes('not found')) {
            return res.status(404).json({ error: 'Deck not found' });
        }
        if (error instanceof Error && (error.message.includes('duplicate') || error.message.includes('unique constraint'))) {
            return res.status(409).json({ error: 'Deck with this name already exists' });
        }
        if (error instanceof Error && error.message.includes('validation')) {
            return res.status(400).json({ error: 'Invalid input data', details: error.message });
        }
        res.status(500).json({ error: 'Internal server error' });
    }
});
deckRouter.delete('/:id', AuthMiddleware_1.authRequired, async (req, res) => {
    try {
        const deckId = req.params.id;
        const userId = req.user.userId;
        (0, Logger_1.logRequest)('Soft delete deck endpoint accessed', req, res, { deckId, userId });
        const result = await DIContainer_1.container.deleteDeckCommandHandler.execute({ id: deckId, soft: true });
        (0, Logger_1.logRequest)('Deck soft delete successful', req, res, { deckId, userId, success: result });
        res.json({ success: result });
    }
    catch (error) {
        (0, Logger_1.logError)('Soft delete deck endpoint error', error, req, res);
        if (error instanceof Error && error.message.includes('not found')) {
            return res.status(404).json({ error: 'Deck not found' });
        }
        res.status(500).json({ error: 'Internal server error' });
    }
});
exports.default = deckRouter;
//# sourceMappingURL=deckRouter.js.map