/**
 * Subscription DTOs
 *
 * Data Transfer Objects for subscription management API
 */

import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { IsString, IsEnum, IsUrl, IsOptional } from 'class-validator';

/**
 * Subscription plan types
 */
export enum SubscriptionPlanDto {
  BRONZE = 'BRONZE',
  SILVER = 'SILVER',
  GOLD = 'GOLD',
  PLATINIUM = 'PLATINIUM',
}

/**
 * Subscription status types
 */
export enum SubscriptionStatusDto {
  ACTIVE = 'ACTIVE',
  PAST_DUE = 'PAST_DUE',
  CANCELED = 'CANCELED',
  INCOMPLETE = 'INCOMPLETE',
  INCOMPLETE_EXPIRED = 'INCOMPLETE_EXPIRED',
  TRIALING = 'TRIALING',
  UNPAID = 'UNPAID',
  PAUSED = 'PAUSED',
}

/**
 * Billing interval types
 */
export enum BillingIntervalDto {
  MONTHLY = 'monthly',
  YEARLY = 'yearly',
}

/**
 * Create Checkout Session DTO
 */
export class CreateCheckoutSessionDto {
  @ApiProperty({
    example: SubscriptionPlanDto.SILVER,
    description: 'The subscription plan to purchase',
    enum: SubscriptionPlanDto,
  })
  @IsEnum(SubscriptionPlanDto)
  plan: SubscriptionPlanDto;

  @ApiProperty({
    example: BillingIntervalDto.MONTHLY,
    description: 'Billing interval (monthly or yearly)',
    enum: BillingIntervalDto,
  })
  @IsEnum(BillingIntervalDto)
  billingInterval: BillingIntervalDto;

  @ApiPropertyOptional({
    example: 'https://app.xpeditis.com/dashboard/settings/subscription?success=true',
    description: 'URL to redirect to after successful payment',
  })
  @IsUrl()
  @IsOptional()
  successUrl?: string;

  @ApiPropertyOptional({
    example: 'https://app.xpeditis.com/dashboard/settings/subscription?canceled=true',
    description: 'URL to redirect to if payment is canceled',
  })
  @IsUrl()
  @IsOptional()
  cancelUrl?: string;
}

/**
 * Create Portal Session DTO
 */
export class CreatePortalSessionDto {
  @ApiPropertyOptional({
    example: 'https://app.xpeditis.com/dashboard/settings/subscription',
    description: 'URL to return to after using the portal',
  })
  @IsUrl()
  @IsOptional()
  returnUrl?: string;
}

/**
 * Sync Subscription DTO
 */
export class SyncSubscriptionDto {
  @ApiPropertyOptional({
    example: 'cs_test_a1b2c3d4e5f6g7h8',
    description: 'Stripe checkout session ID (used after checkout completes)',
  })
  @IsString()
  @IsOptional()
  sessionId?: string;
}

/**
 * Checkout Session Response DTO
 */
export class CheckoutSessionResponseDto {
  @ApiProperty({
    example: 'cs_test_a1b2c3d4e5f6g7h8',
    description: 'Stripe checkout session ID',
  })
  sessionId: string;

  @ApiProperty({
    example: 'https://checkout.stripe.com/pay/cs_test_a1b2c3',
    description: 'URL to redirect user to for payment',
  })
  sessionUrl: string;
}

/**
 * Portal Session Response DTO
 */
export class PortalSessionResponseDto {
  @ApiProperty({
    example: 'https://billing.stripe.com/session/test_YWNjdF8x',
    description: 'URL to redirect user to for subscription management',
  })
  sessionUrl: string;
}

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

  @ApiProperty({
    example: '550e8400-e29b-41d4-a716-446655440001',
    description: 'User ID',
  })
  userId: string;

  @ApiProperty({
    example: 'john.doe@example.com',
    description: 'User email',
  })
  userEmail: string;

  @ApiProperty({
    example: 'John Doe',
    description: 'User full name',
  })
  userName: string;

  @ApiProperty({
    example: 'ADMIN',
    description: 'User role (ADMIN users have unlimited licenses)',
  })
  userRole: string;

  @ApiProperty({
    example: 'ACTIVE',
    description: 'License status',
  })
  status: string;

  @ApiProperty({
    example: '2025-01-15T10:00:00Z',
    description: 'When the license was assigned',
  })
  assignedAt: Date;

  @ApiPropertyOptional({
    example: '2025-02-15T10:00:00Z',
    description: 'When the license was revoked (if applicable)',
  })
  revokedAt?: Date;
}

/**
 * Plan Details DTO
 */
export class PlanDetailsDto {
  @ApiProperty({
    example: SubscriptionPlanDto.SILVER,
    description: 'Plan identifier',
    enum: SubscriptionPlanDto,
  })
  plan: SubscriptionPlanDto;

  @ApiProperty({
    example: 'Silver',
    description: 'Plan display name',
  })
  name: string;

  @ApiProperty({
    example: 5,
    description: 'Maximum number of licenses (-1 for unlimited)',
  })
  maxLicenses: number;

  @ApiProperty({
    example: 249,
    description: 'Monthly price in EUR',
  })
  monthlyPriceEur: number;

  @ApiProperty({
    example: 2739,
    description: 'Yearly price in EUR (11 months)',
  })
  yearlyPriceEur: number;

  @ApiProperty({
    example: -1,
    description: 'Maximum shipments per year (-1 for unlimited)',
  })
  maxShipmentsPerYear: number;

  @ApiProperty({
    example: 3,
    description: 'Commission rate percentage on shipments',
  })
  commissionRatePercent: number;

  @ApiProperty({
    example: 'email',
    description: 'Support level: none, email, direct, dedicated_kam',
  })
  supportLevel: string;

  @ApiProperty({
    example: 'silver',
    description: 'Status badge: none, silver, gold, platinium',
  })
  statusBadge: string;

  @ApiProperty({
    example: ['dashboard', 'wiki', 'user_management', 'csv_export'],
    description: 'List of plan feature flags',
    type: [String],
  })
  planFeatures: string[];

  @ApiProperty({
    example: ["Jusqu'à 5 utilisateurs", 'Expéditions illimitées', 'Import CSV'],
    description: 'List of human-readable features included in this plan',
    type: [String],
  })
  features: string[];
}

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

  @ApiProperty({
    example: '550e8400-e29b-41d4-a716-446655440001',
    description: 'Organization ID',
  })
  organizationId: string;

  @ApiProperty({
    example: SubscriptionPlanDto.SILVER,
    description: 'Current subscription plan',
    enum: SubscriptionPlanDto,
  })
  plan: SubscriptionPlanDto;

  @ApiProperty({
    description: 'Details about the current plan',
    type: PlanDetailsDto,
  })
  planDetails: PlanDetailsDto;

  @ApiProperty({
    example: SubscriptionStatusDto.ACTIVE,
    description: 'Current subscription status',
    enum: SubscriptionStatusDto,
  })
  status: SubscriptionStatusDto;

  @ApiProperty({
    example: 3,
    description: 'Number of licenses currently in use',
  })
  usedLicenses: number;

  @ApiProperty({
    example: 5,
    description: 'Maximum licenses available (-1 for unlimited)',
  })
  maxLicenses: number;

  @ApiProperty({
    example: 2,
    description: 'Number of licenses available',
  })
  availableLicenses: number;

  @ApiProperty({
    example: false,
    description: 'Whether the subscription is scheduled for cancellation',
  })
  cancelAtPeriodEnd: boolean;

  @ApiPropertyOptional({
    example: '2025-01-01T00:00:00Z',
    description: 'Start of current billing period',
  })
  currentPeriodStart?: Date;

  @ApiPropertyOptional({
    example: '2025-02-01T00:00:00Z',
    description: 'End of current billing period',
  })
  currentPeriodEnd?: Date;

  @ApiProperty({
    example: '2025-01-01T00:00:00Z',
    description: 'When the subscription was created',
  })
  createdAt: Date;

  @ApiProperty({
    example: '2025-01-15T10:00:00Z',
    description: 'When the subscription was last updated',
  })
  updatedAt: Date;
}

/**
 * Subscription Overview Response DTO (includes licenses)
 */
export class SubscriptionOverviewResponseDto extends SubscriptionResponseDto {
  @ApiProperty({
    description: 'List of active licenses',
    type: [LicenseResponseDto],
  })
  licenses: LicenseResponseDto[];
}

/**
 * Can Invite Response DTO
 */
export class CanInviteResponseDto {
  @ApiProperty({
    example: true,
    description: 'Whether the organization can invite more users',
  })
  canInvite: boolean;

  @ApiProperty({
    example: 2,
    description: 'Number of available licenses',
  })
  availableLicenses: number;

  @ApiProperty({
    example: 3,
    description: 'Number of used licenses',
  })
  usedLicenses: number;

  @ApiProperty({
    example: 5,
    description: 'Maximum licenses allowed (-1 for unlimited)',
  })
  maxLicenses: number;

  @ApiPropertyOptional({
    example: 'Upgrade to Starter plan to add more users',
    description: 'Message explaining why invitations are blocked',
  })
  message?: string;
}

/**
 * All Plans Response DTO
 */
export class AllPlansResponseDto {
  @ApiProperty({
    description: 'List of all available plans',
    type: [PlanDetailsDto],
  })
  plans: PlanDetailsDto[];
}
