import pool from '../../../../lib/db/db';
import { NextResponse } from 'next/server';
import type { ResultSetHeader } from 'mysql2';
import { sendFormEmail, FormType } from '../../../../lib/mailer';
import { hashData } from '../../../../lib/hashData';
import { DiscountOfferSchema } from '../../../../validations/discount-offer';

// Helper function to log errors (shared across all form APIs)
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);
    }
}

export async function POST(req: Request) {
    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; // Store for error logging
            originalPayload = {
                ...body,
                phone: body.phone // Keep original for reference
            };
        } catch (parseError: any) {
            await logFormError(
                'discount_offer',
                parseError,
                null,
                'JSON_PARSE_ERROR'
            );
            
            return NextResponse.json({ 
                success: false, 
                message: 'Invalid JSON in request body' 
            }, { status: 400 });
        }
        
        // Transform frontend field names to match Zod schema
        const transformedBody = {
            name: body.name,
            email: body.email,
            phone_number: body.phone, // Transform 'phone' to 'phone_number'
            phonecode: body.phonecode,
            last_education: body.lastEducation, // Transform 'lastEducation' to 'last_education'
            last_education_per: body.lastEducationPer, // Transform 'lastEducationPer' to 'last_education_per'
            office_location: body.location, // Transform 'location' to 'office_location'
            family_detail: body.familyDetail // Transform 'familyDetail' to 'family_detail'
        };

        // Validate with Zod schema
        let parsed;
        try {
            parsed = DiscountOfferSchema.parse(transformedBody);
        } catch (validationError: any) {
            // Log validation error with transformed body
            await logFormError(
                'discount_offer',
                validationError,
                { original: originalBody, transformed: transformedBody },
                'VALIDATION_ERROR'
            );
            
            const formattedErrors = validationError.errors?.map((error: any) => ({
                field: error.path.join('.'),
                message: error.message
            })) || [{ field: 'unknown', message: validationError.message }];
            
            return NextResponse.json({ 
                success: false, 
                message: 'Validation failed. Please check your input.',
                errors: formattedErrors
            }, { status: 400 });
        }

        const {
            name,
            email,
            phone_number,
            phonecode,
            last_education,
            last_education_per,
            office_location,
            family_detail
        } = parsed;

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

        // Insert into database
        try {
            const [insertResult] = await connection.query<ResultSetHeader>(
                `INSERT INTO discountOffers 
                (name, email, phone, lastEducation, lastEducationPer, location, familyDetail, city) 
                VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
                [name, email, phoneWithCode, last_education, last_education_per, office_location, family_detail, office_location]
            );

            if (insertResult.affectedRows === 0) {
                await logFormError(
                    'discount_offer',
                    new Error('Database insertion failed - no rows affected'),
                    parsed,
                    'DB_INSERT_FAILED'
                );
                
                await connection.rollback();
                return NextResponse.json(
                    { success: false, message: 'Failed to create discount offer' },
                    { status: 500 }
                );
            }
        } catch (dbError: any) {
            await logFormError(
                'discount_offer',
                dbError,
                parsed,
                'DATABASE_ERROR',
                { query: 'INSERT INTO discountoffers' }
            );
            throw dbError; // Re-throw to be caught by outer catch
        }

        // Prepare payload for CRM
        const crmPayload = {
            name,
            email,
            phone: phoneWithCode,
            lastEducation: last_education,
            lastEducationPer: last_education_per,
            location: office_location,
            familyDetail: family_detail
        };

        // Send to CRM API
        let crmResponse;
        try {
            crmResponse = await fetch("https://crm-universitiespage.com/reactapis/api/website_discount_offer_crm/store?location=lahore", {
                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(
                'discount_offer',
                crmError,
                { originalPayload: parsed, crmPayload },
                'CRM_API_ERROR',
                { responseStatus: crmResponse?.status, endpoint: 'website_discount_offer_crm/store' }
            );
            
            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
        try {
            const [emailHash, phoneHash] = await Promise.all([
                email ? hashData(email) : Promise.resolve(''),
                hashData(phoneWithCode)
            ]);

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

            const payload = { 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(payload),
                }
            );

            if (!fbResponse.ok) {
                // Log Facebook error but don't fail the request
                await logFormError(
                    'discount_offer',
                    new Error(`Facebook Pixel failed: ${fbResponse.status}`),
                    { facebookPayload: payload },
                    'FACEBOOK_PIXEL_ERROR',
                    { responseStatus: fbResponse.status }
                );
                console.error("Facebook Pixel event failed");
            }
        } catch (fbError: any) {
            await logFormError(
                'discount_offer',
                fbError,
                { error: 'Facebook Pixel processing error' },
                'FACEBOOK_PIXEL_ERROR'
            );
            console.error("Facebook Pixel Error:", fbError);
        }

        await connection.commit();

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

        return NextResponse.json(
            { success: true, message: 'Discount offer created successfully' },
            { status: 200 }
        );
        
    } catch (error: any) {
        await connection.rollback();

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

        console.error('DiscountOffers POST error:', error);
        
        // Handle specific error types
        if (error.code?.startsWith('ER_')) {
            return NextResponse.json(
                { success: false, message: 'Database error occurred', error: error.message },
                { status: 500 }
            );
        }
        
        return NextResponse.json(
            { success: false, message: 'Internal server error' },
            { status: 500 }
        );
    } finally {
        connection.release();
    }
}