const axios = require("axios");
const { query } = require("../../../database/dbpromise");

function checkEmbed() {
  return true;
}

// Register phone number
async function registerPhoneNumber({ token, phoneNumId, pin = "123456" }) {
  try {
    const response = await axios.post(
      `https://graph.facebook.com/v24.0/${phoneNumId}/register`,
      {
        messaging_product: "whatsapp",
        pin: pin,
      },
      {
        headers: {
          Authorization: `Bearer ${token}`,
          "Content-Type": "application/json",
        },
      }
    );

    return { success: true, data: response.data };
  } catch (err) {
    const errorMsg = err.response?.data?.error?.message || err?.toString();

    // Check if already registered (error code 133009)
    if (
      err.response?.data?.error?.code === 133009 ||
      errorMsg.includes("already registered") ||
      errorMsg.includes("133009")
    ) {
      return { success: true, alreadyRegistered: true };
    }

    return {
      success: false,
      msg: errorMsg,
    };
  }
}

// Get phone number status
async function getPhoneNumberStatus({ token, phoneNumId }) {
  try {
    const response = await axios.get(
      `https://graph.facebook.com/v24.0/${phoneNumId}`,
      {
        params: {
          fields: "name_status,display_phone_number,verified_name",
          access_token: token,
        },
      }
    );

    return { success: true, data: response.data };
  } catch (err) {
    return {
      success: false,
      msg: err.response?.data?.error?.message || err?.toString(),
    };
  }
}

// Subscribe to webhook
async function subscribeWebhook({ token, wabaId }) {
  try {
    const response = await axios.post(
      `https://graph.facebook.com/v24.0/${wabaId}/subscribed_apps`,
      {},
      {
        params: {
          access_token: token,
        },
      }
    );

    return { success: true, data: response.data };
  } catch (err) {
    return {
      success: false,
      msg: err.response?.data?.error?.message || err?.toString(),
    };
  }
}

// Get WABA details
async function getWABADetails({ token, wabaId }) {
  try {
    const response = await axios.get(
      `https://graph.facebook.com/v24.0/${wabaId}`,
      {
        params: {
          fields: [
            "id",
            "name",
            "currency",
            "timezone_id",
            "business_verification_status",
            "account_review_status",
            "owner_business_info{name,id}",
          ].join(","),
          access_token: token,
        },
      }
    );

    return { success: true, data: response.data };
  } catch (err) {
    return {
      success: false,
      msg: err.response?.data?.error?.message || err?.toString(),
    };
  }
}

// Exchange token - WITH REGISTRATION (SKIPS IF ALREADY REGISTERED)
async function exchangeEmbedToken({
  appId,
  appSecret,
  authCode,
  wabaId,
  phoneNumId,
  businessId,
  registrationPin = "123456",
}) {
  try {
    // Step 1: Exchange token
    const response = await axios.post(
      "https://graph.facebook.com/v24.0/oauth/access_token",
      {
        client_id: appId,
        client_secret: appSecret,
        code: authCode,
        grant_type: "authorization_code",
      }
    );

    if (!response.data.access_token) {
      return { success: false, msg: "Failed to exchange token" };
    }

    const token = response.data.access_token;

    // Step 2: Get WABA details
    const waba = await getWABADetails({ token, wabaId });
    if (!waba.success) {
      return {
        success: false,
        msg: waba.msg || "Failed to fetch WABA details",
      };
    }

    // Step 3: Check phone number status
    const phoneStatus = await getPhoneNumberStatus({ token, phoneNumId });
    if (!phoneStatus.success) {
      return {
        success: false,
        msg: "Failed to fetch phone number details",
      };
    }

    const nameStatus = phoneStatus.data.name_status;

    // Step 4: Register phone number (will skip if already registered)
    const registration = await registerPhoneNumber({
      token,
      phoneNumId,
      pin: registrationPin,
    });

    if (!registration.success) {
      return {
        success: false,
        msg: registration.msg,
      };
    }

    // Log if already registered
    if (registration.alreadyRegistered) {
      console.log("Phone number already registered, skipping...");
    }

    // Step 5: Reject if not approved
    if (
      nameStatus !== "APPROVED" &&
      nameStatus !== "AVAILABLE_WITHOUT_REVIEW"
    ) {
      let errorMsg = "";

      switch (nameStatus) {
        case "PENDING":
          errorMsg =
            "Display name verification is pending. Please wait for Meta approval (24-48 hours) and try again.";
          break;
        case "DECLINED":
          errorMsg =
            "Display name was declined by Meta. Please update your display name in Meta Business Manager and try again.";
          break;
        case "NONE":
        case "UNVERIFIED":
          errorMsg =
            "Phone number is not verified. Please complete verification in Meta Business Manager first.";
          break;
        default:
          errorMsg = `Phone number status is ${nameStatus}. Only approved numbers can be added.`;
      }

      return {
        success: false,
        msg: errorMsg,
      };
    }

    // Step 6: Subscribe to webhook
    const webhook = await subscribeWebhook({ token, wabaId });
    if (!webhook.success) {
      console.error("Webhook subscription failed:", webhook.msg);
      // Don't fail the entire process for webhook error
    }

    // Step 7: Return success
    const obj = {
      token: token,
      authCode: authCode,
      waba: waba.data,
      phoneNumId: phoneNumId,
      businessId: businessId,
      phoneDetails: phoneStatus.data,
      webhookSubscribed: webhook.success,
    };

    return { success: true, data: obj };
  } catch (err) {
    return {
      success: false,
      msg: err.response?.data?.error?.message || err?.toString(),
    };
  }
}

async function genEmbedWebhook(params) {
  try {
    const [admin] = await query(`SELECT * FROM admin LIMIT 1`, []);
    const webhook = `${process.env.FRONTENDURI}/api/inbox/embed/webhook/${admin?.uid}`;
    return webhook;
  } catch (err) {
    return null;
  }
}

module.exports = { checkEmbed, exchangeEmbedToken, genEmbedWebhook };
