module Baidu
  class TongjiService < ApplicationService
    attr_reader :client_id, :client_secret, :site_id
    # login、code、password、password_confirmation
    def initialize
      @client_id      = "6dMO2kqKUaMZkBrMaUMxQSNAT49v0Mjq"
      @client_secret  = "qvWqF33AOmGs1tPCgsROvis9EQCuNmd3"
      @site_id = 18657013
    end

    def call

    end


    def init_overview_data_by(start_date = nil, end_date = nil)
      start_date = Time.now.prev_year.beginning_of_year if start_date.nil?
      end_date = Time.now
      Rails.logger.info("*********开始百度统计-概览:#{start_date}-#{end_date}*********")
      sql_connection = ActiveRecord::Base.connection
      sql_connection.begin_db_transaction

      # 如果存在数据 先清空
      # sql_connection.execute("delete from daily_platform_statistics where date between '#{start_date}' and '#{end_date}'")
      multiple_days_data = overview_multiple_days_data(start_date, end_date)
      if multiple_days_data.present?
        sql = "replace into daily_platform_statistics (date,pv,visitor,ip,created_at,updated_at) values #{multiple_days_data.join(",")}"
        sql_connection.execute(sql)
      end
      sql_connection.commit_db_transaction
      Rails.logger.info("*********结束百度统计-概览:#{start_date}-#{end_date}*********")
    end

    def init_source_from_data_by(start_date = nil, end_date = nil)
      start_date = Time.now.prev_year.beginning_of_year if start_date.nil?
      end_date = Time.now
      Rails.logger.info("*********开始百度统计-来源:#{start_date}-#{end_date}*********")
      source_from_batch_add(start_date, end_date)
      Rails.logger.info("*********结束百度统计-来源:#{start_date}-#{end_date}*********")
    end

    # 按日期获取来源数据
    def source_from_batch_add(start_date,end_date)
      # 补充更新开始时间的当天数据
      source_from_by_date(start_date)
      diff_days(start_date, end_date).times.each do |t|
        new_start_date = start_date + (t + 1).days
        source_from_by_date(new_start_date)
      end
      # 补充更新最后时间一天数据
      source_from_by_date(end_date)
    end

    # 按天获取来源数据
    def source_from_by_date(start_date)
      return [] unless access_token.present? && start_date.present?
      source_from_data = api("source/all/a", start_date, start_date, "pv_count,visitor_count,ip_count")
      source_from = []
      #当日的bing来源数量
      bing_number = bing_link_number(start_date)
      source_from_data['items'][1].each_with_index do |source, index|
        source_number = case index
                        when 1 # link 数据
                          source[0].to_f - bing_number
                        when 2 # search数据
                          source[0].to_f + bing_number
                        else
                          source[0].to_f
                        end
        source_from.push((( source_number / source_from_data['sum'][0][0].to_f) * 100).round(2))
      end
      daily_statistic = DailyPlatformStatistic.find_or_initialize_by(date: start_date)
      daily_statistic.source_through = source_from[0]
      daily_statistic.source_link = source_from[1]
      daily_statistic.source_search = source_from[2]
      daily_statistic.source_custom = source_from[3]
      daily_statistic.save
    end

    def  bing_link_number(start_date)
      return [] unless access_token.present? && start_date.present?
      source_from_data = api("source/link/a", start_date, start_date, "pv_count")
      # 提取链接项和对应的数据项
      link_items = source_from_data["items"][0]
      value_items = source_from_data["items"][1]

      # 目标链接名称
      target_name = "http://cn.bing.com"
      target_number = 0

      # 遍历查找匹配的 name
      link_items.each_with_index do |link_array, index|
        link = link_array.first
        if link["name"] == target_name
          stats = value_items[index]
          target_number = stats[0]
          break
        end
      end
      target_number.to_f
    end


    def diff_days(start_date, end_date)
      (end_date.beginning_of_day.to_i - start_date.beginning_of_day.to_i) / (24 * 3600)
    end

    def overview_batch_add(start_date, end_date)
      return [] unless access_token.present? && start_date.present? && end_date.present?
      start_date = Time.now - 1.days if start_date.strftime("%Y%m%d") == end_date.strftime("%Y%m%d")
      overview_data = api("overview/getTimeTrendRpt", start_date, end_date, "pv_count,visitor_count,ip_count")
      overview_data['items'][0].each_with_index do |date, index|
        pv = overview_data['items'][1][index][0]
        visitor = overview_data['items'][1][index][1]
        ip = overview_data['items'][1][index][2]
        job_date = date[0].to_s.gsub("/", "-")
        daily_statistic = DailyPlatformStatistic.find_or_initialize_by(date: job_date)
        daily_statistic.date = job_date
        daily_statistic.pv = pv
        daily_statistic.visitor = visitor
        daily_statistic.ip = ip
        daily_statistic.save
      end
      overview_data
    end

    def overview_multiple_days_data(start_date, end_date)
      return [] unless access_token.present? && start_date.present? && end_date.present?
      overview_data = api("overview/getTimeTrendRpt", start_date, end_date, "pv_count,visitor_count,ip_count")
      data = []
      created_at = Time.now.strftime("%Y-%m-%d 00:00:00")
      overview_data['items'][0].each_with_index do |date, index|
        pv = overview_data['items'][1][index][0]
        visitor = overview_data['items'][1][index][1]
        ip = overview_data['items'][1][index][2]
        data.push("('#{date[0].to_s.gsub("/", "-")}', #{pv.to_s.gsub("--","0")}, #{visitor.to_s.gsub("--","0")}, #{ip.to_s.gsub("--","0")},\"#{created_at}\",\"#{created_at}\")")
      end
      data
    end

    def code_url
      "http://openapi.baidu.com/oauth/2.0/authorize?response_type=code&client_id=#{client_id}&redirect_uri=oob&scope=basic&display=popup"
    end

    def oauth_url(code)
      "http://openapi.baidu.com/oauth/2.0/token?grant_type=authorization_code&code=#{code}&client_id=#{client_id}&client_secret=#{client_secret}&redirect_uri=oob"
    end

    def get_access_token(code)
      uri = URI.parse(oauth_url(code))
      response = Net::HTTP.get_response(uri)
      Rails.logger.info "baidu_tongji_auth response.body ===== #{response.body}"
      if response.code.to_i == 200
        data = JSON.parse(response.body)
        access_token = data['access_token']
        refresh_token = data['refresh_token']
        expires_in = data['expires_in']
        if access_token.present?
          Rails.cache.write("baidu_tongji_auth/access_token", access_token, expires_in: expires_in)
          Rails.cache.write("baidu_tongji_auth/refresh_token", refresh_token, expires_in: 1.year)
        end
      end
    end

    def refresh_access_token
      url = "http://openapi.baidu.com/oauth/2.0/token?grant_type=refresh_token&refresh_token=#{refresh_token}&client_id=#{client_id}&client_secret=#{client_secret}"
      uri = URI.parse(url)
      response = Net::HTTP.get_response(uri)
      Rails.logger.info "baidu_tongji_auth response.body ===== #{response.body}"
      if response.code.to_i == 200
        data = JSON.parse(response.body)
        access_token = data['access_token']
        refresh_token = data['refresh_token']
        expires_in = data['expires_in']
        if access_token.present?
          Rails.cache.write("baidu_tongji_auth/access_token", access_token, expires_in: expires_in)
          Rails.cache.write("baidu_tongji_auth/refresh_token", refresh_token, expires_in: 1.year)
        end
      end
    end

    def access_token
      access_token = Rails.cache.read("baidu_tongji_auth/access_token")
      if access_token.blank? && refresh_token.present?
        refresh_access_token
        access_token = Rails.cache.read("baidu_tongji_auth/access_token")
      end
      access_token
    end

    def refresh_token
      refresh_token = Rails.cache.read("baidu_tongji_auth/refresh_token")
      # 如果刷新token失效，access_token也重置
      if refresh_token.blank?
        Rails.cache.delete("baidu_tongji_auth/access_token")
      end
      refresh_token
    end

    # 网站概况(趋势数据)
    def api_overview
      start_date = Time.now.beginning_of_week
      end_date = Time.now
      start_date = Time.now - 1.days if start_date.strftime("%Y%m%d") == end_date.strftime("%Y%m%d")
      api("overview/getTimeTrendRpt", start_date, end_date, "pv_count,visitor_count,ip_count")
    end

    # 网站概况(来源网站、搜索词、入口页面、受访页面)
    def api_overview_getCommonTrackRpt
      start_date = Time.now.beginning_of_week
      end_date = Time.now
      api("overview/getCommonTrackRpt", start_date, end_date, "pv_count")
    end

    # 全部来源
    def source_from
      start_date = Time.now.beginning_of_week
      end_date = Time.now
      api("source/all/a", start_date, end_date, "pv_count,visitor_count,ip_count")
    end

    def api(api_method, start_date, end_date, metrics = nil)
      start_date_fmt = start_date.strftime("%Y%m%d")
      end_date_fmt = end_date.strftime("%Y%m%d")
      api_url = "https://openapi.baidu.com/rest/2.0/tongji/report/getData?access_token=#{access_token}&site_id=#{site_id}&method=#{api_method}&start_date=#{start_date_fmt}&end_date=#{end_date_fmt}&metrics=#{metrics}"
      data = url_http_post(api_url, {})
      data['result']
    end

    def url_http_post(api_url, params)
      Rails.logger.info "api_url==#{api_url}"
      uri = URI.parse(api_url)
      http = Net::HTTP.new uri.host, uri.port
      http.open_timeout = 60
      http.read_timeout = 60
      if uri.scheme == 'https'
        http.verify_mode = OpenSSL::SSL::VERIFY_NONE
        http.use_ssl = true
      end
      begin
        request = Net::HTTP::Post.new(uri)
        request.set_form_data(params) if params.present?
        request['Content-Type'] = 'application/json;charset=utf-8'
        # request['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8'
        response = http.start { |http| http.request(request) }
        Rails.logger.info "api response.body==#{response.body}"
        JSON.parse response.body
      rescue => err
        Rails.logger.error("#############api_url:#{api_url},error:#{err.message.size}")
        # Rails.logger.error("#############api_url:#{api_url},error:#{err.message}")
        return {}
      end
    end
  end
end
