// =============================================================================
// TudadaSDK Payment API (Unity)
//
// 결제 메서드 묶음. JS 측 `TudadaSDK.payment.getProducts()` 등과 일치하도록
// `TudadaSDK.Instance.payment.GetProducts(...)` 형태로 노출합니다.
// 게임은 결제 레일/수단을 모르며(rail-agnostic) productId 로만 구매합니다.
//
// JS SDK(window.tudadaSDK.payment)가 플랫폼(game-web)으로 라운드트립하여 동작합니다.
//    Unity는 jslib 브릿지를 통해 그대로 위임하며, 가용성·결과 판정은 플랫폼이 내립니다
//    (결제 미제공 컨텍스트는 PAYMENT_UNAVAILABLE). Editor에서는 WebGL 브릿지가 없어
//    onFail 폴백으로 귀결됩니다.
// =============================================================================

using System;
using System.Runtime.InteropServices;
using UnityEngine;
using Tudada;

public partial class TudadaSDK : MonoBehaviour
{
    #region Payment - jslib bindings

#if UNITY_WEBGL && !UNITY_EDITOR
    [DllImport("__Internal")]
    private static extern void TudadaSDK_Payment_GetProducts(int callbackId);

    [DllImport("__Internal")]
    private static extern void TudadaSDK_Payment_GetProduct(string productId, int callbackId);

    [DllImport("__Internal")]
    private static extern void TudadaSDK_Payment_Purchase(string productId, string passthroughPayload, int callbackId);

    [DllImport("__Internal")]
    private static extern void TudadaSDK_Payment_GetTransaction(string txnKey, int callbackId);
#endif

    #endregion

    #region Payment - jslib callback handlers (SendMessage 대상)

    public void OnPaymentGetProductsSuccess(string data) => HandleCallback(data, true);
    public void OnPaymentGetProductsFail(string data) => HandlePaymentFailCallback(data);
    public void OnPaymentGetProductSuccess(string data) => HandleCallback(data, true);
    public void OnPaymentGetProductFail(string data) => HandlePaymentFailCallback(data);
    public void OnPaymentPurchaseSuccess(string data) => HandleCallback(data, true);
    public void OnPaymentPurchaseFail(string data) => HandlePaymentFailCallback(data);
    public void OnPaymentGetTransactionSuccess(string data) => HandleCallback(data, true);
    public void OnPaymentGetTransactionFail(string data) => HandlePaymentFailCallback(data);

    #endregion

    #region Payment - Public namespace

    private PaymentApi _payment;

    /// <summary>
    /// 결제 메서드 묶음 — JS 측 <c>TudadaSDK.payment</c> 와 동일.
    /// getProducts / getProduct / purchase / getTransaction.
    /// </summary>
    public PaymentApi payment
    {
        get
        {
            if (_payment == null) _payment = new PaymentApi(this);
            return _payment;
        }
    }

    /// <summary>
    /// TudadaSDK.payment — 결제 API. 콜백(onSuccess/onFail) 기반.
    /// </summary>
    public class PaymentApi
    {
        private readonly TudadaSDK _sdk;

        internal PaymentApi(TudadaSDK sdk) { _sdk = sdk; }

        /// <summary>
        /// 구매 상품 목록 조회. 빈 배열이면 상점 UI 를 노출하지 않는다.
        /// </summary>
        public void GetProducts(Action<GetProductsResult> onSuccess = null, Action<PaymentFailResult> onFail = null)
        {
            _sdk.LogDebug("payment.GetProducts");
#if UNITY_WEBGL && !UNITY_EDITOR
            int callbackId = _sdk.RegisterPaymentCallbacks(onSuccess, onFail, new GetProductsResult());
            TudadaSDK_Payment_GetProducts(callbackId);
#else
            _sdk.LogEditor("payment.GetProducts");
            onFail?.Invoke(NotImplemented("getProducts"));
#endif
        }

        /// <summary>
        /// 단일 상품 조회. 미존재/판매 불가 → PRODUCT_NOT_FOUND.
        /// </summary>
        public void GetProduct(string productId, Action<GetProductResult> onSuccess = null, Action<PaymentFailResult> onFail = null)
        {
            _sdk.LogDebug($"payment.GetProduct - productId: {productId}");
#if UNITY_WEBGL && !UNITY_EDITOR
            int callbackId = _sdk.RegisterPaymentCallbacks(onSuccess, onFail, new GetProductResult());
            TudadaSDK_Payment_GetProduct(productId ?? "", callbackId);
#else
            _sdk.LogEditor("payment.GetProduct", productId);
            onFail?.Invoke(NotImplemented("getProduct"));
#endif
        }

        /// <summary>
        /// 상품 구매. status:GRANTED/PENDING 성공, 그 외 실패.
        /// </summary>
        /// <param name="productId">구매할 상품 ID</param>
        /// <param name="passthroughPayload">불투명 echo 문자열(≤1000 UTF-8 바이트). webhook·조회로 원문 반환</param>
        public void Purchase(string productId, string passthroughPayload = null, Action<PurchaseResult> onSuccess = null, Action<PaymentFailResult> onFail = null)
        {
            _sdk.LogDebug($"payment.Purchase - productId: {productId}");
#if UNITY_WEBGL && !UNITY_EDITOR
            int callbackId = _sdk.RegisterPaymentCallbacks(onSuccess, onFail, new PurchaseResult());
            TudadaSDK_Payment_Purchase(productId ?? "", passthroughPayload ?? "", callbackId);
#else
            _sdk.LogEditor("payment.Purchase", productId);
            onFail?.Invoke(NotImplemented("purchase"));
#endif
        }

        /// <summary>
        /// 트랜잭션 상태·결과 조회(본인·세션 무관). 미존재/미소유 → TRANSACTION_NOT_FOUND.
        /// </summary>
        public void GetTransaction(string txnKey, Action<GetTransactionResult> onSuccess = null, Action<PaymentFailResult> onFail = null)
        {
            _sdk.LogDebug($"payment.GetTransaction - txnKey: {txnKey}");
#if UNITY_WEBGL && !UNITY_EDITOR
            int callbackId = _sdk.RegisterPaymentCallbacks(onSuccess, onFail, new GetTransactionResult());
            TudadaSDK_Payment_GetTransaction(txnKey ?? "", callbackId);
#else
            _sdk.LogEditor("payment.GetTransaction", txnKey);
            onFail?.Invoke(NotImplemented("getTransaction"));
#endif
        }

        /// <summary>Editor 폴백 — 결제는 WebGL 빌드에서 JS SDK 브릿지로만 동작한다.</summary>
        private static PaymentFailResult NotImplemented(string method)
            => new PaymentFailResult
            {
                code = PaymentErrorCode.PaymentUnavailable,
                errMsg = $"payment.{method} is only available in WebGL builds (editor fallback)",
                txnKey = "",
                failReason = "",
            };
    }

    #endregion
}
