-module(db@db).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).

-export([select_last_id/2, select/3, insert/3, connect/1]).
-export_type([select_last_id_error/0]).

-type select_last_id_error() :: {db_err, binary()} | empty_table.

-spec select_last_id(sqlight:connection(), binary()) -> {ok, integer()} |
    {error, select_last_id_error()}.
select_last_id(Conn, Table) ->
    Query = <<"SELECT MAX(id) FROM "/utf8, Table/binary>>,
    Res = sqlight:'query'(
        Query,
        Conn,
        [],
        gleam@dynamic:element(0, fun gleam@dynamic:int/1)
    ),
    case begin
        _pipe = Res,
        gleam@io:debug(_pipe)
    end of
        {ok, [Id | _]} ->
            {ok, Id};

        {ok, []} ->
            _pipe@1 = empty_table,
            {error, _pipe@1};

        {error, E} ->
            _pipe@2 = erlang:element(3, E),
            _pipe@3 = {db_err, _pipe@2},
            {error, _pipe@3}
    end.

-spec params_to_sqlite(list(cake@param:param())) -> list(sqlight:value()).
params_to_sqlite(Params) ->
    _pipe = Params,
    gleam@list:map(_pipe, fun(Param) -> case Param of
                {bool_param, Param@1} ->
                    sqlight:bool(Param@1);

                {float_param, Param@2} ->
                    sqlight:float(Param@2);

                {int_param, Param@3} ->
                    sqlight:int(Param@3);

                {string_param, Param@4} ->
                    sqlight:text(Param@4);

                null_param ->
                    sqlight_ffi:null()
            end end).

-spec select(
    sqlight:connection(),
    cake@internal@read_query:read_query(),
    fun((gleam@dynamic:dynamic_()) -> {ok, BEU} |
        {error, list(gleam@dynamic:decode_error())})
) -> {ok, list(BEU)} | {error, sqlight:error()}.
select(Conn, Query, Decoder) ->
    Statement = begin
        _pipe = Query,
        cake@dialect@sqlite_dialect:query_to_prepared_statement(_pipe)
    end,
    Sql = begin
        _pipe@1 = Statement,
        _pipe@2 = cake:get_sql(_pipe@1),
        gleam@io:debug(_pipe@2)
    end,
    Params = begin
        _pipe@3 = Statement,
        _pipe@4 = cake:get_params(_pipe@3),
        params_to_sqlite(_pipe@4)
    end,
    sqlight:'query'(Sql, Conn, Params, Decoder).

-spec insert(
    sqlight:connection(),
    cake@internal@write_query:write_query(BFB),
    fun((gleam@dynamic:dynamic_()) -> {ok, BFB} |
        {error, list(gleam@dynamic:decode_error())})
) -> {ok, nil} | {error, sqlight:error()}.
insert(Conn, Query, Decoder) ->
    Statement = begin
        _pipe = Query,
        cake@dialect@sqlite_dialect:write_query_to_prepared_statement(_pipe)
    end,
    Sql = begin
        _pipe@1 = Statement,
        _pipe@2 = cake:get_sql(_pipe@1),
        gleam@io:debug(_pipe@2)
    end,
    Params = begin
        _pipe@3 = Statement,
        _pipe@4 = cake:get_params(_pipe@3),
        params_to_sqlite(_pipe@4)
    end,
    gleam@result:'try'(
        sqlight:'query'(Sql, Conn, Params, Decoder),
        fun(_) -> {ok, nil} end
    ).

-spec connect(fun((sqlight:connection()) -> BHJ)) -> BHJ.
connect(Callback) ->
    sqlight:with_connection(
        <<"temp_ting.db"/utf8>>,
        fun(Conn) -> Callback(Conn) end
    ).
