class RouterInventoryUpdateWorker
  include Sidekiq::Worker
  sidekiq_options queue: :inventory_update, retry: false, backtrace: true

  def perform(params)
    Rails.logger.info("[RI-WORKER] Started with params: #{params.inspect}")

    nasid = params['nasid']
    ri = RouterInventory.where(mac_id: nasid).last

    unless ri.present?
      Rails.logger.warn("[RI-WORKER] No RouterInventory found with mac_id: #{nasid}")
      return
    end

    firmware_changed = params['current_firmware'].present?
    bn_changed = params['build_number'].present?
    ip_changed = params['public_ip'].present? && params['current_active_uplink'].present?

    Rails.logger.info("[RI-WORKER] Changes detected - firmware_changed: #{firmware_changed}, bn_changed: #{bn_changed}, ip_changed: #{ip_changed}")

    if firmware_changed || bn_changed
      update_router_inventory_columns(ri, params, firmware_changed, bn_changed)
    else
      Rails.logger.info("[RI-WORKER] No firmware or build number changes to update")
    end

    if ip_changed
      update_uplinks_public_ip(ri.id, params)
    else
      Rails.logger.info("[RI-WORKER] No IP changes to update uplinks")
    end

    Rails.logger.info("[RI-WORKER] Finished processing RouterInventoryUpdateWorker for mac_id: #{nasid}")
  end

  def update_router_inventory_columns(router_inventory, params, firmware_changed, bn_changed)
    return unless router_inventory.present?

    update_attributes = {}

    if firmware_changed && params['current_firmware'].present?
      update_attributes[:previous_firmware] = params['previous_firmware'] if params['previous_firmware'].present?
      update_attributes[:current_firmware] = params['current_firmware']
    end

    if bn_changed && params['build_number'].present?
      update_attributes[:build_number] = params['build_number']
    end

    if update_attributes.any?
      Rails.logger.info("[RI-WORKER] Updating RouterInventory ##{router_inventory.id} with: #{update_attributes.inspect}")
      RouterInventory.where(id: router_inventory.id).update_all(update_attributes)
      router_inventory.reload
      router_inventory.__elasticsearch__.index_document
      Rails.logger.info("[RI-WORKER] Update complete and document reindexed")
    else
      Rails.logger.info("[RI-WORKER] No attributes to update for RouterInventory ##{router_inventory.id}")
    end
  end

  def update_uplinks_public_ip(router_inventory_id, params)
    return unless params['public_ip'].present? && params['current_active_uplink'].present?

    public_ip = params['public_ip']
    current_active_uplink_id = params['current_active_uplink'].to_i

    Rails.logger.info("[RI-WORKER] Updating uplinks for RouterInventory ##{router_inventory_id} with public IP: #{public_ip} and active uplink ID: #{current_active_uplink_id}")

    uplink_exists = Uplink.exists?(router_inventory_id: router_inventory_id, id: current_active_uplink_id)

    unless uplink_exists
      Rails.logger.warn("[RI-WORKER] No uplink found for RouterInventory ##{router_inventory_id} with ID: #{current_active_uplink_id}")
      return
    end

    current_pub_ip = Uplink.where(router_inventory_id: router_inventory_id, id: current_active_uplink_id).pluck(:public_ip).first

    if current_pub_ip != public_ip
      Rails.logger.info("[RI-WORKER] Public IP changed for Uplink ##{current_active_uplink_id} of RouterInventory ##{router_inventory_id}. Updating to: #{public_ip}")
      Uplink.where(router_inventory_id: router_inventory_id, id: current_active_uplink_id).update_all(public_ip: public_ip)
      Rails.logger.info("[RI-WORKER] Uplink public IP updated successfully")
    else
      Rails.logger.info("[RI-WORKER] No change in public IP for Uplink ##{current_active_uplink_id} of RouterInventory ##{router_inventory_id}")
    end
  end

end
