class MonitoringChild
  include Mongoid::Document

  field :monitoring_data, type: Hash
  field :info, type: Hash, default: {}
  field :s_info, type: Hash, default: {}
  field :m_info, type: Hash, default: {}
  field :lan, type: Hash, default: {}
  field :uplink, type: Array, default: []
  field :ssids, type: Array, default: []
  field :clients, type: Array, default: []
  field :cmd_res, type: Array, default: []
  field :sensor_data, type: Hash, default: {}
  field :radio, type: Array, default: []
  field :sw_prt, type: Array, default: []
  field :created_at, type: Time

  #index({"monitoring_data.INFO.NASID" => 1, "monitoring_data.present_date" => 1}, { background: true })
  index({"info.NASID" => 1, "created_at" => 1}, { background: true })
  index({"info.NASID" => 1, "clients.MAC"=> 1, "created_at" => 1}, { background: true })

  def self.new_mobile_status(mobile_status)
    ms = mobile_status[0]
    return ["IMEI: #{ms["IMEI"]} (#{ms['VD']}) | IMSI: #{ms['IMSI']} | ICCID: #{ms['ICCID']} |", mobile_status[1], ms["MM"], ms["NT"],ms["CID"], ms["LAC"], ms["LBC"], mobile_status[2] ]
  end

  def self.mobile_operator(mcc_mnc)
    operator_details = JSON.parse(File.read('operator_detail.json'))
    operator_name = operator_details.select{|n| (n["mcc"] + n["mnc"]) == mcc_mnc}.last
    return operator_name.blank? ? "" : operator_name["operator"]
  end

  def self.check_imsi(mobile_status)
    return nil unless mobile_status
    return mobile_status[0]['IMSI'] if mobile_status[0].is_a?(Hash)
    return mobile_status[0].split("|")[1].split(":")[1].try(:strip) unless mobile_status[0].split("|")[1].blank?
    return nil
  end

  def self.update_eid(uplink,mobile_status)
    return nil if uplink.blank? || uplink.mo_apn != "pronto"
    req_imsi = self.check_imsi(mobile_status)
    db_imsi = uplink.imsi
    uplink.esim_eid_request(req_imsi) if !req_imsi.blank? && (req_imsi != db_imsi || uplink.eid.blank?)
  end

  def self.save_mobile_status_details_in_uplink(data, router_inventory)
    if data["INTERFACE_STATS"].present? && data["INTERFACE_STATS"]["UPLINK"].present?
      uplinks = router_inventory.uplinks.map{|uplink| uplink if uplink.uplink_type == "4"}.compact
      uplinks.each do |uplink|
        mobile_status = data["INTERFACE_STATS"]["UPLINK"].select {|d| d["UID"] == uplink.id.to_s}.map {|a| [(a["MOBILE_STATUS"] || a["MS"]),a["UPLINK_IP"],a["APN"]] if a["TYPE"] == 4 }.compact[0]
        apn = mobile_status.present? ? mobile_status[2] : nil
        mobile_status = self.new_mobile_status(mobile_status) if mobile_status && mobile_status[0].is_a?(Hash)
        #update_eid(uplink,mobile_status) if mobile_status.present? && mobile_status[0].present?
        #update_ri_id_in_simmanagement(mobile_status[0],router_inventory) if mobile_status.present? && mobile_status[0].present?
        p "[#{router_inventory.mac_id}] MS: #{mobile_status}"
        if uplink.present?
      ##    uplink.mo_apn = apn if apn.present? && uplink.mo_apn != apn
       ##   if uplink.mo_apn != "pronto"
       ##     uplink.eid = nil
       ##     uplink.imsi = nil
       ##     uplink.last_mobile_status = nil
       ##   end
          if mobile_status.present? && mobile_status[0].present?
            exisiting_uplink_mm = uplink.mm
            uplink.last_mobile_status = mobile_status[0] if mobile_status[0].present?
            # uplink.imsi = mobile_status[0].split("|")[1].split(":")[1] if mobile_status[0].present?
            uplink.last_seen_ip = mobile_status[1]
            uplink.mm = mobile_status[2].present? ? mobile_status[2] : ""
            uplink.imsi = self.check_imsi(mobile_status)
            uplink.nt = mobile_status[3].present? ? mobile_status[3] : ""
            uplink.cid = mobile_status[4].present? ? mobile_status[4].hex : ""
            uplink.lac = mobile_status[5].present? ? mobile_status[5].hex : ""
            #uplink.default_lbc = mobile_status[6].present? ? mobile_status[6] : "" if uplink.default_lbc.blank?
            uplink.wl_ssid_name = self.mobile_operator(mobile_status[2]) if mobile_status[2].present?
            uplink.operator = (APPLICATION['defaults']['operator_mapping'][self.mobile_operator(mobile_status[2])] || "OTHERS") if mobile_status[2].present?
            unless exisiting_uplink_mm == uplink.mm
              mcc = (mobile_status[2] || "")[0,3]
              mnc = (mobile_status[2] || "")[3,(mobile_status[2] || "").length]
              p "[#{router_inventory.mac_id}] MCC: #{mcc}, MNC: #{mnc}, #{{cid: uplink.cid, lac: uplink.lac}}"
              if mcc.present? && mnc.present? && uplink.cid.present? && uplink.lac.present?
                params = {token: APPLICATION['defaults']['opencell_api_token'],mcc: mcc, mnc: mnc, cells: [{cid: uplink.cid, lac: uplink.lac}]}
                p "[#{router_inventory.mac_id}] params: #{params}"
                cell_location = self.external_opencellid(params)
                p "[#{router_inventory.mac_id}] Opencell: #{cell_location}"
                if cell_location["status"] == "ok"
                  uplink.lat = cell_location['lat']
                  uplink.lng = cell_location['lon']
                end
              end
            end
          end
          if uplink.changed?
            Uplink.check_activity_perission
            uplink.save
          end
        end
      end
    end
  end

  #params = {token: "pk.8d14a2cbe1ad74046ce4f63c3d957201",mcc: 310, mnc: 404, cells: [{ lac: 7033, cid: 17811 }]}
  def self.external_opencellid(params)
    if (params[:mnc] && params[:mcc] && params[:cells]).present?
      uri = URI('https://us1.unwiredlabs.com/v2/process.php')
      http = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl = true
      http.read_timeout = 30
      request = Net::HTTP::Post.new(uri.path, {'Content-Type' => 'application/json'})
      request.body = params.to_json
      response = http.request(request)
      
      JSON.parse(response.body)
    else
      {}
    end
  end

  def self.update_ri_id_in_simmanagement(mobile_status,router_inventory)
    mobile_status.split("|").each do |mobile_status|
      if mobile_status.downcase.match("iccid:")
        iccid = mobile_status.gsub(/[^0-9]/,'')
        sim_management = SimManagement.where(iccid: iccid).first
        sim_management.update_column("router_inventory_id",router_inventory.id) if sim_management.present?
      end
    end
  end

  def self.update_kernal_version(data,router_inventory)
    router_inventory.update_column("kernal_version", data["SYSTEM_INFO"]["KERNEL_VERSION"]) if data["SYSTEM_INFO"].present? && data["SYSTEM_INFO"]["KERNEL_VERSION"].present?
  end

  def self.mobile_status_changed(data)
    ms_data = false
    return ms_data if data["INTERFACE_STATS"].blank? || data["INTERFACE_STATS"]["UPLINK"].blank? || data["INTERFACE_STATS"]["UPLINK"].is_a?(Hash)
    data["INTERFACE_STATS"]["UPLINK"].map {|a| ms_data = true if a["MS"].present? || a['APN'].present? }
    return ms_data 
  end
  
  def self.save_hb(data)
    # data = JSON.parse(data)
    #Make sure MAC id should be in upcase
    data["INFO"]["NASID"] = data["INFO"]["NASID"].try(:upcase)
    if (data["INFO"]["FIRST_HB"] == 1 || mobile_status_changed(data))
      MobileStatusUpdateWorker.perform_async(data.slice("INFO", "INTERFACE_STATS", "SYSTEM_INFO"))
    end
    commands = data["COMMAND_RESULTS"]
    
    unless commands.blank?
      commands.each do |k|
        cmd = Command.find_by_id(k["CMD_ID"])
        cmd.update({:status=>"success", :result=>k["CMD_OUTPUT"]}) unless cmd.blank?
        router_inventory = RouterInventory.where(mac_id: data["INFO"]["NASID"]).last
        router_inventory.update_redis(false) unless router_inventory.blank?
      end
    end

    mc = self.new
    #mc.monitoring_data = data.deep_dup
    mc.info = data["INFO"]
    if data["INTERFACE_STATS"].present?
      if data["INTERFACE_STATS"]["UPLINK"].nil?
        uplink = data["INTERFACE_STATS"].delete("LAN")
        uplink = [uplink] unless uplink.is_a? Array
      else
        uplink = data["INTERFACE_STATS"].delete("UPLINK")
        uplink = [uplink] unless uplink.is_a? Array
      end
      mc.s_info = data["SYSTEM_INFO"]
      mc.m_info = data["MEMINFO"]
      mc.lan = data["INTERFACE_STATS"].delete("LAN")
      mc.uplink = uplink
      mc.ssids = data["INTERFACE_STATS"].values
      mc.clients = data["WLAN_CLIENTS"]
      mc.cmd_res = data["COMMAND_RESULTS"]
    end
    mc.sensor_data = data["SENSORS_DATA"] || {}
    mc.radio = data["RD"] || data["RADIO"] || []
    mc.sw_prt = data["SW_PRT"] || []
    mc.created_at = Time.zone.now.utc

    mc.save
    mc
  end

  def self.ap_last_hb(mac_id, ts)
    MonitoringChild.where("info.NASID" => mac_id.upcase, "created_at" => {"$lt" => ts}).desc("created_at").first
  end
end
