import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import {
  CoManagedWalletSessionEntity,
  CoManagedWalletEntity,
  Participant,
  ThresholdConfig,
} from '../../../domain/entities/co-managed-wallet.entity';
import {
  WalletSessionStatus,
  ParticipantStatus,
} from '../../../domain/enums/wallet-session-status.enum';

/**
 * 参与方响应 DTO
 */
export class ParticipantDto {
  @ApiProperty({ description: '参与方 ID' })
  partyId: string;

  @ApiProperty({ description: '参与方名称' })
  name: string;

  @ApiProperty({ description: '状态', enum: ParticipantStatus })
  status: ParticipantStatus;

  @ApiProperty({ description: '加入时间' })
  joinedAt: string;

  static fromParticipant(participant: Participant): ParticipantDto {
    const dto = new ParticipantDto();
    dto.partyId = participant.partyId;
    dto.name = participant.name;
    dto.status = participant.status;
    dto.joinedAt = participant.joinedAt.toISOString();
    return dto;
  }
}

/**
 * 阈值配置响应 DTO
 */
export class ThresholdDto {
  @ApiProperty({ description: '签名阈值 (T)' })
  t: number;

  @ApiProperty({ description: '参与方总数 (N)' })
  n: number;

  static fromThreshold(threshold: ThresholdConfig): ThresholdDto {
    const dto = new ThresholdDto();
    dto.t = threshold.t;
    dto.n = threshold.n;
    return dto;
  }
}

/**
 * 共管钱包会话响应 DTO
 */
export class CoManagedWalletSessionDto {
  @ApiProperty({ description: '会话 ID' })
  sessionId: string;

  @ApiProperty({ description: '钱包名称' })
  walletName: string;

  @ApiProperty({ description: '阈值配置' })
  threshold: ThresholdDto;

  @ApiProperty({ description: '邀请码' })
  inviteCode: string;

  @ApiProperty({ description: '邀请链接' })
  inviteUrl: string;

  @ApiProperty({ description: '状态', enum: WalletSessionStatus })
  status: WalletSessionStatus;

  @ApiProperty({ description: '参与方列表', type: [ParticipantDto] })
  participants: ParticipantDto[];

  @ApiProperty({ description: '当前轮次' })
  currentRound: number;

  @ApiProperty({ description: '总轮次' })
  totalRounds: number;

  @ApiPropertyOptional({ description: '公钥' })
  publicKey?: string;

  @ApiPropertyOptional({ description: '错误信息' })
  error?: string;

  @ApiProperty({ description: '创建时间' })
  createdAt: string;

  @ApiProperty({ description: '更新时间' })
  updatedAt: string;

  @ApiProperty({ description: '创建者' })
  createdBy: string;

  static fromEntity(
    entity: CoManagedWalletSessionEntity,
    baseUrl: string = 'https://app.rwadurian.com',
  ): CoManagedWalletSessionDto {
    const dto = new CoManagedWalletSessionDto();
    dto.sessionId = entity.id;
    dto.walletName = entity.walletName;
    dto.threshold = ThresholdDto.fromThreshold(entity.threshold);
    dto.inviteCode = entity.inviteCode;
    dto.inviteUrl = `${baseUrl}/join/${entity.inviteCode}`;
    dto.status = entity.status;
    dto.participants = entity.participants.map(ParticipantDto.fromParticipant);
    dto.currentRound = entity.currentRound;
    dto.totalRounds = entity.totalRounds;
    dto.publicKey = entity.publicKey ?? undefined;
    dto.error = entity.error ?? undefined;
    dto.createdAt = entity.createdAt.toISOString();
    dto.updatedAt = entity.updatedAt.toISOString();
    dto.createdBy = entity.createdBy;
    return dto;
  }
}

/**
 * 创建会话响应 DTO
 */
export class CreateSessionResponseDto {
  @ApiProperty({ description: '是否成功' })
  success: boolean;

  @ApiProperty({ description: '会话信息' })
  session: CoManagedWalletSessionDto;
}

/**
 * 验证邀请码响应 DTO
 */
export class ValidateInviteCodeResponseDto {
  @ApiProperty({ description: '是否有效' })
  valid: boolean;

  @ApiPropertyOptional({ description: '会话信息' })
  session?: {
    sessionId: string;
    walletName: string;
    threshold: ThresholdDto;
    initiator: string;
    createdAt: string;
    currentParticipants: number;
  };

  @ApiPropertyOptional({ description: '错误信息' })
  error?: string;
}

/**
 * 会话列表响应 DTO
 */
export class SessionListResponseDto {
  @ApiProperty({ description: '会话列表', type: [CoManagedWalletSessionDto] })
  items: CoManagedWalletSessionDto[];

  @ApiProperty({ description: '总数' })
  total: number;

  @ApiProperty({ description: '当前页' })
  page: number;

  @ApiProperty({ description: '每页数量' })
  pageSize: number;

  @ApiProperty({ description: '总页数' })
  totalPages: number;
}

/**
 * 共管钱包响应 DTO
 */
export class CoManagedWalletDto {
  @ApiProperty({ description: '钱包 ID' })
  id: string;

  @ApiProperty({ description: '会话 ID' })
  sessionId: string;

  @ApiProperty({ description: '钱包名称' })
  name: string;

  @ApiProperty({ description: '公钥' })
  publicKey: string;

  @ApiProperty({ description: '阈值配置' })
  threshold: ThresholdDto;

  @ApiProperty({ description: '参与方数量' })
  participantCount: number;

  @ApiProperty({
    description: '参与方列表',
    type: 'array',
    items: { type: 'object', properties: { partyId: { type: 'string' }, name: { type: 'string' } } },
  })
  participants: Array<{ partyId: string; name: string }>;

  @ApiProperty({ description: '创建时间' })
  createdAt: string;

  @ApiProperty({ description: '创建者' })
  createdBy: string;

  static fromEntity(entity: CoManagedWalletEntity): CoManagedWalletDto {
    const dto = new CoManagedWalletDto();
    dto.id = entity.id;
    dto.sessionId = entity.sessionId;
    dto.name = entity.name;
    dto.publicKey = entity.publicKey;
    dto.threshold = ThresholdDto.fromThreshold(entity.threshold);
    dto.participantCount = entity.participants.length;
    dto.participants = entity.participants;
    dto.createdAt = entity.createdAt.toISOString();
    dto.createdBy = entity.createdBy;
    return dto;
  }
}

/**
 * 钱包列表响应 DTO
 */
export class WalletListResponseDto {
  @ApiProperty({ description: '钱包列表', type: [CoManagedWalletDto] })
  items: CoManagedWalletDto[];

  @ApiProperty({ description: '总数' })
  total: number;

  @ApiProperty({ description: '当前页' })
  page: number;

  @ApiProperty({ description: '每页数量' })
  pageSize: number;

  @ApiProperty({ description: '总页数' })
  totalPages: number;
}
