import { Controller, Post, Get, Body, Req, Headers, HttpCode, Query, HttpException, HttpStatus, Param, UseGuards } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBody, ApiQuery, ApiBearerAuth } from '@nestjs/swagger';
import { AuthGuard } from '@nestjs/passport';
import { IsString, IsNumber, IsOptional, IsIn } from 'class-validator';
import { GatewayPayService } from './gateway-pay.service';
import { PrismaService } from '../../prisma/prisma.service';

class UnifiedOrderDto {
  @IsString()
  description: string;

  @IsString()
  outTradeNo: string;

  @IsNumber()
  amount: number;

  @IsOptional()
  @IsString()
  openid?: string;

  @IsOptional()
  @IsIn(['JSAPI', 'NATIVE', 'MWEB'])
  tradeType?: 'JSAPI' | 'NATIVE' | 'MWEB';
}

class RefundDto {
  @IsString()
  outTradeNo: string;

  @IsNumber()
  amount: number;

  @IsOptional()
  @IsString()
  reason?: string;
}

@ApiTags('支付')
@Controller('payment')
export class PaymentController {
  constructor(
    private gatewayPay: GatewayPayService,
    private prisma: PrismaService,
  ) {}

  @Post('wxpay/unified-order')
  @ApiOperation({ summary: '微信支付统一下单（旧接口，转网关）' })
  @ApiBody({ type: UnifiedOrderDto })
  async unifiedOrder(@Body() body: UnifiedOrderDto) {
    const result = await this.gatewayPay.createOrder({
      merchantOrderId: body.outTradeNo,
      amount: body.amount,
      paymentMethod: 'wechat',
      subject: body.description,
    });
    return {
      prepay_id: result.gatewayOrderId,
      codeUrl: result.qrcode === 'mock://pay' ? 'mock://pay' : result.qrcode,
      gatewayOrderId: result.gatewayOrderId,
    };
  }

  @Post('wxpay/notify')
  @HttpCode(200)
  @ApiOperation({ summary: '微信支付回调通知（转网关webhook处理）' })
  async notify(@Body() body: any) {
    const result = await this.gatewayPay.handleWebhook(body);
    if (result.code === 'SUCCESS') return { code: 'SUCCESS', message: 'OK' };
    return { code: 'FAIL', message: result.message };
  }

  @Post('wxpay/refund')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiOperation({ summary: '微信支付退款（转网关）' })
  @ApiBody({ type: RefundDto })
  async refund(@Body() body: RefundDto) {
    return this.gatewayPay.refund(body.outTradeNo, body.amount, body.reason);
  }

  @Get('wxpay/query')
  @ApiOperation({ summary: '查询订单状态（网关）' })
  @ApiQuery({ name: 'outTradeNo', required: true })
  async query(@Query('outTradeNo') outTradeNo: string) {
    const order = await this.prisma.order.findUnique({ where: { orderNo: outTradeNo } });
    if (!order) throw new HttpException('订单不存在', HttpStatus.NOT_FOUND);

    if (order.gatewayOrderId && !order.gatewayOrderId.startsWith('mock_')) {
      const result = await this.gatewayPay.queryOrder(order.gatewayOrderId);
      return {
        trade_state: result.status === 'paid' ? 'SUCCESS' : 'NOTPAY',
        outTradeNo,
        localStatus: order.status,
        amount: order.amount,
        gatewayStatus: result.status,
      };
    }

    return {
      trade_state: order.status === 'PAID' ? 'SUCCESS' : 'NOTPAY',
      outTradeNo,
      localStatus: order.status,
      amount: order.amount,
      planType: order.planType,
    };
  }

  @Post('gateway/webhook')
  @HttpCode(200)
  @ApiOperation({ summary: '统一支付网关Webhook' })
  async gatewayWebhook(@Body() body: any) {
    const result = await this.gatewayPay.handleWebhook(body);
    if (result.code === 'SUCCESS') return 'success';
    return 'fail';
  }

  @Post('gateway/sync/:orderNo')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiOperation({ summary: '手动同步订单状态（从网关查询并更新本地）' })
  async syncOrderStatus(@Param('orderNo') orderNo: string) {
    const result = await this.gatewayPay.syncOrderStatus(orderNo);
    if (result.status === 'not_found') {
      throw new HttpException('订单不存在', HttpStatus.NOT_FOUND);
    }
    return result;
  }

  @Post('gateway/close/:gatewayOrderId')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiOperation({ summary: '关闭未支付订单' })
  async closeOrder(@Param('gatewayOrderId') gatewayOrderId: string) {
    const ok = await this.gatewayPay.closeOrder(gatewayOrderId);
    if (!ok) throw new HttpException('关闭订单失败', HttpStatus.BAD_REQUEST);
    return { code: 0, message: '订单已关闭' };
  }
}
