-- Card-acquiring schema (카드 매입/승인/정산/원장 + ac 모듈 상세 테이블)
-- Loaded into PostgreSQL on first boot (docker-entrypoint-initdb.d).

-- ---------------------------------------------------------------------------
-- 가맹점 (merchant)
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS merchant (
    merchant_id  TEXT PRIMARY KEY,
    name         TEXT NOT NULL,
    mdr_bps      INTEGER NOT NULL DEFAULT 25,   -- Merchant Discount Rate, basis points (0.25%)
    daily_limit  BIGINT  NOT NULL DEFAULT 100000000,
    status       TEXT NOT NULL DEFAULT 'ACTIVE',
    created_at   TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- ---------------------------------------------------------------------------
-- 매입 (purchase) - the acquiring transaction
-- ---------------------------------------------------------------------------
CREATE SEQUENCE IF NOT EXISTS purchase_seq;
CREATE TABLE IF NOT EXISTS purchase (
    purchase_id  BIGINT PRIMARY KEY,
    merchant_id  TEXT NOT NULL,
    amount       BIGINT NOT NULL,              -- minor units (원, 정수)
    fee          BIGINT NOT NULL,              -- MDR fee
    net          BIGINT NOT NULL,              -- amount - fee
    status       TEXT NOT NULL,                -- A=접수, M=대사완료, S=정산완료, C=취소, H=보류, V=void
    biz_date     DATE NOT NULL,
    channel      TEXT NOT NULL DEFAULT 'POS',  -- POS/EDC/EDI/FOREIGN
    issuer       TEXT NOT NULL DEFAULT 'UNKNOWN',
    category     TEXT NOT NULL DEFAULT 'GEN',
    created_at   TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at   TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- ---------------------------------------------------------------------------
-- 승인 (approval)
-- ---------------------------------------------------------------------------
CREATE SEQUENCE IF NOT EXISTS approval_seq;
CREATE TABLE IF NOT EXISTS approval (
    approval_id  BIGINT PRIMARY KEY,
    purchase_id  BIGINT NOT NULL,
    approved     BOOLEAN NOT NULL DEFAULT true,
    approved_at  TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- ---------------------------------------------------------------------------
-- 원장 (ledger) - recon/settle entries
-- ---------------------------------------------------------------------------
CREATE SEQUENCE IF NOT EXISTS ledger_seq;
CREATE TABLE IF NOT EXISTS ledger (
    ledger_id    BIGINT PRIMARY KEY,
    purchase_id  BIGINT NOT NULL,
    entry_type   TEXT NOT NULL,                -- RECON / SETTLE / XFER / SETTLELINK
    amount       BIGINT NOT NULL,
    biz_date     DATE NOT NULL,
    created_at   TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- ---------------------------------------------------------------------------
-- 정산 (settlement) - netting written during 정산
-- ---------------------------------------------------------------------------
CREATE SEQUENCE IF NOT EXISTS settlement_seq;
CREATE TABLE IF NOT EXISTS settlement (
    settlement_id BIGINT PRIMARY KEY,
    purchase_id   BIGINT NOT NULL,
    merchant_id   TEXT NOT NULL,
    net           BIGINT NOT NULL,
    biz_date      DATE NOT NULL,
    status        TEXT NOT NULL DEFAULT 'SETTLED',
    settled_at    TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- ---------------------------------------------------------------------------
-- ac 모듈 상세 테이블 (취소/할부/수수료조정/원천/세금계산서/해외/EDI/미매입/집계)
-- ---------------------------------------------------------------------------
CREATE SEQUENCE IF NOT EXISTS ac_cancel_seq;
CREATE TABLE IF NOT EXISTS ac_cancel (
    cancel_id    BIGINT PRIMARY KEY,
    purchase_id  BIGINT NOT NULL,
    cancel_type  TEXT NOT NULL,                -- FULL / PARTIAL / REFUND / VOID
    amount       BIGINT NOT NULL,
    reason       TEXT NOT NULL DEFAULT '',
    biz_date     DATE NOT NULL,
    created_at   TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE SEQUENCE IF NOT EXISTS ac_install_seq;
CREATE TABLE IF NOT EXISTS ac_install (
    install_id   BIGINT PRIMARY KEY,
    purchase_id  BIGINT NOT NULL,
    seq_no       INTEGER NOT NULL,
    months       INTEGER NOT NULL,
    month_amount BIGINT NOT NULL,
    biz_date     DATE NOT NULL
);

CREATE SEQUENCE IF NOT EXISTS ac_feeadj_seq;
CREATE TABLE IF NOT EXISTS ac_fee_adj (
    adj_id       BIGINT PRIMARY KEY,
    purchase_id  BIGINT NOT NULL,
    delta        BIGINT NOT NULL,
    reason       TEXT NOT NULL DEFAULT '',
    biz_date     DATE NOT NULL,
    created_at   TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE SEQUENCE IF NOT EXISTS ac_wht_seq;
CREATE TABLE IF NOT EXISTS ac_wht (
    wht_id       BIGINT PRIMARY KEY,
    purchase_id  BIGINT NOT NULL,
    tax_amount   BIGINT NOT NULL,
    biz_date     DATE NOT NULL
);

CREATE SEQUENCE IF NOT EXISTS ac_taxinv_seq;
CREATE TABLE IF NOT EXISTS ac_tax_invoice (
    inv_id       BIGINT PRIMARY KEY,
    purchase_id  BIGINT NOT NULL,
    merchant_id  TEXT NOT NULL,
    supply       BIGINT NOT NULL,
    vat          BIGINT NOT NULL,
    biz_date     DATE NOT NULL
);

CREATE SEQUENCE IF NOT EXISTS ac_fx_seq;
CREATE TABLE IF NOT EXISTS ac_fx (
    fx_id        BIGINT PRIMARY KEY,
    purchase_id  BIGINT NOT NULL,
    ccy          TEXT NOT NULL,
    fx_amount    BIGINT NOT NULL,
    krw_amount   BIGINT NOT NULL,
    rate_bps     BIGINT NOT NULL,
    biz_date     DATE NOT NULL
);

CREATE SEQUENCE IF NOT EXISTS ac_edi_seq;
CREATE TABLE IF NOT EXISTS ac_edi (
    edi_id       BIGINT PRIMARY KEY,
    merchant_id  TEXT NOT NULL,
    doc_no       TEXT NOT NULL,
    amount       BIGINT NOT NULL,
    biz_date     DATE NOT NULL
);

CREATE SEQUENCE IF NOT EXISTS ac_unmatch_seq;
CREATE TABLE IF NOT EXISTS ac_unmatch (
    unmatch_id   BIGINT PRIMARY KEY,
    purchase_id  BIGINT NOT NULL,
    reason       TEXT NOT NULL,
    biz_date     DATE NOT NULL
);

-- 가맹점 일별 집계 (배치가 채움)
CREATE TABLE IF NOT EXISTS merchant_summary (
    merchant_id  TEXT NOT NULL,
    biz_date     DATE NOT NULL,
    txn_count    BIGINT NOT NULL DEFAULT 0,
    gross_amount BIGINT NOT NULL DEFAULT 0,
    fee_amount   BIGINT NOT NULL DEFAULT 0,
    net_amount   BIGINT NOT NULL DEFAULT 0,
    updated_at   TIMESTAMPTZ NOT NULL DEFAULT now(),
    PRIMARY KEY (merchant_id, biz_date)
);

-- Seed merchants so ACQUIRE has a valid counterparty.
INSERT INTO merchant (merchant_id, name, mdr_bps, daily_limit) VALUES
    ('M0001', '클라로 커피', 25, 100000000),
    ('M0002', '포지 마트',   25, 100000000),
    ('M0003', '클라로 면세점', 30, 500000000)
ON CONFLICT (merchant_id) DO NOTHING;
