import { Type } from 'class-transformer'
import {
  IsArray,
  IsEmail,
  IsEnum,
  IsInt,
  IsOptional,
  IsString,
  Matches,
  Max,
  MaxLength,
  Min,
  MinLength,
  ValidateNested,
} from 'class-validator'

class BillingInfoDto {
  @IsOptional() @IsString() @MaxLength(200) companyName?: string
  @IsOptional() @IsString() @MaxLength(40) vatId?: string
  @IsOptional() @IsString() @MaxLength(2) country?: string
  @IsOptional() @IsString() @MaxLength(200) contactEmail?: string
}

export class CreateTenantDto {
  @IsString()
  @Matches(/^[a-z0-9]([a-z0-9-]{0,38}[a-z0-9])?$/, {
    message: 'slug must be lowercase, 2-40 chars, hyphen-separated',
  })
  slug!: string

  @IsString() @MinLength(2) @MaxLength(120)
  name!: string

  @IsOptional() @IsEnum(['mvp', 'pro', 'enterprise'])
  plan?: 'mvp' | 'pro' | 'enterprise'

  // Billing cycle for the auto-created Subscription. Defaults to monthly
  // when omitted. Drives which Price catalog row attaches to the sub.
  @IsOptional() @IsEnum(['monthly', 'quarterly', 'yearly'])
  cycle?: 'monthly' | 'quarterly' | 'yearly'

  // Currency this customer is billed in. Picked by the partner in the
  // wizard. The matching Price row must have an amount set for this
  // currency or the tenant is created without a Subscription (operator
  // fixes up later).
  @IsOptional() @IsEnum(['DKK', 'EUR', 'USD'])
  currency?: 'DKK' | 'EUR' | 'USD'

  // First-admin invite. Optional — when present, the wizard's "First admin"
  // step has been filled in and the platform creates an Authentik user +
  // local User doc tied to this tenant as part of provisioning. Failures
  // here don't roll back the tenant — the operator can re-invite later.
  @IsOptional() @IsString() @MinLength(1) @MaxLength(200)
  adminName?: string

  @IsOptional() @IsEmail() @MaxLength(254)
  adminEmail?: string

  // Initial seat count. Upper bound is generous — partners can provision
  // bulk-license tenants and the platform doesn't impose a hard cap here.
  @IsOptional() @IsInt() @Min(0) @Max(10000)
  seats?: number

  @IsOptional() @IsArray() @IsString({ each: true })
  domains?: string[]

  @IsOptional() @ValidateNested() @Type(() => BillingInfoDto)
  billingInfo?: BillingInfoDto
}
