const { onRequest } = require("firebase-functions/v2/https");
const admin = require("firebase-admin");
const OpenAI = require("openai");
const Stripe = require("stripe");

const serviceAccount = require("./auditly-c0027-firebase-adminsdk-fbsvc-1db7c58141.json");

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount)
});
const db = admin.firestore();

// Initialize OpenAI if API key is available
const openai = process.env.OPENAI_API_KEY ? new OpenAI({
    apiKey: process.env.OPENAI_API_KEY,
}) : null;

// Initialize Stripe if API key is available
const stripe = process.env.STRIPE_SECRET_KEY ? new Stripe(process.env.STRIPE_SECRET_KEY, {
    apiVersion: '2024-11-20.acacia',
}) : null;

const RESPONSE_FORMAT = {
    type: "json_schema",
    json_schema: {
        name: "company_artifacts",
        strict: true,
        schema: {
            type: "object",
            additionalProperties: false,
            properties: {
                report: {
                    type: "object",
                    additionalProperties: false,
                    properties: {
                        companyPerformance: {
                            type: "object",
                            additionalProperties: false,
                            properties: {
                                summary: { type: "string" },
                                metrics: {
                                    type: "array",
                                    items: {
                                        type: "object",
                                        additionalProperties: false,
                                        properties: {
                                            name: { type: "string" },
                                            value: { anyOf: [{ type: "string" }, { type: "number" }] },
                                            trend: { enum: ["up", "down", "flat"] }
                                        },
                                        required: ["name", "value", "trend"]
                                    }
                                }
                            },
                            required: ["summary", "metrics"]
                        },
                        keyPersonnelChanges: {
                            type: "array",
                            items: {
                                type: "object",
                                additionalProperties: false,
                                properties: {
                                    person: { type: "string" },
                                    change: { type: "string" }, // e.g. "Promoted to VP Eng"
                                    impact: { type: "string" },
                                    effectiveDate: { type: "string" }
                                },
                                required: ["person", "change", "impact", "effectiveDate"]
                            }
                        },
                        immediateHiringNeeds: {
                            type: "array",
                            items: {
                                type: "object",
                                additionalProperties: false,
                                properties: {
                                    role: { type: "string" },
                                    urgency: { enum: ["low", "medium", "high"] },
                                    reason: { type: "string" }
                                },
                                required: ["role", "urgency", "reason"]
                            }
                        },
                        forwardOperatingPlan: {
                            type: "object",
                            additionalProperties: false,
                            properties: {
                                nextQuarterObjectives: { type: "array", items: { type: "string" } },
                                initiatives: {
                                    type: "array",
                                    items: {
                                        type: "object",
                                        additionalProperties: false,
                                        properties: {
                                            name: { type: "string" },
                                            owner: { type: "string" },
                                            kpis: { type: "array", items: { type: "string" } }
                                        },
                                        required: ["name", "owner", "kpis"]
                                    }
                                },
                                risks: {
                                    type: "array",
                                    items: {
                                        type: "object",
                                        additionalProperties: false,
                                        properties: {
                                            risk: { type: "string" },
                                            mitigation: { type: "string" }
                                        },
                                        required: ["risk", "mitigation"]
                                    }
                                }
                            },
                            required: ["nextQuarterObjectives", "initiatives", "risks"]
                        },
                        organizationalInsights: {
                            type: "object",
                            additionalProperties: false,
                            properties: {
                                culture: { type: "string" },
                                teamDynamics: { type: "string" },
                                blockers: { type: "array", items: { type: "string" } }
                            },
                            required: ["culture", "teamDynamics", "blockers"]
                        },
                        strengths: { type: "array", items: { type: "string" } },
                        gradingOverview: {
                            type: "array",
                            items: {
                                type: "object",
                                additionalProperties: false,
                                properties: {
                                    department: { type: "string" },
                                    grade: { enum: ["A", "B", "C", "D", "F"] },
                                    notes: { type: "string" }
                                },
                                required: ["department", "grade", "notes"]
                            }
                        }
                    },
                    required: ["companyPerformance", "keyPersonnelChanges", "immediateHiringNeeds", "forwardOperatingPlan", "organizationalInsights", "strengths", "gradingOverview"]
                },
                wiki: {
                    type: "object",
                    additionalProperties: false,
                    properties: {
                        companyName: { type: "string" },
                        industry: { type: "string" },
                        description: { type: "string" },
                        mission: { type: "string" },
                        values: { type: "array", items: { type: "string" } },
                        culture: { type: "string" },
                        orgInfo: {
                            type: "object",
                            additionalProperties: false,
                            properties: {
                                hq: { type: "string" },
                                foundedYear: { type: "number" },
                                headcount: { type: "number" },
                                products: { type: "array", items: { type: "string" } }
                            },
                            required: ["hq", "foundedYear", "headcount", "products"]
                        }
                    },
                    required: ["companyName", "industry", "description", "mission", "values", "culture", "orgInfo"]
                }
            },
            required: ["report", "wiki"]
        }
    }
};


// Helper function to generate OTP
const generateOTP = () => {
    return Math.floor(100000 + Math.random() * 900000).toString();
};


// Send OTP Function
exports.sendOTP = onRequest({ cors: true }, async (req, res) => {
    if (req.method !== "POST") {
        return res.status(405).json({ error: "Method not allowed" });
    }

    const { email, inviteCode } = req.body;

    if (!email) {
        return res.status(400).json({ error: "Email is required" });
    }

    try {
        // Generate OTP
        const otp = generateOTP();
        const expiresAt = Date.now() + (5 * 60 * 1000); // 5 minutes expiry

        // Store OTP in Firestore
        await db.collection("otps").doc(email).set({
            otp,
            expiresAt,
            attempts: 0,
            inviteCode: inviteCode || null,
            createdAt: Date.now(),
        });

        // In production, send actual email
        console.log(`📧 OTP for ${email}: ${otp} (expires in 5 minutes)`);

        res.json({
            success: true,
            message: "Verification code sent to your email",
            // Always include OTP in emulator mode for testing
            otp,
        });
    } catch (error) {
        console.error("Send OTP error:", error);
        res.status(500).json({ error: "Failed to send verification code" });
    }
});

// Verify OTP Function
exports.verifyOTP = onRequest({ cors: true }, async (req, res) => {
    if (req.method !== "POST") {
        return res.status(405).json({ error: "Method not allowed" });
    }

    const { email, otp } = req.body;

    if (!email || !otp) {
        return res.status(400).json({ error: "Email and OTP are required" });
    }

    try {
        // Retrieve OTP document
        const otpDoc = await db.collection("otps").doc(email).get();

        if (!otpDoc.exists) {
            return res.status(400).json({ error: "Invalid verification code" });
        }

        const otpData = otpDoc.data();

        // Check if OTP is expired
        if (Date.now() > otpData.expiresAt) {
            await otpDoc.ref.delete();
            return res.status(400).json({ error: "Verification code has expired" });
        }

        // Check if too many attempts
        if (otpData.attempts >= 5) {
            await otpDoc.ref.delete();
            return res.status(400).json({ error: "Too many failed attempts" });
        }

        // Verify OTP
        if (otpData.otp !== otp) {
            await otpDoc.ref.update({
                attempts: (otpData.attempts || 0) + 1,
            });
            return res.status(400).json({ error: "Invalid verification code" });
        }

        // OTP is valid - clean up and create/find user
        await otpDoc.ref.delete();

        // Generate a unique user ID for this email if it doesn't exist
        let userId;
        let userDoc;

        // Check if user already exists by email
        const existingUserQuery = await db.collection("users")
            .where("email", "==", email)
            .limit(1)
            .get();

        if (!existingUserQuery.empty) {
            // User exists, get their ID
            userDoc = existingUserQuery.docs[0];
            userId = userDoc.id;
        } else {
            // Create new user
            userId = `user_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
            userDoc = null;
        }

        // Prepare user object for response
        const user = {
            uid: userId,
            email: email,
            displayName: email.split("@")[0],
            emailVerified: true,
        };

        // Create or update user document in Firestore
        const userRef = db.collection("users").doc(userId);

        const userData = {
            id: userId,
            email: email,
            displayName: email.split("@")[0],
            emailVerified: true,
            lastLoginAt: Date.now(),
        };

        if (!userDoc) {
            // Create new user document
            userData.createdAt = Date.now();
            await userRef.set(userData);
        } else {
            // Update existing user with latest login info
            await userRef.update({
                lastLoginAt: Date.now(),
            });
        }

        // Generate a simple session token (in production, use proper JWT)
        const customToken = `session_${userId}_${Date.now()}`;

        // Handle invitation if present
        let inviteData = null;
        if (otpData.inviteCode) {
            try {
                const inviteDoc = await db
                    .collectionGroup("invites")
                    .where("code", "==", otpData.inviteCode)
                    .where("status", "==", "pending")
                    .limit(1)
                    .get();

                if (!inviteDoc.empty) {
                    inviteData = inviteDoc.docs[0].data();
                }
            } catch (error) {
                console.error("Error fetching invite:", error);
            }
        }

        res.json({
            success: true,
            user,
            token: customToken,
            invite: inviteData,
        });
    } catch (error) {
        console.error("Verify OTP error:", error);
        res.status(500).json({ error: "Failed to verify code" });
    }
});

// Create Invitation Function
exports.createInvitation = onRequest({ cors: true }, async (req, res) => {

    if (req.method === 'OPTIONS') {
        res.status(204).send('');
        return;
    }

    if (req.method !== "POST") {
        return res.status(405).json({ error: "Method not allowed" });
    }

    const { orgId, name, email, role = "employee", department } = req.body;

    if (!orgId || !email || !name) {
        return res.status(400).json({ error: "Organization ID, name, and email are required" });
    }

    try {
        // Generate invite code
        const code = Math.random().toString(36).substring(2, 15);

        // Generate employee ID
        const employeeId = `emp_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;

        // Create employee object for the invite
        const employee = {
            id: employeeId,
            name: name.trim(),
            email: email.trim(),
            role: role?.trim() || "employee",
            department: department?.trim() || "General",
            status: "invited",
            inviteCode: code
        };

        // Store invitation with employee data
        const inviteRef = await db
            .collection("orgs")
            .doc(orgId)
            .collection("invites")
            .doc(code);

        await inviteRef.set({
            code,
            employee,
            email,
            orgId,
            status: "pending",
            createdAt: Date.now(),
            expiresAt: Date.now() + (7 * 24 * 60 * 60 * 1000), // 7 days
        });

        // Generate invite links
        const baseUrl = process.env.CLIENT_URL || 'http://localhost:5173';
        const inviteLink = `${baseUrl}/#/employee-form/${code}`;
        const emailLink = `mailto:${email}?subject=You're invited to join our organization&body=Hi ${name},%0A%0AYou've been invited to complete a questionnaire for our organization. Please click the link below to get started:%0A%0A${inviteLink}%0A%0AThis link will expire in 7 days.%0A%0AThank you!`;

        // In production, send actual invitation email
        console.log(`📧 Invitation sent to ${email} (${name}) with code: ${code}`);
        console.log(`📧 Invite link: ${inviteLink}`);

        res.json({
            success: true,
            code,
            employee,
            inviteLink,
            emailLink,
            message: "Invitation sent successfully",
        });
    } catch (error) {
        console.error("Create invitation error:", error);
        res.status(500).json({ error: "Failed to create invitation" });
    }
});

// Get Invitation Status Function
exports.getInvitationStatus = onRequest({ cors: true }, async (req, res) => {
    if (req.method === 'OPTIONS') {
        res.status(204).send('');
        return;
    }

    if (req.method !== "GET") {
        return res.status(405).json({ error: "Method not allowed" });
    }

    const { code } = req.query;

    if (!code) {
        return res.status(400).json({ error: "Invitation code is required" });
    }

    try {
        const inviteDoc = await db
            .collectionGroup("invites")
            .where("code", "==", code)
            .limit(1)
            .get();

        if (inviteDoc.empty) {
            return res.status(404).json({ error: "Invitation not found" });
        }

        const invite = inviteDoc.docs[0].data();

        // Check if expired
        if (Date.now() > invite.expiresAt) {
            return res.status(400).json({ error: "Invitation has expired" });
        }

        res.json({
            success: true,
            used: invite.status !== 'pending',
            employee: invite.employee,
            invite,
        });
    } catch (error) {
        console.error("Get invitation status error:", error);
        res.status(500).json({ error: "Failed to get invitation status" });
    }
});

// Consume Invitation Function
exports.consumeInvitation = onRequest({ cors: true }, async (req, res) => {
    if (req.method === 'OPTIONS') {
        res.status(204).send('');
        return;
    }

    if (req.method !== "POST") {
        return res.status(405).json({ error: "Method not allowed" });
    }

    const { code, userId } = req.body;

    if (!code) {
        return res.status(400).json({ error: "Invitation code is required" });
    }

    try {
        const inviteSnapshot = await db
            .collectionGroup("invites")
            .where("code", "==", code)
            .where("status", "==", "pending")
            .limit(1)
            .get();

        if (inviteSnapshot.empty) {
            return res.status(404).json({ error: "Invitation not found or already used" });
        }

        const inviteDoc = inviteSnapshot.docs[0];
        const invite = inviteDoc.data();

        // Check if expired
        if (Date.now() > invite.expiresAt) {
            return res.status(400).json({ error: "Invitation has expired" });
        }

        // Get employee data from the invite
        const employee = invite.employee;
        if (!employee) {
            return res.status(400).json({ error: "Invalid invitation data - missing employee information" });
        }

        // Mark invitation as consumed
        await inviteDoc.ref.update({
            status: "consumed",
            consumedBy: employee.id,
            consumedAt: Date.now(),
        });

        // Add employee to organization using data from invite
        await db
            .collection("orgs")
            .doc(invite.orgId)
            .collection("employees")
            .doc(employee.id)
            .set({
                id: employee.id,
                name: employee.name || employee.email.split("@")[0],
                email: employee.email,
                role: employee.role || "employee",
                department: employee.department || "General",
                joinedAt: Date.now(),
                status: "active",
                inviteCode: code,
            });

        res.json({
            success: true,
            orgId: invite.orgId,
            message: "Invitation consumed successfully",
        });
    } catch (error) {
        console.error("Consume invitation error:", error);
        res.status(500).json({ error: "Failed to consume invitation" });
    }
});

// Submit Employee Answers Function
exports.submitEmployeeAnswers = onRequest({ cors: true }, async (req, res) => {

    if (req.method === 'OPTIONS') {
        res.status(204).send('');
        return;
    }

    if (req.method !== "POST") {
        return res.status(405).json({ error: "Method not allowed" });
    }

    const { orgId, employeeId, answers, inviteCode } = req.body;

    // For invite-based submissions, we need inviteCode and answers
    // For regular submissions, we need orgId, employeeId, and answers
    if (inviteCode) {
        if (!inviteCode || !answers) {
            return res.status(400).json({ error: "Invite code and answers are required for invite submissions" });
        }
    } else {
        if (!orgId || !employeeId || !answers) {
            return res.status(400).json({ error: "Organization ID, employee ID, and answers are required" });
        }
    }

    try {
        let finalOrgId, finalEmployeeId;

        if (inviteCode) {
            // For invite-based submissions, look up the invite to get employee and org data
            const inviteSnapshot = await db
                .collectionGroup("invites")
                .where("code", "==", inviteCode)
                .where("status", "==", "consumed")
                .limit(1)
                .get();

            if (inviteSnapshot.empty) {
                return res.status(404).json({ error: "Invitation not found or not consumed yet" });
            }

            const invite = inviteSnapshot.docs[0].data();
            finalOrgId = invite.orgId;
            finalEmployeeId = invite.employee.id;
        } else {
            // Regular submission
            finalOrgId = orgId;
            finalEmployeeId = employeeId;
        }

        // Store submission
        const submissionRef = await db
            .collection("orgs")
            .doc(finalOrgId)
            .collection("submissions")
            .doc(finalEmployeeId);

        await submissionRef.set({
            employeeId: finalEmployeeId,
            answers,
            submittedAt: Date.now(),
            status: "completed",
            submissionType: inviteCode ? "invite" : "regular",
            ...(inviteCode && { inviteCode })
        });

        res.json({
            success: true,
            message: "Employee answers submitted successfully",
        });
    } catch (error) {
        console.error("Submit employee answers error:", error);
        res.status(500).json({ error: "Failed to submit answers" });
    }
});

// Generate Employee Report Function
exports.generateEmployeeReport = onRequest({ cors: true }, async (req, res) => {

    if (req.method === 'OPTIONS') {
        res.status(204).send('');
        return;
    }

    if (req.method !== "POST") {
        return res.status(405).json({ error: "Method not allowed" });
    }

    const { employee, submission, companyWiki } = req.body;

    if (!employee || !submission) {
        return res.status(400).json({ error: "Employee and submission data are required" });
    }

    try {
        let report;

        if (openai) {
            // Use OpenAI to generate the report
            const prompt = `
You are an expert HR analyst. Generate a comprehensive employee performance report based on the following data:

Employee Information:
- Name: ${employee.name || employee.email}
- Role: ${employee.role || "Team Member"}
- Department: ${employee.department || "General"}

Employee Submission Data:
${JSON.stringify(submission, null, 2)}

Company Context:
${companyWiki ? JSON.stringify(companyWiki, null, 2) : "No company context provided"}

Generate a detailed report with the following structure:
- roleAndOutput: Current role assessment and performance rating
- behavioralInsights: Work style, communication, and team dynamics
- strengths: List of employee strengths
- weaknesses: Areas for improvement (mark critical issues)
- opportunities: Growth and development opportunities
- risks: Potential risks or concerns
- recommendations: Specific action items
- grading: Numerical scores for different performance areas

Return ONLY valid JSON that matches this structure. Be thorough but professional.
            `.trim();

            const completion = await openai.chat.completions.create({
                model: "gpt-4o",
                messages: [
                    {
                        role: "system",
                        content: "You are an expert HR analyst. Generate comprehensive employee performance reports in JSON format."
                    },
                    {
                        role: "user",
                        content: prompt
                    }
                ],
                response_format: { type: "json_object" },
                temperature: 0.7,
            });

            const aiResponse = completion.choices[0].message.content;
            const parsedReport = JSON.parse(aiResponse);

            report = {
                employeeId: employee.id,
                generatedAt: Date.now(),
                summary: `AI-generated performance analysis for ${employee.name || employee.email}`,
                ...parsedReport
            };
        } else {
            // Fallback to mock report when OpenAI is not available
            report = {
                employeeId: employee.id,
                generatedAt: Date.now(),
                summary: `Performance analysis for ${employee.name || employee.email}`,
                roleAndOutput: {
                    currentRole: employee.role || "Team Member",
                    keyResponsibilities: ["Task completion", "Team collaboration", "Quality delivery"],
                    performanceRating: 85,
                },
                behavioralInsights: {
                    workStyle: "Collaborative and detail-oriented",
                    communicationSkills: "Strong verbal and written communication",
                    teamDynamics: "Positive team player",
                },
                strengths: [
                    "Excellent problem-solving abilities",
                    "Strong attention to detail",
                    "Reliable and consistent performance",
                ],
                weaknesses: [
                    "Could improve time management",
                    "Needs to be more proactive in meetings",
                ],
                opportunities: [
                    "Leadership development opportunities",
                    "Cross-functional project involvement",
                    "Skill enhancement in emerging technologies",
                ],
                risks: [
                    "Potential burnout from heavy workload",
                    "Limited growth opportunities in current role",
                ],
                recommendations: [
                    "Provide leadership training",
                    "Assign mentorship role",
                    "Consider promotion to senior position",
                ],
                grading: {
                    overall: 85,
                    technical: 88,
                    communication: 82,
                    teamwork: 90,
                    leadership: 75,
                },
            };
        }

        res.json({
            success: true,
            report,
        });
    } catch (error) {
        console.error("Generate employee report error:", error);
        res.status(500).json({ error: "Failed to generate employee report" });
    }
});

// Generate Company Wiki Function
exports.generateCompanyWiki = onRequest({ cors: true }, async (req, res) => {
    if (req.method === 'OPTIONS') {
        res.status(204).send('');
        return;
    }

    if (req.method !== "POST") {
        return res.status(405).json({ error: "Method not allowed" });
    }

    const { org, submissions = [] } = req.body;

    if (!org) {
        return res.status(400).json({ error: "Organization data is required" });
    }

    try {
        let report, wiki;

        if (openai) {
            // Use OpenAI to generate the company report and wiki
            const system = "You are a cut-and-dry expert business analyst. Return ONLY JSON that conforms to the provided schema.";
            const user = [
                "Generate a COMPANY REPORT and COMPANY WIKI that fully leverage the input data.",
                "Be thorough and professional.",
                "",
                "Organization Information:",
                JSON.stringify(org, null, 2),
                "",
                "Employee Submissions:",
                JSON.stringify(submissions, null, 2)
            ].join("\n");

            const completion = await openai.chat.completions.create({
                model: "gpt-4o",
                temperature: 0, // consistency
                response_format: RESPONSE_FORMAT,
                messages: [
                    { role: "system", content: system },
                    { role: "user", content: user }
                ]
            });

            // content is guaranteed to be schema-conformant JSON
            console.log(completion.choices[0].message);
            console.log(completion.choices[0].message.content);
            const parsed = JSON.parse(completion.choices[0].message.content);

            const report = {
                generatedAt: Date.now(),
                ...parsed.report
            };

            const wiki = {
                companyName: org?.name ?? parsed.wiki.companyName,
                generatedAt: Date.now(),
                ...parsed.wiki,
            };
            console.log(report);
            console.log(wiki);

        } else {
            // Fallback to mock data when OpenAI is not available
            report = {
                generatedAt: Date.now(),
                companyPerformance: {
                    overallScore: 82,
                    trend: "improving",
                    keyMetrics: {
                        productivity: 85,
                        satisfaction: 79,
                        retention: 88,
                    },
                },
                keyPersonnelChanges: [
                    {
                        type: "promotion",
                        employee: "John Doe",
                        details: "Promoted to Senior Developer",
                        impact: "positive",
                    },
                ],
                immediateHiringNeeds: [
                    {
                        role: "Frontend Developer",
                        priority: "high",
                        timeline: "2-4 weeks",
                        skills: ["React", "TypeScript", "CSS"],
                    },
                ],
                forwardOperatingPlan: {
                    nextQuarter: "Focus on product development and team expansion",
                    challenges: ["Scaling infrastructure", "Talent acquisition"],
                    opportunities: ["New market segments", "Technology partnerships"],
                },
                organizationalInsights: {
                    teamDynamics: "Strong collaboration across departments",
                    culturalHealth: "Positive and inclusive work environment",
                    communicationEffectiveness: "Good but could improve cross-team coordination",
                },
                strengths: [
                    "Strong technical expertise",
                    "Collaborative team culture",
                    "Innovative problem-solving approach",
                ],
                gradingOverview: {
                    averagePerformance: 82,
                    topPerformers: 3,
                    needsImprovement: 1,
                    departmentBreakdown: {
                        engineering: 85,
                        design: 80,
                        product: 78,
                    },
                },
            };

            wiki = {
                companyName: org.name,
                industry: org.industry,
                description: org.description,
                mission: org.mission || "To deliver excellent products and services",
                values: org.values || ["Innovation", "Teamwork", "Excellence"],
                culture: "Collaborative and growth-oriented",
                generatedAt: Date.now(),
            };
        }

        res.json({
            success: true,
            ...report,
            ...wiki,
        });
    } catch (error) {
        console.error("Generate company wiki error:", error);
        res.status(500).json({ error: "Failed to generate company wiki" });
    }
});

// Chat Function
exports.chat = onRequest({ cors: true }, async (req, res) => {

    if (req.method === 'OPTIONS') {
        res.status(204).send('');
        return;
    }

    if (req.method !== "POST") {
        return res.status(405).json({ error: "Method not allowed" });
    }

    const { message, employeeId, context, mentions, attachments } = req.body;

    if (!message) {
        return res.status(400).json({ error: "Message is required" });
    }

    try {
        let response;

        if (openai) {
            // Use OpenAI for chat responses
            const systemPrompt = `
You are an expert HR consultant and business analyst with access to employee performance data and company analytics.
You provide thoughtful, professional advice based on the employee context and company data provided.

${context ? `
Current Context:
${JSON.stringify(context, null, 2)}
` : ''}

${mentions && mentions.length > 0 ? `
Mentioned Employees:
${mentions.map(emp => `- ${emp.name} (${emp.role || 'Employee'})`).join('\n')}
` : ''}

Provide helpful, actionable insights while maintaining professional confidentiality and focusing on constructive feedback.
            `.trim();

            // Build the user message content
            let userContent = [
                {
                    type: "text",
                    text: message
                }
            ];

            // Add image attachments if present
            if (attachments && attachments.length > 0) {
                attachments.forEach(attachment => {
                    if (attachment.type.startsWith('image/') && attachment.data) {
                        userContent.push({
                            type: "image_url",
                            image_url: {
                                url: attachment.data,
                                detail: "high"
                            }
                        });
                    }
                    // For non-image files, add them as text context
                    else if (attachment.data) {
                        userContent.push({
                            type: "text",
                            text: `[Attached file: ${attachment.name} (${attachment.type})]`
                        });
                    }
                });
            }

            const completion = await openai.chat.completions.create({
                model: "gpt-4o",
                messages: [
                    {
                        role: "system",
                        content: systemPrompt
                    },
                    {
                        role: "user",
                        content: userContent
                    }
                ],
                temperature: 0.7,
                max_tokens: 1000, // Increased for more detailed responses when analyzing images
            });

            response = completion.choices[0].message.content;
        } else {
            // Fallback responses when OpenAI is not available
            const attachmentText = attachments && attachments.length > 0
                ? ` I can see you've attached ${attachments.length} file(s), but I'm currently unable to process attachments.`
                : '';

            const responses = [
                `That's an interesting point about performance metrics.${attachmentText} Based on the data, I'd recommend focusing on...`,
                `I can see from the employee report that there are opportunities for growth in...${attachmentText}`,
                `The company analysis suggests that this area needs attention.${attachmentText} Here's what I would suggest...`,
                `Based on the performance data, this employee shows strong potential in...${attachmentText}`,
            ];

            response = responses[Math.floor(Math.random() * responses.length)];
        }

        res.json({
            success: true,
            response,
            timestamp: Date.now(),
        });
    } catch (error) {
        console.error("Chat error:", error);
        res.status(500).json({ error: "Failed to process chat message" });
    }
});

// Create Organization Function
exports.createOrganization = onRequest({ cors: true }, async (req, res) => {
    if (req.method === 'OPTIONS') {
        res.status(204).send('');
        return;
    }

    if (req.method !== "POST") {
        return res.status(405).json({ error: "Method not allowed" });
    }

    const { name, userId } = req.body;

    if (!name || !userId) {
        return res.status(400).json({ error: "Organization name and user ID are required" });
    }

    try {
        // Generate unique organization ID
        const orgId = `org_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;

        // Create comprehensive organization document
        const orgData = {
            name,
            createdAt: Date.now(),
            updatedAt: Date.now(),
            onboardingCompleted: false,
            ownerId: userId,
            // Subscription fields (will be populated after Stripe setup)
            subscription: {
                status: 'trial', // trial, active, past_due, canceled
                stripeCustomerId: null,
                stripeSubscriptionId: null,
                currentPeriodStart: null,
                currentPeriodEnd: null,
                trialEnd: Date.now() + (14 * 24 * 60 * 60 * 1000), // 14 day trial
            },
            // Usage tracking
            usage: {
                employeeCount: 0,
                reportsGenerated: 0,
                lastReportGeneration: null,
            },
            // Organization settings
            settings: {
                allowedEmployeeCount: 50, // Default limit
                featuresEnabled: {
                    aiReports: true,
                    chat: true,
                    analytics: true,
                }
            }
        };

        const orgRef = db.collection("orgs").doc(orgId);
        await orgRef.set(orgData);

        // Get user information from Firestore (since we don't use Firebase Auth)
        const userRef = db.collection("users").doc(userId);
        const userDoc = await userRef.get();

        if (!userDoc.exists) {
            console.error("User document not found:", userId);
            return res.status(400).json({ error: "User not found" });
        }

        const userData = userDoc.data();

        // Add user as owner to organization's employees collection
        const employeeRef = orgRef.collection("employees").doc(userId);
        await employeeRef.set({
            id: userId,
            role: "owner",
            isOwner: true,
            joinedAt: Date.now(),
            status: "active",
            name: userData.displayName || userData.email.split("@")[0],
            email: userData.email,
            department: "Management",
        });

        // Add organization to user's organizations (for multi-org support)
        const userOrgRef = db.collection("users").doc(userId).collection("organizations").doc(orgId);
        await userOrgRef.set({
            orgId,
            name,
            role: "owner",
            onboardingCompleted: false,
            joinedAt: Date.now(),
        });

        // Update user document with latest activity
        await userRef.update({
            lastLoginAt: Date.now(),
        });

        res.json({
            success: true,
            orgId,
            name,
            role: "owner",
            onboardingCompleted: false,
            joinedAt: Date.now(),
            subscription: orgData.subscription,
            requiresSubscription: true, // Signal frontend to show subscription flow
        });
    } catch (error) {
        console.error("Create organization error:", error);
        res.status(500).json({ error: "Failed to create organization" });
    }
});

// Get User Organizations Function
exports.getUserOrganizations = onRequest({ cors: true }, async (req, res) => {

    if (req.method === 'OPTIONS') {
        res.status(204).send('');
        return;
    }

    if (req.method !== "GET") {
        return res.status(405).json({ error: "Method not allowed" });
    }

    const userId = req.query.userId || req.params.userId;

    if (!userId) {
        return res.status(400).json({ error: "User ID is required" });
    }

    try {
        // Get user's organizations
        const userOrgsSnapshot = await db
            .collection("users")
            .doc(userId)
            .collection("organizations")
            .get();

        const organizations = [];
        userOrgsSnapshot.forEach(doc => {
            organizations.push({
                orgId: doc.id,
                ...doc.data(),
            });
        });

        res.json({
            success: true,
            organizations,
        });
    } catch (error) {
        console.error("Get user organizations error:", error);
        res.status(500).json({ error: "Failed to get user organizations" });
    }
});

// Join Organization Function (via invite)
exports.joinOrganization = onRequest({ cors: true }, async (req, res) => {
    if (req.method === 'OPTIONS') {
        res.status(204).send('');
        return;
    }

    if (req.method !== "POST") {
        return res.status(405).json({ error: "Method not allowed" });
    }

    const { userId, inviteCode } = req.body;

    if (!userId || !inviteCode) {
        return res.status(400).json({ error: "User ID and invite code are required" });
    }

    try {
        // Find the invitation
        const inviteSnapshot = await db
            .collectionGroup("invites")
            .where("code", "==", inviteCode)
            .where("status", "==", "pending")
            .limit(1)
            .get();

        if (inviteSnapshot.empty) {
            return res.status(404).json({ error: "Invitation not found or already used" });
        }

        const inviteDoc = inviteSnapshot.docs[0];
        const invite = inviteDoc.data();

        // Check if expired
        if (Date.now() > invite.expiresAt) {
            return res.status(400).json({ error: "Invitation has expired" });
        }

        const orgId = invite.orgId;

        // Get organization details
        const orgDoc = await db.collection("orgs").doc(orgId).get();
        if (!orgDoc.exists()) {
            return res.status(404).json({ error: "Organization not found" });
        }

        const orgData = orgDoc.data();

        // Get user information from Firestore (since we don't use Firebase Auth)
        const userRef = db.collection("users").doc(userId);
        const userDoc = await userRef.get();

        if (!userDoc.exists) {
            console.error("User document not found:", userId);
            return res.status(400).json({ error: "User not found" });
        }

        const userData = userDoc.data();

        // Mark invitation as consumed
        await inviteDoc.ref.update({
            status: "consumed",
            consumedBy: userId,
            consumedAt: Date.now(),
        });

        // Add user to organization employees with full information
        await db
            .collection("orgs")
            .doc(orgId)
            .collection("employees")
            .doc(userId)
            .set({
                id: userId,
                email: userData.email,
                name: userData.displayName || userData.email.split("@")[0],
                role: invite.role || "employee",
                joinedAt: Date.now(),
                status: "active",
            });

        // Add organization to user's organizations
        await db
            .collection("users")
            .doc(userId)
            .collection("organizations")
            .doc(orgId)
            .set({
                orgId,
                name: orgData.name,
                role: invite.role || "employee",
                onboardingCompleted: orgData.onboardingCompleted || false,
                joinedAt: Date.now(),
            });

        // Update user document with latest login activity
        await userRef.update({
            lastLoginAt: Date.now(),
        });

        res.json({
            success: true,
            orgId,
            name: orgData.name,
            role: invite.role || "employee",
            onboardingCompleted: orgData.onboardingCompleted || false,
            joinedAt: Date.now(),
        });
    } catch (error) {
        console.error("Join organization error:", error);
        res.status(500).json({ error: "Failed to join organization" });
    }
});

// Create Stripe Checkout Session Function
exports.createCheckoutSession = onRequest({ cors: true }, async (req, res) => {
    if (req.method === 'OPTIONS') {
        res.status(204).send('');
        return;
    }

    if (req.method !== "POST") {
        return res.status(405).json({ error: "Method not allowed" });
    }

    const { orgId, userId, userEmail, priceId } = req.body;

    if (!orgId || !userId || !userEmail) {
        return res.status(400).json({ error: "Organization ID, user ID, and email are required" });
    }

    if (!stripe) {
        return res.status(500).json({ error: "Stripe not configured" });
    }

    try {
        // Get or create Stripe customer
        let customer;
        const existingCustomers = await stripe.customers.list({
            email: userEmail,
            limit: 1,
        });

        if (existingCustomers.data.length > 0) {
            customer = existingCustomers.data[0];
        } else {
            customer = await stripe.customers.create({
                email: userEmail,
                metadata: {
                    userId,
                    orgId,
                },
            });
        }

        // Default to standard plan if no priceId provided
        const defaultPriceId = priceId || process.env.STRIPE_PRICE_ID || 'price_standard_monthly';

        // Create checkout session
        const session = await stripe.checkout.sessions.create({
            customer: customer.id,
            payment_method_types: ['card'],
            line_items: [
                {
                    price: defaultPriceId,
                    quantity: 1,
                },
            ],
            mode: 'subscription',
            success_url: `${process.env.CLIENT_URL || 'http://localhost:5174'}/#/dashboard?session_id={CHECKOUT_SESSION_ID}`,
            cancel_url: `${process.env.CLIENT_URL || 'http://localhost:5174'}/#/dashboard?canceled=true`,
            metadata: {
                orgId,
                userId,
            },
            subscription_data: {
                metadata: {
                    orgId,
                    userId,
                },
                trial_period_days: 14, // 14-day trial
            },
        });

        // Update organization with customer ID
        const orgRef = db.collection("orgs").doc(orgId);
        await orgRef.update({
            'subscription.stripeCustomerId': customer.id,
            'subscription.checkoutSessionId': session.id,
            updatedAt: Date.now(),
        });

        res.json({
            success: true,
            sessionId: session.id,
            sessionUrl: session.url,
            customerId: customer.id,
        });
    } catch (error) {
        console.error("Create checkout session error:", error);
        res.status(500).json({ error: "Failed to create checkout session" });
    }
});

// Handle Stripe Webhook Function
exports.stripeWebhook = onRequest(async (req, res) => {
    if (!stripe) {
        return res.status(500).send('Stripe not configured');
    }

    const sig = req.headers['stripe-signature'];
    const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET;

    let event;

    try {
        event = stripe.webhooks.constructEvent(req.rawBody, sig, endpointSecret);
    } catch (err) {
        console.error('Webhook signature verification failed:', err.message);
        return res.status(400).send(`Webhook Error: ${err.message}`);
    }

    // Handle the event
    try {
        switch (event.type) {
            case 'checkout.session.completed':
                await handleCheckoutCompleted(event.data.object);
                break;
            case 'customer.subscription.created':
                await handleSubscriptionCreated(event.data.object);
                break;
            case 'customer.subscription.updated':
                await handleSubscriptionUpdated(event.data.object);
                break;
            case 'customer.subscription.deleted':
                await handleSubscriptionDeleted(event.data.object);
                break;
            case 'invoice.payment_succeeded':
                await handlePaymentSucceeded(event.data.object);
                break;
            case 'invoice.payment_failed':
                await handlePaymentFailed(event.data.object);
                break;
            default:
                console.log(`Unhandled event type ${event.type}`);
        }

        res.json({ received: true });
    } catch (error) {
        console.error('Webhook handler error:', error);
        res.status(500).json({ error: 'Webhook handler failed' });
    }
});

// Get Subscription Status Function
exports.getSubscriptionStatus = onRequest({ cors: true }, async (req, res) => {
    if (req.method === 'OPTIONS') {
        res.status(204).send('');
        return;
    }

    if (req.method !== "GET") {
        return res.status(405).json({ error: "Method not allowed" });
    }

    const { orgId } = req.query;

    if (!orgId) {
        return res.status(400).json({ error: "Organization ID is required" });
    }

    try {
        const orgDoc = await db.collection("orgs").doc(orgId).get();

        if (!orgDoc.exists()) {
            return res.status(404).json({ error: "Organization not found" });
        }

        const orgData = orgDoc.data();
        const subscription = orgData.subscription || {};

        // If we have a Stripe subscription ID, get the latest status
        if (stripe && subscription.stripeSubscriptionId) {
            try {
                const stripeSubscription = await stripe.subscriptions.retrieve(subscription.stripeSubscriptionId);

                // Update local subscription data
                await orgDoc.ref.update({
                    'subscription.status': stripeSubscription.status,
                    'subscription.currentPeriodStart': stripeSubscription.current_period_start * 1000,
                    'subscription.currentPeriodEnd': stripeSubscription.current_period_end * 1000,
                    updatedAt: Date.now(),
                });

                subscription.status = stripeSubscription.status;
                subscription.currentPeriodStart = stripeSubscription.current_period_start * 1000;
                subscription.currentPeriodEnd = stripeSubscription.current_period_end * 1000;
            } catch (stripeError) {
                console.error('Failed to fetch Stripe subscription:', stripeError);
            }
        }

        res.json({
            success: true,
            subscription,
            orgId,
        });
    } catch (error) {
        console.error("Get subscription status error:", error);
        res.status(500).json({ error: "Failed to get subscription status" });
    }
});

// Webhook Helper Functions
async function handleCheckoutCompleted(session) {
    const orgId = session.metadata?.orgId;
    if (!orgId) return;

    const orgRef = db.collection("orgs").doc(orgId);
    await orgRef.update({
        'subscription.status': 'trialing',
        'subscription.stripeSubscriptionId': session.subscription,
        'subscription.checkoutSessionId': session.id,
        updatedAt: Date.now(),
    });
}

async function handleSubscriptionCreated(subscription) {
    const orgId = subscription.metadata?.orgId;
    if (!orgId) return;

    const orgRef = db.collection("orgs").doc(orgId);
    await orgRef.update({
        'subscription.status': subscription.status,
        'subscription.stripeSubscriptionId': subscription.id,
        'subscription.currentPeriodStart': subscription.current_period_start * 1000,
        'subscription.currentPeriodEnd': subscription.current_period_end * 1000,
        'subscription.trialEnd': subscription.trial_end ? subscription.trial_end * 1000 : null,
        updatedAt: Date.now(),
    });
}

async function handleSubscriptionUpdated(subscription) {
    const orgId = subscription.metadata?.orgId;
    if (!orgId) return;

    const orgRef = db.collection("orgs").doc(orgId);
    await orgRef.update({
        'subscription.status': subscription.status,
        'subscription.currentPeriodStart': subscription.current_period_start * 1000,
        'subscription.currentPeriodEnd': subscription.current_period_end * 1000,
        'subscription.trialEnd': subscription.trial_end ? subscription.trial_end * 1000 : null,
        updatedAt: Date.now(),
    });
}

async function handleSubscriptionDeleted(subscription) {
    const orgId = subscription.metadata?.orgId;
    if (!orgId) return;

    const orgRef = db.collection("orgs").doc(orgId);
    await orgRef.update({
        'subscription.status': 'canceled',
        'subscription.currentPeriodEnd': subscription.current_period_end * 1000,
        updatedAt: Date.now(),
    });
}

async function handlePaymentSucceeded(invoice) {
    const subscriptionId = invoice.subscription;
    if (!subscriptionId) return;

    // Update subscription status to active
    const subscription = await stripe.subscriptions.retrieve(subscriptionId);
    const orgId = subscription.metadata?.orgId;

    if (orgId) {
        const orgRef = db.collection("orgs").doc(orgId);
        await orgRef.update({
            'subscription.status': 'active',
            'subscription.currentPeriodStart': subscription.current_period_start * 1000,
            'subscription.currentPeriodEnd': subscription.current_period_end * 1000,
            updatedAt: Date.now(),
        });
    }
}

async function handlePaymentFailed(invoice) {
    const subscriptionId = invoice.subscription;
    if (!subscriptionId) return;

    const subscription = await stripe.subscriptions.retrieve(subscriptionId);
    const orgId = subscription.metadata?.orgId;

    if (orgId) {
        const orgRef = db.collection("orgs").doc(orgId);
        await orgRef.update({
            'subscription.status': 'past_due',
            updatedAt: Date.now(),
        });
    }
}

// exports.helloWorld = onRequest((request, response) => {
//     response.send("Hello from Firebase!");
// });

// exports.sendOTP = onRequest(async (request, response) => {
//     // Set CORS headers
//     response.set('Access-Control-Allow-Origin', '*');
//     response.set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
//     response.set('Access-Control-Allow-Headers', 'Content-Type');

//     if (request.method === 'OPTIONS') {
//         response.status(204).send('');
//         return;
//     }

//     if (request.method !== 'POST') {
//         response.status(405).json({ error: 'Method not allowed' });
//         return;
//     }

//     const { email } = request.body;

//     if (!email) {
//         response.status(400).json({ error: 'Email is required' });
//         return;
//     }

//     // Generate a simple OTP
//     const otp = Math.floor(100000 + Math.random() * 900000).toString();

//     response.json({
//         success: true,
//         message: 'Verification code sent to your email',
//         otp: otp // Always return OTP in emulator mode
//     });
// });

// exports.verifyOTP = onRequest(async (request, response) => {
//     // Set CORS headers
//     response.set('Access-Control-Allow-Origin', '*');
//     response.set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
//     response.set('Access-Control-Allow-Headers', 'Content-Type');

//     if (request.method === 'OPTIONS') {
//         response.status(204).send('');
//         return;
//     }

//     if (request.method !== 'POST') {
//         response.status(405).json({ error: 'Method not allowed' });
//         return;
//     }

//     const { email, otp } = request.body;

//     if (!email || !otp) {
//         response.status(400).json({ error: 'Email and OTP are required' });
//         return;
//     }

//     // Mock verification - accept any 6-digit code
//     if (otp.length === 6) {
//         response.json({
//             success: true,
//             user: {
//                 uid: 'demo-user-123',
//                 email: email,
//                 displayName: email.split('@')[0],
//                 emailVerified: true
//             },
//             token: 'demo-token-123'
//         });
//     } else {
//         response.status(400).json({ error: 'Invalid verification code' });
//     }
// });

// Save Company Report Function
exports.saveCompanyReport = onRequest({ cors: true }, async (req, res) => {
    if (req.method === 'OPTIONS') {
        res.status(204).send('');
        return;
    }

    if (req.method !== "POST") {
        return res.status(405).json({ error: "Method not allowed" });
    }

    const { orgId, report } = req.body;

    if (!orgId || !report) {
        return res.status(400).json({ error: "Organization ID and report are required" });
    }

    try {
        // Add ID and timestamp if not present
        if (!report.id) {
            report.id = `report_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
        }
        if (!report.createdAt) {
            report.createdAt = Date.now();
        }

        // Save to Firestore
        const reportRef = db.collection("orgs").doc(orgId).collection("fullCompanyReports").doc(report.id);
        await reportRef.set(report);

        console.log(`Company report saved successfully for org ${orgId}`);

        res.json({
            success: true,
            reportId: report.id,
            message: "Company report saved successfully"
        });
    } catch (error) {
        console.error("Save company report error:", error);
        res.status(500).json({ error: "Failed to save company report" });
    }
});