// =============================================================================
// TudadaSDK Payment Types
//
// 결제 API 타입 정의. JS 측 TudadaSDK.payment.* 표면(게임사 가이드 §3)과 일치.
// 게임은 결제 레일/수단을 모르며(rail-agnostic) productId 로만 구매한다.
//
// JS 측 TudadaSDK.payment.* 와 일치하는 타입. 동작은 플랫폼(game-web) 라운드트립(JS SDK 경유).
// =============================================================================

using System;

namespace Tudada
{
    /// <summary>
    /// 트랜잭션 상태. JS PaymentTransaction.status 와 동일.
    /// purchase 성공 시엔 GRANTED/PENDING 만, getTransaction 은 5종 모두 가능.
    /// </summary>
    public static class PaymentTxnStatus
    {
        public const string Pending = "PENDING";
        public const string Granted = "GRANTED";
        public const string Failed = "FAILED";
        public const string PartiallyRefunded = "PARTIALLY_REFUNDED";
        public const string Refunded = "REFUNDED";
    }

    /// <summary>
    /// 결제 에러 코드(10종). 분기는 항상 code(=errMsg 가 아닌 코드)로 한다.
    /// </summary>
    public static class PaymentErrorCode
    {
        public const string PaymentUnavailable = "PAYMENT_UNAVAILABLE";
        public const string UserCancelled = "USER_CANCELLED";
        public const string PaymentFailed = "PAYMENT_FAILED";
        public const string ProductNotFound = "PRODUCT_NOT_FOUND";
        public const string InvalidParam = "INVALID_PARAM";
        public const string PurchaseRejected = "PURCHASE_REJECTED";
        public const string PaymentInProgress = "PAYMENT_IN_PROGRESS";
        public const string TransactionNotFound = "TRANSACTION_NOT_FOUND";
        public const string SessionExpired = "SESSION_EXPIRED";
        public const string NetworkError = "NETWORK_ERROR";
    }

    /// <summary>
    /// 구매 상품. 가격은 사용자 환경 기준 표시-완성 문자열이며 산술 금지.
    /// </summary>
    [Serializable]
    public class PaymentProduct
    {
        /// <summary>마켓 무관 단일 상품 ID — 구매 시 지정</summary>
        public string productId;

        /// <summary>투다다 등록 상품명</summary>
        public string name;

        /// <summary>
        /// (할인 적용된) 현재 가격 — 표시-완성 금액(KRW "4,400", USD "4.99").
        /// 그대로 표시한다. 산술 금지.
        /// </summary>
        public string price;

        /// <summary>통화/재화 식별 문자열(약속된 값, 예 "KRW"). 게임이 이미지·기호로 맵핑</summary>
        public string currency;

        /// <summary>할인 전 가격(표시-완성 문자열). 할인 없으면 빈 문자열. 취소선 등 표시용</summary>
        public string originalPrice;

        /// <summary>할인율 표시 문자열(예 "20%") — 마케팅 표기. price/originalPrice 로 역산 금지</summary>
        public string discountRate;
    }

    /// <summary>
    /// 트랜잭션 — 검증·UX 용 축소 뷰(금액·영수증 없음).
    /// 권위 정보(지급)는 게임 서버·투다다 서버가 보유한다.
    /// </summary>
    [Serializable]
    public class PaymentTransaction
    {
        /// <summary>고유 키 — 재조회에 사용</summary>
        public string txnKey;

        /// <summary>트랜잭션 상태 — <see cref="PaymentTxnStatus"/> 상수 사용 권장</summary>
        public string status;

        /// <summary>거래 상품 (항상 존재)</summary>
        public string productId;

        /// <summary>진단·로깅용 — 사용자 노출 금지, 값 변경 가능. 없으면 빈 문자열</summary>
        public string failReason;

        /// <summary>구매 시 넘긴 값 그대로. 생략·빈 문자열이면 빈 문자열</summary>
        public string passthroughPayload;

        /// <summary>서버 기준 Unix epoch ms</summary>
        public long requestedAt;

        /// <summary>최초 지급 시각(epoch ms) — GRANTED/환불계열 non-null, PENDING/FAILED null</summary>
        public long grantedAt;

        /// <summary>grantedAt 존재 여부 (JsonUtility long 은 null 불가 — 0/null 구분용)</summary>
        public bool hasGrantedAt;
    }

    /// <summary>getProducts 결과</summary>
    [Serializable]
    public class GetProductsResult
    {
        public string errMsg;
        public PaymentProduct[] products;
    }

    /// <summary>getProduct 결과</summary>
    [Serializable]
    public class GetProductResult
    {
        public string errMsg;
        public PaymentProduct product;
    }

    /// <summary>purchase 결과</summary>
    [Serializable]
    public class PurchaseResult
    {
        public string errMsg;
        public PaymentTransaction transaction;
    }

    /// <summary>getTransaction 결과</summary>
    [Serializable]
    public class GetTransactionResult
    {
        public string errMsg;
        public PaymentTransaction transaction;
    }

    /// <summary>
    /// 결제 실패 결과 — onFail 콜백 인자. 분기는 항상 code(errMsg 아님).
    /// </summary>
    [Serializable]
    public class PaymentFailResult
    {
        /// <summary>결제 에러 코드(10종) — 분기 기준. <see cref="PaymentErrorCode"/> 상수.</summary>
        public string code;

        /// <summary>진단·로깅용 메시지(사용자 노출 금지).</summary>
        public string errMsg;

        /// <summary>거래가 서버에 기록된 실패(PAYMENT_FAILED·PURCHASE_REJECTED)에만 존재. 없으면 빈 문자열.</summary>
        public string txnKey;

        /// <summary>서버 측 상세 실패 코드 — 진단용. 없으면 빈 문자열.</summary>
        public string failReason;
    }
}
