import get from "../../actions/get";
import post from "../../actions/post";
import sqlGenerator from "../../functions/dsql/sql/sql-generator";
import { DsqlCrudParam, PostReturn } from "../../types";

export default async function dsqlCrud<
    T extends { [key: string]: any } = { [key: string]: any }
>({
    action,
    data,
    table,
    targetId,
    query,
    sanitize,
    debug,
}: DsqlCrudParam<T>): Promise<
    | (PostReturn & {
          queryObject?: ReturnType<Awaited<typeof sqlGenerator>>;
      })
    | null
> {
    const finalData = sanitize ? sanitize(data) : data;
    const finalId = targetId;
    let queryObject: ReturnType<Awaited<typeof sqlGenerator>> | undefined;

    switch (action) {
        case "get":
            queryObject = sqlGenerator({
                tableName: table,
                genObject: query,
            });

            const GET_RES = await get({
                query: queryObject?.string || "",
                queryValues: queryObject?.values || [],
                debug,
                forceLocal: true,
            });

            return { ...GET_RES, queryObject };

        case "insert":
            return await post({
                query: {
                    action: "insert",
                    table,
                    data: finalData,
                },
                forceLocal: true,
            });

        case "update":
            delete data?.id;

            return await post({
                query: {
                    action: "update",
                    table,
                    identifierColumnName: "id",
                    identifierValue: String(finalId),
                    data: finalData,
                },
                forceLocal: true,
            });

        case "delete":
            return await post({
                query: {
                    action: "delete",
                    table,
                    identifierColumnName: "id",
                    identifierValue: String(finalId),
                },
                forceLocal: true,
            });

        default:
            return null;
    }
}
