import pool from '../../../../lib/db/db';
import { NextRequest, NextResponse } from 'next/server';
import { FreeConsultationSchemaSoft as Schema } from '../../../../validations/freeconsultation';
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
) {
    try {
        const connection = await pool.getConnection();
        
        await connection.query(
            `INSERT INTO form_submission_errors 
             (form_type, error_message, error_code, payload, error_stack) 
             VALUES (?, ?, ?, ?, ?)`,
            [
                formType,
                error?.message || 'Unknown error',
                errorCode || error?.code || null,
                payload ? JSON.stringify(payload) : null,
                error?.stack?.substring(0, 1000) || null  // Limit stack trace length
            ]
        );
        
        connection.release();
    } catch (logError) {
        console.error('Failed to log error:', logError);
    }
}

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

    try {
        await connection.beginTransaction();

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

        // Validate request body
        let body;
        try {
            body = await req.json();
            originalPayload = body; // Store for error logging
        } catch (parseError: any) {
            // Log JSON parse error
            await logFormError(
                'free_consultation',
                parseError,
                null,
                'JSON_PARSE_ERROR'
            );
            
            return NextResponse.json(
                { 
                    success: false, 
                    message: 'Invalid JSON in request body' 
                },
                { status: 400 }
            );
        }

        // Validate with Zod schema
        let parsed;
        try {
            parsed = Schema.parse(body);
        } catch (validationError: any) {
            // Log Zod validation error
            await logFormError(
                'free_consultation',
                validationError,
                body,
                'VALIDATION_ERROR'
            );
            
            const fieldErrors: Record<string, string[]> = {};
            if (validationError?.issues) {
                for (const issue of validationError.issues) {
                    const key = (issue.path?.[0] as string) ?? '_';
                    fieldErrors[key] = fieldErrors[key] || [];
                    fieldErrors[key].push(issue.message);
                }
            }
            
            return NextResponse.json(
                { 
                    success: false, 
                    message: 'Validation failed',
                    errors: fieldErrors 
                },
                { status: 400 }
            );
        }

        const { 
            name, email, phone_number, last_education, 
            interested_country, apply_for, office_to_visit, phonecode 
        } = parsed;

        const combinePhonecode = `${phonecode}${phone_number}`;

        // Check country code
        const [getCountry] = await connection.query<RowDataPacket[]>(
            "SELECT name FROM countries_with_phone WHERE phonecode = ?", 
            [phonecode]
        );

        if(getCountry.length === 0) {
            await logFormError(
                'free_consultation',
                new Error('Invalid country code'),
                parsed,
                'INVALID_COUNTRY_CODE'
            );
            
            return NextResponse.json(
                {
                    success: false,
                    message: 'Invalid country code'
                },
                { status: 400 }
            );
        }

        // Insert into database
        const [newConsultation] = await connection.query<ResultSetHeader>(
            `INSERT INTO free_consulations 
             (name, email, phone_number, last_education, interested_country, apply_for, office_to_visit, country, city) 
             VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
            [name, email, combinePhonecode, last_education, interested_country, apply_for, office_to_visit, getCountry[0].name, office_to_visit]
        );

        if (newConsultation.affectedRows === 0) {
            await logFormError(
                'free_consultation',
                new Error('Database insertion failed - no rows affected'),
                parsed,
                'DB_INSERT_FAILED'
            );
            
            await connection.rollback();
            return NextResponse.json(
                { 
                    success: false, 
                    message: 'Failed to create consultation record' 
                },
                { status: 500 }
            );
        }

        // Prepare payload for CRM
        const crmPayload = {
            name,
            email,
            phone_number: combinePhonecode,
            last_education,
            interested_country,
            office_to_visit,
            apply_for,
            country: getCountry[0].name
        };

        // Send to CRM API
        let crmResponse;
        try {
            crmResponse = await fetch(
                "https://crm-universitiespage.com/reactapis/api/website_free_consultation_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 crmData = await crmResponse.json();
            
            console.log(crmData);

            if (crmData?.status_code !== 200) {
                throw new Error('CRM API returned non-success status');
            }

        } catch (crmError: any) {
            // Log CRM error with full payload
            await logFormError(
                'free_consultation',
                crmError,
                { originalPayload: parsed, crmPayload },
                'CRM_API_ERROR'
            );
            
            await connection.rollback();
            console.error('CRM API Error:', crmError);
            
            return NextResponse.json(
                {
                    success: false,
                    message: "Failed to submit your form to CRM. Please try again later."
                },
                { status: 502 }
            );
        }

        // Facebook Pixel Event
        try {
            const [emailHash, phoneHash] = await Promise.all([
                hashData(email),
                hashData(combinePhonecode)
            ]);

            const event = {
                event_name: "Free Consultation",
                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) {
                // Log Facebook error but don't rollback main transaction
                await logFormError(
                    'free_consultation',
                    new Error(`Facebook Pixel failed: ${fbResponse.status}`),
                    { facebookPayload: fbPayload, responseStatus: fbResponse.status },
                    'FACEBOOK_PIXEL_ERROR'
                );
                console.warn('Facebook Pixel event failed, but continuing...');
            }
        } catch (fbError: any) {
            await logFormError(
                'free_consultation',
                fbError,
                { error: 'Facebook Pixel processing error' },
                'FACEBOOK_PIXEL_ERROR'
            );
            console.warn('Facebook Pixel Error:', fbError);
        }

        // Commit transaction if everything succeeded
        await connection.commit();

        return NextResponse.json(
            { 
                success: true, 
                message: 'Consultation created successfully' 
            },
            { status: 200 }
        );

    } catch (err: any) {
        await connection.rollback();

        // Log any unhandled error
        await logFormError(
            'free_consultation',
            err,
            originalPayload,
            err.code?.startsWith('ER_') ? 'DATABASE_ERROR' : 'UNHANDLED_ERROR'
        );

        // Database errors
        if (err.code?.startsWith('ER_')) {
            console.error('Database error:', err);
            return NextResponse.json(
                { 
                    success: false, 
                    message: 'Database error occurred' 
                },
                { status: 500 }
            );
        }

        // Generic server errors
        console.error("Free consultation POST error:", err);
        return NextResponse.json(
            { 
                success: false, 
                message: "Internal server error" 
            },
            { status: 500 }
        );
    } finally {
        connection.release();
    }
}