const { validationResult } = require('express-validator');
const GroupContact = require('../models/GroupContact');
class GroupContactController {
    // Get all mappings (replaces getAllGroupContacts)
    static async getAllGroupContacts(req, res, next) {
        try {
            const { page = 1, limit = 50, search = '', organization_id = '', department_id = '', contact_id = '' } = req.query;
            const isSuperAdmin = (user) => {
                if (!user)
                    return false;
                const roleName = (user.role || '').toLowerCase();
                return user.role_id === 1 || roleName === 'super admin' || roleName === 'super_admin';
            };
            const parsedRequestedOrg = (() => {
                if (organization_id === undefined || organization_id === null || organization_id === '')
                    return null;
                const n = Number(organization_id);
                return Number.isNaN(n) ? null : n;
            })();
            const effectiveOrganizationId = isSuperAdmin(req.user)
                ? (parsedRequestedOrg || null)
                : (req.user?.organization_id || null);
            console.log('🔍 GroupContactController.getAllGroupContacts - Calling GroupContact.findAll');
            const result = await GroupContact.findAll({
                page: parseInt(page),
                limit: parseInt(limit),
                search,
                organization_id: effectiveOrganizationId,
                department_id: department_id || '',
                contact_id: contact_id || ''
            });
            console.log('✅ GroupContactController.getAllGroupContacts - Result received:', result.mappings.length, 'mappings');
            res.status(200).json({
                status: 'success',
                message: 'Group contact mappings retrieved successfully',
                data: {
                    mappings: result.mappings,
                    pagination: result.pagination
                }
            });
        }
        catch (error) {
            console.error('❌ GroupContactController.getAllGroupContacts - Error:', error.message);
            console.error('❌ GroupContactController.getAllGroupContacts - Error stack:', error.stack);
            next(error);
        }
    }
    // Get mapping by ID
    static async getGroupContactById(req, res, next) {
        try {
            const { id } = req.params;
            const mapping = await GroupContact.getMappingById(parseInt(id));
            if (!mapping) {
                return res.status(200).json({
                    status: 'success',
                    message: 'Mapping not found',
                    data: {
                        mapping: null,
                        contacts: []
                    }
                });
            }
            const contacts = await GroupContact.getContactsFromMappings({
                organization_id: mapping.organization_id
            });
            res.status(200).json({
                status: 'success',
                message: 'Mapping retrieved successfully',
                data: {
                    mapping: mapping,
                    contacts: contacts
                }
            });
        }
        catch (error) {
            next(error);
        }
    }
    // Create mappings (replaces createGroupContact)
    static async createGroupContact(req, res, next) {
        try {
            const errors = validationResult(req);
            if (!errors.isEmpty()) {
                return res.status(400).json({
                    status: 'error',
                    message: 'Validation failed',
                    errors: errors.array()
                });
            }
            const { mappings } = req.body;
            if (!mappings || !Array.isArray(mappings) || mappings.length === 0) {
                return res.status(400).json({
                    status: 'error',
                    message: 'Mappings array is required'
                });
            }
            const result = await GroupContact.addMappings(mappings);
            const skipped = Math.max(result.total - (result.inserted + result.updated), 0);
            console.log('📊 Mappings creation result:', {
                total: result.total,
                inserted: result.inserted,
                updated: result.updated,
                skipped
            });
            res.status(201).json({
                status: 'success',
                message: skipped > 0
                    ? `Mappings created successfully. ${result.inserted} new mappings added, ${skipped} duplicates skipped.`
                    : 'Mappings created successfully',
                data: {
                    mappings: mappings,
                    stats: {
                        total: result.total,
                        inserted: result.inserted,
                        updated: result.updated,
                        skipped
                    }
                }
            });
        }
        catch (error) {
            next(error);
        }
    }
    // Update mapping
    static async updateGroupContact(req, res, next) {
        try {
            const { id } = req.params;
            const { organization_id, department_id, contact_id } = req.body;
            // First, remove the old mapping
            await GroupContact.removeMappings([parseInt(id)]);
            // Then add the new mapping
            if (organization_id && contact_id) {
                await GroupContact.addMappings([{
                        organization_id,
                        department_id: department_id || null,
                        contact_id
                    }]);
            }
            res.status(200).json({
                status: 'success',
                message: 'Mapping updated successfully'
            });
        }
        catch (error) {
            next(error);
        }
    }
    // Delete mapping
    static async deleteGroupContact(req, res, next) {
        try {
            const { id } = req.params;
            const deleted = await GroupContact.removeMappings([parseInt(id)]);
            if (deleted === 0) {
                return res.status(200).json({
                    status: 'success',
                    message: 'Mapping already removed'
                });
            }
            res.status(200).json({
                status: 'success',
                message: 'Mapping deleted successfully'
            });
        }
        catch (error) {
            next(error);
        }
    }
    // Get all mappings (independent endpoint)
    static async getAllMappings(req, res, next) {
        try {
            const { organization_id = '', department_id = '', contact_id = '' } = req.query;
            const isSuperAdmin = (user) => {
                if (!user)
                    return false;
                const roleName = (user.role || '').toLowerCase();
                return user.role_id === 1 || roleName === 'super admin' || roleName === 'super_admin';
            };
            const parsedRequestedOrg = (() => {
                if (organization_id === undefined || organization_id === null || organization_id === '')
                    return null;
                const n = Number(organization_id);
                return Number.isNaN(n) ? null : n;
            })();
            const effectiveOrganizationId = isSuperAdmin(req.user)
                ? (parsedRequestedOrg || null)
                : (req.user?.organization_id || null);
            const mappings = await GroupContact.getMappings({
                organization_id: effectiveOrganizationId,
                department_id: department_id || null,
                contact_id: contact_id || null
            });
            res.status(200).json({
                status: 'success',
                message: 'Mappings retrieved successfully',
                data: {
                    mappings: mappings
                }
            });
        }
        catch (error) {
            next(error);
        }
    }
    static async syncGroupContacts(req, res, next) {
        try {
            const { organization_id, department_id, contact_ids } = req.body;
            if (!organization_id || typeof organization_id !== 'number') {
                return res.status(400).json({ status: 'error', message: 'organization_id is required' });
            }
            if (department_id === undefined) {
                return res.status(400).json({ status: 'error', message: 'department_id is required' });
            }
            if (!Array.isArray(contact_ids)) {
                return res.status(400).json({ status: 'error', message: 'contact_ids array is required' });
            }
            // Purge any invalid mappings (contact_id not in contacts)
            try {
                await GroupContact.purgeInvalidMappings({ organization_id, department_id });
            }
            catch (e) {
                console.warn('⚠️ purgeInvalidMappings failed:', e?.message || e);
            }
            const existing = await GroupContact.getMappings({ organization_id, department_id });
            const keepSet = new Set(contact_ids.map(id => Number(id)));
            const toDeleteIds = existing
                .filter(m => !keepSet.has(Number(m.contact_id)))
                .map(m => Number(m.id));
            let deleted = 0;
            if (toDeleteIds.length > 0) {
                deleted = await GroupContact.removeMappings(toDeleteIds);
            }
            const existingKeys = new Set(existing.map(m => `${m.organization_id}-${m.department_id || 'null'}-${m.contact_id}`));
            const toCreate = contact_ids
                .map(cid => ({ organization_id, department_id, contact_id: Number(cid) }))
                .filter(m => !existingKeys.has(`${m.organization_id}-${m.department_id || 'null'}-${m.contact_id}`));
            let inserted = 0;
            let updated = 0;
            if (toCreate.length > 0) {
                const result = await GroupContact.addMappings(toCreate);
                inserted = result.inserted;
                updated = result.updated;
            }
            return res.status(200).json({
                status: 'success',
                message: 'Mappings synchronized',
                data: {
                    stats: { deleted, inserted, updated },
                    total_selected: contact_ids.length
                }
            });
        }
        catch (error) {
            next(error);
        }
    }
    static async getDepartmentContactTree(req, res, next) {
        try {
            const { organization_id = '' } = req.query;
            const isSuperAdmin = (user) => {
                if (!user)
                    return false;
                const roleName = (user.role || '').toLowerCase();
                return user.role_id === 1 || roleName === 'super admin' || roleName === 'super_admin';
            };
            const parsedRequestedOrg = (() => {
                if (organization_id === undefined || organization_id === null || organization_id === '')
                    return null;
                const n = Number(organization_id);
                return Number.isNaN(n) ? null : n;
            })();
            const superAdmin = isSuperAdmin(req.user);
            const effectiveOrganizationId = superAdmin ? (parsedRequestedOrg || null) : (Number(req.user?.organization_id) || null);
            if (!superAdmin && !effectiveOrganizationId) {
                return res.status(400).json({ status: 'error', message: 'organization_id is required' });
            }
            if (effectiveOrganizationId) {
                const tree = await GroupContact.getDepartmentContactTree(effectiveOrganizationId);
                return res.status(200).json({
                    status: 'success',
                    message: 'Department contact tree retrieved successfully',
                    data: { tree }
                });
            }
            const { pool } = require('../config/database');
            const [orgRows] = await pool.execute('SELECT id, name FROM organizations WHERE is_active = 1 ORDER BY name');
            const aggregated = [];
            for (const org of orgRows) {
                try {
                    const subTree = await GroupContact.getDepartmentContactTree(Number(org.id));
                    aggregated.push({ id: -Number(org.id), name: org.name, children: subTree });
                }
                catch (_) {
                }
            }
            return res.status(200).json({
                status: 'success',
                message: 'Aggregated department contact tree retrieved successfully',
                data: { tree: aggregated }
            });
        }
        catch (error) {
            next(error);
        }
    }
}
module.exports = GroupContactController;
//# sourceMappingURL=groupContactController.js.map