import { prisma } from '../../models';
import crypto from 'crypto';

// 懒加载支付 SDK（避免 Node.js ESM 兼容性问题）
let AlipaySdk: any = null;
let WeChatPay: any = null;
let sdkInitialized = false;

// 初始化支付 SDK
async function initPaymentSdks() {
  if (sdkInitialized) return;
  sdkInitialized = true;

  try {
    const sdk = await import('alipay-sdk');
    AlipaySdk = sdk.AlipaySdk;
    console.log('[Payment] 支付宝 SDK 加载成功');
  } catch (e) {
    console.warn('[Payment] 支付宝 SDK 加载失败:', e);
  }

  try {
    // 直接 require，因为 wechatpay-node-v3 是 CommonJS 模块
    WeChatPay = require('wechatpay-node-v3');
    console.log('[Payment] 微信支付 SDK 加载成功');
  } catch (e) {
    console.warn('[Payment] 微信支付 SDK 加载失败:', e);
  }
}

// 生成订单号
export function generateOrderNo(): string {
  const now = new Date();
  const dateStr = now.toISOString().slice(0, 10).replace(/-/g, '');
  const random = Math.random().toString(36).substring(2, 8).toUpperCase();
  return `PAY${dateStr}${random}`;
}

// 初始化支付宝 SDK
let alipaySdk: any | null = null;

function getAlipaySdk(): any | null {
  if (!AlipaySdk) {
    console.warn('[Alipay] 支付宝 SDK 未加载');
    return null;
  }
  const appId = process.env.ALIPAY_APP_ID || '';
  // dotenv 不解析多行 PEM，手动加 PEM 头尾
  const rawPrivateKey = process.env.ALIPAY_PRIVATE_KEY || '';
  // 自动检测密钥格式：PKCS#1 (BEGIN RSA PRIVATE KEY) 或 PKCS#8 (BEGIN PRIVATE KEY)
  let privateKey: string;
  if (rawPrivateKey.includes('BEGIN PRIVATE KEY')) {
    privateKey = rawPrivateKey; // 已是 PKCS#8 格式
  } else if (rawPrivateKey.includes('BEGIN RSA PRIVATE KEY')) {
    privateKey = rawPrivateKey; // 已是 PKCS#1 格式
  } else {
    // 没有头尾，添加 PKCS#1 格式头尾（支付宝推荐格式）
    privateKey = `-----BEGIN RSA PRIVATE KEY-----\n${rawPrivateKey}\n-----END RSA PRIVATE KEY-----`;
  }
  const rawPublicKey = process.env.ALIPAY_PUBLIC_KEY || '';
  const alipayPublicKey = rawPublicKey.includes('BEGIN') ? rawPublicKey
    : `-----BEGIN PUBLIC KEY-----\n${rawPublicKey}\n-----END PUBLIC KEY-----`;

  if (!appId || !privateKey || !alipayPublicKey) {
    console.warn('[Alipay] 未配置支付宝参数', { appId: !!appId, hasPrivateKey: !!privateKey, hasPublicKey: !!alipayPublicKey });
    return null;
  }

  console.log('[Alipay] 初始化 SDK', { 
    appId, 
    privateKeyStart: privateKey.substring(0, 50),
    alipayPublicKeyStart: alipayPublicKey.substring(0, 50)
  });

  if (!alipaySdk) {
    alipaySdk = new AlipaySdk({
      appId,
      privateKey,
      alipayPublicKey,
      gateway: 'https://openapi.alipay.com/gateway.do',
    });
  }

  return alipaySdk;
}

// 初始化微信支付 SDK
let wechatPay: any | null = null;

function getWechatPay(): any | null {
  if (!WeChatPay) {
    console.warn('[WeChatPay] 微信支付 SDK 未加载');
    return null;
  }

  const appId = process.env.WECHAT_APP_ID;
  const mchId = process.env.WECHAT_MCH_ID;
  const serialNo = process.env.WECHAT_SERIAL_NO;
  const apiv3Key = process.env.WECHAT_APIV3_KEY;

  // 读取私钥和公钥文件（dotenv 无法正确解析多行 PEM 密钥）
  const fs = require('fs');
  const path = require('path');
  const certDir = path.join(__dirname, '../../../cert/wx');
  const privateKeyPath = path.join(certDir, 'apiclient_key.pem');
  const publicKeyPath = path.join(certDir, 'pub_key.pem');
  let privateKey = '';
  let publicKey = '';
  try {
    privateKey = fs.readFileSync(privateKeyPath, 'utf8');
    publicKey = fs.readFileSync(publicKeyPath, 'utf8');
  } catch (e) {
    console.warn('[WeChatPay] 未找到证书文件:', e.message);
  }

  if (!appId || !mchId || !privateKey || !serialNo || !apiv3Key) {
    console.warn('[WeChatPay] 未配置微信支付参数');
    return null;
  }

  if (!wechatPay) {
    // 从私钥导出公钥（dotenv无法正确解析多行PEM，且提供的pub_key.pem与私钥不匹配）
    const privKeyObj = crypto.createPrivateKey(privateKey);
    const pubKeyFromPriv = crypto.createPublicKey(privKeyObj);
    const publicKeyDer = pubKeyFromPriv.export({ type: 'spki', format: 'der' });

    wechatPay = new WeChatPay({
      appid: appId,
      mchid: mchId,
      serial_no: serialNo,
      publicKey: publicKeyDer,
      privateKey: Buffer.from(privateKey),
      key: apiv3Key,
    });
  }

  return wechatPay;
}

// 创建支付订单
export async function createPaymentOrder(
  userId: number,
  planId: number,
  paymentMethod: 'alipay' | 'wechat' | 'mock',
  period: 'monthly' | 'yearly' = 'monthly',
  returnUrl?: string
): Promise<{
  orderNo: string;
  amount: number;
  planName: string;
  paymentUrl?: string;
  qrcode?: string;
}> {
  // 确保 SDK 已加载
  await initPaymentSdks();

  // 获取套餐信息
  const plan = await prisma.subscriptionPlan.findUnique({
    where: { id: planId }
  });

  if (!plan) {
    throw new Error('套餐不存在');
  }

  // 生成订单号
  const orderNo = generateOrderNo();

  // 根据周期选择价格
  const amount = period === 'yearly' ? Number(plan.priceYearly) : Number(plan.priceMonthly);

  // 创建订单记录
  await prisma.order.create({
    data: {
      userId,
      orderNo,
      planId,
      productType: period,
      amount,
      status: 'pending',
      paymentMethod,
    }
  });

  // 生成支付信息
  let paymentUrl: string | undefined;
  let qrcode: string | undefined;

  try {
    if (paymentMethod === 'alipay') {
      const alipayResult = await generateAlipayPayment(orderNo, amount, plan.name, returnUrl);
      paymentUrl = alipayResult.paymentUrl;
      qrcode = alipayResult.qrcode;
    } else if (paymentMethod === 'wechat') {
      const wechatResult = await generateWechatPayment(orderNo, amount, plan.name);
      qrcode = wechatResult.qrcode;
      paymentUrl = wechatResult.h5Url;
    }
  } catch (error) {
    console.error('[Payment] 支付链接生成失败:', error);
    throw error;
  }

  return {
    orderNo,
    amount,
    planName: plan.name,
    paymentUrl,
    qrcode
  };
}

// 生成支付宝支付链接
async function generateAlipayPayment(
  orderNo: string,
  amount: number,
  subject: string,
  returnUrl?: string
): Promise<{ paymentUrl?: string; qrcode?: string }> {
  const sdk = getAlipaySdk();
  const isProduction = process.env.NODE_ENV === 'production';

  // 默认回调地址
  const defaultReturnUrl = process.env.ALIPAY_RETURN_URL || `${process.env.BASE_URL || 'https://your-domain.com'}/#/pages/payment-result/index`;
  const finalReturnUrl = returnUrl || defaultReturnUrl;

  if (!sdk) {
    console.warn('[Alipay] 未配置支付宝，返回模拟支付链接');
    return {
      paymentUrl: `https://openapi.alipay.com/gateway.do?out_trade_no=${orderNo}&total_amount=${amount}&subject=${encodeURIComponent(subject)}`
    };
  }

  // 使用电脑网站支付 API
  try {
    const bizContent = {
      out_trade_no: orderNo,
      total_amount: String(amount),
      subject: subject,
      product_code: 'FAST_INSTANT_TRADE_PAY',
      quit_url: finalReturnUrl,
    };

    // 使用 wap.pay 返回表单，提取 action URL 用于跳转
    const htmlForm = sdk.pageExec('alipay.trade.wap.pay', {
      bizContent: {
        out_trade_no: orderNo,
        total_amount: String(amount),
        subject: subject,
        quit_url: finalReturnUrl,
      },
      useSandbox: false,
    });

    // 从 HTML 表单中提取 action URL
    const actionMatch = String(htmlForm).match(/action="([^"]+)"/);
    const paymentUrl = actionMatch ? actionMatch[1] : '';

    return {
      paymentUrl,
    };
  } catch (error) {
    console.error('[Alipay] 支付链接生成失败:', error);
    throw new Error('支付宝支付链接生成失败');
  }
}

// 生成微信支付二维码链接
async function generateWechatPayment(
  orderNo: string,
  amount: number,
  subject: string
): Promise<{ qrcode?: string; h5Url?: string }> {
  const wechat = getWechatPay();

  if (!wechat) {
    console.warn('[WeChatPay] 未配置微信支付，返回模拟支付链接');
    return {
      qrcode: `https://api.mch.weixin.qq.com/qrcode/${orderNo}`,
      h5Url: `weixin://wxpay/bizpayurl?pr=${encodeURIComponent(orderNo)}`
    };
  }

  try {
    console.log('[WeChatPay] 开始创建 NATIVE 支付订单:', { orderNo, amount, subject });

    // 使用 NATIVE 支付（扫码支付）
    const result: any = await wechat.transactions_native({
      description: subject,
      out_trade_no: orderNo,
      amount: {
        total: Math.round(amount * 100), // 转换为分
        currency: 'CNY',
      },
      notify_url: process.env.WECHAT_NOTIFY_URL || `${process.env.BASE_URL || 'https://your-domain.com'}/api/payment/wechat/notify`,
    });

    console.log('[WeChatPay] 支付接口返回, result:', JSON.stringify(result));

    // 检查返回状态（SDK 不会reject错误响应，而是返回包含error的对象）
    if (result.status !== 200 && result.status !== '200') {
      const errorMsg = result.error || JSON.stringify(result);
      console.error('[WeChatPay] 支付失败:', errorMsg);
      // 微信支付签名错误通常是商户证书问题，返回更友好的错误信息
      throw new Error(`微信支付暂不可用，请稍后重试或使用其他支付方式`);
    }

    console.log('[WeChatPay] 支付二维码生成成功, code_url:', result.code_url);

    // 返回二维码链接（前端自行生成二维码图片）
    return {
      qrcode: result.code_url,
    };
  } catch (error: any) {
    console.error('[WeChatPay] 支付二维码生成失败:', error.message || error);
    throw new Error('微信支付暂不可用，请稍后重试或使用其他支付方式');
  }
}

// 生成支付宝扫码支付二维码
export async function generateAlipayQrcode(
  orderNo: string,
  amount: number,
  subject: string
): Promise<string> {
  const sdk = getAlipaySdk();

  if (!sdk) {
    console.warn('[Alipay] 未配置支付宝，返回模拟二维码链接');
    return `https://qr.alipay.com/${orderNo}`;
  }

  try {
    // 使用当面付预下单 API
    const bizContent = {
      outTradeNo: orderNo,
      totalAmount: amount,
      subject: subject,
    };

    const result = await sdk.exec(
      'alipay.trade.precreate',
      {},
      { bizContent, useSandbox: false }
    );

    // 解析返回的二维码链接
    const response = result as any;
    if (response.qr_code) {
      return response.qr_code;
    }

    return result as string;
  } catch (error) {
    console.error('[Alipay] 扫码支付二维码生成失败:', error);
    throw new Error('支付宝扫码支付生成失败');
  }
}

// 验证支付宝回调签名
export function verifyAlipaySign(params: Record<string, string>): boolean {
  const sdk = getAlipaySdk();
  if (!sdk) {
    console.warn('[Alipay] 未配置支付宝，跳过签名验证');
    return true;
  }

  try {
    const signVerified = sdk.checkNotifySign(params);
    console.log('[Alipay] 签名验证结果:', signVerified);
    return signVerified;
  } catch (error) {
    console.error('[Alipay] 签名验证失败:', error);
    return false;
  }
}

// 处理支付回调
export async function handlePaymentCallback(
  orderNo: string,
  paymentId: string,
  status: 'success' | 'failed'
) {
  const order = await prisma.order.findFirst({
    where: { orderNo }
  });

  if (!order) {
    throw new Error('订单不存在');
  }

  if (order.status === 'paid') {
    // 订单已经支付成功，直接返回
    return { success: true, message: '订单已支付' };
  }

  if (status === 'failed') {
    await prisma.order.update({
      where: { id: order.id },
      data: {
        status: 'failed',
        paymentId,
        updatedAt: new Date()
      }
    });
    return { success: false, message: '支付失败' };
  }

  // 支付成功
  await prisma.order.update({
    where: { id: order.id },
    data: {
      status: 'paid',
      paymentId,
      paidAt: new Date(),
      updatedAt: new Date()
    }
  });

  // 激活订阅
  if (order.planId) {
    await activateSubscription(order.userId, order.planId, order.productType);
  }

  return { success: true, message: '支付成功' };
}

// 激活订阅
export async function activateSubscription(userId: number, planId: number, productType: string = 'monthly') {
  const plan = await prisma.subscriptionPlan.findUnique({
    where: { id: planId }
  });

  if (!plan) {
    throw new Error('套餐不存在');
  }

  const now = new Date();
  // 根据订单的产品类型确定有效天数
  const days = productType === 'yearly' ? 365 : 30;
  const endDate = new Date(now.getTime() + days * 24 * 60 * 60 * 1000);

  const existingSubscription = await prisma.subscription.findFirst({
    where: {
      userId,
      status: 'active',
      endDate: { gt: now }
    }
  });

  let subscriptionEndDate = endDate;

  if (existingSubscription) {
    subscriptionEndDate = new Date(existingSubscription.endDate.getTime() + days * 24 * 60 * 60 * 1000);
    await prisma.subscription.update({
      where: { id: existingSubscription.id },
      data: {
        planId,
        endDate: subscriptionEndDate,
        updatedAt: now
      }
    });
  } else {
    await prisma.subscription.create({
      data: {
        userId,
        planId,
        startDate: now,
        endDate: subscriptionEndDate,
        status: 'active',
        autoRenew: false
      }
    });
  }

  // 更新用户会员等级
  await prisma.user.update({
    where: { id: userId },
    data: {
      memberLevel: plan.level,
      memberExpireAt: subscriptionEndDate
    }
  });

  // 更新Token余额
  const monthlyTokens = plan.monthlyTokens;
  const currentBalance = await prisma.tokenBalance.findUnique({
    where: { userId }
  });

  if (monthlyTokens !== -1) {
    if (currentBalance) {
      await prisma.tokenBalance.update({
        where: { userId },
        data: {
          totalTokens: monthlyTokens,
          usedTokens: 0,
          resetDate: new Date(now.getFullYear(), now.getMonth() + 1, 1)
        }
      });
    } else {
      await prisma.tokenBalance.create({
        data: {
          userId,
          totalTokens: monthlyTokens,
          usedTokens: 0,
          resetDate: new Date(now.getFullYear(), now.getMonth() + 1, 1)
        }
      });
    }
  } else {
    if (currentBalance) {
      await prisma.tokenBalance.update({
        where: { userId },
        data: {
          totalTokens: -1,
          usedTokens: 0,
          resetDate: null
        }
      });
    } else {
      await prisma.tokenBalance.create({
        data: {
          userId,
          totalTokens: -1,
          usedTokens: 0
        }
      });
    }
  }
}

// 模拟支付成功
export async function mockPaymentSuccess(orderNo: string, userId: number) {
  return handlePaymentCallback(orderNo, 'MOCK_' + Date.now(), 'success');
}

// 获取订单列表
export async function getOrderList(userId: number, page: number = 1, pageSize: number = 20) {
  const where = { userId };
  const total = await prisma.order.count({ where });

  const list = await prisma.order.findMany({
    where,
    include: { plan: true },
    orderBy: { createdAt: 'desc' },
    skip: (page - 1) * pageSize,
    take: pageSize
  });

  return {
    list: list.map(order => ({
      ...order,
      amount: Number(order.amount),
      planName: order.plan?.name || ''
    })),
    total,
    page,
    pageSize,
    totalPages: Math.ceil(total / pageSize)
  };
}

// 获取订单详情
export async function getOrderDetail(orderNo: string, userId: number) {
  const order = await prisma.order.findFirst({
    where: { orderNo, userId },
    include: { plan: true }
  });

  if (!order) {
    throw new Error('订单不存在');
  }

  return {
    ...order,
    amount: Number(order.amount),
    planName: order.plan?.name || ''
  };
}

// 查询微信支付订单状态
export async function queryWechatOrder(outTradeNo: string) {
  const wechat = getWechatPay();

  if (!wechat) {
    return null;
  }

  try {
    const result = await wechat.query({ out_trade_no: outTradeNo });
    return result;
  } catch (error) {
    console.error('[WeChatPay] 查询订单失败:', error);
    return null;
  }
}

// 初始化 SDK
initPaymentSdks();