"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getTrendingSearches = exports.getAutocompleteSuggestions = exports.searchBooks = void 0;
const database_1 = __importDefault(require("../config/database"));
const search_1 = require("../config/search");
const response_utils_1 = require("../utils/response.utils");
// 1. Intelligent Search Endpoint (Supports Meilisearch / Database Fallback)
const searchBooks = async (req, res) => {
    try {
        const { query = '', category, language, author, publisher, minPrice, maxPrice, minRating, sortBy = 'relevance', limit = 20, page = 1, } = req.query;
        const take = Math.max(1, Math.min(100, Number(limit) || 20));
        const currentPage = Math.max(1, Number(page) || 1);
        const skip = (currentPage - 1) * take;
        // Try Meilisearch index query if query text is provided
        try {
            if (query && search_1.meiliClient) {
                const index = search_1.meiliClient.index('books');
                const searchRes = await index.search(String(query), {
                    limit: take,
                    offset: skip,
                    filter: [
                        language ? `language = "${language}"` : null,
                        minPrice ? `price >= ${minPrice}` : null,
                        maxPrice ? `price <= ${maxPrice}` : null,
                    ].filter(Boolean),
                });
                if (searchRes.hits && searchRes.hits.length > 0) {
                    return (0, response_utils_1.sendSuccess)(res, 'Search results from Meilisearch', {
                        hits: searchRes.hits,
                        totalHits: searchRes.estimatedTotalHits,
                        source: 'MEILISEARCH',
                    });
                }
            }
        }
        catch (searchErr) {
            // Fallback seamlessly to MySQL fulltext search
        }
        // MySQL Database Fallback Query
        const where = { isActive: true };
        if (query) {
            const qStr = String(query).trim();
            where.OR = [
                { title: { contains: qStr } },
                { isbn: { contains: qStr } },
                { barcode: { contains: qStr } },
                { description: { contains: qStr } },
                { publisher: { name: { contains: qStr } } },
                { bookAuthors: { some: { author: { name: { contains: qStr } } } } },
                { bookCategories: { some: { category: { name: { contains: qStr } } } } },
            ];
        }
        if (language)
            where.language = String(language);
        if (category) {
            const value = String(category);
            where.bookCategories = { some: { category: { OR: [{ id: value }, { slug: value }, { name: value }] } } };
        }
        if (author) {
            const value = String(author);
            where.bookAuthors = { some: { author: { OR: [{ id: value }, { slug: value }, { name: value }] } } };
        }
        if (publisher) {
            const value = String(publisher);
            where.publisher = { OR: [{ id: value }, { slug: value }, { name: value }] };
        }
        if (minPrice || maxPrice) {
            where.price = {};
            if (minPrice)
                where.price.gte = Number(minPrice);
            if (maxPrice)
                where.price.lte = Number(maxPrice);
        }
        if (minRating)
            where.ratingAverage = { gte: Number(minRating) };
        let orderBy = { createdAt: 'desc' };
        if (sortBy === 'price_asc')
            orderBy = { price: 'asc' };
        if (sortBy === 'price_desc')
            orderBy = { price: 'desc' };
        if (sortBy === 'rating')
            orderBy = { ratingAverage: 'desc' };
        const [books, total] = await Promise.all([
            database_1.default.book.findMany({
                where,
                take,
                skip,
                include: {
                    publisher: true,
                    bookAuthors: { include: { author: true } },
                    bookCategories: { include: { category: true } },
                },
                orderBy,
            }),
            database_1.default.book.count({ where }),
        ]);
        const formattedResults = books.map((b) => ({
            id: b.id,
            title: b.title,
            slug: b.slug,
            isbn: b.isbn,
            price: Number(b.price),
            discountPrice: b.discountPrice ? Number(b.discountPrice) : null,
            coverImage: b.coverImage,
            ratingAverage: Number(b.ratingAverage),
            authorName: b.bookAuthors[0]?.author.name || 'Indian Author',
            publisherName: b.publisher?.name || 'IBW Press',
            categoryName: b.bookCategories[0]?.category.name || 'General',
        }));
        return (0, response_utils_1.sendSuccess)(res, 'Search results retrieved', {
            books: formattedResults,
            pagination: {
                total,
                page: currentPage,
                limit: take,
                totalPages: Math.ceil(total / take),
            },
            source: 'MYSQL_DATABASE',
        });
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'Search query failed', error.message, 500);
    }
};
exports.searchBooks = searchBooks;
// 2. Fast Autocomplete Suggestions Endpoint
const getAutocompleteSuggestions = async (req, res) => {
    try {
        const { q = '' } = req.query;
        const queryStr = String(q).trim();
        if (!queryStr) {
            return (0, response_utils_1.sendSuccess)(res, 'Empty search query', { suggestions: [] });
        }
        const books = await database_1.default.book.findMany({
            where: {
                isActive: true,
                OR: [
                    { title: { contains: queryStr } },
                    { isbn: { contains: queryStr } },
                    { bookAuthors: { some: { author: { name: { contains: queryStr } } } } },
                ],
            },
            take: 6,
            select: {
                id: true,
                title: true,
                slug: true,
                coverImage: true,
                price: true,
                discountPrice: true,
                bookAuthors: { select: { author: { select: { name: true } } } },
            },
        });
        const suggestions = books.map((b) => ({
            id: b.id,
            title: b.title,
            slug: b.slug,
            coverImage: b.coverImage,
            price: Number(b.discountPrice || b.price),
            authorName: b.bookAuthors[0]?.author.name || 'Indian Author',
        }));
        return (0, response_utils_1.sendSuccess)(res, 'Autocomplete suggestions fetched', { suggestions });
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'Autocomplete failed', error.message, 500);
    }
};
exports.getAutocompleteSuggestions = getAutocompleteSuggestions;
// 3. Trending & Popular Search Keywords Endpoint
const getTrendingSearches = async (req, res) => {
    try {
        const trending = [
            { keyword: 'The Mahabharata Unabridged', count: '12.4k searches' },
            { keyword: 'Rabindranath Tagore Gitanjali', count: '9.8k searches' },
            { keyword: 'Srimad Bhagavad Gita Sanskrit', count: '8.2k searches' },
            { keyword: 'R.K. Narayan Malgudi Days', count: '6.5k searches' },
            { keyword: 'Amish Tripathi Shiva Trilogy', count: '5.1k searches' },
            { keyword: 'Discovery of India Jawaharlal Nehru', count: '4.8k searches' },
        ];
        return (0, response_utils_1.sendSuccess)(res, 'Trending searches retrieved', { trending });
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'Failed to fetch trending searches', error.message, 500);
    }
};
exports.getTrendingSearches = getTrendingSearches;
//# sourceMappingURL=search.controller.js.map