# frozen_string_literal: true

namespace :geoip do
  desc "Update the GeoIP database"
  task update: :environment do
    puts "Updating GeoIP database..."
    success = GeoIpService.update_database!

    if success
      puts "✅ GeoIP database successfully updated"
    else
      puts "❌ Failed to update GeoIP database"
    end
  end

  desc "Lookup country for a specific IP address"
  task :lookup, [:ip_address] => :environment do |_t, args|
    ip_address = args[:ip_address]

    if ip_address.blank?
      puts "❌ Please provide an IP address: rails geoip:lookup[8.8.8.8]"
      exit 1
    end

    puts "Looking up country for #{ip_address}..."

    begin
      country = GeoIpService.lookup_country(ip_address)

      if country.present?
        puts "📍 #{ip_address} → #{country}"
      else
        puts "❓ No country found for #{ip_address}"
      end
    rescue => e
      puts "❌ Error looking up #{ip_address}: #{e.message}"
    end
  end

  desc "Show GeoIP database status"
  task status: :environment do
    puts "GeoIP Database Status"
    puts "=" * 40

    geo_service = GeoIpService.new
    database_info = geo_service.database_info

    if geo_service.database_available? && database_info
      puts "✅ Active database found:"
      puts "   Type: #{database_info[:type]}"
      puts "   Version: #{database_info[:version]}"
      puts "   Size: #{number_to_human_size(database_info[:size])}"
      puts "   Modified: #{database_info[:modified_at].strftime('%Y-%m-%d %H:%M:%S UTC')}"
      puts "   Age: #{database_info[:age_days]} days"
      puts "   Path: #{database_info[:file_path]}"
      puts "   Valid: #{geo_service.database_available? ? '✅' : '❌'}"

      if database_info[:age_days] > Rails.application.config.maxmind.max_age_days
        puts "   ⚠️  Database is outdated (older than #{Rails.application.config.maxmind.max_age_days} days)"
      end
    else
      puts "❌ No active GeoIP database found"
      puts ""
      puts "To download the database, run:"
      puts "  rails geoip:update"
    end

    puts ""
    puts "Configuration:"
    config = Rails.application.config.maxmind
    puts "   Auto-updates: #{config.auto_update_enabled ? '✅' : '❌'}"
    puts "   Update interval: #{config.update_interval_days} days"
    puts "   Max age: #{config.max_age_days} days"
    puts "   Storage path: #{config.storage_path}"
  end

  desc "Enrich existing events missing country codes"
  task enrich_missing: :environment do
    puts "Finding events without country codes..."

    events_without_country = Event.where(country_code: [nil, ''])
                                 .where.not(ip_address: [nil, ''])
                                 .limit(1000) # Process in batches

    if events_without_country.empty?
      puts "✅ No events found missing country codes"
      exit 0
    end

    puts "Found #{events_without_country.count} events without country codes"
    puts "Processing batch..."

    geo_service = GeoIpService.new
    updated_count = 0

    events_without_country.find_each do |event|
      country = geo_service.lookup_country(event.ip_address)

      if country.present?
        event.update!(country_code: country)
        updated_count += 1
      end

      # Add small delay to avoid overwhelming the service
      sleep(0.01) if updated_count % 100 == 0
    end

    puts "✅ Updated #{updated_count} events with country codes"
  end

  desc "Test GeoIP service with sample IPs"
  task test: :environment do
    puts "Testing GeoIP service..."
    puts "=" * 30

    test_ips = [
      '8.8.8.8',        # Google DNS (US)
      '1.1.1.1',        # Cloudflare DNS (US)
      '208.67.222.222', # OpenDNS (US)
      '9.9.9.9',        # Quad9 DNS (US)
      '8.8.4.4',        # Google DNS (US)
      '1.0.0.1',        # Cloudflare DNS (AU)
      '64.6.64.6',      # Verisign DNS (US)
      '94.140.14.14',   # AdGuard DNS (DE)
      '2001:4860:4860::8888', # Google DNS IPv6
      '2606:4700:4700::1111'  # Cloudflare DNS IPv6
    ]

    geo_service = GeoIpService.new

    if !geo_service.database_available?
      puts "❌ GeoIP database not available. Please run 'rails geoip:update' first."
      exit 1
    end

    puts "Database info:"
    info = geo_service.database_info
    puts "  Type: #{info[:type]}"
    puts "  Version: #{info[:version]}"
    puts "  Size: #{number_to_human_size(info[:size])}"
    puts ""

    test_ips.each do |ip|
      begin
        country = geo_service.lookup_country(ip)
        puts "#{ip.ljust(30)} → #{country || 'Unknown'}"
      rescue => e
        puts "#{ip.ljust(30)} → Error: #{e.message}"
      end
    end
  end

  
  private

  def number_to_human_size(bytes)
    units = %w[B KB MB GB TB]
    size = bytes.to_f
    unit_index = 0

    while size >= 1024 && unit_index < units.length - 1
      size /= 1024
      unit_index += 1
    end

    "#{size.round(2)} #{units[unit_index]}"
  end
end