import {
    InferSchemaType,
    LiteralSchema,
    ObjectSchema,
    Schema,
    StringSchema,
    z,
} from "@shared/utils/validator.ts";

type ErrorDefinition<T extends string, I extends Schema<any>> = ObjectSchema<
    { type: LiteralSchema<T>; info: I }
>;

export function defineError<
    T extends string,
    I extends Schema<any> = StringSchema,
>(
    type: T,
    info?: I,
): ErrorDefinition<T, I> {
    return z.obj({
        type: z.literal(type),
        info: (info ?? z.string()) as I,
    });
}
export function createErrorFactory<
    T extends string,
    I extends Schema<any>,
>(
    errorDefinition: ErrorDefinition<T, I>,
): (info: InferSchemaType<I>) => InferSchemaType<ErrorDefinition<T, I>> {
    return (info: InferSchemaType<I>) => {
        return {
            type: errorDefinition.shape.type.literal,
            info,
        };
    };
}
