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

const adminSchema = new mongoose.Schema({
    email: {
        type: String,
        required: [true, 'Email is required'],
        unique: true,
        trim: true,
        lowercase: true
    },
    password: {
        type: String,
        required: [true, 'Password is required']
    },
    name: {
        type: String,
        required: [true, 'Name is required'],
        trim: true
    },
    role: {
        type: String,
        enum: ['super_admin', 'admin', 'moderator'],
        default: 'admin'
    },
    isActive: {
        type: Boolean,
        default: true
    },
    lastLogin: {
        type: Date
    },
    loginAttempts: {
        type: Number,
        default: 0
    },
    lockUntil: {
        type: Date
    }
}, {
    timestamps: true
});

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

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

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

// Method to update last login
adminSchema.methods.updateLastLogin = function() {
    this.lastLogin = new Date();
    this.loginAttempts = 0;
    this.lockUntil = undefined;
    return this.save();
};

// Method to increment login attempts
adminSchema.methods.incLoginAttempts = function() {
    // If we have a previous lock that has expired, restart at 1
    if (this.lockUntil && this.lockUntil < Date.now()) {
        return this.updateOne({
            $unset: { lockUntil: 1 },
            $set: { loginAttempts: 1 }
        });
    }
    
    const updates = { $inc: { loginAttempts: 1 } };
    
    // Lock account after 5 failed attempts for 2 hours
    if (this.loginAttempts + 1 >= 5 && !this.isLocked) {
        updates.$set = { lockUntil: Date.now() + 2 * 60 * 60 * 1000 }; // 2 hours
    }
    
    return this.updateOne(updates);
};

// Virtual for checking if account is locked
adminSchema.virtual('isLocked').get(function() {
    return !!(this.lockUntil && this.lockUntil > Date.now());
});

// Static method to create default admin
adminSchema.statics.createDefaultAdmin = async function() {
    const existingAdmin = await this.findOne({ email: 'reconnectifly.rif@gmail.com' });
    
    if (!existingAdmin) {
        const defaultAdmin = new this({
            email: 'reconnectifly.rif@gmail.com',
            password: 'Reconnectifly.Rif2025',
            name: 'Reconnectifly Admin',
            role: 'super_admin'
        });
        
        await defaultAdmin.save();
        console.log('Default admin created successfully');
        return defaultAdmin;
    }
    
    return existingAdmin;
};

module.exports = mongoose.model('Admin', adminSchema);
