class EdFi::Wisconsin::IdentityService < EdFi::Wisconsin::ApplicationService
  def search
    response = RestClient.post("#{api_url}/search", student_props.to_json, headers)
    return if response.body.blank?

    body = JSON.parse(response.body)
    { key: body['searchKey'], body: body['searchResponses'].first['responses'] }
  rescue RestClient::Exception => e
    return if e.response&.body.blank?

    { error: JSON.parse(e.response.body) }
  end

  def create(key)
    response = RestClient.post(api_url, create_props(key).to_json, headers)
    additional_id = student.find_or_build_state_number
    additional_id.update!(number: response.body.delete('\\"'))
    {
      id: additional_id.id,
      code: additional_id.code,
      full_name: student.full_name,
      number: additional_id.number
    }
  rescue RestClient::Exception => e
    return if e.response&.body.blank?

    { error: JSON.parse(e.response.body) }
  end

  def find(id)
    response = RestClient.post("#{api_url}/find", [id].to_json, headers)
    JSON.parse(response.body)
  rescue RestClient::Exception => e
    e.response.body
  end

  private
    def api_url
      "#{base_url}/identity/v2/#{school_year.academic_year}/identities"
    end

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

    def student_detail
      @student_detail ||= student.find_or_build_detail
    end

    def primary_contacts
      student.all_contact_families.primary
    end

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

    def student_props
      gender = if student.male?
        'M'
      elsif student.female?
        'F'
      elsif student.non_binary?
        'X'
      end

      [{
        lastSurname: student.last_name,
        firstName: student.first_name,
        middleName: student.middle_name,
        birthDate: student.date_of_birth,
        sexType: gender,
        educationOrganizationId: student.school.additional_ids.lea.first.number
      }]
    end

    def create_props(key)
      student_props.first.merge({
        searchKey: key,
        multipleBirthIndicator: student_detail.multi_birth_status,
        isHispanicLatino: student.hispanic?,
        raceCodes: student.race_students.map { |r| race_descriptors[r.race_id] },
        birthLocation: {
          city: student_detail.birth_city,
          country: student_detail.birth_country&.name
        },
        locals: [{
          educationOrganizationId: student.school.additional_ids.lea.first.number,
          localPersonId: student.id.to_s,
          email: student.email,
          typeDescription: :Student
        }],
        names: [{
          lastSurname: student.last_name,
          firstName: student.first_name,
          middleName: student.middle_name
        }],
        parentGuardianNames: primary_contacts.map { |c| parent_props(c) }
      })
    end

    def parent_props(contact_family)
      {
        firstName: contact_family.contact.first_name,
        lastSurname: contact_family.contact.last_name,
        typeDescription: parent_type_description(contact_family.relationship&.name)
      }
    end

    def parent_type_description(relationship)
      case relationship
      when 'Mother'
        :Mother
      when 'Father'
        :Father
      when 'Guardian'
        :Guardian
      else
        :Other
      end
    end
end
