module UnityRelation
  extend ActiveSupport::Concern

  def location_networks
    if self.is_admin? || self.is_super_admin || self.machine_token_user? || (self.network_tags[:full] && self.network_tags[:full].include?("all:all")) || (self.network_tags[:limited] && self.network_tags[:limited].include?("all:all")) 
      self.organisation.location_networks
    else
      self.organisation.location_networks.joins(:taggings).where("`location_networks`.`id` IN (?) OR `taggings`.`tag_id` IN (?)", self.unities.where(locatable_type: "LocationNetwork").map(&:locatable_id), self.unities.where(locatable_type: "ActsAsTaggableOn::Tag").map(&:locatable_id))
    end
  end

  def network_ssids
    NetworkSsid.where(location_network_id: location_networks.select(:id))
  end

  def wired_configs
    WiredConfig.where(location_network_id: location_networks.select(:id))
  end

  def radio_profiles
    RadioProfile.where(location_network_id: location_networks.select(:id))
  end

  def router_inventories
    RouterInventory.where(location_network_id: location_networks.select(:id))
  end

  def reports
    Report.where(location_network_id: location_networks.select(:id))
  end

  def ntp_servers
    NtpServer.where(location_network_id: location_networks.select(:id))
  end

  def alerts
    Alert.where(location_network_id: location_networks.select(:id))
  end

  def firewall_configs
    FirewallConfig.where(location_network_id: location_networks.select(:id))
  end

  def loggings
    Logging.where(location_network_id: location_networks.select(:id))
  end

  def vpn_configs
    VpnConfig.where(location_network_id: location_networks.select(:id))
  end

  def static_routes
    StaticRoute.where(location_network_id: location_networks.select(:id))
  end

  def switch_configurations
    SwitchConfiguration.where(location_network_id: location_networks.select(:id))
  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.select(: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

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

  def commands_limited

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

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

  def upgrades_limited
    Upgrade.where(router_inventory_id: router_inventories_limited.select(: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
