/*
 * ACQ_DISPUTE_OPEN.pgc - ac 모듈 서비스 ACQ_DISPUTE_OPEN (one service = one file).
 * 채그백/분쟁 개시: 매입 원장을 확인하고 ac_dispute 에 FIRST_CB/OPEN 분쟁행을 만든다.
 * 분쟁금액은 매입금액, reason_code 는 카드망 분쟁코드(10.4 사기 / 13.1 상품미수취 /
 * 12.6 중복 ...)를 그대로 적재하고 사기·상품·중복 등급(tier)으로 분류한다.
 * 입출력 계약: 입력 T_PURCHASE_ID + T_STR1(reason_code)[+ T_AMOUNT/T_MERCHANT/T_BIZDATE],
 *             출력 T_ID1(dispute_id) / T_STATUS='FIRST_CB'.
 * Runs on the caller's XA branch (no EXEC SQL CONNECT). Advertised by ac_svr.
 */
#include "ACQ_DISPUTE_OPEN.h"

void ACQ_DISPUTE_OPEN(TPSVCINFO *p)
{
    UBFH *b = (UBFH *)p->data;
    const char *SVC = "ACQ_DISPUTE_OPEN";
    char bizdate[16], reason[64], memo[256], logmsg[256];
    long tier = 0;
    EXEC SQL BEGIN DECLARE SECTION;
    long h_pid, h_amt, h_did, h_logid, h_dup, h_cnt, h_merchcb;
    char h_bizdate[16], h_reason[64], h_merch[64], h_pstat[16];
    char h_memo[256], h_logmsg[256];
    EXEC SQL END DECLARE SECTION;

    /* 지역/호스트 변수 초기화 (DECLARE SECTION 밖) */
    h_pid = h_amt = h_did = h_logid = h_dup = h_cnt = h_merchcb = 0;
    bizdate[0] = reason[0] = memo[0] = logmsg[0] = 0;
    h_bizdate[0] = h_reason[0] = 0;
    strcpy(h_merch, "UNKNOWN"); strcpy(h_pstat, "S");
    userlog("%s 진입: 분쟁/채그백 개시 요청", SVC);

    /* [1] 입력 검증부 -------------------------------------------------- */
    h_pid = getl(b, T_PURCHASE_ID);
    if (h_pid <= 0) {
        Bchg(b, T_MSG, 0, "매입 ID 오류", 0L); setl(b, T_RC, 7201); FAIL(b);
    }
    gets_(b, T_STR1, reason, sizeof(reason));
    if (reason[0] == 0) strcpy(reason, "13.1");   /* 기본: 13.1 상품미수취 */
    strncpy(h_reason, reason, sizeof(h_reason)-1); h_reason[sizeof(h_reason)-1] = 0;
    gets_(b, T_BIZDATE, bizdate, sizeof(bizdate));
    strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
    if (h_bizdate[0] == 0) {
        EXEC SQL SELECT param_val INTO :h_bizdate FROM cm_param WHERE param_key = 'BIZ_DATE';
        if (sqlca.sqlcode != 0) strcpy(h_bizdate, "2026-07-19");
    }

    /* [2] 마스터/상태 조회부 (XA 격리: 미커밋이면 전문값 사용, 100 을 FAIL 로 다루지 않음) */
    EXEC SQL SELECT amount, merchant_id, status INTO :h_amt, :h_merch, :h_pstat
        FROM purchase WHERE purchase_id = :h_pid;
    if (sqlca.sqlcode < 0) {
        userlog("%s: 매입원장 조회 실패 [%d] %s", SVC, sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
        setl(b, T_RC, 90); FAIL(b);
    }
    if (sqlca.sqlcode == 100) {
        /* 체인 내 신규 매입(미커밋): 요청 전문에 실린 값으로 진행 */
        h_amt = getl(b, T_AMOUNT);
        gets_(b, T_MERCHANT, h_merch, sizeof(h_merch));
        if (h_merch[0] == 0) strcpy(h_merch, "UNKNOWN");
        strcpy(h_pstat, "S");
        userlog("%s: 매입 미커밋(체인) pid=%ld — 전문값 사용", SVC, h_pid);
    }
    if (h_amt <= 0) h_amt = getl(b, T_AMOUNT);
    if (h_amt <= 0) {
        Bchg(b, T_MSG, 0, "분쟁 금액 산정 불가", 0L); setl(b, T_RC, 7202); FAIL(b);
    }
    userlog("%s 컨텍스트: pid=%ld merch=%s 상태=%s 금액=%ld reason=%s",
            SVC, h_pid, h_merch, h_pstat, h_amt, h_reason);

    /* [3] 업무규칙 분기부: 중복 분쟁 방지 + reason 등급 분류 -------------- */
    EXEC SQL SELECT count(*) INTO :h_dup FROM ac_dispute
        WHERE purchase_id = :h_pid AND status = 'OPEN';
    if (sqlca.sqlcode < 0) { setl(b, T_RC, 90); FAIL(b); }
    if (h_dup > 0) {
        userlog("%s 거절: 이미 진행중인 분쟁 존재 pid=%ld", SVC, h_pid);
        Bchg(b, T_MSG, 0, "이미 진행중인 분쟁 존재", 0L); setl(b, T_RC, 7203); FAIL(b);
    }
    /* 무효/취소된 매입은 분쟁 개시 자체가 성립하지 않는다 */
    if (strcmp(h_pstat, "V") == 0) {
        Bchg(b, T_MSG, 0, "무효 매입은 분쟁 불가", 0L); setl(b, T_RC, 7204); FAIL(b);
    }
    /* reason 등급: 사기(10.x)=3 최우선, 상품(13.x)=2, 중복(12.x)=1, 그 외=0 */
    if      (strncmp(h_reason, "10.", 3) == 0) tier = 3;
    else if (strncmp(h_reason, "13.", 3) == 0) tier = 2;
    else if (strncmp(h_reason, "12.", 3) == 0) tier = 1;
    else                                        tier = 0;

    /* [4] 본처리부: dispute INSERT (FIRST_CB / OPEN) --------------------- */
    EXEC SQL SELECT nextval('ac_dispute_seq') INTO :h_did;
    if (sqlca.sqlcode < 0) { setl(b, T_RC, 90); FAIL(b); }
    snprintf(memo, sizeof(memo), "채그백 개시 pid=%ld reason=%s tier=%ld bizdate=%s",
             h_pid, h_reason, tier, h_bizdate);
    strncpy(h_memo, memo, sizeof(h_memo)-1); h_memo[sizeof(h_memo)-1] = 0;
    EXEC SQL INSERT INTO ac_dispute
        (dispute_id, purchase_id, merchant_id, reason_code, amount, stage, status, memo)
        VALUES (:h_did, :h_pid, :h_merch, :h_reason, :h_amt, 'FIRST_CB', 'OPEN', :h_memo);
    if (sqlca.sqlcode < 0) {
        userlog("%s: 분쟁행 적재 실패 [%d] %s", SVC, sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
        setl(b, T_RC, 90); FAIL(b);
    }

    /* [5] 이력/감사 적재부 (cm_log) ------------------------------------- */
    snprintf(logmsg, sizeof(logmsg), "분쟁개시 did=%ld pid=%ld reason=%s amt=%ld tier=%ld",
             h_did, h_pid, h_reason, h_amt, tier);
    strncpy(h_logmsg, logmsg, sizeof(h_logmsg)-1); h_logmsg[sizeof(h_logmsg)-1] = 0;
    EXEC SQL SELECT nextval('cm_log_seq') INTO :h_logid;
    if (sqlca.sqlcode < 0) { setl(b, T_RC, 90); FAIL(b); }
    EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
        VALUES (:h_logid, 'ACQ_DISPUTE_OPEN', 'I', :h_logmsg, :h_bizdate);
    if (sqlca.sqlcode < 0) { setl(b, T_RC, 90); FAIL(b); }

    /* [6] 집계/요약 갱신부: 가맹점 진행중 분쟁 수 + LOST 확정 채그백 누계 ---- */
    EXEC SQL SELECT count(*) INTO :h_cnt FROM ac_dispute
        WHERE merchant_id = :h_merch AND status = 'OPEN';
    if (sqlca.sqlcode < 0) { setl(b, T_RC, 90); FAIL(b); }
    EXEC SQL SELECT coalesce(sum(amount),0) INTO :h_merchcb FROM ac_dispute
        WHERE merchant_id = :h_merch AND status = 'LOST';
    if (sqlca.sqlcode < 0) { setl(b, T_RC, 90); FAIL(b); }
    userlog("%s 집계: merch=%s 진행중=%ld LOST누계=%ld", SVC, h_merch, h_cnt, h_merchcb);

    /* [7] 응답부 (계약 보존: T_ID1=dispute_id / T_STATUS='FIRST_CB') ------ */
    setl(b, T_ID1, h_did);
    Bchg(b, T_STATUS, 0, "FIRST_CB", 0L);
    setl(b, T_PURCHASE_ID, h_pid);
    setl(b, T_AMOUNT, h_amt);
    Bchg(b, T_MERCHANT, 0, h_merch, 0L);
    Bchg(b, T_STR1, 0, h_reason, 0L);
    Bchg(b, T_BIZDATE, 0, h_bizdate, 0L);
    setl(b, T_ARG1, tier);
    setl(b, T_COUNT, h_cnt);
    setl(b, T_GROSS, h_merchcb);
    Bchg(b, T_MSG, 0, "분쟁 개시(FIRST_CB/OPEN)", 0L);
    setl(b, T_RC, 0);
    userlog("%s 완료: did=%ld pid=%ld amt=%ld tier=%ld", SVC, h_did, h_pid, h_amt, tier);
    OK(b);
}

/* vim: set ts=4 sw=4 et smartindent: */
