const mongoose = require('mongoose');

const groupSchema = new mongoose.Schema({
    groupType: {
        type: String,
        required: [true, 'Group type is required'],
        enum: ['school', 'college', 'professional'],
        trim: true,
        index: true
    },
    
    userId: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User',
        required: [true, 'User ID is required'],
        index: true
    },
    
    schoolId: {
        type: String,
        unique: true,
        sparse: true, // Allows null values but ensures uniqueness when present
        trim: true,
        maxlength: [100, 'School ID cannot exceed 100 characters'],
        index: true
    },
    
    collegeId: {
        type: String,
        unique: true,
        sparse: true, // Allows null values but ensures uniqueness when present
        trim: true,
        maxlength: [200, 'College ID cannot exceed 200 characters'],
        index: true
    },
    
    // Additional fields for future use
    groupName: {
        type: String,
        trim: true,
        maxlength: [200, 'Group name cannot exceed 200 characters']
    },
    
    description: {
        type: String,
        trim: true,
        maxlength: [500, 'Description cannot exceed 500 characters']
    },
    
    isActive: {
        type: Boolean,
        default: true
    },
    
    memberCount: {
        type: Number,
        default: 1,
        min: [0, 'Member count cannot be negative']
    },
    
    // Members array
    members: [{
        user_id: {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'User',
            required: true
        },
        name: {
            type: String,
            required: true,
            trim: true,
            maxlength: [100, 'Member name cannot exceed 100 characters']
        },
        joinDate: {
            type: Date,
            default: Date.now,
            required: true
        },
        role: {
            type: String,
            enum: ['member', 'admin', 'moderator'],
            default: 'member'
        },
        isActive: {
            type: Boolean,
            default: true
        }
    }]
}, {
    timestamps: true,
    collection: 'groups'
});

// Compound index for efficient queries
groupSchema.index({ groupType: 1, schoolId: 1 });
groupSchema.index({ groupType: 1, collegeId: 1 });
groupSchema.index({ userId: 1, groupType: 1 });

// Static method to find or create school group
groupSchema.statics.findOrCreateSchoolGroup = async function(userId, schoolId, schoolDetails) {
    console.log(`🏫 [GROUP DEBUG] Finding or creating school group for userId: ${userId}, schoolId: ${schoolId}`);
    
    try {
        // Check if school group already exists
        let group = await this.findOne({ 
            groupType: 'school', 
            schoolId: schoolId 
        });
        
        if (group) {
            console.log(`✅ [GROUP DEBUG] Existing school group found: ${group._id}`);
            return group;
        }
        
        // Create new school group with error handling for duplicate key
        console.log(`🆕 [GROUP DEBUG] Creating new school group for schoolId: ${schoolId}`);
        
        try {
            group = new this({
                groupType: 'school',
                userId: userId,
                schoolId: schoolId,
                groupName: `${schoolDetails.schoolName} - ${schoolDetails.academicYear}`,
                description: `School group for ${schoolDetails.schoolName} (${schoolDetails.academicYear})`,
                memberCount: 0,
                members: []
            });
            
            await group.save();
            console.log(`✅ [GROUP DEBUG] New school group created: ${group._id}`);
            
            return group;
            
        } catch (duplicateError) {
            // Handle duplicate key error (race condition)
            if (duplicateError.code === 11000) {
                console.log(`🔄 [GROUP DEBUG] Duplicate key error, fetching existing group`);
                
                // Try to find the group that was created by another process
                group = await this.findOne({ 
                    groupType: 'school', 
                    schoolId: schoolId 
                });
                
                if (group) {
                    console.log(`✅ [GROUP DEBUG] Found existing group after duplicate error: ${group._id}`);
                    return group;
                }
            }
            
            // Re-throw if it's not a duplicate key error
            throw duplicateError;
        }
        
    } catch (error) {
        console.error(`❌ [GROUP ERROR] Find or create school group failed:`, error);
        throw error;
    }
};

// Static method to get groups by user
groupSchema.statics.getUserGroups = async function(userId, groupType = null) {
    console.log(`👥 [GROUP DEBUG] Getting groups for userId: ${userId}, groupType: ${groupType}`);
    
    try {
        let query = { userId: userId };
        if (groupType) {
            query.groupType = groupType;
        }
        
        const groups = await this.find(query)
            .populate('userId', 'name mobile')
            .sort({ createdAt: -1 });
        
        console.log(`📊 [GROUP DEBUG] Found ${groups.length} groups for user`);
        return groups;
        
    } catch (error) {
        console.error(`❌ [GROUP ERROR] Get user groups failed:`, error);
        throw error;
    }
};

// Static method to find or create college group
groupSchema.statics.findOrCreateCollegeGroup = async function(userId, collegeId, collegeDetails) {
    console.log(`🎓 [GROUP DEBUG] Finding or creating college group for userId: ${userId}, collegeId: ${collegeId}`);
    
    try {
        // Check if college group already exists
        let group = await this.findOne({ 
            groupType: 'college', 
            collegeId: collegeId 
        });
        
        if (group) {
            console.log(`✅ [GROUP DEBUG] Existing college group found: ${group._id}`);
            return group;
        }
        
        // Create new college group with error handling for duplicate key
        console.log(`🆕 [GROUP DEBUG] Creating new college group for collegeId: ${collegeId}`);
        
        try {
            group = new this({
                groupType: 'college',
                userId: userId,
                collegeId: collegeId,
                groupName: `${collegeDetails.collegeName} - ${collegeDetails.courseName}`,
                description: `College group for ${collegeDetails.collegeName} (${collegeDetails.courseName} - ${collegeDetails.courseSubBranch})`,
                memberCount: 0,
                members: []
            });
            
            await group.save();
            console.log(`✅ [GROUP DEBUG] New college group created: ${group._id}`);
            
            return group;
            
        } catch (duplicateError) {
            // Handle duplicate key error (race condition)
            if (duplicateError.code === 11000) {
                console.log(`🔄 [GROUP DEBUG] Duplicate key error, fetching existing college group`);
                
                // Try to find the group that was created by another process
                group = await this.findOne({ 
                    groupType: 'college', 
                    collegeId: collegeId 
                });
                
                if (group) {
                    console.log(`✅ [GROUP DEBUG] Found existing college group after duplicate error: ${group._id}`);
                    return group;
                }
            }
            
            // Re-throw if it's not a duplicate key error
            throw duplicateError;
        }
        
    } catch (error) {
        console.error(`❌ [GROUP ERROR] Find or create college group failed:`, error);
        throw error;
    }
};

// Static method to get group by school ID
groupSchema.statics.getGroupBySchoolId = async function(schoolId) {
    console.log(`🏫 [GROUP DEBUG] Getting group by schoolId: ${schoolId}`);
    
    try {
        const group = await this.findOne({ 
            groupType: 'school', 
            schoolId: schoolId 
        }).populate('userId', 'name mobile');
        
        if (group) {
            console.log(`✅ [GROUP DEBUG] Group found: ${group._id}`);
        } else {
            console.log(`❌ [GROUP DEBUG] Group not found for schoolId: ${schoolId}`);
        }
        
        return group;
        
    } catch (error) {
        console.error(`❌ [GROUP ERROR] Get group by school ID failed:`, error);
        throw error;
    }
};

// Static method to get group by college ID
groupSchema.statics.getGroupByCollegeId = async function(collegeId) {
    console.log(`🎓 [GROUP DEBUG] Getting group by collegeId: ${collegeId}`);
    
    try {
        const group = await this.findOne({ 
            groupType: 'college', 
            collegeId: collegeId 
        }).populate('userId', 'name mobile');
        
        if (group) {
            console.log(`✅ [GROUP DEBUG] College group found: ${group._id}`);
        } else {
            console.log(`❌ [GROUP DEBUG] College group not found for collegeId: ${collegeId}`);
        }
        
        return group;
        
    } catch (error) {
        console.error(`❌ [GROUP ERROR] Get group by college ID failed:`, error);
        throw error;
    }
};

// Static method to update member count
groupSchema.statics.updateMemberCount = async function(groupId, increment = true) {
    console.log(`👥 [GROUP DEBUG] Updating member count for group: ${groupId}, increment: ${increment}`);
    
    try {
        const group = await this.findById(groupId);
        if (!group) {
            throw new Error('Group not found');
        }
        
        if (increment) {
            group.memberCount += 1;
        } else {
            group.memberCount = Math.max(0, group.memberCount - 1);
        }
        
        await group.save();
        console.log(`✅ [GROUP DEBUG] Member count updated to: ${group.memberCount}`);
        
        return group;
        
    } catch (error) {
        console.error(`❌ [GROUP ERROR] Update member count failed:`, error);
        throw error;
    }
};

module.exports = mongoose.model('Group', groupSchema);
