import {
  IsEmail,
  IsString,
  MinLength,
  IsOptional,
  ValidateNested,
  IsEnum,
  MaxLength,
  Matches,
  IsBoolean,
} from 'class-validator';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import { OrganizationType } from '@domain/entities/organization.entity';

export class LoginDto {
  @ApiProperty({
    example: 'john.doe@acme.com',
    description: 'Email address',
  })
  @IsEmail({}, { message: 'Invalid email format' })
  email: string;

  @ApiProperty({
    example: 'SecurePassword123!',
    description: 'Password',
  })
  @IsString()
  password: string;

  @ApiPropertyOptional({
    example: true,
    description: 'Remember me for extended session',
  })
  @IsBoolean()
  @IsOptional()
  rememberMe?: boolean;
}

export class ContactFormDto {
  @ApiProperty({ example: 'Jean', description: 'First name' })
  @IsString()
  @MinLength(1)
  firstName: string;

  @ApiProperty({ example: 'Dupont', description: 'Last name' })
  @IsString()
  @MinLength(1)
  lastName: string;

  @ApiProperty({ example: 'jean@acme.com', description: 'Sender email' })
  @IsEmail({}, { message: 'Invalid email format' })
  email: string;

  @ApiPropertyOptional({ example: 'Acme Logistics', description: 'Company name' })
  @IsString()
  @IsOptional()
  company?: string;

  @ApiPropertyOptional({ example: '+33 6 12 34 56 78', description: 'Phone number' })
  @IsString()
  @IsOptional()
  phone?: string;

  @ApiProperty({ example: 'demo', description: 'Subject category' })
  @IsString()
  @MinLength(1)
  subject: string;

  @ApiProperty({ example: 'Bonjour, je souhaite...', description: 'Message body' })
  @IsString()
  @MinLength(10)
  message: string;
}

export class ForgotPasswordDto {
  @ApiProperty({
    example: 'john.doe@acme.com',
    description: 'Email address for password reset',
  })
  @IsEmail({}, { message: 'Invalid email format' })
  email: string;
}

export class ResetPasswordDto {
  @ApiProperty({
    example: 'abc123token...',
    description: 'Password reset token from email',
  })
  @IsString()
  token: string;

  @ApiProperty({
    example: 'NewSecurePassword123!',
    description: 'New password (minimum 12 characters)',
    minLength: 12,
  })
  @IsString()
  @MinLength(12, { message: 'Password must be at least 12 characters' })
  newPassword: string;
}

/**
 * Organization data for registration (nested in RegisterDto)
 */
export class RegisterOrganizationDto {
  @ApiProperty({
    example: 'Acme Freight Forwarding',
    description: 'Organization name',
    minLength: 2,
    maxLength: 200,
  })
  @IsString()
  @MinLength(2)
  @MaxLength(200)
  name: string;

  @ApiProperty({
    example: OrganizationType.FREIGHT_FORWARDER,
    description: 'Organization type',
    enum: OrganizationType,
  })
  @IsEnum(OrganizationType)
  type: OrganizationType;

  @ApiProperty({
    example: '123 Main Street',
    description: 'Street address',
  })
  @IsString()
  street: string;

  @ApiProperty({
    example: 'Rotterdam',
    description: 'City',
  })
  @IsString()
  city: string;

  @ApiPropertyOptional({
    example: 'South Holland',
    description: 'State or province',
  })
  @IsString()
  @IsOptional()
  state?: string;

  @ApiProperty({
    example: '3000 AB',
    description: 'Postal code',
  })
  @IsString()
  postalCode: string;

  @ApiProperty({
    example: 'NL',
    description: 'Country code (ISO 3166-1 alpha-2)',
    minLength: 2,
    maxLength: 2,
  })
  @IsString()
  @MinLength(2)
  @MaxLength(2)
  @Matches(/^[A-Z]{2}$/, { message: 'Country must be a 2-letter ISO code (e.g., NL, US, CN)' })
  country: string;

  @ApiProperty({
    example: '123456789',
    description: 'French SIREN number (9 digits, required)',
    minLength: 9,
    maxLength: 9,
  })
  @IsString()
  @MinLength(9, { message: 'SIREN must be exactly 9 digits' })
  @MaxLength(9, { message: 'SIREN must be exactly 9 digits' })
  @Matches(/^[0-9]{9}$/, { message: 'SIREN must be 9 digits' })
  siren: string;

  @ApiPropertyOptional({
    example: '12345678901234',
    description: 'French SIRET number (14 digits, optional)',
    minLength: 14,
    maxLength: 14,
  })
  @IsString()
  @IsOptional()
  @MinLength(14, { message: 'SIRET must be exactly 14 digits' })
  @MaxLength(14, { message: 'SIRET must be exactly 14 digits' })
  @Matches(/^[0-9]{14}$/, { message: 'SIRET must be 14 digits' })
  siret?: string;

  @ApiPropertyOptional({
    example: 'MAEU',
    description: 'Standard Carrier Alpha Code (4 uppercase letters, required for carriers only)',
    minLength: 4,
    maxLength: 4,
  })
  @IsString()
  @IsOptional()
  @MinLength(4)
  @MaxLength(4)
  @Matches(/^[A-Z]{4}$/, { message: 'SCAC must be 4 uppercase letters' })
  scac?: string;
}

export class RegisterDto {
  @ApiProperty({
    example: 'john.doe@acme.com',
    description: 'Email address',
  })
  @IsEmail({}, { message: 'Invalid email format' })
  email: string;

  @ApiProperty({
    example: 'SecurePassword123!',
    description: 'Password (minimum 12 characters)',
    minLength: 12,
  })
  @IsString()
  @MinLength(12, { message: 'Password must be at least 12 characters' })
  password: string;

  @ApiPropertyOptional({
    example: 'John',
    description: 'First name (optional if using invitation token)',
  })
  @IsString()
  @IsOptional()
  @MinLength(2, { message: 'First name must be at least 2 characters' })
  firstName: string;

  @ApiPropertyOptional({
    example: 'Doe',
    description: 'Last name (optional if using invitation token)',
  })
  @IsString()
  @IsOptional()
  @MinLength(2, { message: 'Last name must be at least 2 characters' })
  lastName: string;

  @ApiPropertyOptional({
    example: 'abc123def456',
    description: 'Invitation token (for invited users)',
    required: false,
  })
  @IsString()
  @IsOptional()
  invitationToken?: string;

  @ApiPropertyOptional({
    example: '550e8400-e29b-41d4-a716-446655440000',
    description:
      'Organization ID (optional - for invited users). If not provided, organization data must be provided.',
    required: false,
  })
  @IsString()
  @IsOptional()
  organizationId?: string;

  @ApiPropertyOptional({
    description:
      'Organization data (required if organizationId and invitationToken are not provided)',
    type: RegisterOrganizationDto,
    required: false,
  })
  @ValidateNested()
  @Type(() => RegisterOrganizationDto)
  @IsOptional()
  organization?: RegisterOrganizationDto;
}

export class AuthResponseDto {
  @ApiProperty({
    example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
    description: 'JWT access token (valid 15 minutes)',
  })
  accessToken: string;

  @ApiProperty({
    example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
    description: 'JWT refresh token (valid 7 days)',
  })
  refreshToken: string;

  @ApiProperty({
    example: {
      id: '550e8400-e29b-41d4-a716-446655440000',
      email: 'john.doe@acme.com',
      firstName: 'John',
      lastName: 'Doe',
      role: 'user',
      organizationId: '550e8400-e29b-41d4-a716-446655440001',
    },
    description: 'User information',
  })
  user: {
    id: string;
    email: string;
    firstName: string;
    lastName: string;
    role: string;
    organizationId: string;
  };
}

export class RefreshTokenDto {
  @ApiProperty({
    example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
    description: 'Refresh token',
  })
  @IsString()
  refreshToken: string;
}
