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';

// POST create new consultation
export async function POST(req: NextRequest) {

    const incomingHeaders = req.headers.get("authorization");

    if (incomingHeaders !== process.env.APP_API_KEY) {
        return NextResponse.json(
            { success: false, message: 'Unauthorized Access' },
            { status: 401 }
        );
    }
  
  const connection = await pool.getConnection();

  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();
    } catch (parseError) {
      return NextResponse.json(
        { 
          success: false, 
          message: 'Invalid JSON in request body' 
        },
        { status: 400 }
      );
    }



    // Validate with Zod schema
    const parsed = Schema.parse(body);
    const { 
      name, 
      email, 
      phone_number, 
      last_education, 
      interested_country, 
      apply_for, 
      office_to_visit, phonecode 
    } = parsed;

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

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

    if(getCountry.length === 0)
    {
      return NextResponse.json(
        {
          success: false,
          message: 'Invalid country code'
        },
        {
          status: 500
        }
      )
    }

    // 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 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,
      lead_type: 'mobile',
      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();

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

    } catch (crmError) {
      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 } // Bad Gateway
      );
    }

    // 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) {
        console.warn('Facebook Pixel event failed, but continuing...');
        // Don't fail the entire request if Facebook Pixel fails
      }
    } catch (fbError) {
      console.warn('Facebook Pixel Error:', fbError);
      // Continue with the request even if Facebook Pixel fails
    }

    await sendFormEmail(FormType.FREE_CONSULTATION, { email });
    
    // 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();

    // Zod validation errors
    if (err?.issues) {
      const fieldErrors: Record<string, string[]> = {};
      for (const issue of err.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 }
      );
    }

    // 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();
  }
}