import { z } from "zod"

export type RequestOtpResponseError = "TOO_MANY_REQUESTS" | "UNKNOWN"

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

export type RequestOtpError = {
  errorCode: RequestOtpResponseError | RequestOtpGeneralError
}
export function parseSASRequestOtpError(
  error: SasOtpRequestError | {}
): RequestOtpError {
  const parseResult = sasOtpRequestErrorSchema.safeParse(error)
  if (!parseResult.success) {
    const generalErrorResult = requestOtpGeneralError.safeParse(error)
    if (!generalErrorResult.success) {
      return {
        errorCode: "UNKNOWN",
      }
    }

    return {
      errorCode: generalErrorResult.data,
    }
  }

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

const SAS_REQUEST_OTP_ERROR_CODES: {
  [key in Exclude<RequestOtpResponseError, "UNKNOWN">]: number
} = {
  TOO_MANY_REQUESTS: 10,
}

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

  console.log("[SAS] getErrorCodeByNumber", number, v)
  return v as RequestOtpResponseError
}

const sasOtpRequestErrorSchema = z.object({
  status: z.enum([
    "VERIFIED",
    "ABUSED",
    "EXPIRED",
    "PENDING",
    "RETRY",
    "SENT",
    "NULL",
    "NOTSENT",
  ]),
  otpExpiration: z.string().datetime(),
  error: z.string(),
  errorCode: z.number(),
  databaseUUID: z.string().uuid(),
})

export type SasOtpRequestError = z.infer<typeof sasOtpRequestErrorSchema>
