const mongoose = require('mongoose');
const User = require('../models/userSchema');
const Role = require('../models/roleSchema');
const Resource = require('../models/resourceSchema');
const bcrypt = require('bcryptjs');
const readline = require('readline');
const Joi = require('joi');
const dotenv = require('dotenv');
dotenv.config();

// Email validation schema
const emailSchema = Joi.string().email().required();

async function connectToDatabase() {
    try {
        await mongoose.connect(process.env.MONGO_URI, {
            useNewUrlParser: true,
            useUnifiedTopology: true,
            serverSelectionTimeoutMS: 30000, // 30 seconds
        });
        console.log('✅ Connected to MongoDB successfully');
    } catch (error) {
        console.error('❌ MongoDB connection failed:', error.message);
        process.exit(1);
    }
}

function askQuestion(question) {
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });

    return new Promise((resolve) => {
        rl.question(question, (answer) => {
            rl.close();
            resolve(answer.trim());
        });
    });
}

async function validateEmail(email) {
    const { error } = emailSchema.validate(email);
    return !error;
}

async function bootstrap() {
    try {
        // Connect to database first
        await connectToDatabase();

        console.log('🚀 Starting Super Admin bootstrap...');

        // Check if Super Admin already exists
        console.log('Checking if Super Admin role already exists...');
        const existingSuperAdmin = await Role.findOne({ name: 'super_admin' });
        if (existingSuperAdmin) {
            console.log('⚠️ Super Admin role already exists. Exiting...');
            await mongoose.disconnect();
            process.exit(0);
        }

        // Create resources
        console.log('Creating/updating resources...');
        const resources = [
            {
                name: 'tenant',
                displayName: 'Tenant Management',
                description: 'Manage tenants'
            },
            {
                name: 'user',
                displayName: 'User Management',
                description: 'Manage users'
            },
            {
                name: 'role',
                displayName: 'Role Management',
                description: 'Manage roles'
            },
            {
                name: 'resource',
                displayName: 'Resource Management',
                description: 'Manage resources'
            },
            {
                name: 'kyc_session',
                displayName: 'KYC Session Management',
                description: 'Manage KYC sessions'
            },
            {
                name: 'customer',
                displayName: 'Customer Management',
                description: 'Manage customers'
            },
            {
                name: 'report',
                displayName: 'Report Management',
                description: 'Generate and view reports'
            },
            {
                name: 'kyc_review',
                displayName: 'Kyc Review Management',
                description: 'Review kyc'
            }
        ];

        // Insert/Update resources using upsert to handle duplicates
        const createdResources = [];
        for (const resourceData of resources) {
            console.log(`Processing resource: ${resourceData.name}`);
            try {
                const resource = await Resource.findOneAndUpdate(
                    { name: resourceData.name }, // Only filter by unique 'name' field
                    {
                        $set: {
                            displayName: resourceData.displayName,
                            description: resourceData.description,
                            isActive: true
                        }
                    },
                    {
                        upsert: true,
                        new: true,
                        setDefaultsOnInsert: true
                    }
                );
                createdResources.push(resource);
                console.log(`✅ Resource '${resourceData.name}' processed successfully`);
            } catch (resourceError) {
                console.error(`❌ Error processing resource '${resourceData.name}':`, resourceError.message);
                throw resourceError;
            }
        }
        console.log('✅ All resources processed successfully');

        // Get all resources for role creation
        const allResources = await Resource.find({ isActive: true }).limit(4);
        console.log(`Found ${allResources.length} active resources`);

        // Create Super Admin role
        console.log('Creating Super Admin role...');
        const superAdminRole = await Role.create({
            name: 'super_admin',
            description: 'System administrator with full access',
            permissions: allResources.map(resource => ({
                resource: resource._id,
                actions: ['view', 'add', 'edit', 'delete', 'update']
            })),
            isActive: true
        });
        console.log('✅ Super Admin role created');

        // Get user input
        let email = '';
        let password = '';

        // Get email with validation
        while (true) {
            email = await askQuestion('Enter email for Super Admin: ');
            email = email.toLowerCase();

            if (!email) {
                console.log('❌ Email cannot be empty. Please try again.');
                continue;
            }

            if (await validateEmail(email)) {
                // Check if user already exists
                const existingUser = await User.findOne({ email: email });
                if (existingUser) {
                    console.log('❌ User with this email already exists. Please use a different email.');
                    continue;
                }
                break;
            } else {
                console.log('❌ Invalid email format. Please enter a valid email.');
            }
        }

        // Get password
        while (true) {
            password = await askQuestion('Enter password for Super Admin (min 8 characters): ');

            if (!password) {
                console.log('❌ Password cannot be empty. Please try again.');
                continue;
            }

            if (password.length < 8) {
                console.log('❌ Password must be at least 8 characters long. Please try again.');
                continue;
            }

            break;
        }

        // Create Super Admin user
        console.log('Creating Super Admin user...');

        const superAdminUser = await User.create({
            name: 'Green Finch',
            email: email,
            passwordHash: password, // Use plain password for bcrypt to hash
            role: superAdminRole._id,
            isActive: true,
            tenantId: null // Super Admin doesn't belong to any specific tenant
        });

        console.log('✅ Super Admin user created successfully');
        console.log('\n🎉 Bootstrap completed successfully!');
        console.log('\n📝 Login Credentials:');
        console.log(`Email: ${email}`);
        console.log(`Password: [Hidden for security]`);
        console.log('\n⚠️ Please save these credentials securely!');

    } catch (error) {
        console.error('❌ Error during Super Admin bootstrap:', error.message);
        console.error('Stack trace:', error.stack);
    } finally {
        // Always disconnect from database
        await mongoose.disconnect();
        console.log('📤 Disconnected from MongoDB');
        process.exit(0);
    }
}

// Run bootstrap
bootstrap();
