const { MenuCategory, Menu, sequelize } = require('../models/associations');
const { Op } = require('sequelize');

class MenuCategoryController {
    // Get all categories with search and pagination
    async getAllCategories(req, res) {
        try {
            const {
                page = 1,
                limit = 10,
                search = '',
                actif,
                sort_by = 'ordre',
                sort_order = 'ASC'
            } = req.query;

            const offset = (parseInt(page) - 1) * parseInt(limit);
            
            // Build where conditions
            const whereConditions = {};
            
            if (search) {
                whereConditions[Op.or] = [
                    { nom: { [Op.like]: `%${search}%` } },
                    { description: { [Op.like]: `%${search}%` } }
                ];
            }
            
            if (actif !== undefined) {
                whereConditions.actif = actif === 'true';
            }

            // Validate sort fields
            const validSortFields = ['nom', 'ordre', 'created_at', 'updated_at'];
            const sortField = validSortFields.includes(sort_by) ? sort_by : 'ordre';
            const sortOrder = ['ASC', 'DESC'].includes(sort_order.toUpperCase()) ? 
                              sort_order.toUpperCase() : 'ASC';

            const { count, rows } = await MenuCategory.findAndCountAll({
                where: whereConditions,
                include: [{
                    model: Menu,
                    as: 'menus', // ✅ Utiliser l'alias défini dans associations.js
                    attributes: ['id'],
                    required: false
                }],
                order: [[sortField, sortOrder]],
                limit: parseInt(limit),
                offset: offset,
                distinct: true
            });

            // Add menu count to each category
            const categoriesWithCount = rows.map(category => ({
                ...category.toJSON(),
                menu_count: category.menus ? category.menus.length : 0, // ✅ Utiliser l'alias
                menus: undefined // Remove the menus array from response
            }));

            res.json({
                success: true,
                data: {
                    categories: categoriesWithCount,
                    pagination: {
                        currentPage: parseInt(page),
                        totalPages: Math.ceil(count / parseInt(limit)),
                        totalItems: count,
                        itemsPerPage: parseInt(limit)
                    }
                }
            });
        } catch (error) {
            console.error('❌ Error in getAllCategories:', error);
            res.status(500).json({
                success: false,
                message: 'Erreur lors de la récupération des catégories',
                error: error.message
            });
        }
    }

    // Get active categories only (for dropdowns, etc.)
    async getActiveCategories(req, res) {
        try {
            const categories = await MenuCategory.findAll({
                where: { actif: true },
                order: [['ordre', 'ASC'], ['nom', 'ASC']],
                attributes: ['id', 'nom', 'description', 'ordre']
            });

            res.json({
                success: true,
                data: categories
            });
        } catch (error) {
            res.status(500).json({
                success: false,
                message: 'Erreur lors de la récupération des catégories actives',
                error: error.message
            });
        }
    }

    // Get category by ID
    async getCategoryById(req, res) {
        try {
            const { id } = req.params;

            const category = await MenuCategory.findByPk(id, {
                include: [{
                    model: Menu,
                    as: 'menus', // ✅ Utiliser l'alias
                    attributes: ['id', 'nom', 'prix', 'actif'],
                    required: false
                }]
            });

            if (!category) {
                return res.status(404).json({
                    success: false,
                    message: 'Catégorie non trouvée'
                });
            }

            const categoryData = {
                ...category.toJSON(),
                menu_count: category.menus ? category.menus.length : 0 // ✅ Utiliser l'alias
            };

            res.json({
                success: true,
                data: categoryData
            });
        } catch (error) {
            res.status(500).json({
                success: false,
                message: 'Erreur lors de la récupération de la catégorie',
                error: error.message
            });
        }
    }

    // Get all menus in a category
    async getCategoryMenus(req, res) {
        try {
            const { id } = req.params;
            const { actif } = req.query;

            const category = await MenuCategory.findByPk(id);
            if (!category) {
                return res.status(404).json({
                    success: false,
                    message: 'Catégorie non trouvée'
                });
            }

            const whereConditions = { categorie_id: id }; // ✅ Utiliser le bon nom de colonne
            if (actif !== undefined) {
                whereConditions.actif = actif === 'true';
            }

            const menus = await Menu.findAll({
                where: whereConditions,
                order: [['nom', 'ASC']]
            });

            res.json({
                success: true,
                data: {
                    category: {
                        id: category.id,
                        nom: category.nom,
                        description: category.description
                    },
                    menus: menus
                }
            });
        } catch (error) {
            res.status(500).json({
                success: false,
                message: 'Erreur lors de la récupération des menus de la catégorie',
                error: error.message
            });
        }
    }

    // Get category statistics
    async getCategoryStats(req, res) {
        try {
            const [total, active, inactive] = await Promise.all([
                MenuCategory.count(),
                MenuCategory.count({ where: { actif: true } }),
                MenuCategory.count({ where: { actif: false } })
            ]);

            // Get total menus across all categories
            const totalMenus = await Menu.count();

            // Get categories with most menus
            const categoriesWithMenuCount = await MenuCategory.findAll({
                attributes: [
                    'id',
                    'nom',
                    [sequelize.fn('COUNT', sequelize.col('menus.id')), 'menu_count'] // ✅ Utiliser l'alias
                ],
                include: [{
                    model: Menu,
                    as: 'menus', // ✅ Utiliser l'alias
                    attributes: [],
                    required: false
                }],
                group: ['MenuCategory.id', 'MenuCategory.nom'], // ✅ Ajouter tous les champs non-agrégés
                order: [[sequelize.fn('COUNT', sequelize.col('menus.id')), 'DESC']],
                limit: 5
            });

            res.json({
                success: true,
                data: {
                    total,
                    active,
                    inactive,
                    totalMenus,
                    topCategories: categoriesWithMenuCount.map(cat => ({
                        id: cat.id,
                        nom: cat.nom,
                        menu_count: parseInt(cat.dataValues.menu_count || 0)
                    }))
                }
            });
        } catch (error) {
            console.error('❌ Error in getCategoryStats:', error);
            res.status(500).json({
                success: false,
                message: 'Erreur lors de la récupération des statistiques',
                error: error.message
            });
        }
    }

    // Create new category
    async createCategory(req, res) {
        try {
            const { nom, description, ordre = 0, actif = true } = req.body;

            // Validation
            if (!nom || nom.trim().length === 0) {
                return res.status(400).json({
                    success: false,
                    message: 'Le nom de la catégorie est requis'
                });
            }

            if (nom.length > 100) {
                return res.status(400).json({
                    success: false,
                    message: 'Le nom ne peut pas dépasser 100 caractères'
                });
            }

            // Check if category name already exists
            const existingCategory = await MenuCategory.findOne({
                where: { nom: nom.trim() }
            });

            if (existingCategory) {
                return res.status(400).json({
                    success: false,
                    message: 'Une catégorie avec ce nom existe déjà'
                });
            }

            // If no order specified, set it to be last
            let finalOrder = ordre;
            if (!ordre || ordre === 0) {
                const maxOrder = await MenuCategory.max('ordre') || 0;
                finalOrder = maxOrder + 1;
            }

            const category = await MenuCategory.create({
                nom: nom.trim(),
                description: description?.trim(),
                ordre: finalOrder,
                actif
            });

            res.status(201).json({
                success: true,
                message: 'Catégorie créée avec succès',
                data: category
            });
        } catch (error) {
            console.error('❌ Error in createCategory:', error);
            res.status(500).json({
                success: false,
                message: 'Erreur lors de la création de la catégorie',
                error: error.message
            });
        }
    }

    // Update category
    async updateCategory(req, res) {
        try {
            const { id } = req.params;
            const { nom, description, ordre, actif } = req.body;

            const category = await MenuCategory.findByPk(id);
            if (!category) {
                return res.status(404).json({
                    success: false,
                    message: 'Catégorie non trouvée'
                });
            }

            // Validation
            if (!nom || nom.trim().length === 0) {
                return res.status(400).json({
                    success: false,
                    message: 'Le nom de la catégorie est requis'
                });
            }

            if (nom.length > 100) {
                return res.status(400).json({
                    success: false,
                    message: 'Le nom ne peut pas dépasser 100 caractères'
                });
            }

            // Check if category name already exists (excluding current category)
            const existingCategory = await MenuCategory.findOne({
                where: { 
                    nom: nom.trim(),
                    id: { [Op.ne]: id }
                }
            });

            if (existingCategory) {
                return res.status(400).json({
                    success: false,
                    message: 'Une catégorie avec ce nom existe déjà'
                });
            }

            // Update category
            await category.update({
                nom: nom.trim(),
                description: description?.trim(),
                ordre: ordre !== undefined ? ordre : category.ordre,
                actif: actif !== undefined ? actif : category.actif
            });

            res.json({
                success: true,
                message: 'Catégorie mise à jour avec succès',
                data: category
            });
        } catch (error) {
            res.status(500).json({
                success: false,
                message: 'Erreur lors de la mise à jour de la catégorie',
                error: error.message
            });
        }
    }

    // Toggle category status
    async toggleCategoryStatus(req, res) {
        try {
            const { id } = req.params;

            const category = await MenuCategory.findByPk(id);
            if (!category) {
                return res.status(404).json({
                    success: false,
                    message: 'Catégorie non trouvée'
                });
            }

            await category.update({ actif: !category.actif });

            res.json({
                success: true,
                message: `Catégorie ${category.actif ? 'activée' : 'désactivée'} avec succès`,
                data: category
            });
        } catch (error) {
            res.status(500).json({
                success: false,
                message: 'Erreur lors de la mise à jour du statut',
                error: error.message
            });
        }
    }

    // Delete category  
    async deleteCategory(req, res) {
        try {
            const { id } = req.params;

            const category = await MenuCategory.findByPk(id, {
                include: [{
                    model: Menu,
                    as: 'menus', // ✅ Utiliser l'alias
                    attributes: ['id'],
                    required: false
                }]
            });

            if (!category) {
                return res.status(404).json({
                    success: false,
                    message: 'Catégorie non trouvée'
                });
            }

            // Check if category has associated menus
            if (category.menus && category.menus.length > 0) { // ✅ Utiliser l'alias
                return res.status(400).json({
                    success: false,
                    message: `Impossible de supprimer la catégorie. Elle contient ${category.menus.length} menu(s). Veuillez d'abord supprimer ou déplacer les menus.`
                });
            }

            await category.destroy();

            res.json({
                success: true,
                message: 'Catégorie supprimée avec succès'
            });
        } catch (error) {
            res.status(500).json({
                success: false,
                message: 'Erreur lors de la suppression de la catégorie',
                error: error.message
            });
        }
    }

    // Reorder categories
    async reorderCategories(req, res) {
        const transaction = await sequelize.transaction();
        
        try {
            const { categories } = req.body;

            if (!Array.isArray(categories) || categories.length === 0) {
                return res.status(400).json({
                    success: false,
                    message: 'Liste des catégories requise'
                });
            }

            // Validate each category object
            for (const cat of categories) {
                if (!cat.id || cat.ordre === undefined) {
                    return res.status(400).json({
                        success: false,
                        message: 'Chaque catégorie doit avoir un ID et un ordre'
                    });
                }
            }

            // Update each category's order
            const updatePromises = categories.map(cat =>
                MenuCategory.update(
                    { ordre: cat.ordre },
                    { 
                        where: { id: cat.id },
                        transaction
                    }
                )
            );

            await Promise.all(updatePromises);
            await transaction.commit();

            res.json({
                success: true,
                message: 'Ordre des catégories mis à jour avec succès'
            });
        } catch (error) {
            await transaction.rollback();
            
            res.status(500).json({
                success: false,
                message: 'Erreur lors de la réorganisation des catégories',
                error: error.message
            });
        }
    }
}

module.exports = new MenuCategoryController();
