const WebSocket = require('ws');
const jwt = require('jsonwebtoken');
const User = require('./models/User');
const CareerPath = require('./models/CareerPath');
const CareerProgression = require('./models/CareerProgression');
const Certification = require('./models/Certification');
const IndustryAnalysis = require('./models/IndustryAnalysis');

class CareerGuidanceWebSocket {
    constructor(server) {
        try {
            this.wss = new WebSocket.Server({ 
                server,
                path: '/ws/career-guidance',
                perMessageDeflate: false,
                maxPayload: 16 * 1024 * 1024 // 16MB max payload
            });
            
            this.clients = new Map();
            
            // Connection statistics
            this.stats = {
                totalConnections: 0,
                activeConnections: 0,
                totalMessages: 0,
                errors: 0
            };
            
            console.log('🎯 [WEBSOCKET] Career Guidance WebSocket server started on /ws/career-guidance');
            
            this.setupWebSocket();
            this.setupPeriodicCleanup();
            
        } catch (error) {
            console.error('❌ [WEBSOCKET] Failed to initialize Career Guidance WebSocket:', error);
            throw error;
        }
    }

    setupPeriodicCleanup() {
        // Clean up broken connections every 30 seconds
        setInterval(() => {
            this.cleanupBrokenConnections();
        }, 30000);
        
        // Log statistics every 5 minutes
        setInterval(() => {
            this.logStatistics();
        }, 300000);
    }
    
    cleanupBrokenConnections() {
        let cleanedCount = 0;
        const brokenClients = [];
        
        for (const [clientId, client] of this.clients.entries()) {
            if (client.ws.readyState !== WebSocket.OPEN) {
                brokenClients.push(clientId);
                cleanedCount++;
            }
        }
        
        // Remove broken clients
        brokenClients.forEach(clientId => {
            this.clients.delete(clientId);
        });
        
        if (cleanedCount > 0) {
            console.log(`🧹 [WEBSOCKET] Cleaned up ${cleanedCount} broken Career Guidance connections`);
        }
    }
    
    logStatistics() {
        console.log(`📊 [WEBSOCKET STATS] Career Guidance:`, {
            totalConnections: this.stats.totalConnections,
            activeConnections: this.stats.activeConnections,
            currentClients: this.clients.size,
            totalMessages: this.stats.totalMessages,
            errors: this.stats.errors
        });
    }

    setupWebSocket() {
        this.wss.on('connection', async (ws, req) => {
            this.stats.totalConnections++;
            this.stats.activeConnections++;
            
            try {
                // Extract token from query parameters or headers
                const url = new URL(req.url, `http://${req.headers.host}`);
                const token = url.searchParams.get('token') || req.headers.authorization?.split(' ')[1];
                
                if (!token) {
                    this.sendError(ws, "Authentication token required");
                    ws.close(1008, "Authentication required");
                    return;
                }

                // Verify JWT token
                const decoded = jwt.verify(token, process.env.JWT_SECRET || 'your-secret-key');
                const user = await User.findById(decoded.id).select('-password');
                
                if (!user) {
                    this.sendError(ws, "Invalid token - user not found");
                    ws.close(1008, "Invalid token");
                    return;
                }

                const clientId = this.generateClientId();
                this.clients.set(clientId, {
                    ws,
                    id: clientId,
                    user: user,
                    connectedAt: new Date()
                });

                console.log(`🎯 [WEBSOCKET] Client connected: ${clientId} (User: ${user.email})`);
                
                // Send welcome message
                this.sendMessage(ws, {
                    type: "connection",
                    message: "Connected to Career Guidance Server. Send your userId and occupation for personalized career guidance.",
                    clientId: clientId,
                    user: {
                        id: user._id,
                        email: user.email,
                        name: user.name
                    }
                }, user);

                // Set up event handlers after successful authentication
                ws.on('message', async (data) => {
                    try {
                        const message = JSON.parse(data.toString());
                        console.log(`🎯 [WEBSOCKET] Message received from ${user.email}:`, message);
                        await this.handleMessage(clientId, message);
                    } catch (error) {
                        console.error("🎯 [WEBSOCKET] Error parsing message:", error);
                        this.sendError(ws, "Invalid message format");
                    }
                });

                ws.on('close', () => {
                    this.stats.activeConnections--;
                    console.log(`🎯 [WEBSOCKET] Client disconnected: ${clientId}`);
                    this.clients.delete(clientId);
                });

                ws.on('error', (error) => {
                    this.stats.errors++;
                    this.stats.activeConnections--;
                    console.error(`🎯 [WEBSOCKET] WebSocket error for client ${clientId}:`, error);
                    this.clients.delete(clientId);
                });

            } catch (error) {
                console.error("🎯 [WEBSOCKET] WebSocket authentication error:", error);
                if (error.name === 'JsonWebTokenError') {
                    this.sendError(ws, "Invalid token");
                } else if (error.name === 'TokenExpiredError') {
                    this.sendError(ws, "Token expired");
                } else {
                    this.sendError(ws, "Authentication failed");
                }
                ws.close(1008, "Authentication failed");
                return;
            }
        });

        console.log("🎯 [WEBSOCKET] Career Guidance WebSocket server initialized");
    }

    generateClientId() {
        return "career_client_" + Math.random().toString(36).substr(2, 9);
    }

    async handleMessage(clientId, message) {
        this.stats.totalMessages++;
        
        const client = this.clients.get(clientId);
        if (!client) {
            console.error("🎯 [WEBSOCKET] Client not found:", clientId);
            return;
        }

        const { type, userId, occupation } = message;

        switch (type) {
            case "career_guidance":
                await this.handleCareerGuidance(client, userId, occupation);
                break;
            case "ping":
                this.sendMessage(client.ws, { type: "pong", timestamp: Date.now() }, client.user);
                break;
            default:
                this.sendError(client.ws, "Unknown message type", client.user);
        }
    }

    async handleCareerGuidance(client, userId, occupation) {
        try {
            console.log(`🎯 [WEBSOCKET] Processing career guidance for user ${userId}, occupation: ${occupation}`);
            
            // Validate input
            if (!userId || !occupation) {
                this.sendError(client.ws, "Both userId and occupation are required", client.user);
                return;
            }

            // Send processing indicator
            this.sendMessage(client.ws, {
                type: "processing",
                message: "Analyzing your career profile and generating personalized guidance..."
            }, client.user);

            // Generate career guidance response
            const careerGuidance = await this.generateCareerGuidance(userId, occupation);
            
            // Send structured response
            this.sendMessage(client.ws, {
                type: "career_guidance_response",
                data: careerGuidance,
                timestamp: new Date().toISOString()
            }, client.user);

            console.log(`🎯 [WEBSOCKET] Career guidance sent to ${client.user.email}`);

        } catch (error) {
            console.error("🎯 [WEBSOCKET] Career guidance error:", error);
            this.sendError(client.ws, "Failed to generate career guidance. Please try again.", client.user);
        }
    }

    async generateCareerGuidance(userId, occupation) {
        try {
            // Get user details
            const user = await User.findById(userId).select('name email mobile');
            
            // Generate related occupations
            const relatedOccupations = await this.getRelatedOccupations(occupation);
            
            // Get recommended certifications
            const certifications = await this.getRecommendedCertifications(occupation);
            
            // Get industrial switching opportunities
            const switchingOpportunities = await this.getIndustrialSwitchingOpportunities(occupation);
            
            // Generate skills assessment
            const skillsAssessment = await this.generateSkillsAssessment(occupation);
            
            // Generate career progression roadmap
            const careerRoadmap = await this.generateCareerRoadmap(occupation);

            return {
                user: {
                    id: user?._id,
                    name: user?.name,
                    email: user?.email
                },
                currentOccupation: occupation,
                relatedOccupations: relatedOccupations,
                recommendedCertifications: certifications,
                industrialSwitchingOpportunities: switchingOpportunities,
                skillsAssessment: skillsAssessment,
                careerProgressionRoadmap: careerRoadmap,
                generatedAt: new Date().toISOString()
            };

        } catch (error) {
            console.error("🎯 [WEBSOCKET] Error generating career guidance:", error);
            throw error;
        }
    }

    async getRelatedOccupations(occupation) {
        // This would typically query a database or AI service
        // For now, returning mock data based on occupation
        const occupationMap = {
            'software engineer': [
                'Senior Software Engineer',
                'Tech Lead',
                'Software Architect',
                'DevOps Engineer',
                'Full Stack Developer',
                'Mobile App Developer',
                'Data Engineer'
            ],
            'teacher': [
                'Senior Teacher',
                'Department Head',
                'Principal',
                'Education Consultant',
                'Curriculum Developer',
                'Training Manager',
                'Academic Coordinator'
            ],
            'doctor': [
                'Specialist Doctor',
                'Senior Consultant',
                'Medical Director',
                'Healthcare Administrator',
                'Medical Researcher',
                'Public Health Officer',
                'Medical Educator'
            ],
            'business analyst': [
                'Senior Business Analyst',
                'Product Manager',
                'Project Manager',
                'Business Consultant',
                'Data Analyst',
                'Operations Manager',
                'Strategy Consultant'
            ]
        };

        return occupationMap[occupation.toLowerCase()] || [
            'Senior ' + occupation,
            occupation + ' Manager',
            'Lead ' + occupation,
            'Senior Consultant',
            'Director of ' + occupation
        ];
    }

    async getRecommendedCertifications(occupation) {
        const certificationMap = {
            'software engineer': [
                { name: 'AWS Certified Solutions Architect', provider: 'Amazon Web Services', duration: '3 months' },
                { name: 'Google Cloud Professional Developer', provider: 'Google Cloud', duration: '2 months' },
                { name: 'Microsoft Azure Developer Associate', provider: 'Microsoft', duration: '2 months' },
                { name: 'Certified Kubernetes Administrator', provider: 'CNCF', duration: '1 month' }
            ],
            'teacher': [
                { name: 'Post Graduate Diploma in Education', provider: 'Various Universities', duration: '1 year' },
                { name: 'Certified Educational Technology Specialist', provider: 'ISTE', duration: '6 months' },
                { name: 'Advanced Teaching Methods Certification', provider: 'Education Board', duration: '3 months' }
            ],
            'doctor': [
                { name: 'Board Certification in Specialty', provider: 'Medical Board', duration: '3-5 years' },
                { name: 'Advanced Life Support Certification', provider: 'Medical Association', duration: '1 month' },
                { name: 'Healthcare Management Certification', provider: 'Healthcare Institute', duration: '6 months' }
            ],
            'business analyst': [
                { name: 'Certified Business Analysis Professional', provider: 'IIBA', duration: '6 months' },
                { name: 'Agile Analysis Certification', provider: 'IIBA', duration: '3 months' },
                { name: 'Data Analysis Certification', provider: 'Various', duration: '4 months' }
            ]
        };

        return certificationMap[occupation.toLowerCase()] || [
            { name: 'Professional Certification in ' + occupation, provider: 'Industry Association', duration: '6 months' },
            { name: 'Advanced ' + occupation + ' Certificate', provider: 'Professional Body', duration: '3 months' }
        ];
    }

    async getIndustrialSwitchingOpportunities(occupation) {
        const switchingMap = {
            'software engineer': [
                { industry: 'FinTech', roles: ['FinTech Developer', 'Blockchain Developer', 'Payment Systems Engineer'] },
                { industry: 'Healthcare Tech', roles: ['HealthTech Developer', 'Medical Software Engineer', 'Telemedicine Developer'] },
                { industry: 'EdTech', roles: ['EdTech Developer', 'Learning Management System Developer', 'Educational Software Engineer'] },
                { industry: 'E-commerce', roles: ['E-commerce Developer', 'Digital Commerce Engineer', 'Online Platform Developer'] }
            ],
            'teacher': [
                { industry: 'Corporate Training', roles: ['Corporate Trainer', 'Learning & Development Specialist', 'Training Manager'] },
                { industry: 'EdTech', roles: ['EdTech Consultant', 'Educational Content Creator', 'Online Learning Specialist'] },
                { industry: 'Publishing', roles: ['Educational Content Writer', 'Curriculum Developer', 'Educational Publisher'] }
            ],
            'doctor': [
                { industry: 'Pharmaceutical', roles: ['Medical Affairs Manager', 'Clinical Research Associate', 'Medical Advisor'] },
                { industry: 'Healthcare IT', roles: ['Health Informatics Specialist', 'Medical Software Consultant', 'Healthcare Data Analyst'] },
                { industry: 'Insurance', roles: ['Medical Underwriter', 'Health Claims Specialist', 'Medical Review Officer'] }
            ],
            'business analyst': [
                { industry: 'Consulting', roles: ['Management Consultant', 'Strategy Consultant', 'Business Process Consultant'] },
                { industry: 'Technology', roles: ['Product Manager', 'Technical Business Analyst', 'IT Business Analyst'] },
                { industry: 'Finance', roles: ['Financial Analyst', 'Risk Analyst', 'Investment Analyst'] }
            ]
        };

        return switchingMap[occupation.toLowerCase()] || [
            { industry: 'Technology', roles: ['Tech ' + occupation, 'Digital ' + occupation] },
            { industry: 'Consulting', roles: ['Consultant', 'Senior ' + occupation + ' Consultant'] }
        ];
    }

    async generateSkillsAssessment(occupation) {
        const skillsMap = {
            'software engineer': {
                currentSkills: ['Programming', 'Problem Solving', 'System Design', 'Database Management'],
                recommendedSkills: ['Cloud Computing', 'DevOps', 'Machine Learning', 'Microservices', 'Security']
            },
            'teacher': {
                currentSkills: ['Communication', 'Subject Knowledge', 'Classroom Management', 'Student Assessment'],
                recommendedSkills: ['Educational Technology', 'Online Teaching', 'Data Analysis', 'Curriculum Design', 'Multimedia Creation']
            },
            'doctor': {
                currentSkills: ['Medical Knowledge', 'Patient Care', 'Diagnosis', 'Treatment Planning'],
                recommendedSkills: ['Digital Health', 'Telemedicine', 'Medical Research', 'Healthcare Technology', 'Patient Management Systems']
            },
            'business analyst': {
                currentSkills: ['Analytical Thinking', 'Requirements Gathering', 'Process Mapping', 'Stakeholder Management'],
                recommendedSkills: ['Data Analytics', 'Agile Methodologies', 'Business Intelligence', 'Project Management', 'Digital Transformation']
            }
        };

        return skillsMap[occupation.toLowerCase()] || {
            currentSkills: ['Core ' + occupation + ' Skills', 'Industry Knowledge', 'Problem Solving'],
            recommendedSkills: ['Advanced ' + occupation + ' Skills', 'Technology Integration', 'Leadership', 'Innovation']
        };
    }

    async generateCareerRoadmap(occupation) {
        const roadmapMap = {
            'software engineer': [
                { level: 'Entry Level (0-2 years)', roles: ['Junior Developer', 'Software Engineer I'], skills: ['Basic Programming', 'Version Control', 'Testing'] },
                { level: 'Mid Level (2-5 years)', roles: ['Software Engineer II', 'Senior Developer'], skills: ['System Design', 'Code Review', 'Mentoring'] },
                { level: 'Senior Level (5-8 years)', roles: ['Senior Software Engineer', 'Tech Lead'], skills: ['Architecture', 'Team Leadership', 'Strategic Planning'] },
                { level: 'Expert Level (8+ years)', roles: ['Principal Engineer', 'Engineering Manager', 'CTO'], skills: ['Technical Strategy', 'Team Management', 'Business Acumen'] }
            ],
            'teacher': [
                { level: 'Entry Level (0-2 years)', roles: ['Assistant Teacher', 'Teacher'], skills: ['Classroom Management', 'Lesson Planning', 'Student Assessment'] },
                { level: 'Mid Level (2-5 years)', roles: ['Senior Teacher', 'Subject Coordinator'], skills: ['Curriculum Development', 'Mentoring', 'Educational Technology'] },
                { level: 'Senior Level (5-8 years)', roles: ['Department Head', 'Academic Coordinator'], skills: ['Team Leadership', 'Policy Development', 'Educational Research'] },
                { level: 'Expert Level (8+ years)', roles: ['Principal', 'Education Director'], skills: ['Strategic Planning', 'Institutional Management', 'Educational Innovation'] }
            ]
        };

        return roadmapMap[occupation.toLowerCase()] || [
            { level: 'Entry Level', roles: ['Junior ' + occupation], skills: ['Basic Skills', 'Learning', 'Adaptation'] },
            { level: 'Mid Level', roles: ['Senior ' + occupation], skills: ['Advanced Skills', 'Mentoring', 'Leadership'] },
            { level: 'Senior Level', roles: ['Lead ' + occupation], skills: ['Expertise', 'Strategy', 'Innovation'] },
            { level: 'Expert Level', roles: ['Director', 'VP'], skills: ['Strategic Vision', 'Management', 'Business Acumen'] }
        ];
    }

    sendMessage(ws, message, user = null) {
        if (ws.readyState === WebSocket.OPEN) {
            const userInfo = user ? ` (User: ${user.email})` : ' (User: unknown)';
            console.log(`🎯 [WEBSOCKET] Sending message to user${userInfo}:`, JSON.stringify(message, null, 2));
            ws.send(JSON.stringify(message));
        }
    }

    sendError(ws, errorMessage, user = null) {
        console.log(`❌ [WEBSOCKET] Sending error message to user: ${errorMessage}`);
        this.sendMessage(ws, {
            type: "error",
            message: errorMessage,
            timestamp: new Date().toISOString()
        }, user);
    }

    // Broadcast message to all connected clients
    broadcast(message) {
        this.clients.forEach((client) => {
            this.sendMessage(client.ws, message, client.user);
        });
    }

    // Get connected clients count
    getConnectedClientsCount() {
        return this.clients.size;
    }

    // Get client info
    getClientInfo() {
        return Array.from(this.clients.values()).map(client => ({
            id: client.id,
            connectedAt: client.connectedAt,
            user: client.user
        }));
    }
}

module.exports = CareerGuidanceWebSocket;
