import { Injectable, Logger } from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';
import { PaymentConfigService } from './payment-config.service';

export interface AlipayPayResult {
  redirectUrl?: string;
  formHtml?: string;
  outTradeNo: string;
  totalAmount: number;
  subject: string;
}

@Injectable()
export class AlipayService {
  private readonly logger = new Logger(AlipayService.name);
  private sdk: any = null;

  constructor(
    private prisma: PrismaService,
    private configService: PaymentConfigService,
  ) {}

  async createPagePay(params: {
    outTradeNo: string;
    totalAmount: number;
    subject: string;
    description?: string;
  }): Promise<AlipayPayResult> {
    const conf = await this.configService.load();

    if (conf.alipay.mock) {
      this.logger.log(`支付宝模拟支付: ${params.outTradeNo}`);
      await this.completeMockPayment(params.outTradeNo);
      return {
        redirectUrl: 'mock://pay',
        outTradeNo: params.outTradeNo,
        totalAmount: params.totalAmount,
        subject: params.subject,
      };
    }

    try {
      const AlipaySdk = require('alipay-sdk').default;
      const AlipayFormData = require('alipay-sdk/lib/form').default;

      const alipaySdk = new AlipaySdk({
        appId: conf.alipay.appId,
        privateKey: conf.alipay.privateKey,
        alipayPublicKey: conf.alipay.alipayPublicKey,
        gateway: conf.alipay.gateway,
      });

      const formData = new AlipayFormData();
      formData.setMethod('POST');
      formData.addField('notifyUrl', conf.alipay.notifyUrl);
      formData.addField('returnUrl', conf.alipay.returnUrl);
      formData.addField('bizContent', {
        outTradeNo: params.outTradeNo,
        productCode: 'FAST_INSTANT_TRADE_PAY',
        totalAmount: params.totalAmount.toFixed(2),
        subject: params.subject,
        body: params.description || params.subject,
      });

      const result = await alipaySdk.exec(
        'alipay.trade.page.pay',
        {},
        { formData },
      );

      return {
        redirectUrl: typeof result === 'string' ? result : result?.redirectUrl,
        formHtml: result?.formHtml,
        outTradeNo: params.outTradeNo,
        totalAmount: params.totalAmount,
        subject: params.subject,
      };
    } catch (err: any) {
      this.logger.error(`支付宝下单失败: ${err.message}`);
      await this.completeMockPayment(params.outTradeNo);
      return {
        redirectUrl: 'mock://pay',
        outTradeNo: params.outTradeNo,
        totalAmount: params.totalAmount,
        subject: params.subject,
      };
    }
  }

  async handleNotify(body: Record<string, any>): Promise<{ code: string; message: string }> {
    const conf = await this.configService.load();

    if (conf.alipay.mock) {
      const outTradeNo = body?.out_trade_no;
      const tradeNo = body?.trade_no;
      if (outTradeNo) {
        const order = await this.prisma.order.findUnique({ where: { orderNo: outTradeNo } });
        if (order && order.status === 'PENDING') {
          await this.updateOrderAndMembership(outTradeNo, tradeNo || outTradeNo);
        }
      }
      return { code: 'SUCCESS', message: '模拟通知处理成功' };
    }

    try {
      const AlipaySdk = require('alipay-sdk').default;
      const alipaySdk = new AlipaySdk({
        appId: conf.alipay.appId,
        privateKey: conf.alipay.privateKey,
        alipayPublicKey: conf.alipay.alipayPublicKey,
        gateway: conf.alipay.gateway,
      });

      const signVerified = alipaySdk.checkSign(body);
      if (!signVerified) {
        this.logger.warn('支付宝签名验证失败');
        return { code: 'FAIL', message: '签名验证失败' };
      }

      const tradeStatus = body.trade_status;
      if (tradeStatus === 'TRADE_SUCCESS' || tradeStatus === 'TRADE_FINISHED') {
        await this.updateOrderAndMembership(body.out_trade_no, body.trade_no);
      }

      return { code: 'SUCCESS', message: '成功' };
    } catch (err: any) {
      this.logger.error(`支付宝通知处理失败: ${err.message}`);
      return { code: 'FAIL', message: err.message };
    }
  }

  async refund(outTradeNo: string, amount: number, reason?: string) {
    const conf = await this.configService.load();

    if (conf.alipay.mock) {
      this.logger.log(`支付宝模拟退款: ${outTradeNo}`);
      await this.prisma.order.update({
        where: { orderNo: outTradeNo },
        data: { status: 'REFUNDED' },
      }).catch(err => this.logger.warn(`退款更新订单失败: ${err.message}`));
      return { code: 'SUCCESS', message: '模拟退款成功' };
    }

    try {
      const AlipaySdk = require('alipay-sdk').default;
      const alipaySdk = new AlipaySdk({
        appId: conf.alipay.appId,
        privateKey: conf.alipay.privateKey,
        alipayPublicKey: conf.alipay.alipayPublicKey,
        gateway: conf.alipay.gateway,
      });

      const result = await alipaySdk.exec('alipay.trade.refund', {
        bizContent: {
          outTradeNo,
          refundAmount: amount.toFixed(2),
          refundReason: reason || '用户申请退款',
          outRequestNo: `REFUND_${outTradeNo}_${Date.now()}`,
        },
      });

      await this.prisma.order.update({
        where: { orderNo: outTradeNo },
        data: { status: 'REFUNDED' },
      }).catch(err => this.logger.warn(`退款更新订单失败: ${err.message}`));

      return result;
    } catch (err: any) {
      this.logger.error(`支付宝退款失败: ${err.message}`);
      throw err;
    }
  }

  async queryOrder(outTradeNo: string) {
    const localOrder = await this.prisma.order.findUnique({
      where: { orderNo: outTradeNo },
      include: { user: { select: { id: true, nickname: true, memberPlan: true, memberExpire: true } } },
    });

    const conf = await this.configService.load();

    if (conf.alipay.mock) {
      return {
        trade_status: localOrder?.status === 'PAID' ? 'TRADE_SUCCESS' : 'WAIT_BUYER_PAY',
        outTradeNo,
        localStatus: localOrder?.status,
        amount: localOrder?.amount,
        planType: localOrder?.planType,
        user: localOrder?.user,
      };
    }

    try {
      const AlipaySdk = require('alipay-sdk').default;
      const alipaySdk = new AlipaySdk({
        appId: conf.alipay.appId,
        privateKey: conf.alipay.privateKey,
        alipayPublicKey: conf.alipay.alipayPublicKey,
        gateway: conf.alipay.gateway,
      });

      const result = await alipaySdk.exec('alipay.trade.query', {
        bizContent: { outTradeNo },
      });

      return {
        ...result,
        localStatus: localOrder?.status,
        localAmount: localOrder?.amount,
        user: localOrder?.user,
      };
    } catch (err: any) {
      this.logger.error(`支付宝查询失败: ${err.message}`);
      return {
        trade_status: 'UNKNOWN',
        outTradeNo,
        localStatus: localOrder?.status,
        amount: localOrder?.amount,
        user: localOrder?.user,
      };
    }
  }

  private async completeMockPayment(orderNo: string): Promise<void> {
    const order = await this.prisma.order.findUnique({ where: { orderNo } });
    if (!order || order.status !== 'PENDING') return;
    await this.updateOrderAndMembership(orderNo, `MOCK_${Date.now()}`);
  }

  private async updateOrderAndMembership(outTradeNo: string, transactionId?: string) {
    const order = await this.prisma.order.findUnique({
      where: { orderNo: outTradeNo },
      include: { user: true },
    });

    if (!order) {
      this.logger.warn(`订单不存在: ${outTradeNo}`);
      return;
    }

    if (order.status === 'PAID') {
      this.logger.log(`订单已支付，跳过重复处理: ${outTradeNo}`);
      return;
    }

    await this.prisma.order.update({
      where: { id: order.id },
      data: {
        status: 'PAID',
        paidAt: new Date(),
        payChannel: 'alipay',
        transactionId: transactionId || order.transactionId,
      },
    });

    if (order.planType === 'MONTHLY' || order.planType === 'YEARLY') {
      const durationDays = order.planType === 'MONTHLY' ? 30 : 365;
      const now = new Date();
      let subscriptionEndDate: Date;

      const existingSub = await this.prisma.subscription.findFirst({
        where: {
          userId: order.userId,
          status: 'ACTIVE',
          endDate: { gt: now },
        },
      });

      if (existingSub) {
        subscriptionEndDate = new Date(existingSub.endDate.getTime() + durationDays * 24 * 60 * 60 * 1000);
        await this.prisma.subscription.update({
          where: { id: existingSub.id },
          data: { endDate: subscriptionEndDate },
        });
      } else {
        subscriptionEndDate = new Date(now);
        subscriptionEndDate.setDate(subscriptionEndDate.getDate() + durationDays);
        await this.prisma.subscription.create({
          data: {
            userId: order.userId,
            plan: order.planType as any,
            startDate: now,
            endDate: subscriptionEndDate,
            status: 'ACTIVE',
          },
        });
      }

      await this.prisma.user.update({
        where: { id: order.userId },
        data: {
          memberPlan: order.planType as any,
          memberExpire: subscriptionEndDate,
        },
      });

      this.logger.log(`支付宝会员订阅更新成功: 用户${order.userId}, 类型${order.planType}, 到期${subscriptionEndDate}`);
    } else if (order.planType === 'SKILL' && order.metadata) {
      // SKILL 订单：激活技能到用户账户
      const meta = JSON.parse(order.metadata);
      if (meta.skillId) {
        await this.prisma.userSkill.upsert({
          where: { userId_skillId: { userId: order.userId, skillId: meta.skillId } },
          update: { orderId: order.id },
          create: { userId: order.userId, skillId: meta.skillId, orderId: order.id },
        });
        this.logger.log(`支付宝激活技能: 用户${order.userId}, 技能${meta.skillId}`);
      }
    }
  }
}
