# JournalKeyValueSectionDetailsViewModel.kt

    /*
     * The MIT License
     *
     * Original work sponsored and donated by The Danish Health Data Authority (http://www.sundhedsdatastyrelsen.dk)
     *
     * Copyright (C) 2020 The Danish Health Data Authority (http://www.sundhedsdatastyrelsen.dk)
     *
     *
     * Permission is hereby granted, free of charge, to any person obtaining a copy of
     * this software and associated documentation files (the "Software"), to deal in
     * the Software without restriction, including without limitation the rights to
     * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
     * of the Software, and to permit persons to whom the Software is furnished to do
     * so, subject to the following conditions:
     *
     *
     * The above copyright notice and this permission notice shall be included in all
     * copies or substantial portions of the Software.
     *
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     * SOFTWARE.
     */

    package dk.nsp.mingraviditet.ui.main.journal.sections.sectiondetails

    import androidx.hilt.Assisted
    import androidx.lifecycle.LiveData
    import androidx.lifecycle.MutableLiveData
    import androidx.lifecycle.SavedStateHandle
    import androidx.lifecycle.ViewModel
    import androidx.lifecycle.viewModelScope
    import dagger.hilt.android.lifecycle.HiltViewModel
    import dk.nsp.domain.dictionary.DictionaryEntry
    import dk.nsp.domain.journal.observations.JournalSectionRow
    import dk.nsp.domain.repository.DataCardRepository
    import dk.nsp.domain.repository.DictionaryRepository
    import dk.nsp.mingraviditet.ui.adapterviews.KeyValueData
    import dk.nsp.mingraviditet.ui.adapterviews.KeyValueRow
    import dk.nsp.mingraviditet.ui.main.journal.JournalKeyValueSectionDetailType
    import dk.nsp.mingraviditet.ui.main.journal.sections.sectiondetails.aroundthepregnancy.AroundThePregnancyHelper
    import dk.nsp.mingraviditet.ui.main.journal.sections.sectiondetails.personaldata.PersonalDataHelper
    import dk.nsp.mingraviditet.ui.main.journal.sections.sectiondetails.professionalcontacts.HealthcareContactsHelper
    import dk.nsp.mingraviditet.ui.main.journal.sections.sectiondetails.screenings.ScreeningsRowsHelper
    import dk.nsp.mingraviditet.util.android.recycler.RecyclerAdapterView
    import dk.nsp.mingraviditet.util.extensions.toSingleEvent
    import dk.nsp.mingraviditet.util.livedata.SingleEvent
    import javax.inject.Inject

    @HiltViewModel
    class JournalKeyValueSectionDetailsViewModel @Inject constructor(
        private val dataCardRepository: DataCardRepository,
        private val dictionaryRepository: DictionaryRepository,
        @Assisted private val savedStateHandle: SavedStateHandle

    ) : ViewModel() {
        private val journalSectionDetailType =
            savedStateHandle.get<JournalKeyValueSectionDetailType>("journalSectionDetailType")

        private val _onDictionary: MutableLiveData<SingleEvent<DictionaryEntry>> = MutableLiveData()
        val onDictionary: LiveData<SingleEvent<DictionaryEntry>> = _onDictionary

        private val _rows: MutableLiveData<List<RecyclerAdapterView<*>>> = MutableLiveData()
        val rows: LiveData<List<RecyclerAdapterView<*>>> = _rows

        private val screeningsRowsHelper: ScreeningsRowsHelper by lazy {
            ScreeningsRowsHelper(dataCardRepository, dictionaryRepository)
        }

        private val aroundThePregnancyHelper by lazy {
            AroundThePregnancyHelper(dataCardRepository, dictionaryRepository)
        }

        private val healthcareContactsHelper by lazy {
            HealthcareContactsHelper(dataCardRepository, dictionaryRepository)
        }

        private val personalDataHelper by lazy {
            PersonalDataHelper(dataCardRepository, dictionaryRepository)
        }

        init {
            when (journalSectionDetailType) {
                JournalKeyValueSectionDetailType.ScreeningsBloodtype -> getBloodTypeSection()
                JournalKeyValueSectionDetailType.ScreeningsDiabetes -> getDiabetesSection()
                JournalKeyValueSectionDetailType.ScreeningsStreptococcusGroupB -> getStreptococcusGroupBSection()
                JournalKeyValueSectionDetailType.ScreeningsVitaminD -> getVitaminDSection()
                JournalKeyValueSectionDetailType.ScreeningsOther -> getOtherScreeningsSection()

                JournalKeyValueSectionDetailType.AroundThePregnancyExpectedDateOfBirth -> getExpectedDateOfBirthSection()
                JournalKeyValueSectionDetailType.AroundThePregnancyAssistedFertility -> getAssistedFertilitySection()
                JournalKeyValueSectionDetailType.AroundThePregnancyRiskAssessment -> getRiskAssessmentSection()

                JournalKeyValueSectionDetailType.AroundThePregnancyHealthSection -> getHealthSection()
                JournalKeyValueSectionDetailType.AroundThePregnancyLifestyle -> getLifestyleSection()
                JournalKeyValueSectionDetailType.AroundThePregnancyWorkEnvironment -> getWorkEnvironmentSection()

                JournalKeyValueSectionDetailType.HealthcareGeneralPractitioner -> getHealthcareGeneralPractitionerSection()
                JournalKeyValueSectionDetailType.HealthcareMidwifeOrganization -> getHealthcareMidwifeSection()
                JournalKeyValueSectionDetailType.HealthcareBirthplace -> getHealthcareBirthPlaceSection()
                JournalKeyValueSectionDetailType.HealthcareNurse -> getHealthcareNurseSection()

                JournalKeyValueSectionDetailType.PersonalContactInformation -> getPersonalDataContactInformation()
                JournalKeyValueSectionDetailType.PersonalLifeTogetherAndHome -> getPersonalLifeTogetherAndHome()
                JournalKeyValueSectionDetailType.PersonalNationalityAndLanguage -> getPersonalNationalityAndLanguage()
                JournalKeyValueSectionDetailType.PersonalRelations -> getPersonalDataRelatives()
                null -> throw NotImplementedError("journalSectionDetailType er ikke fundet (null)")
            }
        }

        private fun mapSectionToRows(sectionItems: List<JournalSectionRow>): List<KeyValueRow> {
            return sectionItems.map {
                val dictCallback =
                    it.onDictionary?.let { { _onDictionary.postValue(it.toSingleEvent()) } }

                KeyValueRow(KeyValueData(it.key, it.value, it.date, dictCallback))
            }
        }

        private fun getBloodTypeSection() {
            val screeningBloodTypeSection =
                screeningsRowsHelper.getScreeningBloodTypeSection(viewModelScope)
            _rows.postValue(mapSectionToRows(screeningBloodTypeSection))
        }

        private fun getDiabetesSection() {
            val diabetesSection = screeningsRowsHelper.getScreeningDiabetesSection(viewModelScope)
            _rows.postValue(mapSectionToRows(diabetesSection))
        }

        private fun getStreptococcusGroupBSection() {
            val streptococcusGroupBSection =
                screeningsRowsHelper.getStreptococcusGroupBSection(viewModelScope)
            _rows.postValue(mapSectionToRows(streptococcusGroupBSection))
        }

        private fun getVitaminDSection() {
            val vitaminDSection = screeningsRowsHelper.getVitaminDSection(viewModelScope)
            _rows.postValue(mapSectionToRows(vitaminDSection))
        }

        private fun getOtherScreeningsSection() {
            val otherScreeningsSection = screeningsRowsHelper.getOtherScreeningsSection(viewModelScope)
            _rows.postValue(mapSectionToRows(otherScreeningsSection))
        }

        private fun getExpectedDateOfBirthSection() {
            val expectedDateOfBirthSection =
                aroundThePregnancyHelper.getExpectedDateOfBirthSection(viewModelScope)
            _rows.postValue(mapSectionToRows(expectedDateOfBirthSection))
        }

        private fun getAssistedFertilitySection() {
            val section = aroundThePregnancyHelper.getAssistedFertilitySection(viewModelScope)
            _rows.postValue(mapSectionToRows(section))
        }

        private fun getRiskAssessmentSection() {
            val section = aroundThePregnancyHelper.getRiskAssessmentSection(viewModelScope)
            _rows.postValue(mapSectionToRows(section))
        }

        private fun getHealthSection() {
            val section = aroundThePregnancyHelper.getHealthSection(
                viewModelScope
            ) { _onDictionary.postValue(it.toSingleEvent()) }

            _rows.postValue(section)
        }

        private fun getLifestyleSection() {
            val section = aroundThePregnancyHelper.getLifestyleSection(viewModelScope) {
                _onDictionary.postValue(it.toSingleEvent())
            }
            _rows.postValue(section)
        }

        private fun getWorkEnvironmentSection() {
            val section = aroundThePregnancyHelper.getWorkEnvironmentSection(viewModelScope) {
                _onDictionary.postValue(it.toSingleEvent())
            }
            _rows.postValue(section)
        }

        private fun getHealthcareMidwifeSection() {
            val section = healthcareContactsHelper.getMidwifeSection(viewModelScope)
            _rows.postValue(mapSectionToRows(section))
        }

        private fun getHealthcareGeneralPractitionerSection() {
            val section = healthcareContactsHelper.getGeneralPractitionerSection(viewModelScope)
            _rows.postValue(mapSectionToRows(section))
        }

        private fun getHealthcareBirthPlaceSection() {
            val section = healthcareContactsHelper.getBirthplaceSection(viewModelScope)
            _rows.postValue(mapSectionToRows(section))
        }

        private fun getHealthcareNurseSection() {
            val section = healthcareContactsHelper.getNurseSection(viewModelScope)
            _rows.postValue(mapSectionToRows(section))
        }

        private fun getPersonalDataContactInformation() {
            val section = personalDataHelper.getContactInformation(viewModelScope)
            _rows.postValue(mapSectionToRows(section))
        }

        private fun getPersonalLifeTogetherAndHome() {
            val section = personalDataHelper.getPersonalLifeTogetherAndHome(viewModelScope)
            _rows.postValue(mapSectionToRows(section))
        }

        private fun getPersonalNationalityAndLanguage() {
            val section = personalDataHelper.getPersonalNationalityAndLanguage(viewModelScope)
            _rows.postValue(mapSectionToRows(section))
        }

        private fun getPersonalDataRelatives() {
            val section = personalDataHelper.getNextOfKinSection(viewModelScope)
            _rows.postValue(section)
        }
    }