import type { AppliedDataSemantic } from '../Semantics.js'
import { SemanticType } from '../Semantics.js'

/**
 * Configuration options for the Phone semantic.
 * Controls validation, formatting, and verification of phone numbers.
 */
export interface PhoneConfig {
  /**
   * List of allowed country codes (ISO 3166-1 alpha-2 format).
   * If not specified, all countries are allowed.
   * Examples: ['US', 'CA', 'GB', 'DE']
   */
  allowedCountries?: string[]

  /**
   * Whether the phone number must include a country code.
   * Defaults to true for international format.
   */
  requireCountryCode?: boolean

  /**
   * Format for phone number validation and display.
   * - 'national': Country-specific format without country code
   * - 'international': E.164 international format with + prefix (e.g., +1234567890)
   * - 'custom': Use customFormat pattern
   */
  format?: 'national' | 'international' | 'custom'

  /**
   * Custom format pattern for phone number validation.
   * Only used when format is set to 'custom'.
   * Examples: '###-###-####', '(###) ###-####'
   */
  customFormat?: string

  /**
   * Whether to allow phone extensions (e.g., +1234567890 ext 123).
   * Defaults to false.
   */
  allowExtension?: boolean

  /**
   * Whether phone number verification is required.
   * Defaults to false.
   */
  requireVerification?: boolean

  /**
   * Method to use for phone verification.
   * - 'sms': Send verification code via SMS
   * - 'call': Make verification call
   */
  verificationMethod?: 'sms' | 'call'

  /**
   * Custom metadata for the phone field.
   */
  metadata?: Record<string, unknown>

  /**
   * Index signature to allow additional properties.
   */
  [key: string]: unknown
}

/**
 * Type-safe configuration for Phone semantic.
 */
export interface AppliedPhoneSemantic extends AppliedDataSemantic {
  id: SemanticType.Phone
  config?: PhoneConfig
}

/**
 * Type guard to check if a semantic is a Phone semantic.
 * @param semantic - The semantic to check
 * @returns True if the semantic is a Phone semantic
 */
export const isPhoneSemantic = (semantic: AppliedDataSemantic): semantic is AppliedPhoneSemantic => {
  return semantic.id === SemanticType.Phone
}

/**
 * Helper function to create a Phone semantic with configuration.
 * @param config - Configuration options for the phone semantic
 * @returns AppliedPhoneSemantic with the specified configuration
 */
export const createPhoneSemantic = (config: PhoneConfig = {}): AppliedPhoneSemantic => {
  const mergedConfig = {
    ...DEFAULT_PHONE_CONFIG,
    ...config,
  }
  if (config.metadata) {
    mergedConfig.metadata = { ...config.metadata }
  }

  return {
    id: SemanticType.Phone,
    config: mergedConfig,
  }
}

/**
 * Default configuration for Phone semantic.
 * Uses international format with country code required and SMS verification.
 */
export const DEFAULT_PHONE_CONFIG: PhoneConfig = {
  requireCountryCode: true,
  format: 'international',
  allowExtension: false,
  requireVerification: false,
  verificationMethod: 'sms',
}
