import { FlowExecCtx } from "@/core/flow.execution.context";
import { ERROR_CODES, type Err } from "@pkg/result";
import { getError } from "@pkg/logger";

export const twofaErrors = {
    dbError: (fctx: FlowExecCtx, detail: string): Err =>
        getError({
            flowId: fctx.flowId,
            code: ERROR_CODES.DATABASE_ERROR,
            message: "Database operation failed",
            description: "Please try again later",
            detail,
        }),

    alreadyEnabled: (fctx: FlowExecCtx): Err =>
        getError({
            flowId: fctx.flowId,
            code: ERROR_CODES.AUTH_ERROR,
            message: "2FA already enabled",
            description: "Disable it first if you want to re-enable it",
            detail: "2FA already enabled",
        }),

    notEnabled: (fctx: FlowExecCtx): Err =>
        getError({
            flowId: fctx.flowId,
            code: ERROR_CODES.AUTH_ERROR,
            message: "2FA not enabled for this user",
            description: "Enable 2FA to perform this action",
            detail: "2FA not enabled for this user",
        }),

    userNotFound: (fctx: FlowExecCtx): Err =>
        getError({
            flowId: fctx.flowId,
            code: ERROR_CODES.AUTH_ERROR,
            message: "User not found",
            description: "Session is invalid or expired",
            detail: "User ID not found in database",
        }),

    sessionNotActive: (fctx: FlowExecCtx): Err =>
        getError({
            flowId: fctx.flowId,
            code: ERROR_CODES.AUTH_ERROR,
            message: "Verification session is no longer active",
            description: "Please request a new verification code",
            detail: "Session status is not 'pending'",
        }),

    sessionExpired: (fctx: FlowExecCtx): Err =>
        getError({
            flowId: fctx.flowId,
            code: ERROR_CODES.AUTH_ERROR,
            message: "Verification session has expired",
            description: "Please request a new verification code",
            detail: "Session expired timestamp passed",
        }),

    sessionNotFound: (fctx: FlowExecCtx): Err =>
        getError({
            flowId: fctx.flowId,
            code: ERROR_CODES.NOT_FOUND,
            message: "Invalid or expired verification session",
            description: "Your verification session has expired or is invalid",
            detail: "Session not found by verification token",
        }),

    tooManyAttempts: (fctx: FlowExecCtx): Err =>
        getError({
            flowId: fctx.flowId,
            code: ERROR_CODES.BANNED,
            message: "Too many failed attempts",
            description:
                "Your account has been banned, contact us to resolve this issue",
            detail: "Max attempts reached for 2FA verification",
        }),

    codeReplay: (fctx: FlowExecCtx): Err =>
        getError({
            flowId: fctx.flowId,
            code: ERROR_CODES.AUTH_ERROR,
            message: "This code has already been used",
            description: "Please request a new verification code",
            detail: "Code replay attempt detected",
        }),

    invalidSetup: (fctx: FlowExecCtx): Err =>
        getError({
            flowId: fctx.flowId,
            code: ERROR_CODES.AUTH_ERROR,
            message: "Invalid 2FA setup found",
            description: "Please contact us to resolve this issue",
            detail: "Invalid 2FA data found",
        }),

    invalidCode: (fctx: FlowExecCtx): Err =>
        getError({
            flowId: fctx.flowId,
            code: ERROR_CODES.AUTH_ERROR,
            message: "Invalid verification code",
            description: "Please try again with the correct code",
            detail: "Code is invalid",
        }),

    notEnabledForVerification: (fctx: FlowExecCtx): Err =>
        getError({
            flowId: fctx.flowId,
            code: ERROR_CODES.AUTH_ERROR,
            message: "2FA not enabled for this user",
            description:
                "Two-factor authentication is not enabled on your account",
            detail: "User has 2FA disabled but verification attempted",
        }),

    revokeSessionsFailed: (fctx: FlowExecCtx): Err =>
        getError({
            flowId: fctx.flowId,
            code: ERROR_CODES.AUTH_ERROR,
            message: "Failed to revoke sessions",
            description: "Please try again later",
            detail: "Failed to revoke other sessions",
        }),

    // Repository errors
    notFound: (fctx: FlowExecCtx): Err =>
        getError({
            flowId: fctx.flowId,
            code: ERROR_CODES.NOT_FOUND,
            message: "2FA not found",
            description: "Likely not enabled, otherwise please contact us :)",
            detail: "2FA not found",
        }),

    setupNotFound: (fctx: FlowExecCtx): Err =>
        getError({
            flowId: fctx.flowId,
            code: ERROR_CODES.VALIDATION_ERROR,
            message: "Cannot perform action",
            description: "If 2FA is not enabled, please refresh and try again",
            detail: "2FA setup not found",
        }),

    maxAttemptsReached: (fctx: FlowExecCtx): Err =>
        getError({
            flowId: fctx.flowId,
            code: ERROR_CODES.AUTH_ERROR,
            message: "Too many failed attempts",
            description: "Please refresh and try again",
            detail: "Max attempts reached for session",
        }),

    backupCodesNotFound: (fctx: FlowExecCtx): Err =>
        getError({
            flowId: fctx.flowId,
            code: ERROR_CODES.NOT_FOUND,
            message: "2FA info not found",
            description: "Please setup 2FA or contact us if this is unexpected",
            detail: "2FA info not found for user",
        }),

    backupCodesAlreadyGenerated: (fctx: FlowExecCtx): Err =>
        getError({
            flowId: fctx.flowId,
            code: ERROR_CODES.AUTH_ERROR,
            message: "Backup codes already generated",
            description:
                "Can only generate if not already present, or all are used up",
            detail: "Backup codes already generated",
        }),

    sessionNotFoundById: (fctx: FlowExecCtx): Err =>
        getError({
            flowId: fctx.flowId,
            code: ERROR_CODES.NOT_FOUND,
            message: "2FA session not found",
            description: "The verification session may have expired",
            detail: "Session ID not found in database",
        }),
};
