module UnityRelation
  extend ActiveSupport::Concern

  def location_networks
    if self.is_user_allowed_all_networks?
      self.organisation.location_networks
    else
      self.get_all_permitted_networks_for_non_admin
    end
  end
  
  def network_ssids
    if self.is_user_allowed_all_networks?
      self.organisation.network_ssids
    else
      NetworkSsid.where(location_network_id: location_networks.select(:id))
    end
  end

  def wired_configs
    if self.is_user_allowed_all_networks?
      self.organisation.wired_configs
    else
      WiredConfig.where(location_network_id: location_networks.select(:id))
    end
  end

  def radio_profiles
    if self.is_user_allowed_all_networks?
      self.organisation.radio_profiles
    else
      RadioProfile.where(location_network_id: location_networks.select(:id))
    end
  end

  def router_inventories
    if self.is_user_allowed_all_networks?
      self.organisation.router_inventories
    else
      if ['network_r&d', 'network_admin'].include?(self.role.name)
        RouterInventory.where("location_network_id IN (?) OR location_network_id IS NULL", location_networks.select(:id))
      else
        RouterInventory.where(location_network_id: location_networks.select(:id))
      end
    end
  end

  def reports
    if self.is_user_allowed_all_networks?
      self.organisation.reports
    else
      Report.where(location_network_id: location_networks.pluck(:id))
    end
  end

  def ntp_servers
    if self.is_user_allowed_all_networks?
      self.organisation.ntp_servers
    else
      NtpServer.where(location_network_id: location_networks.pluck(:id))
    end
  end

  def alerts
    if self.is_user_allowed_all_networks?
      self.organisation.alerts
    else
      Alert.where(location_network_id: location_networks.pluck(:id))
    end
  end

  def firewall_configs
    if self.is_user_allowed_all_networks?
      self.organisation.firewall_configs
    else
      FirewallConfig.where(location_network_id: location_networks.pluck(:id))
    end
  end

  def loggings
    if self.is_user_allowed_all_networks?
      self.organisation.loggings
    else
      Logging.where(location_network_id: location_networks.pluck(:id))
    end
  end

  def vpn_configs
    if self.is_user_allowed_all_networks?
      self.organisation.vpn_configs
    else
      VpnConfig.where(location_network_id: location_networks.pluck(:id))
    end
  end

  def static_routes
    if self.is_user_allowed_all_networks?
      self.organisation.static_routes
    else
      StaticRoute.where(location_network_id: location_networks.pluck(:id))
    end
  end

  def switch_configurations
    if self.is_user_allowed_all_networks?
      self.organisation.switch_configurations
    else
      SwitchConfiguration.where(location_network_id: location_networks.pluck(:id))
    end
  end

  def commands
    command_ids = router_inventories.flat_map { |n| n.commands.pluck(:id) }
    Command.where(id: command_ids)
  end

  def upgrades
    Upgrade.where(router_inventory_id: router_inventories.pluck(:id))
  end

  def networks_with_limited_access
    ln_ids = networks_acc_to_permission('limited')
    LocationNetwork.where(id: ln_ids.uniq)
  end

  def networks_with_full_access
    ln_ids = networks_acc_to_permission('full')
    LocationNetwork.where(id: ln_ids.uniq)
  end

  def router_inventories_full
    RouterInventory.where(location_network_id: networks_acc_to_permission('full').uniq)
  end

  def router_inventories_limited
    RouterInventory.where(location_network_id: networks_acc_to_permission('limited').uniq)
  end

  # causing N+1 query load issue
  def commands_full
    aps = router_inventories_full.pluck(:id).map {|id| "AP:#{id}"}
    Command.where(aps: aps)
  end

  def commands_limited
    aps = router_inventories_limited.pluck(:id).map {|id| "AP:#{id}"}
    Command.where(aps: aps)
  end

  def upgrades_full
    Upgrade.where(router_inventory_id: router_inventories_full.pluck(:id))
  end

  def upgrades_limited
    Upgrade.where(router_inventory_id: router_inventories_limited.pluck(:id))
  end
  
  private

  def networks_acc_to_permission(access)
    if self.is_admin? || self.is_super_admin || self.machine_token_user? || (self.network_tags[:full] && self.network_tags[:full].include?("all:all") && access == 'full')  || (self.network_tags[:limited] && self.network_tags[:limited].include?("all:all") && access == 'limited')
      self.organisation.location_networks.pluck(:id)
    else
     self.organisation.location_networks.tagged_with(self.unities.where(locatable_type: "ActsAsTaggableOn::Tag", permission: access).flat_map { |unity| unity.locatable.name}).pluck(:id) + self.unities.where(locatable_type: 'LocationNetwork', permission: access).pluck(:locatable_id)
    end
  end
end
