class EdFi::Indiana::Sandbox::StaffIdentityService < EdFi::Indiana::Sandbox::ApplicationService
  def search
    response = rest_client_request(:post, "#{url}/search", body: employee_props.to_json)
    response[:success] ? response[:body] : []
  end

  def find(id)
    response = rest_client_request(:get, "#{url}/#{id}")
    response[:success] ? response[:body] : {}
  end

  def create
    return if missing_information.any?

    path = "#{url}/create"
    response = rest_client_request(:post, path, body: employee_props(__method__).to_json)
    return response unless response[:success]

    # Create state number when 200 response otherwise create identity (202 response)
    response[:data] = if response[:http_code] == 200
      state_number = employee.find_or_build_state_number
      state_number.update(number: response[:body]['studentTestNumber'])
      state_number
    else
      update_identity(response[:body])
      identity
    end
    response
  end

  def processing_status
    return {} if identity.request_id.blank?

    response = rest_client_request(:get, "#{url}/create/#{identity.request_id}")
    update_identity(response[:body])
    identity
  end

  def missing_information
    [].tap do |props|
      fields  = [:last_name, :first_name, :date_of_birth]
      fields.each { |f| props << f if employee.send(f).blank? }
      props << :race if employee.race.blank?
      props << :social_security_number if employee.social_security_number.nil?
      props << :gender if employee.no_gender?
    end
  end

  private
    def api_url
      "#{base_url}/identity/v2/idoe"
    end

    def endpoint
      :staff
    end

    def employee
      @employee ||= @params[:employee]
    end

    def identity
      @identity ||= employee.find_or_build_ed_fi_identity
    end

    def race_descriptors
      @race_descriptors ||= EdFi::Descriptor
        .by_race_descriptor(school)
        .map { |r| [r.key, r.code] }
        .to_h
    end

    def update_identity(data)
      identity.school_year = school_year
      identity.request_id = data['requestId']
      identity.status = data['requestStatus'].downcase
      identity.processed_at = data['dateProcessed']
      identity.state_id = data['schoolPersonnelNumber']
      identity.save
    end

    def employee_props(method_name=:search)
      {}.tap do |props|
        props[:lastSurname] = employee.last_name
        props[:firstName] = employee.first_name
        props[:birthDate] = employee.date_of_birth
        return props unless method_name == :create

        props[:middleName] = employee.middle_name
        props[:nameSuffix] = employee.suffix
        props[:sex] = employee.decorate.gender_label
        props[:lastFourSSN] = employee.decorate.social_security_number_number

        # Grab the first race from the employee, since Indiana only accepts 1
        props[:race] = race_descriptors[employee.race.id]
      end
    end

    # TODO: Move this to the ApplicationService and update the other services
    def rest_client_request(method, path, body: {})
      response = RestClient::Request.execute(
        method: method,
        url: path,
        headers: headers,
        payload: body
      )
      http_code = response.code
      response = JSON.parse(response.body)

      { success: true, body: response, http_code: http_code }
    rescue RestClient::Exception => e
      { success: false, error: e.response&.body, http_code: e.http_code }
    end
end
