/**
 * 支付网关工厂 (Payment Gateway Factory)
 * 统一管理所有支付网关，实现工厂模式
 * 
 * 作者: 卡若
 * 版本: v4.0
 */

import { 
  CreateTradeData, 
  TradeResult, 
  NotifyResult,
  PaymentPlatform,
  PaymentGateway,
  GatewayNotFoundError,
  PaymentMethod
} from './types';

/**
 * 抽象支付网关基类
 */
export abstract class AbstractGateway {
  protected config: Record<string, unknown>;

  constructor(config: Record<string, unknown> = {}) {
    this.config = config;
  }

  /**
   * 创建交易
   */
  abstract createTrade(data: CreateTradeData): Promise<TradeResult>;

  /**
   * 验证签名
   */
  abstract verifySign(data: Record<string, string>): boolean;

  /**
   * 解析回调数据
   */
  abstract parseNotify(data: string | Record<string, string>): NotifyResult;

  /**
   * 关闭交易
   */
  abstract closeTrade(tradeSn: string): Promise<boolean>;

  /**
   * 查询交易
   */
  abstract queryTrade(tradeSn: string): Promise<NotifyResult | null>;

  /**
   * 发起退款
   */
  abstract refund(tradeSn: string, refundSn: string, amount: number, reason?: string): Promise<boolean>;

  /**
   * 回调成功响应
   */
  successResponse(): string {
    return 'success';
  }

  /**
   * 回调失败响应
   */
  failResponse(): string {
    return 'fail';
  }
}

// 网关类型映射
type GatewayClass = new (config: Record<string, unknown>) => AbstractGateway;

/**
 * 支付网关工厂
 */
export class PaymentFactory {
  private static gateways: Map<string, GatewayClass> = new Map();

  /**
   * 注册支付网关
   */
  static register(name: string, gatewayClass: GatewayClass): void {
    this.gateways.set(name, gatewayClass);
    console.log(`[PaymentFactory] 注册支付网关: ${name}`);
  }

  /**
   * 创建支付网关实例
   * @param gateway 网关名称，格式如 'wechat_jsapi'，会取下划线前的部分
   */
  static create(gateway: PaymentGateway | string): AbstractGateway {
    const gatewayName = gateway.split('_')[0] as PaymentPlatform;
    
    const GatewayClass = this.gateways.get(gatewayName);
    if (!GatewayClass) {
      throw new GatewayNotFoundError(gateway);
    }

    const config = this.getGatewayConfig(gatewayName);
    return new GatewayClass(config);
  }

  /**
   * 获取网关配置
   */
  private static getGatewayConfig(gateway: PaymentPlatform): Record<string, unknown> {
    const configMap: Record<PaymentPlatform, () => Record<string, unknown>> = {
      alipay: () => ({
        // 支付宝新版接口需要 app_id，如果没有配置则使用 pid（旧版兼容）
        appId: process.env.ALIPAY_APP_ID || process.env.ALIPAY_PID || '2088511801157159',
        pid: process.env.ALIPAY_PID || '2088511801157159',
        sellerEmail: process.env.ALIPAY_SELLER_EMAIL || 'zhengzhiqun@vip.qq.com',
        privateKey: process.env.ALIPAY_PRIVATE_KEY || '',
        publicKey: process.env.ALIPAY_PUBLIC_KEY || '',
        md5Key: process.env.ALIPAY_MD5_KEY || 'lz6ey1h3kl9zqkgtjz3avb5gk37wzbrp',
        enabled: process.env.ALIPAY_ENABLED === 'true',
        mode: process.env.ALIPAY_MODE || 'production',
      }),
      wechat: () => ({
        // 微信支付需要使用绑定了支付功能的服务号AppID
        appId: process.env.WECHAT_APPID || 'wx7c0dbf34ddba300d', // 服务号AppID（已绑定商户号）
        appSecret: process.env.WECHAT_APP_SECRET || 'f865ef18c43dfea6cbe3b1f1aebdb82e',
        serviceAppId: process.env.WECHAT_SERVICE_APPID || 'wx7c0dbf34ddba300d',
        serviceSecret: process.env.WECHAT_SERVICE_SECRET || 'f865ef18c43dfea6cbe3b1f1aebdb82e',
        mchId: process.env.WECHAT_MCH_ID || '1318592501',
        mchKey: process.env.WECHAT_MCH_KEY || 'wx3e31b068be59ddc131b068be59ddc2',
        certPath: process.env.WECHAT_CERT_PATH || '',
        keyPath: process.env.WECHAT_KEY_PATH || '',
        enabled: process.env.WECHAT_ENABLED === 'true',
        mode: process.env.WECHAT_MODE || 'production',
      }),
      paypal: () => ({
        clientId: process.env.PAYPAL_CLIENT_ID || '',
        clientSecret: process.env.PAYPAL_CLIENT_SECRET || '',
        mode: process.env.PAYPAL_MODE || 'sandbox',
        enabled: process.env.PAYPAL_ENABLED === 'true',
      }),
      stripe: () => ({
        publicKey: process.env.STRIPE_PUBLIC_KEY || '',
        secretKey: process.env.STRIPE_SECRET_KEY || '',
        webhookSecret: process.env.STRIPE_WEBHOOK_SECRET || '',
        mode: process.env.STRIPE_MODE || 'test',
        enabled: process.env.STRIPE_ENABLED === 'true',
      }),
      usdt: () => ({
        gatewayType: process.env.USDT_GATEWAY_TYPE || 'nowpayments',
        apiKey: process.env.NOWPAYMENTS_API_KEY || '',
        ipnSecret: process.env.NOWPAYMENTS_IPN_SECRET || '',
        enabled: process.env.USDT_ENABLED === 'true',
      }),
      coin: () => ({
        rate: parseInt(process.env.COIN_RATE || '100', 10),
        enabled: process.env.COIN_ENABLED === 'true',
      }),
    };

    return configMap[gateway]?.() || {};
  }

  /**
   * 获取已启用的支付网关列表
   */
  static getEnabledGateways(): PaymentMethod[] {
    const methods: PaymentMethod[] = [];

    // 支付宝
    if (process.env.ALIPAY_ENABLED === 'true' || true) { // 默认启用
      methods.push({
        gateway: 'alipay_wap',
        name: '支付宝',
        icon: '/icons/alipay.png',
        enabled: true,
        available: true,
      });
    }

    // 微信支付
    if (process.env.WECHAT_ENABLED === 'true' || true) { // 默认启用
      methods.push({
        gateway: 'wechat_native',
        name: '微信支付',
        icon: '/icons/wechat.png',
        enabled: true,
        available: true,
      });
    }

    // PayPal
    if (process.env.PAYPAL_ENABLED === 'true') {
      methods.push({
        gateway: 'paypal',
        name: 'PayPal',
        icon: '/icons/paypal.png',
        enabled: true,
        available: true,
      });
    }

    // Stripe
    if (process.env.STRIPE_ENABLED === 'true') {
      methods.push({
        gateway: 'stripe',
        name: 'Stripe',
        icon: '/icons/stripe.png',
        enabled: true,
        available: true,
      });
    }

    // USDT
    if (process.env.USDT_ENABLED === 'true') {
      methods.push({
        gateway: 'usdt',
        name: 'USDT (TRC20)',
        icon: '/icons/usdt.png',
        enabled: true,
        available: true,
      });
    }

    return methods;
  }

  /**
   * 检查网关是否已注册
   */
  static hasGateway(name: string): boolean {
    return this.gateways.has(name);
  }

  /**
   * 获取所有已注册的网关名称
   */
  static getRegisteredGateways(): string[] {
    return Array.from(this.gateways.keys());
  }
}

// 导出便捷函数
export function createPaymentGateway(gateway: PaymentGateway | string): AbstractGateway {
  return PaymentFactory.create(gateway);
}
