-- V43: 유지보수수당 (persistency_bonus_rule + persistency_bonus)
--      13/25/37/49개월 유지율 충족 시 1회 지급하는 유지보수수당.
--      등급별 정률(RATE) 또는 정액(FIXED) 지급.

-- ============================================================
-- 1. persistency_bonus_rule — 유지보수수당 룰 마스터
-- ============================================================

CREATE TABLE persistency_bonus_rule (
    rule_id                  BIGSERIAL    PRIMARY KEY,
    grade_id                 BIGINT       REFERENCES grade(grade_id),
    -- NULL이면 전 직급 공통 적용
    retention_month          INT          NOT NULL,
    -- 유지 기준 개월수 (13/25/37/49)
    retention_rate_threshold NUMERIC(5,4) NOT NULL,
    -- 유지율 하한 기준 (예: 0.95 = 95% 이상)
    bonus_type               VARCHAR(10)  NOT NULL,
    bonus_value              NUMERIC(15,4) NOT NULL,
    -- RATE: 모집수수료 대비 비율 / FIXED: 지급 고정액
    effective_from           DATE         NOT NULL,
    effective_to             DATE,
    created_at               TIMESTAMP    NOT NULL DEFAULT NOW(),
    created_by               BIGINT,
    updated_at               TIMESTAMP,
    CHECK (retention_month IN (13, 25, 37, 49)),
    CHECK (bonus_type IN ('RATE','FIXED')),
    CHECK (retention_rate_threshold > 0 AND retention_rate_threshold <= 1)
);

COMMENT ON TABLE  persistency_bonus_rule                         IS '유지보수수당 룰 마스터 — 직급/유지개월/유지율 임계치별 지급 기준';
COMMENT ON COLUMN persistency_bonus_rule.grade_id               IS '적용 직급 FK (NULL=전 직급 공통)';
COMMENT ON COLUMN persistency_bonus_rule.retention_month        IS '유지 기준 개월수 (13/25/37/49)';
COMMENT ON COLUMN persistency_bonus_rule.retention_rate_threshold IS '유지율 최소 기준 (0초과~1이하, 예: 0.95)';
COMMENT ON COLUMN persistency_bonus_rule.bonus_type             IS 'RATE=모집수수료 대비 비율 / FIXED=건당 고정금액';
COMMENT ON COLUMN persistency_bonus_rule.bonus_value            IS 'RATE 방식: 비율값 / FIXED 방식: 지급 금액';

CREATE INDEX idx_pbr_grade_month ON persistency_bonus_rule(grade_id, retention_month, effective_from);

-- ============================================================
-- 2. persistency_bonus — 유지보수수당 지급 이력
--    UNIQUE(agent_id, base_month, retention_month) — 동일 기준월·개월수 중복 방지
-- ============================================================

CREATE TABLE persistency_bonus (
    bonus_id          BIGSERIAL      PRIMARY KEY,
    agent_id          BIGINT         NOT NULL REFERENCES agent(agent_id),
    rule_id           BIGINT         REFERENCES persistency_bonus_rule(rule_id),
    base_month        CHAR(6)        NOT NULL,
    -- 계약 체결 기준 정산월 (YYYYMM)
    retention_month   INT            NOT NULL,
    -- 평가 기준 개월수 (13/25/37/49)
    settle_month      CHAR(6)        NOT NULL,
    -- 실제 지급 정산월
    retention_rate    NUMERIC(5,4)   NOT NULL,
    -- 실제 유지율
    bonus_amount      NUMERIC(15,2)  NOT NULL,
    status            VARCHAR(20)    NOT NULL DEFAULT 'CALCULATED',
    created_at        TIMESTAMP      NOT NULL DEFAULT NOW(),
    updated_at        TIMESTAMP,
    UNIQUE (agent_id, base_month, retention_month),
    CHECK (retention_month IN (13, 25, 37, 49)),
    CHECK (status IN ('CALCULATED','CONFIRMED','PAID','CANCELLED'))
);

COMMENT ON TABLE  persistency_bonus                IS '유지보수수당 지급 이력 — 유지율 충족 확인 후 1회 지급';
COMMENT ON COLUMN persistency_bonus.base_month     IS '계약 체결 기준 정산월 (YYYYMM) — 유지율 계산 기산점';
COMMENT ON COLUMN persistency_bonus.retention_month IS '평가 기준 개월수 (13/25/37/49)';
COMMENT ON COLUMN persistency_bonus.settle_month   IS '실제 지급 귀속 정산월 (YYYYMM)';
COMMENT ON COLUMN persistency_bonus.retention_rate IS '평가 시점 실제 유지율';
COMMENT ON COLUMN persistency_bonus.bonus_amount   IS '지급 유지보수수당 금액';

CREATE INDEX idx_pb_agent_settle ON persistency_bonus(agent_id, settle_month);
CREATE INDEX idx_pb_base_month   ON persistency_bonus(base_month, retention_month);
CREATE INDEX idx_pb_status       ON persistency_bonus(status, settle_month);
