const KycSession = require('../models/kycSessionSchema');
const Customer = require('../models/customerSchema');
const User = require('../models/userSchema');
const Tenant = require('../models/tenantSchema');
const AuditLog = require('../models/auditLogSchema');
const mongoose = require('mongoose');

const createKycSession = async (req, res) => {
    try {
        const { tenantId, customerId, fiUserId, officerId, sessionStart, sessionEnd, status, rejectionReason } = req.body;

        // Validate referenced documents exist
        const tenant = await Tenant.findById(tenantId);
        if (!tenant || !tenant.isActive) {
            return res.status(400).json({
                error: 'Invalid or inactive tenant',
                code: 'INVALID_TENANT'
            });
        }

        const customer = await Customer.findById(customerId);
        if (!customer) {
            return res.status(400).json({
                error: 'Customer not found',
                code: 'CUSTOMER_NOT_FOUND'
            });
        }

        const fiUser = await User.findById(fiUserId);
        if (!fiUser || !fiUser.isActive) {
            return res.status(400).json({
                error: 'FI User not found or inactive',
                code: 'FI_USER_NOT_FOUND'
            });
        }

        let officer = null;
        if (officerId) {
            officer = await User.findById(officerId);
            if (!officer || !officer.isActive) {
                return res.status(400).json({
                    error: 'Officer not found or inactive',
                    code: 'OFFICER_NOT_FOUND'
                });
            }
        }

        // Ensure customer belongs to the same tenant
        if (customer.tenantId.toString() !== tenantId) {
            return res.status(400).json({
                error: 'Customer does not belong to the specified tenant',
                code: 'CUSTOMER_TENANT_MISMATCH'
            });
        }

        // Create KYC session
        const kycSession = new KycSession({
            tenantId,
            customerId,
            fiUserId,
            officerId: officerId || null,
            sessionStart: sessionStart || new Date(),
            sessionEnd: sessionEnd || null,
            status: status || 'initiated',
            rejectionReason: rejectionReason || null
        });

        await kycSession.save();

        // Populate the created session
        const populatedSession = await KycSession.findById(kycSession._id)
            .populate('tenantId', 'name code')
            .populate('customerId', 'name caseNo mobile')
            .populate('fiUserId', 'name email')
            .populate('officerId', 'name email');

        // Log the action
        await AuditLog.create({
            userId: req.user._id,
            action: 'kyc_session_created',
            ipAddress: req.ip,
        });

        res.status(201).json({
            message: 'KYC session created successfully',
            kycSession: populatedSession
        });
    } catch (error) {
        console.error('Create KYC session error:', error);
        res.status(500).json({
            error: 'Internal server error',
            code: 'CREATE_KYC_SESSION_FAILED'
        });
    }
}

const getAllKycSessions = async (req, res) => {
    try {
        const {
            tenantId,
            customerId,
            fiUserId,
            officerId,
            status,
            page = 1,
            limit = 10,
            sortBy = 'sessionStart',
            sortOrder = 'desc'
        } = req.query;

        // Build filter
        let filter = {};

        if (tenantId) filter.tenantId = tenantId;
        if (customerId) filter.customerId = customerId;
        if (fiUserId) filter.fiUserId = fiUserId;
        if (officerId) filter.officerId = officerId;
        if (status) filter.status = status;

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

        // Execute query
        const kycSessions = await KycSession.find(filter)
            .populate('tenantId', 'name code')
            .populate('customerId', 'name caseNo mobile kycStatus')
            .populate('fiUserId', 'name email')
            .populate('officerId', 'name email')
            .sort(sort)
            .limit(limit * 1)
            .skip((page - 1) * limit);

        const total = await KycSession.countDocuments(filter);

        res.status(200).json({
            kycSessions,
            pagination: {
                currentPage: parseInt(page),
                totalPages: Math.ceil(total / limit),
                totalRecords: total,
                limit: parseInt(limit)
            },
            message: 'KYC sessions retrieved successfully'
        });
    } catch (error) {
        console.error('Get KYC sessions error:', error);
        res.status(500).json({
            error: 'Internal server error',
            code: 'GET_KYC_SESSIONS_FAILED'
        });
    }
}

const getKycSessionById = async (req, res) => {
    try {
        const { id } = req.params;

        // Validate ID format
        if (!mongoose.Types.ObjectId.isValid(id)) {
            return res.status(400).json({
                error: 'Invalid KYC session ID',
                code: 'INVALID_KYC_SESSION_ID'
            });
        }

        const kycSession = await KycSession.findById(id)
            .populate('tenantId', 'name code')
            .populate('customerId', 'name caseNo mobile kycStatus')
            .populate('fiUserId', 'name email')
            .populate('officerId', 'name email');

        if (!kycSession) {
            return res.status(404).json({
                error: 'KYC session not found',
                code: 'KYC_SESSION_NOT_FOUND'
            });
        }

        res.status(200).json({
            kycSession,
            message: 'KYC session retrieved successfully'
        });
    } catch (error) {
        console.error('Get KYC session by ID error:', error);
        res.status(500).json({
            error: 'Internal server error',
            code: 'GET_KYC_SESSION_BY_ID_FAILED'
        });
    }
}

const updateKycSession = async (req, res) => {
    try {
        const { id } = req.params;
        const updates = req.body;

        if (!mongoose.Types.ObjectId.isValid(id)) {
            return res.status(400).json({
                error: 'Invalid KYC session ID format',
                code: 'INVALID_KYC_SESSION_ID'
            });
        }

        const kycSession = await KycSession.findById(id);
        if (!kycSession) {
            return res.status(404).json({
                error: 'KYC session not found',
                code: 'KYC_SESSION_NOT_FOUND'
            });
        }

        // // Store original values for audit
        // const originalValues = {
        //     status: kycSession.status,
        //     sessionEnd: kycSession.sessionEnd,
        //     rejectionReason: kycSession.rejectionReason
        // };

        // Update fields
        Object.keys(updates).forEach(key => {
            if (updates[key] !== undefined) {
                kycSession[key] = updates[key];
            }
        });

        // Auto-set sessionEnd if status changes to approved/rejected
        if (updates.status && ['approved', 'rejected'].includes(updates.status) && !kycSession.sessionEnd) {
            kycSession.sessionEnd = new Date();
        }

        await kycSession.save();

        // Get updated session with populated fields
        const updatedSession = await KycSession.findById(id)
            .populate('tenantId', 'name code')
            .populate('customerId', 'name caseNo mobile')
            .populate('fiUserId', 'name email')
            .populate('officerId', 'name email');

        // Log the action
        await AuditLog.create({
            userId: req.user._id,
            action: 'kyc_session_updated',
            ipAddress: req.ip,
        });

        res.status(200).json({
            message: 'KYC session updated successfully',
            kycSession: updatedSession
        });
    } catch (error) {
        console.error('Update KYC session error:', error);
        res.status(500).json({
            error: 'Internal server error',
            code: 'UPDATE_KYC_SESSION_FAILED'
        });
    }
}

const deleteKycSession = async (req, res) => {
    try {
        const { id } = req.params;

        if (!mongoose.Types.ObjectId.isValid(id)) {
            return res.status(400).json({
                error: 'Invalid KYC session ID format',
                code: 'INVALID_KYC_SESSION_ID'
            });
        }

        const kycSession = await KycSession.findById(id);
        if (!kycSession) {
            return res.status(404).json({
                error: 'KYC session not found',
                code: 'KYC_SESSION_NOT_FOUND'
            });
        }

        await KycSession.findByIdAndDelete(id);

        // Log the action
        await AuditLog.create({
            userId: req.user._id,
            action: 'kyc_session_deleted',
            ipAddress: req.ip,
        });

        res.status(200).json({
            message: 'KYC session deleted successfully'
        });
    } catch (error) {
        console.error('Delete KYC session error:', error);
        res.status(500).json({
            error: 'Internal server error',
            code: 'DELETE_KYC_SESSION_FAILED'
        });
    }
}


module.exports = {
    createKycSession,
    getAllKycSessions,
    getKycSessionById,
    updateKycSession,
    deleteKycSession
};