import db from '../../database/models/index.js';
import { ROLES } from '../../common/config/constants.js';

/**
 * Synchronizes the Location (District) table's manager IDs with the UserRole table.
 * This ensures the Location table always reflects the "Active" managers for each role type.
 */
export const syncLocationManagers = async (districtId: string) => {
    try {
        const UserRole = db.UserRole;
        const Role = db.Role;
        const Op = db.Sequelize.Op;

        const district = await db.District.findByPk(districtId);
        if (!district) return;

        // Fetch active assignments for this district PLUS any region-level assignments for its parent region
        const orConditions: any[] = [{ districtId, isActive: true }];
        if (district.regionId) {
            orConditions.push({ regionId: district.regionId, isActive: true });
        }
        if (district.zoneId) {
            orConditions.push({ zoneId: district.zoneId, isActive: true });
        }

        const activeAssignments = await UserRole.findAll({
            where: {
                [Op.or]: orConditions
            },
            include: [
                { model: Role, as: 'role', attributes: ['roleCode'] },
                { model: db.User, as: 'user', attributes: ['employeeId'] }
            ]
        });

        // Find primary/last assigned manager for each type
        // ASM and DD-AM are STRICTLY mapped to the District level to prevent territory explosion
        const asm = activeAssignments.find((a: any) => 
            ['ASM', 'AREA SALES MANAGER'].includes((a.role as any)?.roleCode) &&
            a.districtId === districtId
        );
        const ddAm = activeAssignments.find((a: any) => 
            ['DD-AM', 'DD AM', 'AREA MANAGER', ROLES.DD_AM].includes((a.role as any)?.roleCode) &&
            a.districtId === districtId
        );
        
        // ZM can be assigned to the District (legacy/override) or the Region (standard) or Zone (broad)
        // Order of priority: 1. District level, 2. Region level, 3. Zone level
        const zm = activeAssignments.find((a: any) => 
            ((a.role as any)?.roleCode === 'DD-ZM' || (a.role as any)?.roleCode === 'ZM' || (a.role as any)?.roleCode === 'ZONAL MANAGER') &&
            a.districtId === districtId
        ) || activeAssignments.find((a: any) => 
            ((a.role as any)?.roleCode === 'DD-ZM' || (a.role as any)?.roleCode === 'ZM' || (a.role as any)?.roleCode === 'ZONAL MANAGER') &&
            a.regionId === district.regionId && !a.districtId
        ) || activeAssignments.find((a: any) => 
            ((a.role as any)?.roleCode === 'DD-ZM' || (a.role as any)?.roleCode === 'ZM' || (a.role as any)?.roleCode === 'ZONAL MANAGER')
        );

        // Update District table with IDs and Codes
        await db.District.update({
            asmId: asm?.userId || null,
            asmCode: asm?.managerCode || asm?.user?.employeeId || null,
            ddAmId: ddAm?.userId || null,
            ddAmCode: ddAm?.managerCode || ddAm?.user?.employeeId || null,
            zmId: zm?.userId || null,
            zmCode: zm?.managerCode || zm?.user?.employeeId || null
        }, {
            where: { id: districtId }
        });

        console.log(`[Sync] District ${districtId} synchronized successfully`);
    } catch (error) {
        console.error(`[Sync] Error synchronizing District ${districtId}:`, error);
    }
};

/**
 * Synchronizes the Region table's manager ID and Code.
 */
export const syncRegionManager = async (regionId: string) => {
    try {
        const activeAssignment = await db.UserRole.findOne({
            where: { regionId, isActive: true },
            include: [
                { 
                    model: db.Role, 
                    as: 'role', 
                    where: { roleCode: { [db.Sequelize.Op.in]: ['RM', 'RBM', 'REGIONAL MANAGER'] } } 
                },
                { model: db.User, as: 'user', attributes: ['employeeId'] }
            ],
            order: [['assignedAt', 'DESC']]
        });

        await db.Region.update({
            rbmId: activeAssignment?.userId || null,
            rbmCode: activeAssignment?.managerCode || activeAssignment?.user?.employeeId || null
        }, {
            where: { id: regionId }
        });

        console.log(`[Sync] Region ${regionId} synchronized successfully`);
    } catch (error) {
        console.error(`[Sync] Error synchronizing Region ${regionId}:`, error);
    }
};

/**
 * Synchronizes the Zone table's manager ID and Code.
 */
export const syncZoneManager = async (zoneId: string) => {
    try {
        const activeAssignment = await db.UserRole.findOne({
            where: { zoneId, isActive: true },
            include: [
                { 
                    model: db.Role, 
                    as: 'role', 
                    where: { 
                        [db.Sequelize.Op.or]: [
                            { roleCode: ROLES.ZBH },
                            { roleName: { [db.Sequelize.Op.iLike]: '%Zonal Business Head%' } },
                            { roleName: { [db.Sequelize.Op.iLike]: '%Zone Business Head%' } }
                        ]
                    } 
                },
                { model: db.User, as: 'user', attributes: ['employeeId'] }
            ],
            order: [['assignedAt', 'DESC']]
        });

        await db.Zone.update({
            zbhId: activeAssignment?.userId || null,
            zbhCode: activeAssignment?.managerCode || activeAssignment?.user?.employeeId || null
        }, {
            where: { id: zoneId }
        });

        console.log(`[Sync] Zone ${zoneId} synchronized successfully`);
    } catch (error) {
        console.error(`[Sync] Error synchronizing Zone ${zoneId}:`, error);
    }
};

/**
 * Synchronizes all districts within a specific region.
 */
export const syncDistrictsByRegion = async (regionId: string) => {
    try {
        const districts = await db.District.findAll({ where: { regionId }, attributes: ['id'] });
        for (const district of districts) {
            await syncLocationManagers(district.id);
        }
        console.log(`[Sync] All districts in Region ${regionId} synchronized successfully`);
    } catch (error) {
        console.error(`[Sync] Error synchronizing districts for Region ${regionId}:`, error);
    }
};

/**
 * Synchronizes all districts within a specific zone.
 */
export const syncDistrictsByZone = async (zoneId: string) => {
    try {
        const districts = await db.District.findAll({ where: { zoneId }, attributes: ['id'] });
        for (const district of districts) {
            await syncLocationManagers(district.id);
        }
        console.log(`[Sync] All districts in Zone ${zoneId} synchronized successfully`);
    } catch (error) {
        console.error(`[Sync] Error synchronizing districts for Zone ${zoneId}:`, error);
    }
};
