:class Api::V1::DashboardController < Api::V1::ApiController
  protect_from_forgery with: :null_session
  before_action :user_authentication_for_api  
  before_action :last_values_all
  before_action :issues, only: [:dashboard] 

  def last_values_all

    if params["last_update"].present? # for intrem update
      # @time24 = Time.parse(params["last_update"])
      @end_time, @start_time = SensorMonitoringData.time_range Time.at(params["last_update"].to_i), nil
    else
      # @time24 = Time.now
      @end_time, @start_time = SensorMonitoringData.time_range nil, 23.hours
    end

    if params["loc_net"].present? # for particular location network
        @loc_net = @user.location_networks.includes(:router_inventories, :network_ssids).where(:network_type => "pcot", :id => params["loc_net"])
     else
        @loc_net = @user.location_networks.includes(:router_inventories, :network_ssids).where(:network_type => "pcot")
    end

    # @time = Time.now
    @lns = @loc_net.pluck(:id).map(&:to_s).uniq
    # @last_time  = TestProfile::LAST_TIME.to_i
    tpid = TestProperty.joins(:test_profile => [:location_network]).where(test_profiles: { is_enabled: 1, test_category: TestProfile::HOST.keys }).where("location_networks.id IN (?)", @loc_net).pluck(:id).map(&:to_s)
    ri_mac_id = RouterInventory.where(:location_network_id => @loc_net).pluck(:mac_id).flatten.uniq
    ty = ["2"]

    # time = @time24
    # start_time = time.to_i
    # end_time = (time - 24.hours).to_i


    # @last_values_mac_id = SensorMonitoringData.count_type_location_uid_mac_id(@time, @last_time, lns) 
    if params["last_update"].present?
      start_time = @start_time.beginning_of_hour 
      end_time = @start_time.end_of_hour 
    else
      start_time = @start_time.beginning_of_hour 
      end_time = @end_time.beginning_of_hour 
    end
    @last_24hrs_mac_id = SensorMonitoringData.tp_data_241_mac_id(start_time, end_time, @lns, tpid, ty, ri_mac_id)

    # @location_hash = @last_values_mac_id.group_by { |t| t['_id']['lnid'] }
    # @last_hb_mac_id = SensorMonitoringData.count_lnid_ty_mac_id(@time, @last_time, lns)
  end

  def index

  end

  def show

  end

  def band val
    if val > 80
      return "S"
    elsif ((val >= 50) && (val <= 80))
      return "W"
    else
      return "C"
    end  
  end

  def dashboard
    response_hash = {}
    all_networks = []
    tps = TestProfile.where(location_network_id: @loc_net.pluck(:id)).pluck(:id, :location_network_id)
    # loc_test_hash = TestProperty.joins(:test_profile => [:location_network]).where("location_networks.id IN (?)", @loc_net).select("location_networks.id as network_id, COUNT(*) as count").group("location_networks.id").map {|n| [n.network_id,n.count]}.flatten

    loc_test_hash = TestProperty.joins(:test_profile => [:location_network]).where(test_profiles: { is_enabled: 1 }).where("location_networks.id IN (?)", @loc_net).select("location_networks.id as network_id, COUNT(*) as count").group("location_networks.id").map {|n| [n.network_id,n.count]}.flatten
    loc_test_hash = Hash[*loc_test_hash]

    sensor_loc_hash = RouterInventory.where(mac_id: @ln.values.map { |m| m.map {|t| t['sensors'] } }.flatten.uniq).group_by {|g| g.location_network_id}

    ssid_loc_hash = NetworkSsid.where(is_enabled: 1, id: @ln.values.map { |m| m.map {|t| t['uid'] } }.flatten.uniq).group_by {|g| g.location_network_id}    

    all_router_inv = RouterInventory.where(location_network_id: @loc_net).map{|ri| [ri.mac_id, ri.location_network.id] }.flatten
    all_router_inv = Hash[*all_router_inv]
    hash_net_ri = {}
    LocationNetwork.where(:id => @loc_net).each do |ln|
      hash_net_ri[ln.id] = [ln.router_inventories.pluck(:mac_id)].flatten
    end
    @loc_net.includes(:router_inventories, :network_ssids).each do |network|
      network_hash = {}
      network_hash["name"] = network.network_name
      network_hash["n_id"] = network.id
      network_hash["location"] = location network.id
      # network_hash["status"] = status network.id 
      network_hash["total"] = {"sensors"=> 0, "test"=> 0, "ssids"=> 0} 
      network_hash["total"]["sensors"] = network.router_inventories.count
      network_hash["total"]["test"] = loc_test_hash[network.id] || 0
      network_hash["total"]["ssids"] = network.network_ssids.enabled.count
      network_hash["total_affected"] = {"sensors"=> 0, "test"=> 0, "ssids"=> 0} 
      sensors = []
      test =[]
      ssids = []
      v = @ln[network.id.to_s]
      # if v.present? && sensor_loc_hash[network.id].present? && ssid_loc_hash[network.id].present?
      if v.present? && sensor_loc_hash[network.id].present?
        sensors = sensor_loc_hash[network.id].map(&:id).map(&:to_s)
      end
      if v.present? && ssid_loc_hash[network.id].present?
        ssids =  ssid_loc_hash[network.id].map(&:id).map(&:to_s)   
      end   
      if v.present?
          v.each do |g| 
               tpids = g['tpropid'].uniq
               val = network.test_profiles.enabled.includes(:test_properties).map { |tp| tp.test_properties.where(id: tpids).pluck(:id) }
               test << val 
              # tpids = g["tpid"].map{ |t| t['tid']}.flatten.uniq
              # network.test_profiles.enabled.includes(:test_properties).map { |tp| tp.test_properties.where("test_properties.id IN (?)", tpids).pluck(:id) }.flatten.each do |tpid|
              #   test << tpid
              # end                         

          end
      end
      network_hash["total_affected"]["sensors"] = sensors.flatten.uniq.count
      network_hash["total_affected"]["test"] = test.flatten.uniq.count
      network_hash["total_affected"]["ssids"] = ssids.flatten.uniq.count
      network_hash["status_24hr"] = SensorMonitoringData.hour_percentage  @last_24hrs_mac_id["per_values"], network.id,hash_net_ri[network.id]  
      network_hash["ts"] = @last_24hrs_mac_id["ts"]  
      network_hash["last_update"] = network_hash["ts"].last if network_hash["ts"].present?
      all_networks << network_hash
    end
    response_hash["networks"] = all_networks
    response_hash["issues"] = @hash
    response_hash["last_update"] = Time.now.to_i
    render json: {success: true, data: response_hash, msg: "success", code: "200"}
  end
  
  def issues
    tpid = TestProperty.joins(:test_profile => [:location_network]).where(test_profiles: { is_enabled: 1, test_category: TestProfile::HOST.keys }).where("location_networks.id IN (?)", @loc_net).pluck(:id).map(&:to_s)
    loc_name_hash = @loc_net.pluck(:id, :network_name).map { |l| l }.flatten
    loc_name_hash = Hash[*loc_name_hash]
    loc_ssid = NetworkSsid.where(location_network_id: @loc_net, is_enabled: true).pluck(:id, :ssid_name).map { |l| l }.flatten
    uplink_hash_name = RouterInventory.where(location_network_id: @loc_net).map{|ri| ri.uplinks.pluck(:id, :uplink_name) }.flatten
    loc_ssid_hash = Hash[*loc_ssid]
    loc_ssid_wired_hash = loc_ssid.push(uplink_hash_name).flatten  
    loc_ssid_wired_hash = Hash[*loc_ssid_wired_hash]
    avail_ssids = loc_ssid_wired_hash.keys.map(&:to_s)

    loc_sensor_hash = RouterInventory.where(location_network_id: @loc_net).pluck(:mac_id, :name).map { |l| l }.flatten
    loc_sensor_hash = Hash[*loc_sensor_hash]   
    # time = @time24
    # start_time = (time + 15.minutes).to_i
    # end_time = (time - 24.hours).to_i  
    # end_time, start_time = SensorMonitoringData.time_range nil, 24.hours
    alrt = SensorAlert.issues_details @start_time, @end_time, @lns, tpid, avail_ssids  
      @ty = alrt.group_by  { |d| d["_id"]["ty"] }
      @ln = alrt.group_by  { |d| d["_id"]["lnid"] }
      test_cat_hash = TestProfile.where(test_category: TestProfile::HOST.keys, location_network_id: @loc_net).enabled.group_by { |t| t.test_category}
      hash_affected = {}
      @ty.each do |k,v|

        hash1 = {}
        if test_cat_hash[k].present? && v.present?
            hash1["location_networks"] = v.map{ |s| s['lnid']}.flatten.uniq
            hash1["total"] = {"sensors"=> 0, "test"=> 0, "ssids"=> 0}
            # hash1["total"]["sensors"] = test_cat_hash[k].map{|tp| tp.location_network }.map { |s| s.router_inventories }.flatten.map(&:id).uniq.count

            interface_check = test_cat_hash[k].map{|tp| tp.test_properties.map { |t| t.application_interface1 }}.flatten.compact.uniq

            if interface_check.include?("ssids") || interface_check.include?("all") || interface_check.include?("wired")
                hash1["total"]["sensors"] = loc_sensor_hash.keys.count #LocationNetwork.where(id: @loc_net).map { |ln| ln.router_inventories.pluck(:mac_id) }.flatten.uniq.count
                hash1["total"]["ssids"] = loc_ssid_hash.keys.count#LocationNetwork.where(id: @loc_net).map { |ssd| ssd.network_ssids.pluck(:id) }.flatten.uniq.count                
            else
                hash1["total"]["sensors"] = NetworkSsid.where( id: interface_check).map { |ns| ns.router_inventories}.flatten.compact.uniq.count
                hash1["total"]["ssids"] = NetworkSsid.where( id: interface_check).map(&:id).uniq.count                 
            end
            # hash1["total"]["sensors"] = NetworkSsid.where( id: test_cat_hash[k].map{|tp| tp.test_properties.map { |t| t.application_interface1 }}.flatten.uniq).map { |ns| ns.router_inventories}.flatten.uniq
            hash1["total"]["test"] = test_cat_hash[k].map {|tp| tp.test_properties }.flatten.map(&:id).uniq.count 
            # hash1["total"]["ssids"] = NetworkSsid.where( id: test_cat_hash[k].map{|tp| tp.test_properties.map { |t| t.application_interface1 }}.flatten.uniq).map(&:id).uniq.count   
            hash1["total_affected"] = {"sensors"=> 0, "test"=> 0, "ssids"=> 0}
            issue_ssids = v.map{ |s| s['uid']}.flatten.map(&:to_i)
            actual_ssids = loc_ssid_hash.keys

            hash1["total_affected"]["sensors"] = v.map{ |s| s['sensors']}.flatten.uniq.count
            # hash1["total_affected"]["ssids"] = v.map{ |s| s['uid']}.flatten.uniq.count
            hash1["total_affected"]["ssids"] = (issue_ssids & actual_ssids).count
            hash1["total_affected"]["test"] = v.map{ |s| s['tpropid']}.flatten.uniq.count
             # hash1["total_affected_details"] = v.map{ |s| s['tpid']}.flatten.uniq
            affdet = v.map{ |s| s['tpid']}.flatten
            aff_details = []
            affdet.map do |ad|
              hash_af = {}
              hash_af["type"] = ad["ty"]
              hash_af["tyn"] = TestProfile::HOST[ad["ty"]]
              hash_af["mac_id"] = loc_sensor_hash[ad["nid"]] || ad["nid"]
              hash_af["ssid_name"] = loc_ssid_wired_hash[ad["uid"].to_i] || nil
              hash_af["ssid_id"] = ad["uid"]
              hash_af["testid"] = ad["tid"]
              hash_af["ts"] = ad["ts"].to_i
              hash_af["runid"] = ad["runid"].to_i
              hash_af["level"] = ad["level"]
              hash_af["data"] = ad["data"]
              hash_af["alert_type"] = ad["alert_type"]
              # msg = TestProfile::ALERT_THRESHOLD_MSGS[ad["ty"]][ad["data"].keys.first]
              msg = TestProfile::ALERT_THRESHOLD_MSGS[ad["ty"]][ad["data"].try(:keys).try(:first)]
              hash_af["msg"] = msg
              # hash_af["log"] = ""
              hash_af["loc_name"] = loc_name_hash[ad["lnid"].to_i]
              aff_details << hash_af
            end
            hash1["total_affected_details"] = aff_details
            hash_affected[k] = hash1
        end
      end
      @hash = {}
      TestProfile::HOST.keys.each do |key|
        @hash["#{TestProfile::FORM[key]}"] = hash_affected["#{key}"]
      end
      @hash
     # hash["st_ts"] = start_time
     # hash["ed_ts"] = end_time
  end

  def location nw
    val = []
    ln = LocationNetwork.find nw
    ln.router_inventories.each do |ri|
      if (val.empty?) && (ri.latitude.present? && ri.longitude.present?)
          val << ri.latitude
          val << ri.longitude
      end
    end
    val
  end

end
