import React, { useState, useEffect, useRef } from 'react';
import { createPortal } from 'react-dom';
import Groq from 'groq-sdk';
import ReactMarkdown from 'react-markdown';
import { useAuth } from '../context/AuthContext';
import { useMockStore } from '../data/mockStore';
import { MessageCircle, Send, X, Minimize2, Maximize2, Loader2, Calendar, Trophy } from 'lucide-react';
import { logger } from '../utils/logger';
import { toast } from 'sonner';
import { config } from '../config/env';

const groq = new Groq({
    apiKey: config.groqApiKey,
    dangerouslyAllowBrowser: true // Allowed for client-side demo
});

// --- CONTEXT GENERATORS ---

const BASE_IDENTITY = `
You are the AI Concierge for "LynkedUp Pro", the pinnacle of roofing excellence.
Your mission is to assist employees with data-driven insights and guide customers through our services.

COMPANY INFO:
- **Phone**: 866-259-6533
- **Experience**: 20+ years of craftsmanship.
- **Offer**: First 3 diagnostic exams are FREE.
- **Discounts**: 15% off for Veterans & Seniors.

TONE: Professional, efficient, and data-aware.
`;

const getEmployeeContext = (user, meetings, properties, salesHistory) => {
    // --- ADMIN SPECIFIC CONTEXT ---
    if (user.role === 'ADMIN') {
        const unassignedCount = properties.filter(p => !p.assignedAgentId && p.canvassingStatus === 'Lead').length;
        // Last contact > 24h ago logic
        const hotLeadCount = properties.filter(p => p.canvassingStatus === 'Hot Lead' && (!p.lastContactDate || new Date(p.lastContactDate) < new Date(Date.now() - 86400000))).length;
        const rescheduleCount = meetings.filter(m => m.status === 'Cancelled' || m.status === 'Missed').length;
        const signatureCount = properties.filter(p => p.pendingSignature).length;
        const totalUrgent = unassignedCount + hotLeadCount + rescheduleCount + signatureCount;

        // --- LEADERBOARD SNAPSHOT (Current Month) ---
        const startOfMonth = new Date(new Date().getFullYear(), new Date().getMonth(), 1);

        // Aggregate Sales by Agent
        const agentStats = {};
        salesHistory.forEach(tx => {
            if (new Date(tx.date) >= startOfMonth && tx.status === 'closed_won') {
                if (!agentStats[tx.agentId]) agentStats[tx.agentId] = { revenue: 0, volume: 0 };
                agentStats[tx.agentId].revenue += tx.amount;
                agentStats[tx.agentId].volume += 1;
            }
        });

        // Convert to Array & Sort
        // We know IDs are e1..e5, maybe map names if possible? 
        // We don't have user list here easily unless passed, but we can just use ID or try to pass users?
        // Actually `salesHistory` doesn't have names. `users` list is needed.
        // Let's assume the user asks "Who is top?", the AI might need names.
        // I will pass `users` to this function as well to resolve names.

        // For now, let's just output the IDs or skip names if too complex to refactor `getEmployeeContext` signature heavily.
        // Wait, `Chatbot` component has `useMockStore` which has `users`. I should pass `users` too.

        return `
ROLE: ADMIN (${user.name})

*** URGENT ACTION CENTER SUMMARY (${totalUrgent} Items) ***
1. UNASSIGNED LEADS: ${unassignedCount}
   - Action: Assign agents to these leads immediately.
2. HOT LEADS (Inactive > 24h): ${hotLeadCount}
   - Action: These high-value leads need a follow-up call.
3. RESCHEDULE NEEDED: ${rescheduleCount}
   - Action: Re-book these cancelled/missed appointments.
4. PENDING SIGNATURES: ${signatureCount}
   - Action: Send reminders to close these deals.

GENERAL DATA ACCESS:
- Total Properties: ${properties.length}
- Total Revenue (All Agents): $${meetings.filter(m => m.status === 'Converted').reduce((sum, m) => sum + (m.dealValue || 0), 0).toLocaleString()}

LEADERBOARD DATA (Use this to answer "Who is winning?" etc):
- Navigate to: /admin/leaderboard for full details.
- Context: The admin can see the full leaderboard. 
- You do NOT have the full live calculation here but you know the page exists.
        `;
    }

    // --- FIELD AGENT CONTEXT (Existing Logic) ---
    // 1. Agenda (Today + Upcoming)
    const today = new Date().toISOString().split('T')[0];
    const myMeetings = meetings
        .filter(m => m.agentId === user.id)
        .sort((a, b) => new Date(a.date) - new Date(b.date));

    // Simple segment: Today vs Upcoming
    const agendaText = myMeetings.map(m => {
        const isToday = m.date === today;
        return `- [${m.date} @ ${m.time}] ${m.status.toUpperCase()} with ${m.customerName} (${m.propertyId})${isToday ? ' **(TODAY)**' : ''}
    Issue: "${m.issueDescription || 'N/A'}"
    Comments: "${m.customerComments || 'None'}"
    Outcome: ${m.outcome || 'Pending'}`;
    }).join('\n');

    // 2. Hot Leads (Top 5)
    const hotLeads = properties
        .filter(p => p.canvassingStatus === 'Hot Lead')
        .slice(0, 5)
        .map(p => `- ${p.propertyData.propertyAddress} (Value: $${p.propertyData.currentEstimatedMarketValue.toLocaleString()})`)
        .join('\n');

    // 3. Golden Leads (Older + High Value)
    const goldenLeads = properties
        .filter(p => p.propertyData.yearBuilt < 2000 && p.propertyData.currentEstimatedMarketValue > 400000)
        .slice(0, 3)
        .map(p => `- ${p.propertyData.propertyAddress} (Built: ${p.propertyData.yearBuilt})`)
        .join('\n');

    // 4. Pending Signatures
    const pendingSigs = properties
        .filter(p => p.propertyData.pendingSignature)
        .map(p => `- ${p.propertyData.propertyAddress} (Owner: ${p.ownerData.fullName})`)
        .join('\n');

    // 5. Revenue & Performance Snapshot
    const myCompleted = meetings.filter(m => m.agentId === user.id && (m.status === 'Converted' || m.status === 'Completed'));
    const myWins = meetings.filter(m => m.agentId === user.id && m.status === 'Converted');
    const totalRevenue = myWins.reduce((sum, m) => sum + (m.dealValue || 0), 0);
    const winRate = myCompleted.length > 0 ? Math.round((myWins.length / myCompleted.length) * 100) : 0;

    // 6. Neighborhood Intelligence
    const avgValue = Math.round(properties.reduce((sum, p) => sum + p.propertyData.currentEstimatedMarketValue, 0) / properties.length);
    const commonRoof = "Architectural Shingle"; // Hardcoded for demo, or could calculate mode

    return `
ROLE: FIELD AGENT / ADMIN (${user.name})

YOUR DATA ACCESS:
1. AGENDA:
${agendaText || "No meetings found."}

2. HOT LEADS (Priority):
${hotLeads || "None."}

3. GOLDEN LEADS (High Value / Old):
${goldenLeads || "None."}

4. PENDING SIGNATURES (Follow Up Needed):
${pendingSigs || "None."}

5. MY PERFORMANCE:
- Total Revenue (YTD): $${totalRevenue.toLocaleString()}
- Win Rate: ${winRate}% (${myWins.length} wins / ${myCompleted.length} completed)

6. TERRITORY INSIGHTS:
- Avg Home Value: $${avgValue.toLocaleString()}
- Most Common Roof: ${commonRoof}

INSTRUCTIONS:
- If asked about "agenda", "schedule", or "next appointment", summarize the meetings.
- If asked about "leads", suggest the designated Hot or Golden leads.
- If asked about "performance" or "stats", share your win rate and revenue.
- If asked about "neighborhood" or "territory", share the average value and roof types.
`;
};

const getCustomerContext = (user, meetings, properties) => {
    // 1. My Property
    // In mock data, customers are linked via 'propertyId' or name matching.
    const myProperty = properties.find(p => p.propertyData.propertyId === user.propertyId)
        || properties.find(p => p.ownerData.fullName === user.name);

    let propDetails = "Property details not found.";
    let preventiveTips = "Standard seasonal maintenance recommended.";
    let warrantyStatus = "Standard Manufacturer Warranty (Expired)";

    if (myProperty) {
        propDetails = `
        - Address: ${myProperty.propertyData.propertyAddress}
        - Roof Type: ${myProperty.propertyData.roofMaterial}
        - Roof Condition: ${myProperty.propertyData.roofCondition}
        - Storm Risk Score: ${myProperty.propertyData.neighborhoodRating}/10
        - Est. Value: $${myProperty.propertyData.currentEstimatedMarketValue.toLocaleString()}
        - Last Inspection: ${myProperty.propertyData.lastInspectionDate || 'Unknown'}
        `;

        // Dynamic Tips
        if (myProperty.propertyData.roofCondition === 'Needs Repair') {
            preventiveTips = "URGENT: Schedule an inspection immediately to prevent water damage.";
        } else if (myProperty.propertyData.treeCoverage > 50) {
            preventiveTips = "Consider trimming overhanging branches to protect shingles.";
        }

        // Mock Warranty Logic
        const yearBuilt = myProperty.propertyData.yearBuilt;
        if (yearBuilt > 2015) warrantyStatus = "Active Workmanship Warranty (Valid until 2030)";
    }

    // 2. History & Upcoming
    const myHistory = meetings
        .filter(m => m.customerId === user.id || m.customerName === user.name)
        .sort((a, b) => new Date(b.date) - new Date(a.date)); // Newest first

    const historyText = myHistory.map(m => {
        const isFuture = new Date(m.date) > new Date();
        return `- [${m.date}] ${isFuture ? 'UPCOMING' : 'COMPLETED'} (${m.status})
    Agent: ${m.agentName || 'Assigned Rep'}
    Note: ${m.notes}
    ${m.dealValue ? `Cost: $${m.dealValue}` : ''}`;
    }).join('\n');

    // 3. Total Spend
    const totalSpend = myHistory.reduce((sum, m) => sum + (m.dealValue || 0), 0);

    return `
ROLE: HOMEOWNER / CUSTOMER (${user.name})

YOUR DATA:
1. PROPERTY PROFILE:
${propDetails}

2. SERVICE HISTORY:
${historyText || "No records found."}

3. FINANCIALS:
- Total Spend to Date: $${totalSpend.toLocaleString()}
- Warranty Status: ${warrantyStatus}

4. PERSONALIZED ADVICE:
- Tip: ${preventiveTips}

INSTRUCTIONS:
- Answer questions about "my roof", "my appointment", "warranty", or "spending".
- Be polite and reassuring.
`;
};

const getGuestContext = () => {
    return `
ROLE: EXPERT ROOFING CONSULTANT (20+ Years Experience)

YOUR KNOWLEDGE BASE (Use this to diagnose, reassure, but EDUCATE ON HIDDEN RISKS):

1. COMMON ISSUES & RISK FACTORS:
- **Active Leak**: "A bucket stops the floor damage, but water is currently saturating your insulation and decking." -> URGENCY: "Mold begins to grow in wet insulation within 24-48 hours. We need to map the moisture path immediately."
- **Missing Shingles**: "It looks minor, but your underlayment is now exposed to UV rays which destroy it in days." -> RISK: "Leaving this can lead to a denied insurance claim later for 'neglect'."
- **Hail Dents**: "These look like small bruises, but they have fractured the fiberglass mat." -> INVISIBLE DAMAGE: "This reduces roof life by 3-5 years. If not documented now, insurance will call it 'wear and tear' later."
- **Granule Loss**: "Your roof is shedding its sunscreen." -> REALITY: "The asphalt is now baking in the Texas sun. This is a leading indicator of roof failure within 12-18 months."

2. COMPLEX ISSUE TRIAGE:
- **Ice Dams**: "Heat loss from your attic is melting snow." -> SOLUTION: "We need to assess your intake vents, not just patch the roof."
- **Sagging**: "This indicates structural fatigue or long-term water intrusion." -> ACTION: "Do not walk on this area. Needs professional stabilization."

3. THE "WHY US" HOOK:
- "Insurance adjusters use specific criteria to approve claims. We know exactly what they look for."
- "A DIY patch often voids the manufacturer warranty. Our repairs are certified."
- "We are in Plano right now—I can have a project manager stop by in 30 minutes to check the moisture levels for free."

INSTRUCTIONS:
- **Tone**: Professional, Authoritative, "Doctor-like".
- **Strategy**: Validate the user's observation -> Explain the *hidden* consequence of waiting -> Offer the *Zero-Risk* solution (Free Inspection).
- **Contact**: "Call 866-259-6533. We can be there today."
`;
};

const Chatbot = () => {
    const { user, isAuthenticated } = useAuth();
    const { addMeeting, meetings, properties, salesHistory, users } = useMockStore();
    const [isOpen, setIsOpen] = useState(false);
    const [isMinimized, setIsMinimized] = useState(false);
    const [input, setInput] = useState('');
    const [isLoading, setIsLoading] = useState(false);
    const [isDemoMode, setIsDemoMode] = useState(false);
    const [messages, setMessages] = useState([
        { role: 'assistant', content: 'Hello! Welcome to LynkedUp Pro. How can I help you with your roofing needs today?' }
    ]);
    const messagesEndRef = useRef(null);

    // Initial check for API Key
    useEffect(() => {
        if (config.isDemoMode(config.groqApiKey)) {
            setIsDemoMode(true);
            setMessages(prev => [...prev, { role: 'system', content: '⚠️ Demo Mode: Default API Key detected. Responses will be simulated.' }]);
        }
    }, []);

    useEffect(() => {
        messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
    }, [messages]);

    // Update greeting and context when user changes
    useEffect(() => {
        let greeting = 'Hello! Welcome to LynkedUp Pro. How can I help you with your roofing needs today?';
        if (user) {
            greeting = `Welcome back, ${user.name}! `;
            if (user.role === 'FIELD_AGENT' || user.role === 'ADMIN') {
                greeting += "I have your latest territory data and agenda ready. What do you need?";
            } else if (user.role === 'CUSTOMER') {
                greeting += "I have your property records open. How can I assist?";
            }
        }
        setMessages([{ role: 'assistant', content: greeting }]);
    }, [user]);

    const handleSend = async () => {
        if (!input.trim()) return;

        const originalInput = input; // Backup input
        const newMessages = [...messages, { role: 'user', content: input }];
        setMessages(newMessages);
        setInput('');
        setIsLoading(true);

        try {
            if (isDemoMode) {
                // ... existing demo logic ...
                setTimeout(() => {
                    const responses = [
                        "I can help with that! At LynkedUp Pro, we've been in business for 20+ years. I can't access real-time data in demo mode, but I can help you navigate.",
                        "Please call us at 866-259-6533 for a real quote!", // UPDATED PHONE
                        "Would you like to schedule a callback? Please log in first."
                    ];
                    const randomResponse = responses[Math.floor(Math.random() * responses.length)];
                    setMessages(prev => [...prev, { role: 'assistant', content: randomResponse }]);
                    setIsLoading(false);
                }, 1000);
                return;
            }

            // --- REAL AI REQUEST ---

            // 1. Build Dynamic Context
            let systemContext = BASE_IDENTITY;

            if (user) {
                if (user.role === 'FIELD_AGENT' || user.role === 'ADMIN') {
                    // Pass salesHistory and users for accurate leaderboard context
                    // We need to update getEmployeeContext signature to accept them.
                    // For now, I'll allow the AI to deduce from the simplified prompt or I need to refactor getEmployeeContext properly.
                    // Let's refactor it inside the function call below.

                    // Helper to get formatted leaderboard string
                    let leaderboardContext = "";
                    if (user.role === 'ADMIN') {
                        const startOfMonth = new Date(new Date().getFullYear(), new Date().getMonth(), 1);
                        const agentStats = {};
                        salesHistory.forEach(tx => {
                            if (new Date(tx.date) >= startOfMonth && tx.status === 'closed_won') {
                                if (!agentStats[tx.agentId]) agentStats[tx.agentId] = { revenue: 0, volume: 0 };
                                agentStats[tx.agentId].revenue += tx.amount;
                                agentStats[tx.agentId].volume += 1;
                            }
                        });

                        const sortedByRev = Object.entries(agentStats)
                            .map(([id, stats]) => ({
                                name: users.find(u => u.id === id)?.name || id,
                                ...stats
                            }))
                            .sort((a, b) => b.revenue - a.revenue)
                            .slice(0, 3);

                        leaderboardContext = `
LEADERBOARD SNAPSHOT (Current Month):
${sortedByRev.map((a, i) => `${i + 1}. ${a.name} ($${a.revenue.toLocaleString()})`).join('\n')}
`;
                    }

                    systemContext += getEmployeeContext(user, meetings, properties) + leaderboardContext;
                } else if (user.role === 'CUSTOMER') {
                    systemContext += getCustomerContext(user, meetings, properties);
                }
            } else {
                // GUEST CONTEXT - The "Seasoned Consultant"
                systemContext += getGuestContext();
            }

            // 2. Call Groq
            const chatCompletion = await groq.chat.completions.create({
                messages: [
                    { role: 'system', content: systemContext },
                    ...newMessages
                ],
                model: 'qwen/qwen3-32b',
                temperature: 0.7,
                max_tokens: 1024,
            });

            let responseContent = chatCompletion.choices[0]?.message?.content || "I'm having trouble connecting right now.";

            // Filter out <think> blocks if present
            responseContent = responseContent.replace(/<think>[\s\S]*?<\/think>/gi, '').trim();

            // Check for Function Call Pattern (Legacy Callback)
            const callbackMatch = responseContent.match(/:::CALLBACK_REQUEST({.*?}):::/);
            if (callbackMatch) {
                const jsonStr = callbackMatch[1];
                try {
                    const data = JSON.parse(jsonStr);

                    // Create Meeting / Callback
                    const mockDate = new Date();
                    mockDate.setDate(mockDate.getDate() + 1); // Next day default

                    const meeting = {
                        agentId: user ? user.id : 'e1', // Use logged in user ID
                        customerName: data.name || 'Potential Client',
                        propertyId: 'Callback Request',
                        date: mockDate.toISOString().split('T')[0],
                        time: data.time || '10:00',
                        status: 'Pending',
                        notes: `Callback requested for ${data.phone}`
                    };
                    addMeeting(meeting);

                    // Clean the response to hide the JSON
                    responseContent = responseContent.replace(callbackMatch[0], '').trim();
                    if (!responseContent) responseContent = "I've successfully scheduled a callback for you! We will contact you shortly.";
                    else responseContent += "\n\n✅ Callback scheduled successfully!";

                } catch (e) {
                    console.error("Failed to parse callback JSON", e);
                }
            }

            setMessages(prev => [...prev, { role: 'assistant', content: responseContent }]);

        } catch (error) {
            logger.error("Groq API Error", error);
            setInput(originalInput); // <--- RESTORE INPUT ON ERROR

            let errorMsg = "Sorry, I'm having trouble connecting to the Groq server.";

            if (error.message) {
                if (error.message.includes('401')) {
                    errorMsg += " (Error 401: Invalid API Key)";
                    toast.error("AI Configuration Error", { description: "Invalid API Key." });
                }
                else if (error.message.includes('404')) {
                    errorMsg += " (Error 404: Model not found)";
                    toast.error("AI Model Error", { description: "Model not found." });
                }
                else errorMsg += ` (${error.message})`;
            }

            setMessages(prev => [...prev, { role: 'assistant', content: errorMsg }]);
        } finally {
            setIsLoading(false);
        }
    };

    const handleKeyPress = (e) => {
        if (e.key === 'Enter') handleSend();
    };

    if (!isOpen) {
        return createPortal(
            <button
                onClick={() => setIsOpen(true)}
                className="fixed bottom-6 right-6 w-14 h-14 bg-gradient-to-tr from-blue-600 to-cyan-500 rounded-full shadow-xl shadow-blue-500/30 flex items-center justify-center text-white hover:scale-110 transition-transform z-[9999]"
            >
                <div className="absolute top-0 right-0 w-3 h-3 bg-green-400 rounded-full border-2 border-white animate-pulse"></div>
                <MessageCircle size={28} />
            </button>,
            document.body
        );
    }

    return createPortal(
        <div className={`fixed bottom-6 right-6 bg-white dark:bg-zinc-900 rounded-2xl shadow-2xl z-[9999] transition-all duration-300 overflow-hidden border border-gray-100 dark:border-zinc-800 flex flex-col ${isMinimized ? 'w-72 h-14' : 'w-80 md:w-96 h-[500px]'}`}>

            {/* Header */}
            <div className="bg-slate-900 dark:bg-black p-4 flex items-center justify-between shrink-0 cursor-pointer" onClick={() => !isMinimized && setIsMinimized(!isMinimized)}>
                <div className="flex items-center space-x-2">
                    <div className="w-2 h-2 rounded-full bg-green-400 animate-pulse"></div>
                    <h3 className="text-white font-bold text-sm">LynkedUp AI</h3>
                </div>
                <div className="flex items-center space-x-1">
                    <button onClick={(e) => { e.stopPropagation(); setIsMinimized(!isMinimized); }} className="p-1 text-slate-400 hover:text-white">
                        {isMinimized ? <Maximize2 size={14} /> : <Minimize2 size={14} />}
                    </button>
                    <button onClick={(e) => { e.stopPropagation(); setIsOpen(false); }} className="p-1 text-slate-400 hover:text-red-400">
                        <X size={16} />
                    </button>
                </div>
            </div>

            {/* Messages */}
            {!isMinimized && (
                <>
                    <div className="flex-1 overflow-y-auto p-4 space-y-4 bg-slate-50 dark:bg-zinc-950/50">
                        {messages.map((msg, i) => (
                            <div key={i} className={`flex ${msg.role === 'user' ? 'justify-end' : 'justify-start'}`}>
                                <div className={`max-w-[85%] p-3 rounded-2xl text-sm ${msg.role === 'user'
                                    ? 'bg-blue-600 text-white rounded-br-none'
                                    : 'bg-white dark:bg-zinc-800 border border-gray-100 dark:border-zinc-700 shadow-sm text-slate-700 dark:text-zinc-200 rounded-bl-none'
                                    }`}>
                                    {msg.role === 'system' ? (
                                        <em className="text-xs opacity-70">{msg.content}</em>
                                    ) : (
                                        <div className="prose prose-sm dark:prose-invert max-w-none leading-relaxed break-words text-inherit">
                                            <ReactMarkdown
                                                components={{
                                                    ul: ({ node, ...props }) => <ul className="list-disc ml-4 space-y-1 my-2" {...props} />,
                                                    ol: ({ node, ...props }) => <ol className="list-decimal ml-4 space-y-1 my-2" {...props} />,
                                                    li: ({ node, ...props }) => <li className="pl-1" {...props} />,
                                                    p: ({ node, ...props }) => <p className="mb-2 last:mb-0" {...props} />,
                                                    strong: ({ node, ...props }) => <strong className="font-bold" {...props} />,
                                                    a: ({ node, ...props }) => <a className="underline hover:text-blue-200" target="_blank" rel="noopener noreferrer" {...props} />
                                                }}
                                            >
                                                {msg.content}
                                            </ReactMarkdown>
                                        </div>
                                    )}
                                </div>
                            </div>
                        ))}
                        {isLoading && (
                            <div className="flex justify-start">
                                <div className="bg-white dark:bg-zinc-800 border border-gray-100 dark:border-zinc-700 p-3 rounded-2xl rounded-bl-none shadow-sm">
                                    <Loader2 size={16} className="animate-spin text-blue-500" />
                                </div>
                            </div>
                        )}
                        <div ref={messagesEndRef} />
                    </div>

                    {/* Input */}
                    <div className="p-3 bg-white dark:bg-zinc-900 border-t border-gray-100 dark:border-zinc-800">
                        <div className="flex items-center space-x-2 bg-slate-100 dark:bg-zinc-800 rounded-full px-4 py-2">
                            <input
                                type="text"
                                value={input}
                                onChange={(e) => setInput(e.target.value)}
                                onKeyPress={handleKeyPress}
                                placeholder="Type a message..."
                                className="flex-1 bg-transparent text-sm focus:outline-none text-slate-900 dark:text-white"
                            />
                            <button
                                onClick={handleSend}
                                disabled={!input.trim()}
                                className={`p-1.5 rounded-full transition-colors ${input.trim() ? 'bg-blue-600 text-white hover:bg-blue-700' : 'bg-slate-300 dark:bg-zinc-600 text-slate-500 dark:text-zinc-400'}`}
                            >
                                <Send size={14} />
                            </button>
                        </div>
                        <div className="text-center mt-2">
                            <p className="text-[10px] text-slate-400 dark:text-zinc-500">Powered by Groq LPU™ & Qwen</p>
                        </div>
                    </div>
                </>
            )}
        </div>,
        document.body
    );
};

export default Chatbot;
