"use client";

import {
  GoogleAuthProvider,
  FacebookAuthProvider,
  OAuthProvider,
  signInWithPopup,
} from "firebase/auth";

import { auth } from "./firebase";

/* =========================================================
   TYPES
========================================================= */

export interface SocialUser {
  id: number;
  name: string;
  email: string;
  contactNo: string;
  countryCode: string;
  profileImage: string;

  mobileVerified: boolean;
  emailVerified: boolean;

  referralCode?: string;
  roleId?: number;

  lastLogin?: string | null;

  userWallet?: {
    id: number;
    userId: number;
    amount: number;
  };
}

export interface SocialLoginResponse {
  success: boolean;
  message?: string;

  mobile_verification_required?: boolean;

  verification_token?: string;

  is_new_user?: boolean;

  provider?: string;
  platform?: string;

  token?: string;
  access_token?: string;

  refresh_token?: string;

  user?: SocialUser;
}

/* =========================================================
   DEVICE TOKEN
========================================================= */

function getDeviceToken(): string {
  if (typeof window === "undefined") {
    return "";
  }

  let deviceToken =
    localStorage.getItem("device_token");

  if (!deviceToken) {
    deviceToken = crypto.randomUUID();

    localStorage.setItem(
      "device_token",
      deviceToken
    );
  }

  return deviceToken;
}

/* =========================================================
   GOOGLE FIREBASE LOGIN
========================================================= */

export async function signInWithGoogle() {
  const provider =
    new GoogleAuthProvider();

  provider.setCustomParameters({
    prompt: "select_account",
  });

  const result =
    await signInWithPopup(
      auth,
      provider
    );

  const firebaseUser =
    result.user;

  const idToken =
    await firebaseUser.getIdToken(
      true
    );

  return {
    user: firebaseUser,
    idToken,
  };
}

/* =========================================================
   CALL BACKEND SOCIAL WEB LOGIN
========================================================= */
export async function socialWebLogin(
  idToken: string
): Promise<SocialLoginResponse> {
  const response = await fetch(
    "/api/auth/social-login",
    {
      method: "POST",

      headers: {
        "Content-Type": "application/json",
        Accept: "application/json",
      },

      body: JSON.stringify({
        id_token: idToken,

        device_token:
          getDeviceToken(),

        device_name: "browser",
      }),
    }
  );

  const text = await response.text();

  console.log(
    "Next API status:",
    response.status
  );

  console.log(
    "Next API response:",
    text
  );

  let data: SocialLoginResponse;

  try {
    data = JSON.parse(text);
  } catch {
    throw new Error(
      `Social login API returned invalid response. HTTP ${response.status}`
    );
  }

  if (!response.ok || !data.success) {
    throw new Error(
      data.message ||
        "Social login failed."
    );
  }

  return data;
}

/* =========================================================
   SEND MOBILE OTP
========================================================= */

export async function sendSocialMobileOtp(
  verificationToken: string,
  mobile: string,
  countryCode: string
) {
  const response =
    await fetch(
      "/api/auth/social/send-mobile-otp",
      {
        method: "POST",

        headers: {
          "Content-Type":
            "application/json",

          Accept:
            "application/json",
        },

        body: JSON.stringify({
          verification_token:
            verificationToken,

          mobile,

          countryCode,
        }),
      }
    );

  const text =
    await response.text();

  let data;

  try {
    data = JSON.parse(text);
  } catch {
    console.error(
      "Send OTP returned non JSON:",
      text
    );

    throw new Error(
      "Send OTP server returned an invalid response."
    );
  }

  if (!response.ok) {
    throw new Error(
      data?.message ||
        "Unable to send OTP."
    );
  }

  return data;
}

/* =========================================================
   VERIFY MOBILE OTP
========================================================= */

export async function verifySocialMobileOtp(
  verificationToken: string,
  mobile: string,
  otp: string,
  deviceName: string
) {
  const response =
    await fetch(
      "/api/auth/social/verify-mobile-otp",
      {
        method: "POST",

        headers: {
          "Content-Type":
            "application/json",

          Accept:
            "application/json",
        },

        body: JSON.stringify({
          verification_token:
            verificationToken,

          mobile,

          otp,

          device_name:
            deviceName,
        }),
      }
    );

  const text =
    await response.text();

  let data;

  try {
    data = JSON.parse(text);
  } catch {
    console.error(
      "Verify OTP returned non JSON:",
      text
    );

    throw new Error(
      "Verify OTP server returned an invalid response."
    );
  }

  if (!response.ok) {
    throw new Error(
      data?.message ||
        "OTP verification failed."
    );
  }

  return data;
}

export async function signInWithFacebook() {
  const provider = new FacebookAuthProvider();

  provider.setCustomParameters({
    display: "popup",
  });

  const result = await signInWithPopup(
    auth,
    provider
  );

  const firebaseUser = result.user;

  const idToken =
    await firebaseUser.getIdToken();

  return {
    user: firebaseUser,
    idToken,
  };
}

export async function signInWithApple() {
  const provider = new OAuthProvider("apple.com");

  provider.addScope("email");
  provider.addScope("name");

  const result = await signInWithPopup(auth, provider);

  const firebaseUser = result.user;

  const idToken = await firebaseUser.getIdToken();

  return {
    user: firebaseUser,
    idToken,
  };
}