/*
 * st_settle_dbio.pgc - 정산 상세/지급/가맹점 집계 DB 접근 (libstdbio.a).
 * ECPG 함수; 호출자의 XA 브랜치에서 수행. EXEC SQL CONNECT 없음.
 */
#include <string.h>
#include <userlog.h>
#include "st_dbio.h"

long stdb_insert_fee_dtl(long sid, long pid, const char *merch,
                         const char *fee_type, long amount, const char *bizdate)
{
    EXEC SQL BEGIN DECLARE SECTION;
    long h_id, h_sid = sid, h_pid = pid, h_amt = amount;
    char h_merch[64], h_type[16], 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_type, fee_type, sizeof(h_type) - 1);      h_type[sizeof(h_type)-1] = 0;
    strncpy(h_bizdate, bizdate, sizeof(h_bizdate) - 1); h_bizdate[sizeof(h_bizdate)-1] = 0;

    EXEC SQL SELECT nextval('st_dtl_seq') INTO :h_id;
    if (sqlca.sqlcode < 0) return -1;

    EXEC SQL INSERT INTO st_settle_dtl
        (dtl_id, settlement_id, purchase_id, merchant_id, fee_type, amount, biz_date)
        VALUES (:h_id, :h_sid, :h_pid, :h_merch, :h_type, :h_amt, :h_bizdate);
    if (sqlca.sqlcode < 0) {
        userlog("stdb_insert_fee_dtl FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
        return -1;
    }
    return h_id;
}

long stdb_insert_payment(const char *merch, long net, const char *paydate,
                         const char *status, const char *bizdate)
{
    EXEC SQL BEGIN DECLARE SECTION;
    long h_id, h_net = net;
    char h_merch[64], h_paydate[16], h_status[16], 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_paydate, paydate, sizeof(h_paydate) - 1); h_paydate[sizeof(h_paydate)-1] = 0;
    strncpy(h_status, status, sizeof(h_status) - 1);    h_status[sizeof(h_status)-1] = 0;
    strncpy(h_bizdate, bizdate, sizeof(h_bizdate) - 1); h_bizdate[sizeof(h_bizdate)-1] = 0;

    EXEC SQL SELECT nextval('st_pay_seq') INTO :h_id;
    if (sqlca.sqlcode < 0) return -1;

    EXEC SQL INSERT INTO st_payment (pay_id, merchant_id, net_amount, pay_date, status, biz_date)
        VALUES (:h_id, :h_merch, :h_net, :h_paydate, :h_status, :h_bizdate);
    if (sqlca.sqlcode < 0) {
        userlog("stdb_insert_payment FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
        return -1;
    }
    return h_id;
}

int stdb_update_payment_status(const char *merch, const char *from_status,
                               const char *to_status, const char *bizdate)
{
    EXEC SQL BEGIN DECLARE SECTION;
    char h_merch[64], h_from[16], h_to[16], 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_from, from_status, sizeof(h_from) - 1);   h_from[sizeof(h_from)-1] = 0;
    strncpy(h_to, to_status, sizeof(h_to) - 1);         h_to[sizeof(h_to)-1] = 0;
    strncpy(h_bizdate, bizdate, sizeof(h_bizdate) - 1); h_bizdate[sizeof(h_bizdate)-1] = 0;

    EXEC SQL UPDATE st_payment SET status = :h_to
        WHERE merchant_id = :h_merch AND status = :h_from AND biz_date = :h_bizdate;
    if (sqlca.sqlcode < 0) {
        userlog("stdb_update_payment_status FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
        return -1;
    }
    return 0;
}

int stdb_upsert_merch_settle(const char *merch, const char *bizdate, long gross,
                             long fee, long net, long cnt)
{
    EXEC SQL BEGIN DECLARE SECTION;
    long h_gross = gross, h_fee = fee, h_net = net, h_cnt = cnt;
    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 st_merch_settle
        (merchant_id, biz_date, txn_count, gross_amount, fee_amount, net_amount)
        VALUES (:h_merch, :h_bizdate, :h_cnt, :h_gross, :h_fee, :h_net)
        ON CONFLICT (merchant_id, biz_date) DO UPDATE
        SET txn_count = st_merch_settle.txn_count + EXCLUDED.txn_count,
            gross_amount = st_merch_settle.gross_amount + EXCLUDED.gross_amount,
            fee_amount = st_merch_settle.fee_amount + EXCLUDED.fee_amount,
            net_amount = st_merch_settle.net_amount + EXCLUDED.net_amount,
            updated_at = now();
    if (sqlca.sqlcode < 0) {
        userlog("stdb_upsert_merch_settle FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
        return -1;
    }
    return 0;
}
