package com.doctate.watch.tile

import androidx.wear.protolayout.ActionBuilders
import androidx.wear.protolayout.ColorBuilders.argb
import androidx.wear.protolayout.DimensionBuilders.dp
import androidx.wear.protolayout.DimensionBuilders.expand
import androidx.wear.protolayout.LayoutElementBuilders
import androidx.wear.protolayout.LayoutElementBuilders.Box
import androidx.wear.protolayout.LayoutElementBuilders.Column
import androidx.wear.protolayout.LayoutElementBuilders.FontStyle
import androidx.wear.protolayout.LayoutElementBuilders.HORIZONTAL_ALIGN_CENTER
import androidx.wear.protolayout.LayoutElementBuilders.HORIZONTAL_ALIGN_END
import androidx.wear.protolayout.LayoutElementBuilders.HORIZONTAL_ALIGN_START
import androidx.wear.protolayout.LayoutElementBuilders.LayoutElement
import androidx.wear.protolayout.LayoutElementBuilders.Row
import androidx.wear.protolayout.LayoutElementBuilders.Spacer
import androidx.wear.protolayout.LayoutElementBuilders.Text
import androidx.wear.protolayout.LayoutElementBuilders.VERTICAL_ALIGN_BOTTOM
import androidx.wear.protolayout.LayoutElementBuilders.VERTICAL_ALIGN_CENTER
import androidx.wear.protolayout.ModifiersBuilders.Background
import androidx.wear.protolayout.ModifiersBuilders.Clickable
import androidx.wear.protolayout.ModifiersBuilders.Corner
import androidx.wear.protolayout.ModifiersBuilders.Modifiers
import androidx.wear.protolayout.ModifiersBuilders.Padding
import androidx.wear.protolayout.TypeBuilders.StringProp
import com.doctate.watch.domain.CaseEntry
import com.doctate.watch.domain.displayText
import com.doctate.watch.domain.isManual
import com.doctate.watch.presentation.NavCommand

private const val CLICK_ID_LIST = "list"
private const val CLICK_ID_NEW = "new"
private const val CLICK_ID_CONTINUE = "continue"

/** Build the root layout element for the Tile. Returns the "current case" view or an
 *  empty-state view depending on whether any case exists in [CaseStoreStub]. */
internal fun buildTileLayout(packageName: String, current: CaseEntry?): LayoutElement {
    val column = Column.Builder()
        .setWidth(expand())
        .setHeight(expand())
        .setHorizontalAlignment(HORIZONTAL_ALIGN_CENTER)
        .addContent(topRow(packageName))
        .addContent(Spacer.Builder().setHeight(dp(8f)).build())
        .addContent(middleContent(packageName, current))
        .addContent(Spacer.Builder().setHeight(dp(8f)).build())
        .addContent(bottomNewButton(packageName))
        .build()

    return Box.Builder()
        .setWidth(expand())
        .setHeight(expand())
        .setVerticalAlignment(VERTICAL_ALIGN_CENTER)
        .addContent(column)
        .build()
}

private fun topRow(packageName: String): LayoutElement {
    val faelle = Text.Builder()
        .setText("☰ Fälle")
        .setFontStyle(FontStyle.Builder().setSize(sp(14f)).build())
        .setModifiers(
            Modifiers.Builder()
                .setClickable(launchClickable(CLICK_ID_LIST, packageName, NavCommand.OPEN_LIST))
                .setPadding(
                    Padding.Builder().setStart(dp(8f)).setEnd(dp(8f))
                        .setTop(dp(4f)).setBottom(dp(4f)).build(),
                )
                .build(),
        )
        .build()
    // Row has no horizontal-alignment prop; use a Box with END alignment instead.
    return Box.Builder()
        .setWidth(expand())
        .setHorizontalAlignment(HORIZONTAL_ALIGN_END)
        .setVerticalAlignment(VERTICAL_ALIGN_CENTER)
        .addContent(faelle)
        .build()
}

private fun middleContent(packageName: String, current: CaseEntry?): LayoutElement {
    val label = when {
        current == null -> "Noch kein Fall heute"
        else -> current.oneliner.displayText()
            ?.let { if (current.oneliner.isManual()) "👤 $it" else it }
            ?: "…"
    }
    val textBuilder = Text.Builder()
        .setText(label)
        .setMaxLines(3)
        .setFontStyle(FontStyle.Builder().setSize(sp(16f)).build())

    val modifiersBuilder = Modifiers.Builder()
        .setPadding(
            Padding.Builder().setStart(dp(12f)).setEnd(dp(12f))
                .setTop(dp(6f)).setBottom(dp(6f)).build(),
        )
    if (current != null) {
        modifiersBuilder.setClickable(
            launchClickable(
                CLICK_ID_CONTINUE,
                packageName,
                NavCommand.OPEN_CONTINUE,
                caseId = current.caseId,
            ),
        )
    }
    textBuilder.setModifiers(modifiersBuilder.build())
    return textBuilder.build()
}

private fun bottomNewButton(packageName: String): LayoutElement {
    val text = Text.Builder()
        .setText("● Neu")
        .setFontStyle(FontStyle.Builder().setSize(sp(14f)).build())
        .build()
    return Box.Builder()
        .setWidth(expand())
        .setHeight(dp(36f))
        .setVerticalAlignment(VERTICAL_ALIGN_BOTTOM)
        .setHorizontalAlignment(HORIZONTAL_ALIGN_CENTER)
        .setModifiers(
            Modifiers.Builder()
                .setClickable(launchClickable(CLICK_ID_NEW, packageName, NavCommand.OPEN_NEW))
                .setBackground(
                    Background.Builder()
                        .setColor(argb(0xFF1F1F1F.toInt()))
                        .setCorner(Corner.Builder().setRadius(dp(18f)).build())
                        .build(),
                )
                .setPadding(
                    Padding.Builder().setStart(dp(12f)).setEnd(dp(12f))
                        .setTop(dp(6f)).setBottom(dp(6f)).build(),
                )
                .build(),
        )
        .addContent(text)
        .build()
}

private fun launchClickable(
    id: String,
    packageName: String,
    open: String,
    caseId: String? = null,
): Clickable {
    val activity = ActionBuilders.AndroidActivity.Builder()
        .setPackageName(packageName)
        .setClassName("com.doctate.watch.presentation.MainActivity")
        .addKeyToExtraMapping(
            NavCommand.EXTRA_OPEN,
            ActionBuilders.AndroidStringExtra.Builder().setValue(open).build(),
        )
    if (caseId != null) {
        activity.addKeyToExtraMapping(
            NavCommand.EXTRA_CASE_ID,
            ActionBuilders.AndroidStringExtra.Builder().setValue(caseId).build(),
        )
    }
    return Clickable.Builder()
        .setId(id)
        .setOnClick(ActionBuilders.LaunchAction.Builder().setAndroidActivity(activity.build()).build())
        .build()
}

private fun sp(size: Float): androidx.wear.protolayout.DimensionBuilders.SpProp =
    androidx.wear.protolayout.DimensionBuilders.SpProp.Builder().setValue(size).build()
