class EdFi::Wisconsin::ApplicationService
  def self.call(*args, &block)
    service = new(*args, &block)
    service.destroy_logs
    service.call
  end

  def initialize(school_year_id, params={})
    @school_year_id = school_year_id
    @params = params
    set_time_zone
  end

  def valid_token?(credentials=nil)
    access_token(credentials).present?
  end

  def destroy_all
    response = JSON.parse(RestClient.get(url, headers))
    ids = response.map { |r| r['id'] }
    ids.each { |i| RestClient.delete("#{url}/#{i}", headers) }
  end

  def destroy_logs
    school_year.ed_fi_logs.where(endpoint: endpoint).delete_all
  end

  def edfi_school?
    return if state_id.blank?

    RestClient.get("#{api_url}/schools?schoolId=#{state_id.number}", headers)
  rescue
    false
  end

  private
    def set_time_zone
      Time.zone = school.time_zone
    end

    def base_url
      secrets = Rails.application.secrets.edfi[:wisconsin]
      school_year.academic_year > 2023 ? secrets[:v6_base_url] : secrets[:base_url]
    end

    def api_url
      "#{base_url}/data/v3/#{school_year.academic_year}/ed-fi"
    end

    def url
      "#{api_url}/#{endpoint}"
    end

    def school_year
      @school_year ||= SchoolYear.find(@school_year_id)
    end

    def school
      @school ||= school_year.school
    end

    def state_id
      @state_id ||= school.state_id
    end

    def local_education_agency_id
      edfi_school['localEducationAgencyReference']['localEducationAgencyId']
    end

    def reporting_config
      @reporting_config ||= school_year.state_reporting_config
    end

    def school_config
      @school_config ||= school.school_config
    end

    def credential
      @credential ||= school.find_or_build_ed_fi_credential
    end

    def access_token(credentials=nil)
      @access_token ||= request_token(credentials)['access_token'] if request_token(credentials)
    end

    def request_token(credentials=nil)
      body = {
        client_id: credentials&.fetch('key', nil) || credential.key,
        client_secret: credentials&.fetch('secret', nil) || credential.secret,
        grant_type: :client_credentials
      }

      resp = begin RestClient.post("#{base_url}/oauth/token", body)
      rescue RestClient::Exception => e
        false
      end
      JSON.parse(resp) if resp
    end

    def headers
      { Authorization: "Bearer #{access_token}", 'Content-Type' => 'application/json' }
    end

    def rest_client_request(method, path, model, body: {})
      RestClient::Request.execute(
        method: method,
        url: path,
        headers: headers,
        payload: body
      )
    rescue RestClient::Exception => e
      return if e.response.body.blank?

      model.ed_fi_logs.create(
        school_year: school_year,
        endpoint: endpoint,
        json: body,
        response: e.response.body
      )
      false
    end
end
