// app/api/appapis/register/route.ts
import pool from '../../../../lib/db/db';
import { NextRequest, NextResponse } from 'next/server';
import { ResultSetHeader, RowDataPacket } from 'mysql2';
import bcrypt from 'bcryptjs';
import { registrationSchema as Schema } from '../../../../validations/registerValidation';

export async function POST(req: NextRequest) {
  const connection = await pool.getConnection();
  try {
    const body = await req.json();
    const parsed = Schema.parse(body);

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

    if (commingHeaders !== process.env.APP_API_KEY) {
      return NextResponse.json(
        { success: false, message: 'Unauthorized Access' },
        { status: 401 }
      );
    }

    const {
      first_name,
      last_name,
      phone,
      email,
      password,
      confirm_password,
      nationality, // This is the country NAME from payload
      state,       // This is the state NAME from payload
      city,        // This is the city NAME from payload
      program_type,
      gender,
      agree
    } = parsed;

    // email check
    const [checkEmail] = await connection.query<RowDataPacket[]>(
      "SELECT * FROM users WHERE email = ? LIMIT 1",
      [email]
    );

    if (checkEmail.length > 0) {
      connection.release();
      return NextResponse.json(
        {
          success: false,
          message: "This email is already registered. Please choose another one"
        },
        { status: 400 }
      );
    }

    // Start transaction
    await connection.beginTransaction();

    const hashedPassword = await bcrypt.hash(password, 10);

    const [results] = await connection.query<ResultSetHeader>(
      "INSERT INTO users (first_name, last_name, phone, email, password, user_type) VALUES (?, ?, ?, ?, ?, ?)",
      [first_name, last_name, phone, email, hashedPassword, "student"]
    );

    if (results.affectedRows === 0) {
      throw new Error("Failed to insert user");
    }

    const full_name = `${first_name} ${last_name}`;

    // Get country ID from name
    let countryId = null;
    if (nationality) {
      const [getCountry] = await connection.query<RowDataPacket[]>(
        "SELECT id FROM countries_db WHERE name = ?",
        [nationality]
      );
      if (getCountry.length > 0) {
        countryId = getCountry[0].id;
      } else {
        // If country not found, try to insert it? Or log error
        console.log(`Country not found: ${nationality}`);
      }
    }

    // Get state ID from name
    let stateId = null;
    if (state) {
      const [getState] = await connection.query<RowDataPacket[]>(
        "SELECT id FROM states_db WHERE name = ?",
        [state]
      );
      if (getState.length > 0) {
        stateId = getState[0].id;
      } else {
        console.log(`State not found: ${state}`);
      }
    }

    // Get city ID from name
    let cityId = null;
    if (city) {
      const [getCity] = await connection.query<RowDataPacket[]>(
        "SELECT id FROM cities_db WHERE name = ?",
        [city]
      );
      if (getCity.length > 0) {
        cityId = getCity[0].id;
      } else {
        console.log(`City not found: ${city}`);
      }
    }

    // Insert into students table with IDs (not names)
    const [studentData] = await connection.query<ResultSetHeader>(
      "INSERT INTO students (user_id, name, nationality, state, city, gender, prefered_program) VALUES (?, ?, ?, ?, ?, ?, ?)",
      [results.insertId, full_name, countryId, stateId, cityId, gender, program_type]
    );

    if (studentData.affectedRows === 0) {
      throw new Error("Failed to insert student");
    }

    // For CRM API, send the names (not IDs)
    // Get the actual names for CRM
    let countryName = nationality;
    let cityName = city;
    
    // If we have IDs, get the names for CRM
    if (countryId) {
      const [getCountryName] = await connection.query<RowDataPacket[]>(
        "SELECT name FROM countries_db WHERE id = ?",
        [countryId]
      );
      if (getCountryName.length > 0) {
        countryName = getCountryName[0].name;
      }
    }
    
    if (cityId) {
      const [getCityName] = await connection.query<RowDataPacket[]>(
        "SELECT name FROM cities_db WHERE id = ?",
        [cityId]
      );
      if (getCityName.length > 0) {
        cityName = getCityName[0].name;
      }
    }

    // Send to CRM API (send names, not IDs)
    const response = await fetch("https://crm-universitiespage.com/reactapis/api/website_website_student_crm/store", {
      method: "POST",
      body: JSON.stringify({
        first_name: first_name,
        last_name: last_name,
        email: email,
        phone: phone,
        country: countryName,
        city: cityName
      }),
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `${process.env.CRM_API_KEY}`,
      },
    });

    const data = await response.json();

    if (data?.status_code !== 200) {
      await connection.rollback();
      return NextResponse.json(
        {
          message: "Failed to submit your form. Please try again later.",
          success: false
        },
        { status: 500 }
      );
    }

    // Commit transaction
    await connection.commit();

    return NextResponse.json(
      { success: true, message: "User Registered Successfully" },
      { status: 200 }
    );
  } catch (err: any) {
    // Rollback transaction if active
    try {
      await connection.rollback();
    } catch (rollbackErr) {
      console.error("Rollback failed:", rollbackErr);
    }

    if (err?.issues) {
      // ZodError
      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(
        { ok: false, message: fieldErrors },
        { status: 400 }
      );
    }

    console.error("POST /register error:", err);
    return NextResponse.json(
      { ok: false, message: "Internal server error" },
      { status: 500 }
    );
  } finally {
    connection.release();
  }
}