/**
 * MPC Controller
 *
 * REST API endpoints for MPC keygen and signing operations.
 * Called by identity-service to coordinate MPC operations with mpc-system.
 *
 * 调用路径 (DDD 分领域):
 * identity-service (身份域) → mpc-service (MPC域) → mpc-system (Go/TSS实现)
 *
 * 数据存储:
 * - mpc-service: 存储公钥、share（分片）
 * - identity-service: 存储收款地址（BSC、KAVA、DST）
 */

import {
  Controller,
  Post,
  Get,
  Body,
  Param,
  HttpCode,
  HttpStatus,
  Logger,
} from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiParam,
} from '@nestjs/swagger';
import { Public } from '../../shared/decorators/public.decorator';
import { MPCCoordinatorService } from '../../application/services/mpc-coordinator.service';

// ============================================
// Request DTOs
// ============================================

export class CreateKeygenDto {
  username: string;
  thresholdN: number;
  thresholdT: number;
  requireDelegate: boolean;
}

export class CreateSigningDto {
  username: string;
  messageHash: string;
  userShare?: string;
}

// ============================================
// Response DTOs
// ============================================

export class KeygenSessionResponseDto {
  sessionId: string;
  status: string;
}

export class KeygenStatusResponseDto {
  sessionId: string;
  status: string;
  publicKey?: string;
  delegateShare?: {
    partyId: string;
    partyIndex: number;
    encryptedShare: string;
  };
}

export class SigningSessionResponseDto {
  sessionId: string;
  status: string;
}

export class SigningStatusResponseDto {
  sessionId: string;
  status: string;
  signature?: string;
}

@ApiTags('MPC')
@Controller('mpc')
export class MPCController {
  private readonly logger = new Logger(MPCController.name);

  constructor(
    private readonly mpcCoordinatorService: MPCCoordinatorService,
  ) {}

  /**
   * Create keygen session
   * Called by identity-service to start MPC keygen
   */
  @Public()
  @Post('keygen')
  @HttpCode(HttpStatus.CREATED)
  @ApiOperation({
    summary: '创建 MPC Keygen 会话',
    description: '创建一个新的 MPC keygen 会话，协调 mpc-system 完成密钥生成',
  })
  @ApiResponse({
    status: 201,
    description: 'Keygen session created',
    type: KeygenSessionResponseDto,
  })
  async createKeygen(@Body() dto: CreateKeygenDto): Promise<KeygenSessionResponseDto> {
    this.logger.log(`Creating keygen session: username=${dto.username}, ${dto.thresholdT}-of-${dto.thresholdN}, delegate=${dto.requireDelegate}`);

    const result = await this.mpcCoordinatorService.createKeygenSession({
      username: dto.username,
      thresholdN: dto.thresholdN,
      thresholdT: dto.thresholdT,
      requireDelegate: dto.requireDelegate,
    });

    return {
      sessionId: result.sessionId,
      status: result.status,
    };
  }

  /**
   * Get keygen session status
   */
  @Public()
  @Get('keygen/:sessionId/status')
  @ApiOperation({
    summary: '获取 Keygen 会话状态',
    description: '获取 keygen 会话的当前状态，包括公钥和 delegate share',
  })
  @ApiParam({ name: 'sessionId', description: 'Session ID' })
  @ApiResponse({
    status: 200,
    description: 'Keygen session status',
    type: KeygenStatusResponseDto,
  })
  async getKeygenStatus(@Param('sessionId') sessionId: string): Promise<KeygenStatusResponseDto> {
    this.logger.debug(`Getting keygen status: sessionId=${sessionId}`);

    const result = await this.mpcCoordinatorService.getKeygenStatus(sessionId);

    return {
      sessionId: result.sessionId,
      status: result.status,
      publicKey: result.publicKey,
      delegateShare: result.delegateShare,
    };
  }

  /**
   * Create signing session
   * Called by identity-service to start MPC signing
   */
  @Public()
  @Post('sign')
  @HttpCode(HttpStatus.CREATED)
  @ApiOperation({
    summary: '创建 MPC 签名会话',
    description: '创建一个新的 MPC signing 会话',
  })
  @ApiResponse({
    status: 201,
    description: 'Signing session created',
    type: SigningSessionResponseDto,
  })
  async createSigning(@Body() dto: CreateSigningDto): Promise<SigningSessionResponseDto> {
    this.logger.log(`Creating signing session: username=${dto.username}, messageHash=${dto.messageHash.slice(0, 16)}...`);

    const result = await this.mpcCoordinatorService.createSigningSession({
      username: dto.username,
      messageHash: dto.messageHash,
      userShare: dto.userShare,
    });

    return {
      sessionId: result.sessionId,
      status: result.status,
    };
  }

  /**
   * Get signing session status
   */
  @Public()
  @Get('sign/:sessionId/status')
  @ApiOperation({
    summary: '获取签名会话状态',
    description: '获取 signing 会话的当前状态，包括签名结果',
  })
  @ApiParam({ name: 'sessionId', description: 'Session ID' })
  @ApiResponse({
    status: 200,
    description: 'Signing session status',
    type: SigningStatusResponseDto,
  })
  async getSigningStatus(@Param('sessionId') sessionId: string): Promise<SigningStatusResponseDto> {
    this.logger.debug(`Getting signing status: sessionId=${sessionId}`);

    const result = await this.mpcCoordinatorService.getSigningStatus(sessionId);

    return {
      sessionId: result.sessionId,
      status: result.status,
      signature: result.signature,
    };
  }

  /**
   * Get public key by username
   * Used for address derivation
   */
  @Public()
  @Get('wallet/:username/public-key')
  @ApiOperation({
    summary: '获取用户公钥',
    description: '根据用户名获取 MPC 公钥',
  })
  @ApiParam({ name: 'username', description: 'Username' })
  @ApiResponse({
    status: 200,
    description: 'Public key info',
  })
  async getPublicKey(@Param('username') username: string) {
    this.logger.debug(`Getting public key: username=${username}`);

    const result = await this.mpcCoordinatorService.getPublicKeyByUsername(username);

    return {
      username: result.username,
      publicKey: result.publicKey,
    };
  }
}
