import { rejectionErrorFns } from "../errors"
import jwtVerifyCatch from "../jwtVerifyCatch"
import logging from "../logging"
import type { IdToken, RawToken } from "./createTokenDB"
import sendError, { API } from "./sendError"
import jwt from "jsonwebtoken"

async function decodeToken<T>(context: API<T>, rawToken: RawToken) {
  const { value, type } = rawToken

  // Verify the token and get the payload
  let data: string | jwt.JwtPayload
  try {
    data = jwt.verify(value, process.env.TOKEN_SECRET as string)
  } catch (err: any) {
    // Deal with the problem in more detail
    logging(jwtVerifyCatch(type, err).message, ["error"])
    const fallbackData = jwt.decode(value)
    // Making sure the token data is not a string (because it should be an object)
    if (typeof fallbackData === "string")
      throw sendError(context, rejectionErrorFns.tokenWasString(type, value))
    return { id: fallbackData?.id, type }
  }
  // Making sure the token data is not a string (because it should be an object)
  if (typeof data === "string")
    throw sendError(context, rejectionErrorFns.tokenWasString(type, value))

  return { id: data.id, type }
}

export default decodeToken
