"use server";

import { ResponseCookie } from "next/dist/compiled/@edge-runtime/cookies";
import { cookies } from "next/headers";

import { COOKIES_NAME } from "../constants/app";

let cookieOptions:
  | Partial<ResponseCookie>
  | undefined
  | [options: ResponseCookie] = {
  httpOnly: true,
  secure: false, // Only send over HTTPS
  sameSite: "strict", // Prevent cross-site request forgery (CSRF)
  maxAge: 3600, // 1 hour in seconds
};

const getJwExpiredTimeInSeconds = (tokenPayload: string) => {
  const decodedPayload: any = JSON.parse(
    Buffer.from(tokenPayload, "base64").toString(),
  );
  if (decodedPayload?.exp) {
    return decodedPayload?.exp - decodedPayload?.iat;
  }

  return 0;
};

export const setJwtCookie = async ({
  id,
  token,
}: {
  id: string;
  token: string;
}): Promise<boolean> => {
  return new Promise(async (resolve) => {
    // Asynchronous operation here
    try {
      const { set } = await cookies();
      if (!set) return;

      const tokenParts: string[] = token.split(".");

      if (tokenParts.length == 3) {
        const tokenPayload: string = tokenParts[1];

        cookieOptions = {
          ...cookieOptions,
          maxAge: getJwExpiredTimeInSeconds(tokenPayload),
        };

        set(COOKIES_NAME.authToken, token, cookieOptions);
        set(COOKIES_NAME.userSessionId, id, cookieOptions);

        return resolve(true);
      }

      resolve(false);
    } catch {
      resolve(false);
    }
  });
};

export const isTokenExpired = async (): Promise<boolean> => {
  try {
    const { get } = await cookies();
    if (!get) return;

    const token = get(COOKIES_NAME.authToken)?.value;
    if (!token) return true;

    const tokenParts: string[] = token.split(".");
    const tokenPayload: string = tokenParts?.[1];
    if (!tokenPayload) return true;

    const decodedPayload: any = JSON.parse(
      Buffer.from(tokenPayload, "base64").toString(),
    );

    if ((decodedPayload?.exp ?? 0) > Date.now() / 1000) {
      return false;
    }

    // await deleteToken();

    return true;
  } catch {
    return true;
  }
};

export const getToken = async (): Promise<string> => {
  try {
    const { get } = await cookies();
    if (!get) return;

    const token = get(COOKIES_NAME.authToken)?.value;
    if (!token) return "";

    return token;
  } catch {
    return "";
  }
};

export const deleteToken = async (): Promise<boolean> => {
  try {
    const { delete: deleteCookie } = await cookies();

    deleteCookie(COOKIES_NAME.authToken);
    deleteCookie(COOKIES_NAME.userSessionId);
    deleteCookie(COOKIES_NAME.aletaPaymentToken);

    return true;
  } catch {
    return false;
  }
};

export const getTokenExpiredTime = async (): Promise<number> => {
  try {
    const { get } = await cookies();
    if (!get) return;

    const token = get(COOKIES_NAME.authToken)?.value;
    if (!token) return 0;

    const tokenParts: string[] = token.split(".");
    const tokenPayload: string = tokenParts?.[1];
    if (!tokenPayload) return 0;

    const decodedPayload: any = JSON.parse(
      Buffer.from(tokenPayload, "base64").toString(),
    );

    if (decodedPayload?.exp) {
      return parseInt(decodedPayload.exp, 10);
    }

    return 0;
  } catch (error) {
    console.log("🚀 ~ getTokenExpiredTime ~ error:", error);
    return 0;
  }
};

export const getTokenRemainingTime = async () => {
  const expiryTime = await getTokenExpiredTime();
  const now = Date.now() / 1000;

  const remainingSeconds = expiryTime - now;

  return remainingSeconds;
};

export const saveCookie = async (key: string, value: string) => {
  const { set } = await cookies();
  if (!set) return;

  set(key, value, {
    maxAge: 300,
  });
};

export const getCookie = async (key: string) => {
  const { get } = await cookies();
  if (!get) return;

  return get(key)?.value ?? null;
};
