import { Controller, Get, Post, Param, Query, Body, NotFoundException, Req } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiQuery, ApiBearerAuth } from '@nestjs/swagger';
import { IsString, IsIn } from 'class-validator';
import { OrderService } from '../../application/services/order.service';
import { OrderRepository } from '../../infrastructure/persistence/repositories/order.repository';
import { TradingAccountRepository } from '../../infrastructure/persistence/repositories/trading-account.repository';
import { OrderType } from '../../domain/aggregates/order.aggregate';
import { RequireCapability } from '../../shared/decorators/require-capability.decorator';

class CreateOrderDto {
  @IsIn(['BUY', 'SELL'])
  type: 'BUY' | 'SELL';

  @IsString()
  price: string;

  @IsString()
  quantity: string;
}

@ApiTags('Trading')
@ApiBearerAuth()
@Controller('trading')
export class TradingController {
  constructor(
    private readonly orderService: OrderService,
    private readonly orderRepository: OrderRepository,
    private readonly accountRepository: TradingAccountRepository,
  ) {}

  @Get('accounts/:accountSequence')
  @ApiOperation({ summary: '获取交易账户信息' })
  @ApiParam({ name: 'accountSequence', description: '账户序号' })
  async getAccount(@Param('accountSequence') accountSequence: string) {
    const account = await this.accountRepository.findByAccountSequence(accountSequence);
    if (!account) {
      throw new NotFoundException('Account not found');
    }
    return {
      accountSequence: account.accountSequence,
      shareBalance: account.shareBalance.toString(),
      cashBalance: account.cashBalance.toString(),
      availableShares: account.availableShares.toString(),
      availableCash: account.availableCash.toString(),
      frozenShares: account.frozenShares.toString(),
      frozenCash: account.frozenCash.toString(),
      totalBought: account.totalBought.toString(),
      totalSold: account.totalSold.toString(),
    };
  }

  @Get('orderbook')
  @ApiOperation({ summary: '获取订单簿' })
  @ApiQuery({ name: 'limit', required: false, type: Number })
  async getOrderBook(@Query('limit') limit?: number) {
    return this.orderRepository.getOrderBook(limit ?? 20);
  }

  @Post('orders')
  @RequireCapability('TRADING')
  @ApiOperation({ summary: '创建订单' })
  async createOrder(@Body() dto: CreateOrderDto, @Req() req: any) {
    const accountSequence = req.user?.accountSequence;
    if (!accountSequence) {
      throw new Error('Unauthorized');
    }

    return this.orderService.createOrder(
      accountSequence,
      dto.type === 'BUY' ? OrderType.BUY : OrderType.SELL,
      dto.price,
      dto.quantity,
    );
  }

  @Post('orders/:orderNo/cancel')
  @RequireCapability('TRADING')
  @ApiOperation({ summary: '取消订单' })
  @ApiParam({ name: 'orderNo', description: '订单号' })
  async cancelOrder(@Param('orderNo') orderNo: string, @Req() req: any) {
    const accountSequence = req.user?.accountSequence;
    if (!accountSequence) {
      throw new Error('Unauthorized');
    }

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

  @Get('orders')
  @RequireCapability('VIEW_RECORDS')
  @ApiOperation({ summary: '获取用户订单列表' })
  @ApiQuery({ name: 'page', required: false, type: Number })
  @ApiQuery({ name: 'pageSize', required: false, type: Number })
  async getOrders(
    @Req() req: any,
    @Query('page') page?: number,
    @Query('pageSize') pageSize?: number,
  ) {
    const accountSequence = req.user?.accountSequence;
    if (!accountSequence) {
      throw new Error('Unauthorized');
    }

    const result = await this.orderRepository.findByAccountSequence(accountSequence, {
      page: page ?? 1,
      pageSize: pageSize ?? 50,
    });

    return {
      data: result.data.map((o) => ({
        id: o.id,
        orderNo: o.orderNo,
        type: o.type,
        status: o.status,
        price: o.price.toString(),
        quantity: o.quantity.toString(),
        filledQuantity: o.filledQuantity.toString(),
        remainingQuantity: o.remainingQuantity.toString(),
        averagePrice: o.averagePrice.toString(),
        totalAmount: o.totalAmount.toString(),
        createdAt: o.createdAt,
        completedAt: o.completedAt,
        cancelledAt: o.cancelledAt,
      })),
      total: result.total,
    };
  }

  @Get('trades')
  @RequireCapability('VIEW_RECORDS')
  @ApiOperation({ summary: '获取用户成交记录（含手续费明细）' })
  @ApiQuery({ name: 'page', required: false, type: Number })
  @ApiQuery({ name: 'pageSize', required: false, type: Number })
  async getTrades(
    @Req() req: any,
    @Query('page') page?: number,
    @Query('pageSize') pageSize?: number,
  ) {
    const accountSequence = req.user?.accountSequence;
    if (!accountSequence) {
      throw new Error('Unauthorized');
    }

    return this.orderRepository.findTradesByAccountSequence(accountSequence, {
      page: page ?? 1,
      pageSize: pageSize ?? 50,
    });
  }
}
