import pool from '../../../../lib/db/db';
import { NextRequest, NextResponse } from 'next/server';
import { ResultSetHeader, RowDataPacket } from 'mysql2';
import { sendFormEmail, FormType } from '../../../../lib/mailer';
import { hashData } from '../../../../lib/hashData';

// Helper function to log errors
async function logFormError(
    formType: string, 
    error: any, 
    payload?: any,
    errorCode?: string,
    additionalInfo?: any
) {
    try {
        const connection = await pool.getConnection();
        
        await connection.query(
            `INSERT INTO form_submission_errors 
             (form_type, error_message, error_code, payload, error_stack, additional_info) 
             VALUES (?, ?, ?, ?, ?, ?)`,
            [
                formType,
                error?.message || 'Unknown error',
                errorCode || error?.code || null,
                payload ? JSON.stringify(payload) : null,
                error?.stack?.substring(0, 1000) || null,
                additionalInfo ? JSON.stringify(additionalInfo) : null
            ]
        );
        
        connection.release();
    } catch (logError) {
        console.error('Failed to log error:', logError);
    }
}

// POST create complaint
export async function POST(req: NextRequest) {
    const connection = await pool.getConnection();
    let originalPayload: any = null;
    let originalBody: any = null;

    try {
        await connection.beginTransaction();

        const accessToken = process.env.FACEBOOK_ACCESS_CODE;
        const pixelId = process.env.FACEBOOK_PIXEL_ID;

        // Parse request body
        let body;
        try {
            body = await req.json();
            originalBody = body;
            originalPayload = { ...body };
            console.log(JSON.stringify(body));
        } catch (parseError: any) {
            await logFormError(
                'complaints',
                parseError,
                null,
                'JSON_PARSE_ERROR'
            );
            
            return NextResponse.json(
                { success: false, error: "Invalid JSON in request body" },
                { status: 400 }
            );
        }

        const { name, subject, email, phone, message, location } = body;

        // Validation
        const missingFields = [];
        if (!email) missingFields.push('email');
        if (!message) missingFields.push('message');

        if (missingFields.length > 0) {
            await logFormError(
                'complaints',
                new Error(`Missing required fields: ${missingFields.join(', ')}`),
                body,
                'MISSING_REQUIRED_FIELDS',
                { missingFields }
            );
            
            return NextResponse.json(
                { 
                    success: false, 
                    error: `Email and message are required. Missing: ${missingFields.join(', ')}` 
                },
                { status: 400 }
            );
        }

        // Validate email format
        const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        if (!emailRegex.test(email)) {
            await logFormError(
                'complaints',
                new Error(`Invalid email format: ${email}`),
                body,
                'INVALID_EMAIL_FORMAT',
                { email }
            );
            
            return NextResponse.json(
                { success: false, error: "Invalid email format" },
                { status: 400 }
            );
        }

        // Validate phone number if provided
        if (phone && phone !== "" && !/^[\d\s\+\(\)\-]{8,20}$/.test(phone)) {
            await logFormError(
                'complaints',
                new Error(`Invalid phone number format: ${phone}`),
                body,
                'INVALID_PHONE_FORMAT',
                { phone }
            );
            
            return NextResponse.json(
                { success: false, error: "Invalid phone number format" },
                { status: 400 }
            );
        }

        // Insert into database
        let insertResult;
        try {
            const insertQuery = `
                INSERT INTO complaints (name, subject, email, phone, message, location)
                VALUES (?, ?, ?, ?, ?, ?)
            `;
            const [result] = await connection.query<ResultSetHeader>(insertQuery, [
                name || null,
                subject || null,
                email,
                phone || null,
                message,
                location || null,
            ]);
            insertResult = result;

            if (insertResult.affectedRows === 0) {
                await logFormError(
                    'complaints',
                    new Error('Database insertion failed - no rows affected'),
                    body,
                    'DB_INSERT_FAILED'
                );
                
                await connection.rollback();
                return NextResponse.json(
                    { success: false, message: "Failed to create complaint" },
                    { status: 500 }
                );
            }
        } catch (dbError: any) {
            await logFormError(
                'complaints',
                dbError,
                body,
                'DATABASE_ERROR',
                { 
                    table: 'complaints',
                    query: 'INSERT',
                    sqlCode: dbError.code,
                    sqlMessage: dbError.sqlMessage
                }
            );
            throw dbError;
        }

        // Prepare CRM payload
        const crmPayload = {
            name: name || null,
            subject: subject || null,
            email,
            phone: phone || null,
            message,
            location: location || null
        };

        // Send to CRM
        let crmResponse;
        try {
            crmResponse = await fetch(
                "https://crm-universitiespage.com/reactapis/api/website_complaints_crm/store",
                {
                    method: "POST",
                    body: JSON.stringify(crmPayload),
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': `${process.env.CRM_API_KEY}`,
                    },
                }
            );

            if (!crmResponse.ok) {
                throw new Error(`CRM API responded with status: ${crmResponse.status}`);
            }

            const data = await crmResponse.json();

            if (data?.status_code !== 200) {
                throw new Error(`CRM API returned status_code: ${data?.status_code}`);
            }
        } catch (crmError: any) {
            // Log CRM error
            await logFormError(
                'complaints',
                crmError,
                { originalPayload: body, crmPayload },
                'CRM_API_ERROR',
                { 
                    responseStatus: crmResponse?.status,
                    endpoint: 'website_complaints_crm/store',
                    email: email
                }
            );
            
            await connection.rollback();
            console.error('CRM API Error:', crmError);
            
            return NextResponse.json(
                {
                    message: "Failed to submit your form. Please try again later.",
                    success: false
                },
                { status: 502 }
            );
        }

        // Facebook Pixel Event (only if both phone and email are provided)
        let fbSuccess = true;
        if (phone && phone !== "" && email && email !== "") {
            try {
                const [emailHash, phoneHash] = await Promise.all([
                    hashData(email),
                    hashData(phone)
                ]);

                const event = {
                    event_name: "Complaints",
                    event_time: Math.floor(Date.now() / 1000),
                    user_data: {
                        email: emailHash,
                        ph: phoneHash,
                    },
                };

                const fbPayload = { data: [event] };

                const fbResponse = await fetch(
                    `https://graph.facebook.com/v14.0/${pixelId}/events?access_token=${accessToken}`,
                    {
                        method: "POST",
                        headers: { "Content-Type": "application/json" },
                        body: JSON.stringify(fbPayload),
                    }
                );

                if (!fbResponse.ok) {
                    fbSuccess = false;
                    // Log Facebook error but don't fail the request
                    await logFormError(
                        'complaints',
                        new Error(`Facebook Pixel failed: ${fbResponse.status}`),
                        { fbPayload },
                        'FACEBOOK_PIXEL_ERROR',
                        { 
                            responseStatus: fbResponse.status,
                            responseText: await fbResponse.text()
                        }
                    );
                    console.error("Facebook Pixel event failed");
                }
            } catch (fbError: any) {
                fbSuccess = false;
                await logFormError(
                    'complaints',
                    fbError,
                    { error: 'Facebook Pixel processing error' },
                    'FACEBOOK_PIXEL_ERROR'
                );
                console.error("Facebook Pixel Error:", fbError);
            }
        } else {
            // Log that Facebook Pixel was skipped due to missing data
            await logFormError(
                'complaints',
                new Error('Facebook Pixel skipped - missing phone or email'),
                { hasPhone: !!(phone && phone !== ""), hasEmail: !!(email && email !== "") },
                'FACEBOOK_PIXEL_SKIPPED',
                { reason: 'Phone or email missing for hashing' }
            );
        }

        // Commit transaction
        await connection.commit();

        // Send confirmation email
        try {
            await sendFormEmail(FormType.COMPLAINTS, {
                email: email
            });
        } catch (emailError: any) {
            // Log email error but don't fail the request
            await logFormError(
                'complaints',
                emailError,
                { email },
                'EMAIL_SEND_ERROR',
                { formType: FormType.COMPLAINTS }
            );
            console.error('Email send failed:', emailError);
        }

        // Return response with warning if Facebook Pixel failed or was skipped
        let responseMessage = "Complaint created successfully";
        if (!fbSuccess) {
            responseMessage = "Complaint created successfully but tracking event failed";
        } else if (!phone || phone === "") {
            responseMessage = "Complaint created successfully (Facebook tracking skipped - no phone number)";
        }

        return NextResponse.json(
            { 
                success: true, 
                message: responseMessage,
                id: insertResult.insertId,
                ...(!fbSuccess && { warning: 'Facebook tracking failed' }),
                ...((!phone || phone === "") && { notice: 'No phone number provided for tracking' })
            },
            { status: 201 }
        );
        
    } catch (error: any) {
        await connection.rollback();

        // Log any unhandled error
        await logFormError(
            'complaints',
            error,
            originalPayload,
            error.code?.startsWith('ER_') ? 'DATABASE_ERROR' : 'UNHANDLED_ERROR',
            { 
                stage: 'general_catch_block',
                sqlCode: error.code,
                sqlErrno: error.errno,
                sqlMessage: error.sqlMessage
            }
        );

        console.error("❌ POST /complaints error:", error);
        
        // Handle specific database errors
        if (error.code === 'ER_DUP_ENTRY') {
            return NextResponse.json(
                { success: false, error: "Duplicate entry. This complaint may already exist." },
                { status: 409 }
            );
        }
        
        if (error.code === 'ER_BAD_NULL_ERROR') {
            return NextResponse.json(
                { success: false, error: "Required field cannot be null" },
                { status: 400 }
            );
        }
        
        if (error.code?.startsWith('ER_')) {
            return NextResponse.json(
                { success: false, error: "Database error occurred. Please try again later." },
                { status: 500 }
            );
        }
        
        return NextResponse.json(
            { success: false, error: "Internal Server Error", details: error.message },
            { status: 500 }
        );
    } finally {
        connection.release();
    }
}