const mongoose = require('mongoose');
const crypto = require('crypto');
const jwt = require('jsonwebtoken');

const userSchema = new mongoose.Schema({
    name: {
        type: String,
        required: [true, 'Name is required'],
        trim: true
    },
    dob: {
        type: Date,
        required: false, // Make it optional to handle invalid dates gracefully
        validate: {
            validator: function(value) {
                // If value is provided, it must be a valid date
                if (value && isNaN(new Date(value).getTime())) {
                    return false;
                }
                return true;
            },
            message: 'Date of birth must be a valid date'
        }
    },
    mobile: {
        type: String,
        required: [true, 'Mobile number is required'],
        unique: true,
        trim: true
    },
    password: {
        type: String,
        required: [true, 'Password is required']
    },
    otp: {
        code: String,
        expiresAt: Date
    },
    isVerified: {
        type: Boolean,
        default: false
    },
    hasPersonalDetails: {
        type: Boolean,
        default: false
    },
    hasOccupation: {
        type: Boolean,
        default: false
    },
    personalDetailsCompleted: {
        type: Boolean,
        default: false
    },
    occupationCompleted: {
        type: Boolean,
        default: false
    },
    profession_status: {
        type: Boolean,
        default: false,
        required: false
    },
    occupation: {
        type: String,
        enum: ['school student', 'graduate student', 'working professional', 'business', 'public page'],
        trim: true
    },
    
    // Working Professional Details
    workingProfessional: {
        jobCategory: {
            type: String,
            trim: true,
            maxlength: [100, 'Job category cannot exceed 100 characters']
        },
        jobSubcategory: {
            type: String,
            trim: true,
            maxlength: [100, 'Job subcategory cannot exceed 100 characters']
        },
        state: {
            type: String,
            trim: true,
            maxlength: [50, 'State cannot exceed 50 characters']
        },
        district: {
            type: String,
            trim: true,
            maxlength: [50, 'District cannot exceed 50 characters']
        },
        village: {
            type: String,
            trim: true,
            maxlength: [100, 'Village cannot exceed 100 characters']
        }
    },
    
    // Business Details
    business: {
        businessName: {
            type: String,
            trim: true,
            maxlength: [200, 'Business name cannot exceed 200 characters']
        },
        businessArea: {
            type: String,
            trim: true,
            maxlength: [100, 'Business area cannot exceed 100 characters']
        },
        pincode: {
            type: String,
            trim: true,
            maxlength: [10, 'Pincode cannot exceed 10 characters']
        },
        businessCategory: {
            type: String,
            trim: true,
            maxlength: [100, 'Business category cannot exceed 100 characters']
        },
        businessSubCategory: {
            type: String,
            trim: true,
            maxlength: [100, 'Business subcategory cannot exceed 100 characters']
        },
        state: {
            type: String,
            trim: true,
            maxlength: [50, 'State cannot exceed 50 characters']
        },
        village: {
            type: String,
            trim: true,
            maxlength: [100, 'Village cannot exceed 100 characters']
        },
        district: {
            type: String,
            trim: true,
            maxlength: [50, 'District cannot exceed 50 characters']
        }
    },
    profileImage: {
        type: String,
        default: null,
        // Stores the file path to the profile image (e.g., "uploads/profiles/profile_1234567890_abc123.jpg")
        // Not base64 data anymore
    },
    
    // User About and Interests
    about: {
        type: String,
        trim: true,
        maxlength: [1000, 'About cannot exceed 1000 characters'],
        default: ''
    },
    interests: [{
        type: String,
        trim: true,
        maxlength: [100, 'Interest name cannot exceed 100 characters']
    }],
    
    // Personal Details (moved from PersonalDetails model)
    gender: {
        type: String,
        enum: ['Male', 'Female', 'Other'],
        trim: true
    },
    emailId: {
        type: String,
        trim: true,
        lowercase: true,
        match: [
            /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
            'Please provide a valid email address'
        ]
    },
    bloodGroup: {
        type: String,
        enum: ['A+', 'A-', 'B+', 'B-', 'AB+', 'AB-', 'O+', 'O-'],
        trim: true
    },
    pincodeNative: {
        type: String,
        trim: true,
        maxlength: [10, 'Pincode cannot exceed 10 characters']
    },
    state: {
        type: String,
        trim: true,
        maxlength: [50, 'State name cannot exceed 50 characters']
    },
    district: {
        type: String,
        trim: true,
        maxlength: [50, 'District name cannot exceed 50 characters']
    },
    nativePlace: {
        type: String,
        trim: true,
        maxlength: [100, 'Native place cannot exceed 100 characters']
    },
    nameMeaning: {
        type: String,
        trim: true,
        maxlength: [500, 'Name meaning cannot exceed 500 characters']
    },
    
    // School Details
    schoolDetails: {
        schoolState: {
            type: String,
            trim: true,
            maxlength: [50, 'School state cannot exceed 50 characters']
        },
        schoolDistrict: {
            type: String,
            trim: true,
            maxlength: [50, 'School district cannot exceed 50 characters']
        },
        schoolVillage: {
            type: String,
            trim: true,
            maxlength: [100, 'School village cannot exceed 100 characters']
        },
        schoolCode: {
            type: String,
            trim: true,
            maxlength: [50, 'School code cannot exceed 50 characters']
        },
        schoolName: {
            type: String,
            trim: true,
            maxlength: [200, 'School name cannot exceed 200 characters']
        },
        class10thStatus: {
            type: String,
            enum: ['completed', 'ongoing', 'not_started', 'dropped'],
            default: 'not_started'
        },
        academicYear: {
            type: String,
            trim: true,
            maxlength: [10, 'Academic year cannot exceed 10 characters']
        }
    },
    
    // College Details
    collegeDetails: {
        graduationStatus: {
            type: String,
            enum: ['current', 'completed'],
            default: 'current'
        },
        collegeCode: {
            type: String,
            trim: true,
            maxlength: [50, 'College code cannot exceed 50 characters']
        },
        collegeName: {
            type: String,
            trim: true,
            maxlength: [200, 'College name cannot exceed 200 characters']
        },
        courseName: {
            type: String,
            trim: true,
            maxlength: [100, 'Course name cannot exceed 100 characters']
        },
        courseSubBranch: {
            type: String,
            trim: true,
            maxlength: [100, 'Course sub branch cannot exceed 100 characters']
        },
        academicYear: {
            type: String,
            trim: true,
            maxlength: [10, 'Academic year cannot exceed 10 characters']
        },
        selectOnYear: {
            type: String,
            trim: true,
            maxlength: [10, 'Select on year cannot exceed 10 characters']
        }
    },
    
    // Group references
    schoolGroupId: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Group',
        default: null
    },
    collegeGroupId: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Group',
        default: null
    },
    professionalGroupId: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Group',
        default: null
    },
    
    // Profile Image
    profileImage: {
        type: String,
        default: null,
        // Stores the file path to the profile image (e.g., "uploads/profiles/profile_1234567890_abc123.jpg")
        // Not base64 data anymore
    },
    
    // Referral System
    referralCode: {
        type: String,
        unique: true,
        sparse: true, // Allows multiple null values
        uppercase: true,
        trim: true,
        maxlength: [6, 'Referral code must be exactly 6 characters'],
        minlength: [6, 'Referral code must be exactly 6 characters'],
        match: [/^[A-Z0-9]{6}$/, 'Referral code must be exactly 6 uppercase letters and numbers']
    },
    referredBy: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User',
        default: null
    },
    
    // Coins System
    coins: {
        type: Number,
        default: 0,
        min: [0, 'Coins cannot be negative']
    },
    totalReferrals: {
        type: Number,
        default: 0,
        min: [0, 'Total referrals cannot be negative']
    },
    successfulReferrals: {
        type: Number,
        default: 0,
        min: [0, 'Successful referrals cannot be negative']
    }
}, {
    timestamps: true
});

// Hash password using SHA-256 before saving
userSchema.pre('save', function(next) {
    if (this.isModified('password')) {
        this.password = crypto.createHash('sha256')
            .update(this.password)
            .digest('hex');
    }
    next();
});

// Method to verify password
userSchema.methods.verifyPassword = function(password) {
    const hashedPassword = crypto.createHash('sha256')
        .update(password)
        .digest('hex');
    return this.password === hashedPassword;
};

// Generate JWT Token
userSchema.methods.generateToken = function() {
    return jwt.sign(
        { id: this._id, mobile: this.mobile },
        process.env.JWT_SECRET || 'your-secret-key',
        { expiresIn: '24h' }
    );
};

// Calculate personal details completion percentage
userSchema.methods.getPersonalDetailsCompletion = function() {
    const personalFields = [
        'name', 'gender', 'emailId', 'bloodGroup', 
        'pincodeNative', 'state', 'district', 'nativePlace'
    ];
    
    let completedFields = 0;
    personalFields.forEach(field => {
        if (this[field] && this[field].toString().trim() !== '') {
            completedFields++;
        }
    });
    
    const percentage = Math.round((completedFields / personalFields.length) * 100);
    return {
        percentage,
        completedFields,
        totalFields: personalFields.length,
        isCompleted: percentage === 100
    };
};

// Update personal details completion status
userSchema.methods.updatePersonalDetailsStatus = function() {
    const completion = this.getPersonalDetailsCompletion();
    this.personalDetailsCompleted = completion.isCompleted;
    this.hasPersonalDetails = completion.percentage > 0;
    return completion;
};

// Generate unique referral code
userSchema.statics.generateUniqueReferralCode = async function() {
    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    let referralCode;
    let isUnique = false;
    let attempts = 0;
    const maxAttempts = 100; // Prevent infinite loop
    
    while (!isUnique && attempts < maxAttempts) {
        // Generate 6-character code
        referralCode = '';
        for (let i = 0; i < 6; i++) {
            referralCode += characters.charAt(Math.floor(Math.random() * characters.length));
        }
        
        // Check if code already exists
        const existingUser = await this.findOne({ referralCode });
        if (!existingUser) {
            isUnique = true;
        }
        
        attempts++;
    }
    
    if (!isUnique) {
        throw new Error('Unable to generate unique referral code after multiple attempts');
    }
    
    return referralCode;
};

module.exports = mongoose.model('User', userSchema);