package com.sonic.lion.test;

import com.stripe.Stripe;
import com.stripe.exception.StripeException;
import com.stripe.model.Account;
import com.stripe.model.BankAccount;
import com.stripe.model.Payout;
import com.stripe.model.Transfer;
import com.stripe.net.RequestOptions;

import java.util.HashMap;
import java.util.Map;

/**
 * Stripe Connected Accounts 测试流程示例
 * 
 * 这个类演示了使用 Stripe Java SDK 的完整测试流程：
 * 1. 创建一个 Express 类型的连接账户（Connected Account）。
 * 2. 为连接账户添加一个测试银行账户（External Account）。
 * 3. 从平台账户向连接账户转移资金（Transfer）。
 * 4. 为连接账户手动创建提现（Payout）到银行账户。
 * 
 * 注意：
 * - 使用测试密钥（sk_test_...）在测试模式下运行，不会实际转账。
 * - 在生产环境中，需要处理 KYC/Onboarding（例如，通过 Account Links API 引导用户输入真实信息）。
 * - 错误处理是基本的；生产代码应更全面。
 * - 确保已添加 stripe-java 依赖（Maven/Gradle）。
 *
 * 全球付款测试
 * https://docs.stripe.com/global-payouts
 *
 */
public class StripeConnectedAccountPayoutTest {

    private static final String STRIPE_API_KEY = "sk_test_51RoLASRHHBJ3NEeaS8VxcRsjapRASYt4lM4HHn22ZKbHMBzwce0kgJPECtoRcntzG4fktfjoDvHE4Pmx8Vpy8bLU008zUxKdxB";  // 替换为你的 Stripe 测试密钥

    public static void main(String[] args) {
        // 设置 Stripe API 密钥
        Stripe.apiKey = STRIPE_API_KEY;

        try {
//            // 步骤 1: 创建 Express 连接账户
//            Account account = createConnectedAccount();
//            System.out.println("创建连接账户: ID = " + account.getId());
//
//            // 步骤 2: 为连接账户添加测试银行账户
//            BankAccount bankAccount = addBankAccount(account.getId());
//            System.out.println("添加银行账户: ID = " + bankAccount.getId());

            Account account = new Account();
            account.setId("acct_1S7vSrEvZDpJJVSo");
            //ba_1S7vSvEvZDpJJVSok76s8rog

            // 步骤 3: 从平台账户向连接账户转移资金
            Transfer transfer = createTransfer(account.getId(), 1000L); // 1000 美分 = 10 USD
            System.out.println("转移资金: Transfer ID = " + transfer.getId());

            // 步骤 4: 为连接账户创建手动 Payout
            Payout payout = createPayout(account.getId(), 1000L); // 提现 10 USD
            System.out.println("创建 Payout: Payout ID = " + payout.getId());

            System.out.println("测试流程完成！请在 Stripe Dashboard 检查结果。");

        } catch (StripeException e) {
            System.err.println("Stripe API 错误: " + e.getMessage());
            System.err.println("Request ID: " + e.getRequestId()); // 用于在 Stripe Dashboard 追踪
            e.printStackTrace();
        } catch (Exception e) {
            System.err.println("其他错误: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 创建 Express 连接账户
     */
    private static Account createConnectedAccount() throws StripeException {
        Map<String, Object> params = new HashMap<>();
        params.put("type", "express");
        params.put("country", "US");
        params.put("email", "testuser@example.com");
        Map<String, Object> capabilities = new HashMap<>();
        capabilities.put("card_payments", new HashMap<String, Object>() {{
            put("requested", true);
        }});
        capabilities.put("transfers", new HashMap<String, Object>() {{
            put("requested", true);
        }});
        params.put("capabilities", capabilities);
        return Account.create(params);
    }

    /**
     * 为连接账户添加测试银行账户
     * 修复：将银行账户参数嵌套在 external_account 键下，符合 stripe-java 20.108.0 要求
     */
    private static BankAccount addBankAccount(String accountId) throws StripeException {
        RequestOptions options = RequestOptions.builder().setStripeAccount(accountId).build();
        Map<String, Object> params = new HashMap<>();
        Map<String, Object> externalAccount = new HashMap<>();
        externalAccount.put("object", "bank_account");
        externalAccount.put("country", "US");
        externalAccount.put("currency", "usd");
        externalAccount.put("account_holder_name", "Test User");
        externalAccount.put("account_holder_type", "individual");
        externalAccount.put("routing_number", "110000000"); // Stripe 测试路由号
        externalAccount.put("account_number", "000123456789"); // Stripe 测试账号
        params.put("external_account", externalAccount); // 关键：嵌套在 external_account
        return (BankAccount) Account.retrieve(accountId).getExternalAccounts().create(params, options);
    }

    /**
     * 从平台账户向连接账户转移资金
     */
    private static Transfer createTransfer(String accountId, Long amount) throws StripeException {
        Map<String, Object> params = new HashMap<>();
        params.put("amount", amount);
        params.put("currency", "usd");
        params.put("destination", accountId);
        params.put("description", "测试转移到连接账户");
        return Transfer.create(params);
    }

    /**
     * 为连接账户创建手动 Payout
     */
    private static Payout createPayout(String accountId, Long amount) throws StripeException {
        RequestOptions options = RequestOptions.builder().setStripeAccount(accountId).build();
        Map<String, Object> params = new HashMap<>();
        params.put("amount", amount);
        params.put("currency", "usd");
        params.put("method", "standard");
        params.put("description", "测试提现");
        return Payout.create(params, options);
    }
}