export const ERROR_CODES = {
    API_ERROR: "API_ERROR",
    EXTERNAL_API_ERROR: "EXTERNAL_API_ERROR",
    RATE_LIMIT_ERROR: "RATE_LIMIT_ERROR",
    DATABASE_ERROR: "DATABASE_ERROR",
    NETWORK_ERROR: "NETWORK_ERROR",
    BANNED: "BANNED",
    AUTH_ERROR: "AUTH_ERROR",
    PERMISSION_ERROR: "PERMISSION_ERROR",
    VALIDATION_ERROR: "VALIDATION_ERROR",
    UNKNOWN_ERROR: "UNKNOWN_ERROR",
    NOT_FOUND_ERROR: "NOT_FOUND_ERROR",
    NOT_FOUND: "NOT_FOUND",
    INPUT_ERROR: "INPUT_ERROR",
    INTERNAL_SERVER_ERROR: "INTERNAL_SERVER_ERROR",
    EXTERNAL_SERVICE_ERROR: "EXTERNAL_SERVICE_ERROR",
    FILE_SYSTEM_ERROR: "FILE_SYSTEM_ERROR",
    STORAGE_ERROR: "STORAGE_ERROR",
    NOT_ALLOWED: "NOT_ALLOWED",
    NOT_IMPLEMENTED: "NOT_IMPLEMENTED",
    PROCESSING_ERROR: "PROCESSING_ERROR",
    PARSING_ERROR: "PARSING_ERROR",
} as const;

export const errorStatusMap = {
    [ERROR_CODES.VALIDATION_ERROR]: 400,
    [ERROR_CODES.AUTH_ERROR]: 403,
    [ERROR_CODES.BANNED]: 403,
    [ERROR_CODES.NOT_FOUND]: 404,
    [ERROR_CODES.NOT_ALLOWED]: 405,
    [ERROR_CODES.RATE_LIMIT_ERROR]: 429,
    [ERROR_CODES.DATABASE_ERROR]: 500,
    [ERROR_CODES.NETWORK_ERROR]: 500,
    [ERROR_CODES.EXTERNAL_API_ERROR]: 500,
    [ERROR_CODES.API_ERROR]: 500,
    [ERROR_CODES.INTERNAL_SERVER_ERROR]: 500,
    [ERROR_CODES.EXTERNAL_SERVICE_ERROR]: 500,
    [ERROR_CODES.FILE_SYSTEM_ERROR]: 500,
    [ERROR_CODES.STORAGE_ERROR]: 500,
    [ERROR_CODES.PROCESSING_ERROR]: 500,
    [ERROR_CODES.PARSING_ERROR]: 500,
    [ERROR_CODES.NOT_IMPLEMENTED]: 501,
} as Record<string, number>;

export type Err = {
    flowId?: string;
    code: string;
    message: string;
    description: string;
    detail: string;
    actionable?: boolean;
    error?: any;
};

type Success<T> = { data: T; error?: undefined | null };
type Failure<E> = { data?: undefined | null; error: E };

// Legacy now, making use of Effect throughout the project
export type Result<T, E = Err> = Success<T> | Failure<E>;

export async function tryCatch<T, E = Err>(
    promise: Promise<T>,
    err?: E,
): Promise<Result<T, E>> {
    try {
        const data = await promise;
        return { data };
    } catch (e) {
        return {
            // @ts-ignore
            error: !!err
                ? err
                : {
                      code: "UNKNOWN_ERROR",
                      message: "An unknown error occurred",
                      description: "An unknown error occurred",
                      detail: "An unknown error occurred",
                  },
        };
    }
}
