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

/**
 * Address DTO
 */
export class AddressDto {
  @ApiProperty({
    example: '123 Main Street',
    description: 'Street address',
  })
  @IsString()
  @IsNotEmpty()
  street: string;

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

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

  @ApiProperty({
    example: '3000 AB',
    description: 'Postal code',
  })
  @IsString()
  @IsNotEmpty()
  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;
}

/**
 * Create Organization DTO
 */
export class CreateOrganizationDto {
  @ApiProperty({
    example: 'Acme Freight Forwarding',
    description: 'Organization name',
    minLength: 2,
    maxLength: 200,
  })
  @IsString()
  @IsNotEmpty()
  @MinLength(2)
  @MaxLength(200)
  name: string;

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

  @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 (e.g., MAEU, MSCU)' })
  scac?: string;

  @ApiPropertyOptional({
    example: '123456789',
    description: 'French SIREN number (9 digits)',
  })
  @IsString()
  @IsOptional()
  @Matches(/^[0-9]{9}$/, { message: 'SIREN must be 9 digits' })
  siren?: string;

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

  @ApiPropertyOptional({
    example: 'FR123456789',
    description: 'EU EORI number',
  })
  @IsString()
  @IsOptional()
  eori?: string;

  @ApiPropertyOptional({
    example: '+33 6 80 18 28 12',
    description: 'Contact phone number',
  })
  @IsString()
  @IsOptional()
  contact_phone?: string;

  @ApiPropertyOptional({
    example: 'contact@xpeditis.com',
    description: 'Contact email address',
  })
  @IsString()
  @IsOptional()
  contact_email?: string;

  @ApiProperty({
    description: 'Organization address',
    type: AddressDto,
  })
  @ValidateNested()
  @Type(() => AddressDto)
  address: AddressDto;

  @ApiPropertyOptional({
    example: 'https://example.com/logo.png',
    description: 'Logo URL',
  })
  @IsUrl()
  @IsOptional()
  logoUrl?: string;
}

/**
 * Update Organization DTO
 */
export class UpdateOrganizationDto {
  @ApiPropertyOptional({
    example: 'Acme Freight Forwarding Inc.',
    description: 'Organization name',
    minLength: 2,
    maxLength: 200,
  })
  @IsString()
  @IsOptional()
  @MinLength(2)
  @MaxLength(200)
  name?: string;

  @ApiPropertyOptional({
    example: '123456789',
    description: 'French SIREN number (9 digits)',
  })
  @IsString()
  @IsOptional()
  @Matches(/^[0-9]{9}$/, { message: 'SIREN must be 9 digits' })
  siren?: string;

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

  @ApiPropertyOptional({
    example: 'FR123456789',
    description: 'EU EORI number',
  })
  @IsString()
  @IsOptional()
  eori?: string;

  @ApiPropertyOptional({
    example: '+33 6 80 18 28 12',
    description: 'Contact phone number',
  })
  @IsString()
  @IsOptional()
  contact_phone?: string;

  @ApiPropertyOptional({
    example: 'contact@xpeditis.com',
    description: 'Contact email address',
  })
  @IsString()
  @IsOptional()
  contact_email?: string;

  @ApiPropertyOptional({
    description: 'Organization address',
    type: AddressDto,
  })
  @ValidateNested()
  @Type(() => AddressDto)
  @IsOptional()
  address?: AddressDto;

  @ApiPropertyOptional({
    example: 'https://example.com/logo.png',
    description: 'Logo URL',
  })
  @IsUrl()
  @IsOptional()
  logoUrl?: string;

  @ApiPropertyOptional({
    example: true,
    description: 'Active status',
  })
  @IsBoolean()
  @IsOptional()
  isActive?: boolean;
}

/**
 * Organization Document DTO
 */
export class OrganizationDocumentDto {
  @ApiProperty({
    example: '550e8400-e29b-41d4-a716-446655440000',
    description: 'Document ID',
  })
  @IsUUID()
  id: string;

  @ApiProperty({
    example: 'business_license',
    description: 'Document type',
  })
  @IsString()
  type: string;

  @ApiProperty({
    example: 'Business License 2025',
    description: 'Document name',
  })
  @IsString()
  name: string;

  @ApiProperty({
    example: 'https://s3.amazonaws.com/xpeditis/documents/doc123.pdf',
    description: 'Document URL',
  })
  @IsUrl()
  url: string;

  @ApiProperty({
    example: '2025-01-15T10:00:00Z',
    description: 'Upload timestamp',
  })
  uploadedAt: Date;
}

/**
 * Organization Response DTO
 */
export class OrganizationResponseDto {
  @ApiProperty({
    example: '550e8400-e29b-41d4-a716-446655440000',
    description: 'Organization ID',
  })
  id: string;

  @ApiProperty({
    example: 'Acme Freight Forwarding',
    description: 'Organization name',
  })
  name: string;

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

  @ApiPropertyOptional({
    example: 'MAEU',
    description: 'Standard Carrier Alpha Code (carriers only)',
  })
  scac?: string;

  @ApiPropertyOptional({
    example: '123456789',
    description: 'French SIREN number (9 digits)',
  })
  siren?: string;

  @ApiPropertyOptional({
    example: 'FR123456789',
    description: 'EU EORI number',
  })
  eori?: string;

  @ApiPropertyOptional({
    example: '+33 6 80 18 28 12',
    description: 'Contact phone number',
  })
  contact_phone?: string;

  @ApiPropertyOptional({
    example: 'contact@xpeditis.com',
    description: 'Contact email address',
  })
  contact_email?: string;

  @ApiProperty({
    description: 'Organization address',
    type: AddressDto,
  })
  address: AddressDto;

  @ApiPropertyOptional({
    example: 'https://example.com/logo.png',
    description: 'Logo URL',
  })
  logoUrl?: string;

  @ApiProperty({
    description: 'Organization documents',
    type: [OrganizationDocumentDto],
  })
  documents: OrganizationDocumentDto[];

  @ApiPropertyOptional({
    example: '12345678901234',
    description: 'French SIRET number (14 digits)',
  })
  siret?: string;

  @ApiProperty({
    example: false,
    description: 'Whether the SIRET has been verified by an admin',
  })
  siretVerified: boolean;

  @ApiPropertyOptional({
    example: 'none',
    description: 'Organization status badge',
    enum: ['none', 'silver', 'gold', 'platinium'],
  })
  statusBadge?: string;

  @ApiProperty({
    example: true,
    description: 'Active status',
  })
  isActive: boolean;

  @ApiProperty({
    example: '2025-01-01T00:00:00Z',
    description: 'Creation timestamp',
  })
  createdAt: Date;

  @ApiProperty({
    example: '2025-01-15T10:00:00Z',
    description: 'Last update timestamp',
  })
  updatedAt: Date;
}

/**
 * Organization List Response DTO
 */
export class OrganizationListResponseDto {
  @ApiProperty({
    description: 'List of organizations',
    type: [OrganizationResponseDto],
  })
  organizations: OrganizationResponseDto[];

  @ApiProperty({
    example: 25,
    description: 'Total number of organizations',
  })
  total: number;

  @ApiProperty({
    example: 1,
    description: 'Current page number',
  })
  page: number;

  @ApiProperty({
    example: 20,
    description: 'Page size',
  })
  pageSize: number;

  @ApiProperty({
    example: 2,
    description: 'Total number of pages',
  })
  totalPages: number;
}
