import { Controller, Get, Post, Body, Query, HttpCode, HttpStatus } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiQuery } from '@nestjs/swagger';
import { IsBoolean } from 'class-validator';
import { PrismaService } from '../../infrastructure/persistence/prisma/prisma.service';
import { TradingConfigRepository } from '../../infrastructure/persistence/repositories/trading-config.repository';
import { OrderRepository } from '../../infrastructure/persistence/repositories/order.repository';
import { OrderType, OrderStatus, OrderSource } from '../../domain/aggregates/order.aggregate';
import { Public } from '../../shared/guards/jwt-auth.guard';

class SetBuyEnabledDto {
  @IsBoolean()
  enabled: boolean;
}

class SetDepthEnabledDto {
  @IsBoolean()
  enabled: boolean;
}

@ApiTags('Admin')
@Controller('admin')
export class AdminController {
  constructor(
    private readonly prisma: PrismaService,
    private readonly tradingConfigRepository: TradingConfigRepository,
    private readonly orderRepository: OrderRepository,
  ) {}

  @Get('accounts/sync')
  @Public()
  @ApiOperation({ summary: '获取所有交易账户用于同步' })
  async getAllAccountsForSync() {
    const accounts = await this.prisma.tradingAccount.findMany({
      select: {
        accountSequence: true,
        shareBalance: true,
        cashBalance: true,
        frozenShares: true,
        frozenCash: true,
        totalBought: true,
        totalSold: true,
        createdAt: true,
        updatedAt: true,
      },
    });

    return {
      accounts: accounts.map((acc) => ({
        accountSequence: acc.accountSequence,
        shareBalance: acc.shareBalance.toString(),
        cashBalance: acc.cashBalance.toString(),
        frozenShares: acc.frozenShares.toString(),
        frozenCash: acc.frozenCash.toString(),
        totalBought: acc.totalBought.toString(),
        totalSold: acc.totalSold.toString(),
        createdAt: acc.createdAt,
        updatedAt: acc.updatedAt,
      })),
      total: accounts.length,
    };
  }

  @Get('trading/status')
  @Public()
  @ApiOperation({ summary: '获取交易系统状态' })
  @ApiResponse({ status: 200, description: '返回交易系统配置状态' })
  async getTradingStatus() {
    const config = await this.tradingConfigRepository.getConfig();
    if (!config) {
      return {
        initialized: false,
        isActive: false,
        buyEnabled: false,
        activatedAt: null,
        message: '交易系统未初始化',
      };
    }

    return {
      initialized: true,
      isActive: config.isActive,
      buyEnabled: config.buyEnabled,
      activatedAt: config.activatedAt,
      totalShares: config.totalShares.toFixed(8),
      burnTarget: config.burnTarget.toFixed(8),
      burnPeriodMinutes: config.burnPeriodMinutes,
      minuteBurnRate: config.minuteBurnRate.toFixed(18),
      message: config.isActive ? '交易系统已激活' : '交易系统未激活',
    };
  }

  @Get('trading/buy-enabled')
  @Public()
  @ApiOperation({ summary: '获取买入功能开关状态' })
  @ApiResponse({ status: 200, description: '返回买入功能是否启用' })
  async getBuyEnabled() {
    const config = await this.tradingConfigRepository.getConfig();
    return {
      enabled: config?.buyEnabled ?? false,
    };
  }

  @Post('trading/buy-enabled')
  @Public() // TODO: 生产环境应添加管理员权限验证
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: '设置买入功能开关' })
  @ApiResponse({ status: 200, description: '买入功能开关设置成功' })
  async setBuyEnabled(@Body() dto: SetBuyEnabledDto) {
    await this.tradingConfigRepository.setBuyEnabled(dto.enabled);
    return {
      success: true,
      enabled: dto.enabled,
      message: dto.enabled ? '买入功能已开启' : '买入功能已关闭',
    };
  }

  @Post('trading/activate')
  @Public() // TODO: 生产环境应添加管理员权限验证
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: '激活交易/销毁系统' })
  @ApiResponse({ status: 200, description: '交易系统已激活' })
  @ApiResponse({ status: 400, description: '交易系统未初始化' })
  async activateTrading() {
    const config = await this.tradingConfigRepository.getConfig();
    if (!config) {
      return {
        success: false,
        message: '交易系统未初始化，请先启动服务',
      };
    }

    if (config.isActive) {
      return {
        success: true,
        message: '交易系统已处于激活状态',
        activatedAt: config.activatedAt,
      };
    }

    await this.tradingConfigRepository.activate();
    const updatedConfig = await this.tradingConfigRepository.getConfig();

    return {
      success: true,
      message: '交易系统已激活，每分钟销毁已开始运行',
      activatedAt: updatedConfig?.activatedAt,
    };
  }

  @Post('trading/deactivate')
  @Public() // TODO: 生产环境应添加管理员权限验证
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: '关闭交易/销毁系统' })
  @ApiResponse({ status: 200, description: '交易系统已关闭' })
  async deactivateTrading() {
    const config = await this.tradingConfigRepository.getConfig();
    if (!config) {
      return {
        success: false,
        message: '交易系统未初始化',
      };
    }

    if (!config.isActive) {
      return {
        success: true,
        message: '交易系统已处于关闭状态',
      };
    }

    await this.tradingConfigRepository.deactivate();

    return {
      success: true,
      message: '交易系统已关闭，每分钟销毁已暂停',
    };
  }

  @Get('trading/depth-enabled')
  @Public()
  @ApiOperation({ summary: '获取深度显示开关状态' })
  @ApiResponse({ status: 200, description: '返回深度显示是否启用' })
  async getDepthEnabled() {
    const config = await this.tradingConfigRepository.getConfig();
    return {
      enabled: config?.depthEnabled ?? false,
    };
  }

  @Get('orders')
  @Public()
  @ApiOperation({ summary: '获取全局订单列表' })
  @ApiQuery({ name: 'page', required: false, type: Number })
  @ApiQuery({ name: 'pageSize', required: false, type: Number })
  @ApiQuery({ name: 'type', required: false, enum: ['BUY', 'SELL'] })
  @ApiQuery({ name: 'status', required: false, enum: ['PENDING', 'PARTIAL', 'FILLED', 'CANCELLED'] })
  @ApiQuery({ name: 'source', required: false, enum: ['USER', 'MARKET_MAKER', 'DEX_BOT', 'SYSTEM'] })
  @ApiQuery({ name: 'search', required: false, type: String })
  @ApiQuery({ name: 'startDate', required: false, type: String })
  @ApiQuery({ name: 'endDate', required: false, type: String })
  async getOrders(
    @Query('page') page?: number,
    @Query('pageSize') pageSize?: number,
    @Query('type') type?: string,
    @Query('status') status?: string,
    @Query('source') source?: string,
    @Query('search') search?: string,
    @Query('startDate') startDate?: string,
    @Query('endDate') endDate?: string,
  ) {
    const p = page ? Number(page) : 1;
    const ps = pageSize ? Number(pageSize) : 20;

    const result = await this.orderRepository.findAllOrders({
      type: type as OrderType | undefined,
      status: status as OrderStatus | undefined,
      source: source as OrderSource | undefined,
      search: search || undefined,
      startDate: startDate ? new Date(startDate) : undefined,
      endDate: endDate ? new Date(endDate) : undefined,
      page: p,
      pageSize: ps,
    });

    return {
      data: result.data,
      total: result.total,
      page: p,
      pageSize: ps,
      totalPages: Math.ceil(result.total / ps),
    };
  }

  @Get('trades')
  @Public()
  @ApiOperation({ summary: '获取全局成交记录' })
  @ApiQuery({ name: 'page', required: false, type: Number })
  @ApiQuery({ name: 'pageSize', required: false, type: Number })
  @ApiQuery({ name: 'source', required: false, enum: ['USER', 'MARKET_MAKER', 'DEX_BOT', 'SYSTEM'] })
  @ApiQuery({ name: 'search', required: false, type: String })
  @ApiQuery({ name: 'startDate', required: false, type: String })
  @ApiQuery({ name: 'endDate', required: false, type: String })
  async getTrades(
    @Query('page') page?: number,
    @Query('pageSize') pageSize?: number,
    @Query('source') source?: string,
    @Query('search') search?: string,
    @Query('startDate') startDate?: string,
    @Query('endDate') endDate?: string,
  ) {
    const p = page ? Number(page) : 1;
    const ps = pageSize ? Number(pageSize) : 20;

    const result = await this.orderRepository.findAllTrades({
      source: source || undefined,
      search: search || undefined,
      startDate: startDate ? new Date(startDate) : undefined,
      endDate: endDate ? new Date(endDate) : undefined,
      page: p,
      pageSize: ps,
    });

    return {
      data: result.data,
      total: result.total,
      page: p,
      pageSize: ps,
      totalPages: Math.ceil(result.total / ps),
    };
  }

  @Post('trading/depth-enabled')
  @Public() // TODO: 生产环境应添加管理员权限验证
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: '设置深度显示开关' })
  @ApiResponse({ status: 200, description: '深度显示开关设置成功' })
  async setDepthEnabled(@Body() dto: SetDepthEnabledDto) {
    await this.tradingConfigRepository.setDepthEnabled(dto.enabled);
    return {
      success: true,
      enabled: dto.enabled,
      message: dto.enabled ? '深度显示已开启' : '深度显示已关闭',
    };
  }
}
