const Tenant = require('../models/tenantSchema');
const AuditLog = require('../models/auditLogSchema');
const mongoose = require('mongoose');
const User = require("../models/userSchema");
const Role = require("../models/roleSchema");
const generateRandomPassword = require("../utils/generatePassword");
// const createTenant = async (req, res) => {
//     try {
//         const { name, code, isActive } = req.body;
//         const existingTenant = await Tenant.findOne({ code: code.toUpperCase() });
//         if (existingTenant) {
//             return res.status(400).json({ message: 'Tenant already exists' });
//         }
//         const tenantData = new Tenant({
//             name: name.trim(),
//             code: code.trim().toUpperCase(),
//             isActive: isActive
//         });
//         await tenantData.save();
//         await AuditLog.create({
//             action: 'tenant_created',
//             userId: req.user._id, //Need at time of authentication
//             ipAddress: req.ip,
//         });
//         res.status(201).json({ message: 'Tenant created successfully', data: tenantData });
//     } catch (error) {
//         res.status(500).json({ message: 'Internal server error', error: error.message });
//     }
// };
const createTenant = async (req, res) => {
  try {
    const { tenantName, tenantCode, userName, userEmail } = req.body;

    // Check if email already exists
    const existingUser = await User.findOne({ email: userEmail });
    if (existingUser) {
      return res.status(409).json({
        error: 'User with this email already exists',
        code: 'EMAIL_EXISTS'
      });
    }

    const existingTenant = await Tenant.findOne({ code: tenantCode.toUpperCase() });
    if (existingTenant) {
      return res.status(409).json({
        error: 'Tenant with this code already exists',
        code: 'TENANT_CODE_EXISTS'
      });
    }

    const adminRole = await Role.findOne({ name: 'ADMIN' });
    if (!adminRole) {
      return res.status(500).json({
        error: 'ADMIN role not found. Please contact system administrator.',
        code: 'ADMIN_ROLE_NOT_FOUND'
      });
    }

    const tenantData = new Tenant({
      name: tenantName.trim(),
      code: tenantCode.trim().toUpperCase(),
    });
    const tenant = await tenantData.save();

    const password = generateRandomPassword(10);
    console.log("email: ", userEmail, "password: ", password);

    // Create user
    const user = new User({
      name: userName,
      email: userEmail,
      passwordHash: password, // Will be hashed by pre-save middleware
      role: adminRole._id,
      tenantId: tenant._id,
    });

    await user.save();

    await AuditLog.create({
      action: 'User and Tenant Created',
      userId: req.user.userId,
      ipAddress: req.ip,
    });
    // Populate the created user
    const populatedUser = await User.findById(user._id)
      .populate('role', 'name')
      .populate('tenantId', 'name code')
      .select('-passwordHash');

    return res.status(201).json({
      message: 'User created successfully',
      user: populatedUser
    });
  } catch (error) {
    console.error('Create user error:', error);
    res.status(500).json({
      error: 'Internal server error',
      code: 'CREATE_USER_FAILED'
    });
  }
}

const getAllTenants = async (req, res) => {
    try {
        const {
            isActive,
            page = 1,
            limit = 10,
            sortBy = 'createdAt',
            sortOrder = 'desc',
            search
        } = req.query;

        let filter = {};

        if (isActive !== undefined) {
            filter.isActive = isActive === 'true';
        }

        if (search) {
            filter.$or = [
                { name: { $regex: search, $options: 'i' } },
                { code: { $regex: search, $options: 'i' } }
            ];
        }

        // Build sort
        const sort = {};
        sort[sortBy] = sortOrder === 'desc' ? -1 : 1;

        // Execute query with pagination
        const tenants = await Tenant.find(filter)
            .sort(sort)
            .limit(limit * 1)
            .skip((page - 1) * limit)
            .lean();

        const total = await Tenant.countDocuments(filter);

        res.json({
            tenants,
            pagination: {
                currentPage: parseInt(page),
                totalPages: Math.ceil(total / limit),
                totalRecords: total,
                limit: parseInt(limit)
            }
        });
    } catch (error) {
        console.error('Get tenants error:', error);
        res.status(500).json({
            error: 'Internal server error',
            code: 'GET_TENANTS_FAILED'
        });
    }
};

const getTenantById = async (req, res) => {
    try {
        const tenantId = req.params.id;
        const tenant = await Tenant.findById(tenantId);
        if (!mongoose.Types.ObjectId.isValid(id)) {
            return res.status(400).json({
                error: 'Invalid tenant ID format',
                code: 'INVALID_TENANT_ID'
            });
        }
        if (!tenant) {
            return res.status(404).json({ message: 'Tenant not found' });
        }
        res.json.status(200).json({
            message: 'Tenant retrieved successfully',
            data: tenant
        });
    } catch (error) {
        console.error('Get tenant by ID error:', error);
        res.status(500).json({
            error: 'Internal server error',
            code: 'GET_TENANT_BY_ID_FAILED'
        });
    }
};

const updateTenant = async (req, res) => {
    try {
        const tenantId = req.params.id;
        if (!mongoose.Types.ObjectId.isValid(tenantId)) {
            return res.status(400).json({
                error: 'Invalid tenant ID format',
                code: 'INVALID_TENANT_ID'
            });
        }
        const { name, code, isActive } = req.value;
        const tenant = await Tenant.findById(tenantId);
        if (!tenant) {
            return res.status(404).json({ message: 'Tenant not found' });
        }
        if(code && code.trim().toUpperCase() !== tenant.code ) {
            const existingTenant = await Tenant.findOne({ code: code.trim().toUpperCase() });
            if (existingTenant) {
                return res.status(400).json({ message: 'Tenant with this code already exists' });
            }
        }
        tenant.name = name.trim();
        tenant.code = code.trim().toUpperCase();
        tenant.isActive = isActive;
        await tenant.save();
        await AuditLog.create({
            action: 'tenant_updated',
            userId: req.user._id, //Need at time of authentication
            ipAddress: req.ip,
        });
        res.status(200).json({ message: 'Tenant updated successfully', data: tenant });
    } catch (error) {
        console.error('Update tenant error:', error);
        res.status(500).json({
            error: 'Internal server error',
            code: 'UPDATE_TENANT_FAILED'
        });
    }
};
module.exports = {
    createTenant,
    getAllTenants,
    getTenantById,
    updateTenant
};