# OverviewPregnancyState.kt

    /*
     * The MIT License
     *
     * Original work sponsored and donated by The Danish Health Data Authority (http://www.sundhedsdatastyrelsen.dk)
     *
     * Copyright (C) 2021 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.overview.widget

    import dk.nsp.mingraviditet.R
    import dk.nsp.mingraviditet.util.extensions.toTextModelOrDefault
    import dk.nsp.util.textmodel.TextModel
    import java.time.LocalDateTime

    typealias DidGiveBirthCallback = () -> Unit
    typealias PresentDateOfBirthCallback = (LocalDateTime?) -> Unit

    sealed class OverviewPregnancyState {

        abstract val widgetControls: List<OverviewWidgetControl>

        object None : OverviewPregnancyState() {
            override val widgetControls by lazy {
                listOf(
                    OverviewWidgetControl(
                        TextModel.from(R.string.overview_week_title),
                        OverviewWidgetControlType.Value(TextModel.from(R.string.common_missing_data))
                    ),
                    OverviewWidgetControl(
                        TextModel.from(R.string.overview_month_title),
                        OverviewWidgetControlType.Value(TextModel.from(R.string.common_missing_data))
                    ),
                    OverviewWidgetControl(
                        TextModel.from(R.string.overview_trimester_title),
                        OverviewWidgetControlType.Value(TextModel.from(R.string.common_missing_data))
                    )
                )
            }
        }

        class ActiveAndWaitingForBirth(
            val monthsIntoPregnancy: Double?,
            val dueDate: LocalDateTime?,
            val week: Int?,
            val gestationAgeString: String?,
            val trimester: Int?,
            val numberOfFetuses: Int?,
            val onDidGiveBirthPressed: DidGiveBirthCallback
        ) : OverviewPregnancyState() {
            override val widgetControls by lazy {
                listOfNotNull(
                    OverviewWidgetControl(
                        TextModel.from(R.string.overview_week_title),
                        OverviewWidgetControlType.DualValue(
                            week?.let { "$it." }.toTextModelOrDefault(),
                            gestationAgeString.toTextModelOrDefault()
                        )
                    ),
                    OverviewWidgetControl(
                        TextModel.from(R.string.overview_month_title),
                        OverviewWidgetControlType.Value(
                            this.pregnancyMonthAdjustedForDisplay?.toInt()?.let { "$it." }.toTextModelOrDefault()
                        )
                    ),
                    OverviewWidgetControl(
                        TextModel.from(R.string.overview_trimester_title),
                        OverviewWidgetControlType.Value(
                            trimester?.let { "$it." }.toTextModelOrDefault()
                        )
                    ),
                    if ((week ?: 0) >= 36) {
                        OverviewWidgetControl(
                            null,
                            OverviewWidgetControlType.TextAction(
                                TextModel.from(R.string.overview_did_give_birth_button_title),
                                onDidGiveBirthPressed
                            )
                        )
                    } else {
                        null
                    }
                )
            }

            /**
             * Used when displaying the pregnancy month to the user. The app should show e.g 15+3 as 4 months, but value from backend is only 3, so we have to correct it.
             */
            private val pregnancyMonthAdjustedForDisplay
                get() = monthsIntoPregnancy?.let { it + 1 }
        }

        class ActiveAndGaveBirth(
            val dateOfBirth: LocalDateTime,
            val numberOfFetuses: Int?,
            val presentDateOfBirthModal: PresentDateOfBirthCallback
        ) : OverviewPregnancyState() {
            override val widgetControls by lazy {
                listOf(
                    OverviewWidgetControl(
                        TextModel.from(R.string.overview_date_of_birth),
                        OverviewWidgetControlType.DateValue(dateOfBirth, presentDateOfBirthModal)
                    )
                )
            }
        }

        class PregnancyEnded(
            val numberOfFetuses: Int?
        ) : OverviewPregnancyState() {
            override val widgetControls by lazy {
                emptyList<OverviewWidgetControl>()
            }
        }
    }

    class OverviewWidgetControl(
        val title: TextModel?,
        val type: OverviewWidgetControlType
    )

    sealed class OverviewWidgetControlType {
        class Value(val text: TextModel) : OverviewWidgetControlType()
        class DateValue(
            val date: LocalDateTime?,
            val dateOfBirthCallback: PresentDateOfBirthCallback
        ) :
            OverviewWidgetControlType()

        class DualValue(val largeText: TextModel, val smallText: TextModel) :
            OverviewWidgetControlType()

        class TextAction(val text: TextModel, val callback: DidGiveBirthCallback) :
            OverviewWidgetControlType()
    }