import {
  Controller,
  Get,
  Post,
  Param,
  Query,
  Body,
  Req,
  Res,
  HttpCode,
  HttpStatus,
  UseInterceptors,
  UploadedFile,
  BadRequestException,
  NotFoundException,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiParam,
  ApiBearerAuth,
  ApiConsumes,
} from '@nestjs/swagger';
import * as path from 'path';
import * as fs from 'fs';
import { Public } from '../../shared/guards/jwt-auth.guard';
import { C2cService } from '../../application/services/c2c.service';
import {
  CreateC2cOrderDto,
  TakeC2cOrderDto,
  QueryC2cOrdersDto,
  QueryMyC2cOrdersDto,
  C2cOrderResponseDto,
  C2cOrdersPageResponseDto,
} from '../dto/c2c.dto';
import { C2cOrderEntity } from '../../infrastructure/persistence/repositories/c2c-order.repository';
import { RequireCapability } from '../../shared/decorators/require-capability.decorator';

@ApiTags('C2C Trading')
@ApiBearerAuth()
@Controller('c2c')
export class C2cController {
  constructor(private readonly c2cService: C2cService) {}

  /**
   * 将订单实体转为响应DTO
   */
  private toResponseDto(order: C2cOrderEntity): C2cOrderResponseDto {
    return {
      orderNo: order.orderNo,
      type: order.type,
      status: order.status,
      makerAccountSequence: order.makerAccountSequence,
      makerPhone: order.makerPhone || undefined,
      makerNickname: order.makerNickname || undefined,
      takerAccountSequence: order.takerAccountSequence || undefined,
      takerPhone: order.takerPhone || undefined,
      takerNickname: order.takerNickname || undefined,
      price: order.price,
      quantity: order.quantity,
      totalAmount: order.totalAmount,
      minAmount: order.minAmount,
      maxAmount: order.maxAmount,
      // 收款信息
      paymentMethod: order.paymentMethod || undefined,
      paymentAccount: order.paymentAccount || undefined,
      paymentQrCode: order.paymentQrCode || undefined,
      paymentRealName: order.paymentRealName || undefined,
      // 付款水单
      paymentProofUrl: order.paymentProofUrl || undefined,
      // 卖家 Kava 地址
      sellerKavaAddress: order.sellerKavaAddress || undefined,
      // 超时信息
      paymentTimeoutMinutes: order.paymentTimeoutMinutes,
      confirmTimeoutMinutes: order.confirmTimeoutMinutes,
      paymentDeadline: order.paymentDeadline || undefined,
      confirmDeadline: order.confirmDeadline || undefined,
      // 其他
      remark: order.remark || undefined,
      createdAt: order.createdAt,
      matchedAt: order.matchedAt || undefined,
      paidAt: order.paidAt || undefined,
      completedAt: order.completedAt || undefined,
      expiredAt: order.expiredAt || undefined,
    };
  }

  @Get('orders')
  @ApiOperation({ summary: '获取C2C市场订单列表（待接单的广告）' })
  @ApiResponse({ status: 200, description: '订单列表' })
  async getMarketOrders(
    @Query() query: QueryC2cOrdersDto,
    @Req() req: any,
  ): Promise<C2cOrdersPageResponseDto> {
    const accountSequence = req.user?.accountSequence;
    const result = await this.c2cService.getMarketOrders({
      type: query.type,
      page: query.page ?? 1,
      pageSize: query.pageSize ?? 20,
      excludeAccountSequence: accountSequence, // 排除自己的订单
    });

    return {
      data: result.data.map((o) => this.toResponseDto(o)),
      total: result.total,
      page: result.page,
      pageSize: result.pageSize,
    };
  }

  @Get('orders/my')
  @RequireCapability('VIEW_RECORDS')
  @ApiOperation({ summary: '获取我的C2C订单' })
  @ApiResponse({ status: 200, description: '我的订单列表' })
  async getMyOrders(
    @Query() query: QueryMyC2cOrdersDto,
    @Req() req: any,
  ): Promise<C2cOrdersPageResponseDto> {
    const accountSequence = req.user?.accountSequence;
    if (!accountSequence) {
      throw new Error('Unauthorized');
    }

    const result = await this.c2cService.getMyOrders(accountSequence, {
      status: query.status,
      page: query.page ?? 1,
      pageSize: query.pageSize ?? 20,
    });

    return {
      data: result.data.map((o) => this.toResponseDto(o)),
      total: result.total,
      page: result.page,
      pageSize: result.pageSize,
    };
  }

  @Post('orders')
  @RequireCapability('C2C')
  @ApiOperation({ summary: '创建C2C订单（发布广告）' })
  @ApiResponse({ status: 201, description: '订单创建成功' })
  async createOrder(
    @Body() dto: CreateC2cOrderDto,
    @Req() req: any,
  ): Promise<C2cOrderResponseDto> {
    const accountSequence = req.user?.accountSequence;
    if (!accountSequence) {
      throw new Error('Unauthorized');
    }

    const order = await this.c2cService.createOrder(
      accountSequence,
      dto.type,
      dto.price,
      dto.quantity,
      {
        minAmount: dto.minAmount,
        maxAmount: dto.maxAmount,
        // 收款信息
        paymentMethod: dto.paymentMethod,
        paymentAccount: dto.paymentAccount,
        paymentQrCode: dto.paymentQrCode,
        paymentRealName: dto.paymentRealName,
        remark: dto.remark,
        userId: req.user?.userId,
        phone: req.user?.phone,
        nickname: req.user?.nickname,
      },
    );

    return this.toResponseDto(order);
  }

  @Get('orders/:orderNo')
  @ApiOperation({ summary: '获取C2C订单详情' })
  @ApiParam({ name: 'orderNo', description: '订单号' })
  @ApiResponse({ status: 200, description: '订单详情' })
  async getOrderDetail(@Param('orderNo') orderNo: string): Promise<C2cOrderResponseDto> {
    const order = await this.c2cService.getOrderDetail(orderNo);
    return this.toResponseDto(order);
  }

  @Post('orders/:orderNo/take')
  @RequireCapability('C2C')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: '接单（吃单）' })
  @ApiParam({ name: 'orderNo', description: '订单号' })
  @ApiResponse({ status: 200, description: '接单成功' })
  async takeOrder(
    @Param('orderNo') orderNo: string,
    @Body() dto: TakeC2cOrderDto,
    @Req() req: any,
  ): Promise<C2cOrderResponseDto> {
    const accountSequence = req.user?.accountSequence;
    if (!accountSequence) {
      throw new Error('Unauthorized');
    }

    const order = await this.c2cService.takeOrder(orderNo, accountSequence, {
      quantity: dto.quantity,
      // 收款信息（接买单时由taker提供）
      paymentMethod: dto.paymentMethod,
      paymentAccount: dto.paymentAccount,
      paymentQrCode: dto.paymentQrCode,
      paymentRealName: dto.paymentRealName,
      userId: req.user?.userId,
      phone: req.user?.phone,
      nickname: req.user?.nickname,
    });

    return this.toResponseDto(order);
  }

  @Post('orders/:orderNo/cancel')
  @RequireCapability('C2C')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: '取消C2C订单' })
  @ApiParam({ name: 'orderNo', description: '订单号' })
  @ApiResponse({ status: 200, description: '取消成功' })
  async cancelOrder(
    @Param('orderNo') orderNo: string,
    @Req() req: any,
  ): Promise<{ success: boolean }> {
    const accountSequence = req.user?.accountSequence;
    if (!accountSequence) {
      throw new Error('Unauthorized');
    }

    await this.c2cService.cancelOrder(orderNo, accountSequence);
    return { success: true };
  }

  @Post('orders/:orderNo/confirm-payment')
  @RequireCapability('C2C')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: '确认付款（买方操作）' })
  @ApiParam({ name: 'orderNo', description: '订单号' })
  @ApiResponse({ status: 200, description: '确认付款成功' })
  async confirmPayment(
    @Param('orderNo') orderNo: string,
    @Req() req: any,
  ): Promise<C2cOrderResponseDto> {
    const accountSequence = req.user?.accountSequence;
    if (!accountSequence) {
      throw new Error('Unauthorized');
    }

    const order = await this.c2cService.confirmPayment(orderNo, accountSequence);
    return this.toResponseDto(order);
  }

  @Post('orders/:orderNo/confirm-received')
  @RequireCapability('C2C')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: '确认收款（卖方操作）' })
  @ApiParam({ name: 'orderNo', description: '订单号' })
  @ApiResponse({ status: 200, description: '确认收款成功，交易完成' })
  async confirmReceived(
    @Param('orderNo') orderNo: string,
    @Req() req: any,
  ): Promise<C2cOrderResponseDto> {
    const accountSequence = req.user?.accountSequence;
    if (!accountSequence) {
      throw new Error('Unauthorized');
    }

    const order = await this.c2cService.confirmReceived(orderNo, accountSequence);
    return this.toResponseDto(order);
  }

  @Post('orders/:orderNo/upload-proof')
  @RequireCapability('C2C')
  @HttpCode(HttpStatus.OK)
  @UseInterceptors(FileInterceptor('file', {
    limits: { fileSize: 10 * 1024 * 1024 }, // 10MB
    fileFilter: (_req: any, file: any, cb: any) => {
      if (!file.mimetype.match(/^image\/(jpeg|png|gif|webp)$/)) {
        cb(new BadRequestException('仅支持 JPEG/PNG/GIF/WebP 图片'), false);
      } else {
        cb(null, true);
      }
    },
  }))
  @ApiOperation({ summary: '上传付款水单（买方操作）' })
  @ApiConsumes('multipart/form-data')
  @ApiParam({ name: 'orderNo', description: '订单号' })
  @ApiResponse({ status: 200, description: '上传成功' })
  async uploadPaymentProof(
    @Param('orderNo') orderNo: string,
    @UploadedFile() file: { originalname: string; buffer: Buffer; mimetype: string; size: number },
    @Req() req: any,
  ): Promise<C2cOrderResponseDto> {
    const accountSequence = req.user?.accountSequence;
    if (!accountSequence) {
      throw new Error('Unauthorized');
    }
    if (!file) {
      throw new BadRequestException('请上传付款水单图片');
    }

    const order = await this.c2cService.uploadPaymentProof(orderNo, accountSequence, file);
    return this.toResponseDto(order);
  }

  @Public()
  @Get('proofs/:filename')
  @ApiOperation({ summary: '获取付款水单图片' })
  @ApiParam({ name: 'filename', description: '文件名' })
  async getProofImage(
    @Param('filename') filename: string,
    @Res() res: any,
  ): Promise<void> {
    // 防止路径遍历攻击
    const safeName = path.basename(filename);
    const filePath = path.resolve('./uploads/c2c-proofs', safeName);
    if (!fs.existsSync(filePath)) {
      throw new NotFoundException('文件不存在');
    }
    res.sendFile(filePath);
  }
}
