/*
 * au_limit_dbio.pgc - 카드 한도(card_limit) + 승인 일집계 DB 접근 (libaudbio.a).
 */
#include <string.h>
#include <userlog.h>
#include "au_dbio.h"

int audb_limit_get(const char *card, long *limit_out, long *used_out)
{
    EXEC SQL BEGIN DECLARE SECTION;
    long h_limit, h_used;
    char h_card[24];
    EXEC SQL END DECLARE SECTION;

    strncpy(h_card, card, sizeof(h_card) - 1); h_card[sizeof(h_card)-1] = 0;

    EXEC SQL SELECT daily_limit, used_amount INTO :h_limit, :h_used
        FROM card_limit WHERE card_no = :h_card;
    if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) {
        userlog("audb_limit_get FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
        return -1;
    }
    *limit_out = h_limit;
    *used_out = h_used;
    return 0;
}

int audb_limit_dec(const char *card, long amount)
{
    EXEC SQL BEGIN DECLARE SECTION;
    long h_amount = amount;
    char h_card[24];
    EXEC SQL END DECLARE SECTION;

    strncpy(h_card, card, sizeof(h_card) - 1); h_card[sizeof(h_card)-1] = 0;

    EXEC SQL UPDATE card_limit SET used_amount = used_amount + :h_amount, updated_at = now()
        WHERE card_no = :h_card;
    if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) {
        userlog("audb_limit_dec FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
        return -1;
    }
    return 0;
}

int audb_limit_reset(const char *card)
{
    EXEC SQL BEGIN DECLARE SECTION;
    char h_card[24];
    EXEC SQL END DECLARE SECTION;

    strncpy(h_card, card, sizeof(h_card) - 1); h_card[sizeof(h_card)-1] = 0;

    EXEC SQL UPDATE card_limit SET used_amount = 0, updated_at = now()
        WHERE card_no = :h_card;
    if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) {
        userlog("audb_limit_reset FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
        return -1;
    }
    return 0;
}

int audb_limit_set(const char *card, long limit)
{
    EXEC SQL BEGIN DECLARE SECTION;
    long h_limit = limit;
    char h_card[24];
    EXEC SQL END DECLARE SECTION;

    strncpy(h_card, card, sizeof(h_card) - 1); h_card[sizeof(h_card)-1] = 0;

    EXEC SQL INSERT INTO card_limit (card_no, daily_limit, used_amount)
        VALUES (:h_card, :h_limit, 0)
        ON CONFLICT (card_no) DO UPDATE
        SET daily_limit = EXCLUDED.daily_limit, updated_at = now();
    if (sqlca.sqlcode < 0) {
        userlog("audb_limit_set FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
        return -1;
    }
    return 0;
}

int audb_upsert_auth_summary(const char *merch, const char *bizdate, long cnt,
                             long approved, long declined, long amount)
{
    EXEC SQL BEGIN DECLARE SECTION;
    long h_cnt = cnt, h_appr = approved, h_dec = declined, h_amt = amount;
    char h_merch[64], h_bizdate[16];
    EXEC SQL END DECLARE SECTION;

    strncpy(h_merch, merch, sizeof(h_merch) - 1);       h_merch[sizeof(h_merch)-1] = 0;
    strncpy(h_bizdate, bizdate, sizeof(h_bizdate) - 1); h_bizdate[sizeof(h_bizdate)-1] = 0;

    EXEC SQL INSERT INTO au_summary
        (merchant_id, biz_date, auth_count, approve_count, decline_count, auth_amount)
        VALUES (:h_merch, :h_bizdate, :h_cnt, :h_appr, :h_dec, :h_amt)
        ON CONFLICT (merchant_id, biz_date) DO UPDATE
        SET auth_count = au_summary.auth_count + EXCLUDED.auth_count,
            approve_count = au_summary.approve_count + EXCLUDED.approve_count,
            decline_count = au_summary.decline_count + EXCLUDED.decline_count,
            auth_amount = au_summary.auth_amount + EXCLUDED.auth_amount,
            updated_at = now();
    if (sqlca.sqlcode < 0) {
        userlog("audb_upsert_auth_summary FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
        return -1;
    }
    return 0;
}
