namespace :data do
  desc "Remove '_NULL' or '_null' from LocationNetwork network_name (optimized with batch processing)"
  task remove_null_from_network_name: :environment do
    puts "Starting cleanup of LocationNetwork names with '_NULL' or '_null'..."
    updated_network_ids = []
    updated_router_ids = []
    
    # Find all LocationNetworks with '_NULL' or '_null' in network_name
    puts "Finding LocationNetworks with '_NULL' or '_null' in network_name..."
    networks_with_null = LocationNetwork.where("network_name LIKE ? OR network_name LIKE ?", "%_NULL%", "%_null%").pluck(:id, :network_name)
    
    puts "Found #{networks_with_null.size} LocationNetworks with '_NULL' or '_null' in name"
    
    if networks_with_null.empty?
      puts "No networks found with '_NULL' or '_null' in name. Task completed!"
      return
    end
    
    # Process networks in batches
    networks_with_null.each_slice(100) do |batch|
      network_ids = batch.map(&:first)
      networks = LocationNetwork.where(id: network_ids).includes(:router_inventories).index_by(&:id)
      
      batch.each do |network_id, old_name|
        network = networks[network_id]
        next unless network
        next unless network.network_name.to_s =~ /_null/i # case-insensitive check
        
        begin
          new_name = network.network_name.gsub(/_null/i, "") # case-insensitive replacement
          
          # Update network name without callbacks
          network.update_column(:network_name, new_name)
          updated_network_ids << network_id
          
          # Update Redis for associated router inventories
          network.router_inventories.each do |inventory|
            begin
              $redis.hset "AP:#{inventory.mac_id}", "Network", inventory.try(:location_network).try(:network_name)
              updated_router_ids << inventory.id
            rescue => e
              puts "Redis update failed for RouterInventory #{inventory.id}: #{e.message}"
            end
          end
          
          puts "Updated LocationNetwork ID #{network_id}: '#{old_name}' → '#{new_name}'"
          
        rescue => e
          puts "Failed to update LocationNetwork ID #{network_id}: #{e.message}"
        end
      end
    end
    
    # Bulk Elasticsearch update for LocationNetworks
    unless updated_network_ids.empty?
      puts "Updating #{updated_network_ids.size} LocationNetwork records in Elasticsearch..."
      
      batch_index = 0
      updated_network_ids.each_slice(100) do |batch_ids|
        batch_index += 1
        puts "Processing LocationNetwork Elasticsearch batch #{batch_index}"
        
        networks = LocationNetwork.where(id: batch_ids)
        
        bulk_body = networks.map do |network|
          {
            update: {
              _index: LocationNetwork.index_name,
              _id: network.id,
              data: {
                doc: {
                  network_name: network.network_name
                }
              }
            }
          }
        end
        
        if bulk_body.any?
          begin
            LocationNetwork.__elasticsearch__.client.bulk(body: bulk_body)
            puts "Successfully updated LocationNetwork Elasticsearch batch #{batch_index}"
          rescue => e
            puts "Error during LocationNetwork Elasticsearch batch #{batch_index}: #{e.message}"
          end
        end
      end
    end
    
    # Bulk Elasticsearch update for RouterInventories (if they have ES indexing)
    unless updated_router_ids.empty?
      puts "Checking RouterInventory Elasticsearch updates for #{updated_router_ids.uniq.size} records..."
      
      # Only proceed if RouterInventory has Elasticsearch indexing
      if RouterInventory.respond_to?(:__elasticsearch__)
        batch_index = 0
        updated_router_ids.uniq.each_slice(100) do |batch_ids|
          batch_index += 1
          puts "Processing RouterInventory Elasticsearch batch #{batch_index}"
          
          routers = RouterInventory.where(id: batch_ids).includes(:location_network)
          
          bulk_body = routers.map do |router|
            network_name = router.location_network ? router.location_network.network_name : nil
            
            {
              update: {
                _index: RouterInventory.index_name,
                _id: router.id,
                data: {
                  doc: {
                    network_name: network_name
                  }
                }
              }
            }
          end
          
          if bulk_body.any?
            begin
              RouterInventory.__elasticsearch__.client.bulk(body: bulk_body)
              puts "Successfully updated RouterInventory Elasticsearch batch #{batch_index}"
            rescue => e
              puts "Error during RouterInventory Elasticsearch batch #{batch_index}: #{e.message}"
            end
          end
        end
      else
        puts "RouterInventory does not have Elasticsearch indexing - skipping ES updates"
      end
    end
    
    puts "Cleanup completed!"
    puts "Updated #{updated_network_ids.size} LocationNetwork records"
    puts "Updated Redis for #{updated_router_ids.uniq.size} RouterInventory records"
  end
end