import { z } from "zod"

export type VerifyOtpResponseError = "OTP_EXPIRED" | "WRONG_OTP" | "UNKNOWN"

const VerifyOtpGeneralError = z.enum(["AUTH_TOKEN_NOT_FOUND", "UNKNOWN"])
export type VerifyOtpGeneralError = z.infer<typeof VerifyOtpGeneralError>

export type VerifyOtpError = {
  errorCode: VerifyOtpResponseError | VerifyOtpGeneralError
}
export function parseSASVerifyOtpError(
  error: SasOtpVerifyError | {}
): VerifyOtpError {
  const parseResult = sasOtpVerifyErrorSchema.safeParse(error)
  if (!parseResult.success) {
    const generalErrorResult = VerifyOtpGeneralError.safeParse(error)
    if (!generalErrorResult.success) {
      return {
        errorCode: "UNKNOWN",
      }
    }

    return {
      errorCode: generalErrorResult.data,
    }
  }

  return {
    errorCode: getErrorCodeByNumber(parseResult.data.errorCode),
  }
}

const SAS_VERIFY_OTP_ERROR_CODES: {
  [key in Exclude<VerifyOtpResponseError, "UNKNOWN">]: number
} = {
  OTP_EXPIRED: 1,
  WRONG_OTP: 2,
}

const getErrorCodeByNumber = (number: number): VerifyOtpResponseError => {
  const v =
    Object.entries(SAS_VERIFY_OTP_ERROR_CODES).find(
      ([_, value]) => value === number
    )?.[0] ?? "UNKNOWN"

  return v as VerifyOtpResponseError
}

const sasOtpVerifyErrorSchema = z.object({
  status: z.string(),
  otpExpiration: z.string().datetime(),
  error: z.string(),
  errorCode: z.number(),
  databaseUUID: z.string().uuid(),
})

export type SasOtpVerifyError = z.infer<typeof sasOtpVerifyErrorSchema>
