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.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.LayoutElement
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 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 MAX_VISIBLE_CASES = 8

/**
 * Build the root Tile layout: a vertical stack with the most recent cases
 * pinned just above an edge-style "Neu" button. The whole list region is a
 * single tap target — every line routes to the case list, regardless of
 * which case was tapped. Up to [MAX_VISIBLE_CASES] cases are shown; the
 * newest sits at the bottom (next to the edge button).
 */
internal fun buildTileLayout(packageName: String, cases: List<CaseEntry>): LayoutElement {
    return Column.Builder()
        .setWidth(expand())
        .setHeight(expand())
        .setHorizontalAlignment(HORIZONTAL_ALIGN_CENTER)
        .addContent(Spacer.Builder().setHeight(dp(10f)).build())
        .addContent(caseListContent(packageName, cases))
        .addContent(Spacer.Builder().setHeight(dp(4f)).build())
        .addContent(bottomNewButton(packageName))
        .build()
}

private fun caseListContent(packageName: String, cases: List<CaseEntry>): LayoutElement {
    val column = Column.Builder()
        .setWidth(expand())
        .setHorizontalAlignment(HORIZONTAL_ALIGN_CENTER)

    if (cases.isEmpty()) {
        column.addContent(
            Text.Builder()
                .setText("Noch kein Fall heute")
                .setFontStyle(FontStyle.Builder().setSize(sp(14f)).build())
                .build(),
        )
    } else {
        val visible = cases.take(MAX_VISIBLE_CASES).asReversed()
        visible.forEachIndexed { index, case ->
            if (index > 0) {
                column.addContent(Spacer.Builder().setHeight(dp(2f)).build())
            }
            column.addContent(
                Text.Builder()
                    .setText(formatLine(case))
                    .setMaxLines(1)
                    .setFontStyle(FontStyle.Builder().setSize(sp(13f)).build())
                    .build(),
            )
        }
    }

    return Box.Builder()
        .setWidth(expand())
        .setHeight(expand())
        .setHorizontalAlignment(HORIZONTAL_ALIGN_CENTER)
        .setVerticalAlignment(VERTICAL_ALIGN_BOTTOM)
        .setModifiers(
            Modifiers.Builder()
                .setClickable(launchClickable(CLICK_ID_LIST, packageName, NavCommand.OPEN_LIST))
                .build(),
        )
        .addContent(column.build())
        .build()
}

/** "👤 text" if doctor-authored, plain text if auto-generated, "…" placeholder otherwise. */
private fun formatLine(case: CaseEntry): String {
    val text = case.oneliner.displayText() ?: return "…"
    return if (case.oneliner.isManual()) "👤 $text" else text
}

private fun bottomNewButton(packageName: String): LayoutElement {
    val text = Text.Builder()
        .setText("● Neu")
        .setFontStyle(
            FontStyle.Builder()
                .setSize(sp(14f))
                .setColor(argb(0xFF0A305F.toInt()))
                .build(),
        )
        .build()
    return Box.Builder()
        .setWidth(expand())
        .setHeight(dp(48f))
        .setVerticalAlignment(VERTICAL_ALIGN_CENTER)
        .setHorizontalAlignment(HORIZONTAL_ALIGN_CENTER)
        .setModifiers(
            Modifiers.Builder()
                .setClickable(launchClickable(CLICK_ID_NEW, packageName, NavCommand.OPEN_NEW))
                .setBackground(
                    Background.Builder()
                        .setColor(argb(0xFFAAC7FF.toInt()))
                        .setCorner(Corner.Builder().setRadius(dp(24f)).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()
