/**
 * Migration Utilities
 * Story 1.3: Content Migration Script
 */

import { MigrationConfig } from './types'

// ============================================================
// LOGGING UTILITIES
// ============================================================

export const colors = {
  reset: '\x1b[0m',
  bright: '\x1b[1m',
  dim: '\x1b[2m',
  red: '\x1b[31m',
  green: '\x1b[32m',
  yellow: '\x1b[33m',
  blue: '\x1b[34m',
  cyan: '\x1b[36m',
  white: '\x1b[37m',
}

export class Logger {
  private verbose: boolean

  constructor(verbose: boolean = false) {
    this.verbose = verbose
  }

  info(message: string): void {
    console.log(`${colors.blue}ℹ${colors.reset} ${message}`)
  }

  success(message: string): void {
    console.log(`${colors.green}✓${colors.reset} ${message}`)
  }

  error(message: string): void {
    console.log(`${colors.red}✗${colors.reset} ${message}`)
  }

  warn(message: string): void {
    console.log(`${colors.yellow}⚠${colors.reset} ${message}`)
  }

  debug(message: string): void {
    if (this.verbose) {
      console.log(`${colors.dim}  →${colors.reset} ${message}`)
    }
  }

  header(message: string): void {
    console.log(`\n${colors.bright}${colors.cyan}${message}${colors.reset}`)
  }

  progress(current: number, total: number, message: string = ''): void {
    const percent = Math.round((current / total) * 100)
    const bar = '█'.repeat(Math.floor(percent / 2)) + '░'.repeat(50 - Math.floor(percent / 2))
    process.stdout.write(
      `\r${colors.cyan}[${bar}]${colors.reset} ${percent}% ${message}`.padEnd(100),
    )
    if (current === total) {
      process.stdout.write('\n')
    }
  }
}

// ============================================================
// STRING UTILITIES
// ============================================================

/**
 * Convert any string to a URL-friendly slug
 */
export function toSlug(value: string): string {
  return value
    .toString()
    .toLowerCase()
    .trim()
    .normalize('NFD') // Separate accented characters
    .replace(/[\u0300-\u036f]/g, '') // Remove diacritics
    .replace(/[^a-z0-9\u4e00-\u9fa5/-]/g, '-') // Replace non-alphanumeric with hyphen (keep Chinese)
    .replace(/-+/g, '-') // Replace multiple hyphens with single
    .replace(/^-+|-+$/g, '') // Trim hyphens from start/end
}

/**
 * Extract filename from URL
 */
export function getFilenameFromUrl(url: string): string {
  try {
    const urlObj = new URL(url)
    const pathname = urlObj.pathname
    const filename = pathname.split('/').pop()
    return filename || `file-${Date.now()}`
  } catch {
    return `file-${Date.now()}`
  }
}

/**
 * Get file extension from filename or URL
 */
export function getFileExtension(filename: string): string {
  const match = filename.match(/\.([^.]+)$/)
  return match ? match[1].toLowerCase() : 'jpg'
}

/**
 * Parse comma-separated tags into array
 */
export function parseTagsString(tagsString: string): Array<{ tag: string }> {
  if (!tagsString || typeof tagsString !== 'string') {
    return []
  }
  return tagsString
    .split(',')
    .map((tag) => tag.trim())
    .filter(Boolean)
    .map((tag) => ({ tag }))
}

/**
 * Convert hex color to text/background pair
 * Uses luminance to determine if text should be black or white
 */
export function splitColorToTextBackground(
  hexColor: string,
): { textColor: string; backgroundColor: string } {
  // Default to black text on white background
  const defaultResult = {
    textColor: '#000000',
    backgroundColor: '#ffffff',
  }

  if (!hexColor) {
    return defaultResult
  }

  // Ensure hex format
  let hex = hexColor.replace('#', '')
  if (hex.length === 3) {
    hex = hex.split('').map((c) => c + c).join('')
  }
  if (hex.length !== 6) {
    return defaultResult
  }

  // Calculate luminance
  const r = parseInt(hex.substr(0, 2), 16) / 255
  const g = parseInt(hex.substr(2, 2), 16) / 255
  const b = parseInt(hex.substr(4, 2), 16) / 255

  const luminance = 0.299 * r + 0.587 * g + 0.114 * b

  // Use original color as background, choose contrasting text
  return {
    textColor: luminance > 0.5 ? '#000000' : '#ffffff',
    backgroundColor: `#${hex}`,
  }
}

/**
 * Truncate text to max length
 */
export function truncate(text: string, maxLength: number): string {
  if (!text || text.length <= maxLength) {
    return text || ''
  }
  return text.substring(0, maxLength - 3) + '...'
}

// ============================================================
// DATE UTILITIES
// ============================================================

/**
 * Parse various date formats
 */
export function parseDate(dateValue: string | Date): Date {
  if (dateValue instanceof Date) {
    return dateValue
  }
  const parsed = new Date(dateValue)
  if (isNaN(parsed.getTime())) {
    return new Date() // Fallback to now
  }
  return parsed
}

/**
 * Format date for display
 */
export function formatDate(date: Date): string {
  return date.toISOString().split('T')[0]
}

// ============================================================
// HTML CLEANING UTILITIES
// ============================================================

/**
 * Clean HTML content by removing Webflow-specific classes and attributes
 */
export function cleanHTML(html: string): string {
  if (!html) {
    return ''
  }

  return html
    // Remove Webflow-specific classes
    .replace(/\sclass="[^"]*w-[^"]*"/g, '')
    .replace(/\sclass="[^"]*wf-[^"]*"/g, '')
    // Remove data attributes used by Webflow
    .replace(/\sdata-[a-z-]+="[^"]*"/gi, '')
    // Remove empty style attributes
    .replace(/\sstyle=""/g, '')
    // Clean up multiple spaces
    .replace(/\s+/g, ' ')
    .trim()
}

/**
 * Extract plain text from HTML (for excerpts)
 */
export function htmlToPlainText(html: string, maxLength: number = 200): string {
  if (!html) {
    return ''
  }

  // Remove script and style tags
  let text = html.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
  text = text.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '')

  // Replace block elements with newlines
  text = text.replace(/<\/(div|p|h[1-6]|li|tr)>/gi, '\n')
  text = text.replace(/<(br|hr)\s*\/?>/gi, '\n')

  // Remove all other tags
  text = text.replace(/<[^>]+>/g, '')

  // Decode HTML entities
  text = text.replace(/&nbsp;/g, ' ')
  text = text.replace(/&amp;/g, '&')
  text = text.replace(/&lt;/g, '<')
  text = text.replace(/&gt;/g, '>')
  text = text.replace(/&quot;/g, '"')
  text = text.replace(/&#39;/g, "'")

  // Clean up whitespace
  text = text.replace(/\n\s*\n/g, '\n\n').trim()

  return truncate(text, maxLength)
}

// ============================================================
// VALIDATION UTILITIES
// ============================================================

/**
 * Check if a value is a valid URL
 */
export function isValidUrl(value: string): boolean {
  try {
    new URL(value)
    return true
  } catch {
    return false
  }
}

/**
 * Check if a value is a valid image URL
 */
export function isValidImageUrl(value: string): boolean {
  if (!isValidUrl(value)) {
    return false
  }
  const ext = getFileExtension(value)
  return ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'].includes(ext)
}

// ============================================================
// CONFIG UTILITIES
// ============================================================

/**
 * Parse CLI arguments into MigrationConfig
 */
export function parseCliArgs(args: string[]): MigrationConfig {
  const config: MigrationConfig = {
    dryRun: false,
    verbose: false,
    collections: ['all'],
    force: false,
    batchSize: 5,
    sourcePath: './data/webflow-export.json',
  }

  for (let i = 0; i < args.length; i++) {
    const arg = args[i]
    switch (arg) {
      case '--dry-run':
      case '-n':
        config.dryRun = true
        break
      case '--verbose':
      case '-v':
        config.verbose = true
        break
      case '--force':
      case '-f':
        config.force = true
        break
      case '--collection':
      case '-c':
        if (args[i + 1]) {
          const collection = args[++i]
          if (collection === 'all') {
            config.collections = ['all']
          } else if (['categories', 'posts', 'portfolio'].includes(collection)) {
            config.collections = [collection as any]
          }
        }
        break
      case '--source':
      case '-s':
        if (args[i + 1]) {
          config.sourcePath = args[++i]
        }
        break
      case '--batch-size':
        if (args[i + 1]) {
          config.batchSize = parseInt(args[++i], 10) || 5
        }
        break
      case '--help':
      case '-h':
        printHelp()
        process.exit(0)
    }
  }

  return config
}

/**
 * Print help message
 */
export function printHelp(): void {
  console.log(`
${colors.bright}Webflow to Payload CMS Migration Script${colors.reset}

${colors.cyan}Usage:${colors.reset}
  pnpm tsx scripts/migration/migrate.ts [options]

${colors.cyan}Options:${colors.reset}
  -n, --dry-run          Run without making changes (preview mode)
  -v, --verbose          Show detailed logging output
  -f, --force            Overwrite existing items (skip deduplication)
  -c, --collection <name>  Specific collection to migrate (categories|posts|portfolio|all)
  -s, --source <path>     Path to HTML/JSON export file
  --batch-size <number>   Number of items to process in parallel (default: 5)
  -h, --help              Show this help message

${colors.cyan}Examples:${colors.reset}
  pnpm tsx scripts/migration/migrate.ts --dry-run --verbose
  pnpm tsx scripts/migration/migrate.ts --collection posts
  pnpm tsx scripts/migration/migrate.ts --source ./data/export.json

${colors.cyan}Environment Variables:${colors.reset}
  PAYLOAD_CMS_URL        Payload CMS URL (default: http://localhost:3000)
  MIGRATION_ADMIN_EMAIL  Admin user email for authentication
  MIGRATION_ADMIN_PASSWORD  Admin user password
`)
}
