import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { IsBoolean, IsIn, IsNotEmpty, IsOptional, IsString } from 'class-validator';

export class OAuthAuthorizeQueryDto {
  @ApiProperty({ description: 'ID пользователя, который подтверждает OAuth доступ' })
  @IsString({ message: 'ID пользователя должен быть строкой' })
  userId!: string;

  @ApiProperty({ description: 'OAuth client_id приложения' })
  @IsString({ message: 'client_id должен быть строкой' })
  clientId!: string;

  @ApiProperty({ description: 'Разрешенный redirect_uri приложения' })
  @IsString({ message: 'redirect_uri должен быть строкой' })
  redirectUri!: string;

  @ApiProperty({ description: 'Запрошенные scopes через пробел', example: 'openid profile email' })
  @IsString({ message: 'scope должен быть строкой' })
  scope!: string;

  @ApiPropertyOptional({ description: 'OAuth state для защиты клиента' })
  @IsOptional()
  @IsString({ message: 'state должен быть строкой' })
  state?: string;
}

export class OAuthTokenDto {
  @ApiProperty({ description: 'Тип grant', enum: ['authorization_code', 'refresh_token'] })
  @IsIn(['authorization_code', 'refresh_token'], { message: 'grant_type должен быть authorization_code или refresh_token' })
  grantType!: string;

  @ApiPropertyOptional({ description: 'Authorization code' })
  @IsOptional()
  @IsString({ message: 'code должен быть строкой' })
  code?: string;

  @ApiPropertyOptional({ description: 'Refresh token' })
  @IsOptional()
  @IsString({ message: 'refresh_token должен быть строкой' })
  refreshToken?: string;

  @ApiProperty({ description: 'OAuth client_id' })
  @IsString({ message: 'client_id должен быть строкой' })
  clientId!: string;

  @ApiPropertyOptional({ description: 'OAuth client_secret' })
  @IsOptional()
  @IsString({ message: 'client_secret должен быть строкой' })
  clientSecret?: string;

  @ApiPropertyOptional({ description: 'redirect_uri для authorization_code grant' })
  @IsOptional()
  @IsString({ message: 'redirect_uri должен быть строкой' })
  redirectUri?: string;
}

export class SendOtpDto {
  @ApiProperty({ description: 'Почта или телефон получателя' })
  @IsString({ message: 'Получатель должен быть строкой' })
  target!: string;

  @ApiProperty({ description: 'Канал доставки', enum: ['email', 'sms'] })
  @IsIn(['email', 'sms'], { message: 'Канал должен быть email или sms' })
  channel!: string;

  @ApiProperty({ description: 'Назначение кода', example: 'login' })
  @IsString({ message: 'Назначение должно быть строкой' })
  purpose!: string;

  @ApiPropertyOptional({ description: 'ID пользователя, если код привязан к аккаунту' })
  @IsOptional()
  @IsString({ message: 'ID пользователя должен быть строкой' })
  userId?: string;
}

export class VerifyOtpDto {
  @ApiProperty({ description: 'Почта или телефон получателя' })
  @IsString({ message: 'Получатель должен быть строкой' })
  target!: string;

  @ApiProperty({ description: 'Код подтверждения' })
  @IsString({ message: 'Код должен быть строкой' })
  code!: string;

  @ApiProperty({ description: 'Назначение кода', example: 'login' })
  @IsString({ message: 'Назначение должно быть строкой' })
  purpose!: string;
}

export class WebAuthnDto {
  @ApiProperty({ description: 'ID пользователя' })
  @IsString({ message: 'ID пользователя должен быть строкой' })
  userId!: string;
}

export class QrSessionDto {
  @ApiProperty({ description: 'Название устройства', example: 'Chrome на Windows' })
  @IsString({ message: 'Название устройства должно быть строкой' })
  deviceName!: string;

  @ApiPropertyOptional({ description: 'Отпечаток устройства браузера' })
  @IsOptional()
  @IsString({ message: 'Отпечаток устройства должен быть строкой' })
  fingerprint?: string;

  @ApiPropertyOptional({ description: 'Тип устройства', example: 'WEB' })
  @IsOptional()
  @IsString({ message: 'Тип устройства должен быть строкой' })
  deviceType?: string;
}

export class CreateFamilyGroupDto {
  @ApiProperty({ description: 'ID владельца семьи' })
  @IsString({ message: 'ID владельца должен быть строкой' })
  ownerId!: string;

  @ApiProperty({ description: 'Название семейной группы', example: 'Семья Мамедовых' })
  @IsString({ message: 'Название семьи должно быть строкой' })
  @IsNotEmpty({ message: 'Укажите название семьи' })
  name!: string;
}

export class UpdateFamilyGroupDto {
  @ApiProperty({ description: 'Новое название семейной группы' })
  @IsString({ message: 'Название семьи должно быть строкой' })
  name!: string;
}

export class AddFamilyMemberDto {
  @ApiProperty({ description: 'ID пользователя, которого нужно добавить' })
  @IsString({ message: 'ID пользователя должен быть строкой' })
  userId!: string;

  @ApiProperty({ description: 'Роль участника семьи', example: 'member' })
  @IsString({ message: 'Роль должна быть строкой' })
  role!: string;
}

export class SendFamilyInviteDto {
  @ApiPropertyOptional({ description: 'Email, телефон или логин (legacy)' })
  @IsOptional()
  @IsString({ message: 'Укажите контакт приглашаемого' })
  target?: string;

  @ApiPropertyOptional({ description: 'ID пользователя из результатов поиска' })
  @IsOptional()
  @IsString({ message: 'ID пользователя должен быть строкой' })
  inviteeUserId?: string;
}

export class RespondFamilyInviteDto {
  @ApiProperty({ description: 'Принять приглашение' })
  @IsBoolean({ message: 'Укажите accept: true или false' })
  accept!: boolean;
}

