package com.tomhempel.rbarometer.ui

import android.text.Editable
import android.text.TextWatcher
import android.content.res.ColorStateList
import android.graphics.Typeface
import android.view.Gravity
import android.view.View
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.PopupMenu
import android.widget.TextView
import android.widget.Toast
import androidx.core.content.ContextCompat
import com.google.android.material.button.MaterialButton
import com.google.android.material.card.MaterialCardView
import com.tomhempel.rbarometer.MainActivity
import com.tomhempel.rbarometer.R

class DashboardHandler(
    private val activity: MainActivity,
    private val onClose: () -> Unit,
) {
    private data class DashboardClient(
        val code: String,
        val status: String,
        val cycle: Int,
        val session: Int,
        val totalSessions: Int,
        val lastSession: String,
        val nextSession: String,
        val pendingMeasures: Int,
        val syncStatus: String,
        val trend: String,
        val participation: String,
        val cadence: String,
        val ownerNote: String,
    )

    private val clients = listOf(
        DashboardClient(
            code = "A102",
            status = "Due today",
            cycle = 3,
            session = 2,
            totalSessions = 6,
            lastSession = "Jun 17",
            nextSession = "Today",
            pendingMeasures = 2,
            syncStatus = "Sync OK",
            trend = "Stable",
            participation = "Active",
            cadence = "Weekly",
            ownerNote = "Continue current cycle",
        ),
        DashboardClient(
            code = "B447",
            status = "Overdue",
            cycle = 1,
            session = 5,
            totalSessions = 6,
            lastSession = "Jun 10",
            nextSession = "Jun 18",
            pendingMeasures = 4,
            syncStatus = "3 pending sync",
            trend = "Needs review",
            participation = "Active",
            cadence = "Weekly",
            ownerNote = "Needs scheduling contact",
        ),
        DashboardClient(
            code = "C083",
            status = "Upcoming",
            cycle = 2,
            session = 1,
            totalSessions = 6,
            lastSession = "Jun 21",
            nextSession = "Jun 28",
            pendingMeasures = 0,
            syncStatus = "Sync OK",
            trend = "Improving",
            participation = "Active",
            cadence = "Every 2 weeks",
            ownerNote = "Ready for next cycle",
        ),
        DashboardClient(
            code = "D219",
            status = "Paused",
            cycle = 4,
            session = 6,
            totalSessions = 6,
            lastSession = "Jun 03",
            nextSession = "Not planned",
            pendingMeasures = 1,
            syncStatus = "1 pending sync",
            trend = "Participation paused",
            participation = "Inactive",
            cadence = "On hold",
            ownerNote = "Confirm continuation",
        ),
    )

    fun show() {
        activity.setContentView(R.layout.dashboard_screen)
        activity.setBackPressInterceptor {
            close()
            true
        }
        bind()
    }

    private fun bind() {
        activity.findViewById<MaterialButton>(R.id.dashboardBackButton).setOnClickListener {
            close()
        }
        activity.findViewById<TextView>(R.id.dashboardSubtitle).text =
            "Prototype view for repeated limited-session cycles"
        activity.findViewById<TextView>(R.id.dashboardDueValue).text =
            clients.count { it.status == "Due today" || it.status == "Overdue" }.toString()
        activity.findViewById<TextView>(R.id.dashboardActiveValue).text =
            clients.count { it.status != "Paused" }.toString()
        activity.findViewById<TextView>(R.id.dashboardSyncValue).text =
            clients.count { it.syncStatus.contains("pending") }.toString()

        activity.findViewById<EditText>(R.id.dashboardSearchInput).addTextChangedListener(
            object : TextWatcher {
                override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit
                override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                    renderClients(s?.toString().orEmpty())
                }
                override fun afterTextChanged(s: Editable?) = Unit
            },
        )
        renderClients("")
    }

    private fun renderClients(query: String) {
        val list = activity.findViewById<LinearLayout>(R.id.dashboardClientList)
        list.removeAllViews()
        val normalized = query.trim()
        val visibleClients = if (normalized.isBlank()) {
            clients
        } else {
            clients.filter { client ->
                client.code.contains(normalized, ignoreCase = true) ||
                    client.status.contains(normalized, ignoreCase = true) ||
                    client.participation.contains(normalized, ignoreCase = true) ||
                    client.trend.contains(normalized, ignoreCase = true) ||
                    client.nextSession.contains(normalized, ignoreCase = true)
            }
        }
        visibleClients.forEach { client ->
            list.addView(createClientCard(client))
        }
    }

    private fun createClientCard(client: DashboardClient): View {
        val card = MaterialCardView(activity).apply {
            layoutParams = LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT,
            ).also { it.setMargins(0, dp(10), 0, 0) }
            radius = dp(10).toFloat()
            strokeWidth = dp(1)
            setStrokeColor(ContextCompat.getColor(activity, R.color.brand_header_stroke))
            setCardBackgroundColor(ContextCompat.getColor(activity, R.color.brand_header_surface))
            cardElevation = dp(1).toFloat()
        }

        val content = LinearLayout(activity).apply {
            orientation = LinearLayout.VERTICAL
            setPadding(dp(16), dp(14), dp(16), dp(16))
        }

        val header = LinearLayout(activity).apply {
            orientation = LinearLayout.HORIZONTAL
            gravity = Gravity.CENTER_VERTICAL
        }
        val titleBlock = LinearLayout(activity).apply {
            orientation = LinearLayout.VERTICAL
            layoutParams = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)
        }
        val title = TextView(activity).apply {
            text = client.code
            textSize = 20f
            setTypeface(typeface, Typeface.BOLD)
            setTextColor(ContextCompat.getColor(activity, R.color.brand_text_dark))
        }
        val subtitle = TextView(activity).apply {
            text = "Cycle ${client.cycle} - Session ${client.session} of ${client.totalSessions} - ${client.cadence}"
            textSize = 13f
            setTextColor(ContextCompat.getColor(activity, R.color.brand_text_muted))
        }
        titleBlock.addView(title)
        titleBlock.addView(subtitle)
        header.addView(titleBlock)
        header.addView(statusChip(client.status))

        val scheduleRow = metricRow(
            leftTitle = "Last session",
            leftValue = client.lastSession,
            rightTitle = "Next planned",
            rightValue = client.nextSession,
            rightAction = "Edit",
        )

        val workRow = metricRow(
            leftTitle = "Open measures",
            leftValue = client.pendingMeasures.toString(),
            rightTitle = "Data state",
            rightValue = client.syncStatus,
            rightAction = null,
        )

        val trend = TextView(activity).apply {
            text = "Trend: ${client.trend}  -  Participation: ${client.participation}\n${client.ownerNote}"
            textSize = 14f
            setLineSpacing(dp(2).toFloat(), 1f)
            setTextColor(ContextCompat.getColor(activity, R.color.brand_text_dark))
            setPadding(0, dp(12), 0, 0)
        }

        val actionRow = LinearLayout(activity).apply {
            orientation = LinearLayout.HORIZONTAL
            gravity = Gravity.CENTER_VERTICAL
            setPadding(0, dp(14), 0, 0)
        }
        actionRow.addView(primaryAction("Select client", weight = 1.25f))
        actionRow.addView(statusDropdown(client.participation, weight = 1.15f))
        actionRow.addView(destructiveAction("Remove", weight = 0.8f))

        content.addView(header)
        content.addView(scheduleRow)
        content.addView(workRow)
        content.addView(trend)
        content.addView(actionRow)
        card.addView(content)
        return card
    }

    private fun metricRow(
        leftTitle: String,
        leftValue: String,
        rightTitle: String,
        rightValue: String,
        rightAction: String?,
    ): View {
        val row = LinearLayout(activity).apply {
            orientation = LinearLayout.HORIZONTAL
            isBaselineAligned = false
            setPadding(0, dp(12), 0, 0)
        }
        row.addView(metricBlock(leftTitle, leftValue, weight = 1f))
        row.addView(metricBlock(rightTitle, rightValue, weight = 1f, action = rightAction))
        return row
    }

    private fun metricBlock(
        title: String,
        value: String,
        weight: Float,
        action: String? = null,
    ): View {
        val block = LinearLayout(activity).apply {
            orientation = LinearLayout.VERTICAL
            layoutParams = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, weight)
                .also { it.setMargins(0, 0, dp(8), 0) }
            background = ContextCompat.getDrawable(activity, R.drawable.bg_session_metric)
            setPadding(dp(12), dp(10), dp(12), dp(10))
        }
        val titleView = TextView(activity).apply {
            text = title
            textSize = 11f
            setTextColor(ContextCompat.getColor(activity, R.color.brand_text_muted))
        }
        val valueRow = LinearLayout(activity).apply {
            orientation = LinearLayout.HORIZONTAL
            gravity = Gravity.CENTER_VERTICAL
            setPadding(0, dp(3), 0, 0)
        }
        val valueView = TextView(activity).apply {
            text = value
            textSize = 16f
            setTypeface(typeface, Typeface.BOLD)
            setTextColor(ContextCompat.getColor(activity, R.color.brand_text_dark))
            layoutParams = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)
        }
        valueRow.addView(valueView)
        if (action != null) {
            valueRow.addView(smallAction(action))
        }
        block.addView(titleView)
        block.addView(valueRow)
        return block
    }

    private fun statusChip(status: String): TextView {
        val bg = when (status) {
            "Overdue" -> R.drawable.bg_chip_amber
            "Paused" -> R.drawable.bg_chip_locked
            else -> R.drawable.bg_chip_green
        }
        return TextView(activity).apply {
            text = status
            textSize = 12f
            setTypeface(typeface, Typeface.BOLD)
            setTextColor(
                ContextCompat.getColor(
                    activity,
                    if (status == "Paused") R.color.brand_chip_locked_text else R.color.brand_text_on_dark,
                ),
            )
            setBackgroundResource(bg)
            setPadding(dp(10), dp(6), dp(10), dp(6))
        }
    }

    private fun primaryAction(label: String, weight: Float): MaterialButton =
        dashboardButton(label, weight).apply {
            setTextColor(ContextCompat.getColor(activity, R.color.brand_text_on_dark))
            backgroundTintList = ColorStateList.valueOf(ContextCompat.getColor(activity, R.color.brand_purple))
            strokeColor = ColorStateList.valueOf(ContextCompat.getColor(activity, R.color.brand_purple))
        }

    private fun lifecycleAction(label: String, weight: Float): MaterialButton =
        dashboardButton(label, weight).apply {
            setTextColor(ContextCompat.getColor(activity, R.color.brand_text_dark))
            backgroundTintList = ColorStateList.valueOf(ContextCompat.getColor(activity, R.color.brand_header_surface))
            strokeColor = ColorStateList.valueOf(ContextCompat.getColor(activity, R.color.brand_header_stroke))
        }

    private fun statusDropdown(status: String, weight: Float): MaterialButton =
        lifecycleAction("Status: $status", weight).apply {
            setOnClickListener { anchor ->
                PopupMenu(activity, anchor).apply {
                    menu.add("Active")
                    menu.add("Inactive")
                    menu.add("Archived")
                    setOnMenuItemClickListener { item ->
                        Toast.makeText(
                            activity,
                            "Set status to ${item.title} is prototype-only",
                            Toast.LENGTH_SHORT,
                        ).show()
                        true
                    }
                }.show()
            }
        }

    private fun destructiveAction(label: String, weight: Float): MaterialButton =
        dashboardButton(label, weight).apply {
            setTextColor(ContextCompat.getColor(activity, R.color.brand_destructive_text))
            backgroundTintList = ColorStateList.valueOf(ContextCompat.getColor(activity, R.color.brand_destructive_fill))
            strokeColor = ColorStateList.valueOf(ContextCompat.getColor(activity, R.color.brand_destructive_fill))
        }

    private fun dashboardButton(label: String, weight: Float): MaterialButton =
        MaterialButton(activity).apply {
            layoutParams = LinearLayout.LayoutParams(0, dp(42), weight).also {
                it.setMargins(0, 0, dp(6), 0)
            }
            text = label
            textSize = 11f
            isAllCaps = false
            cornerRadius = dp(18)
            strokeWidth = dp(1)
            insetTop = 0
            insetBottom = 0
            setPadding(dp(6), 0, dp(6), 0)
            setOnClickListener {
                Toast.makeText(activity, "$label is prototype-only", Toast.LENGTH_SHORT).show()
            }
        }

    private fun smallAction(label: String): MaterialButton =
        MaterialButton(activity).apply {
            layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, dp(32))
            text = label
            textSize = 11f
            isAllCaps = false
            cornerRadius = dp(16)
            strokeWidth = dp(1)
            insetTop = 0
            insetBottom = 0
            minWidth = dp(52)
            minimumWidth = dp(52)
            setPadding(dp(8), 0, dp(8), 0)
            setTextColor(ContextCompat.getColor(activity, R.color.brand_purple))
            backgroundTintList = ColorStateList.valueOf(ContextCompat.getColor(activity, R.color.brand_header_surface))
            strokeColor = ColorStateList.valueOf(ContextCompat.getColor(activity, R.color.brand_purple))
            setOnClickListener {
                Toast.makeText(activity, "$label next session is prototype-only", Toast.LENGTH_SHORT).show()
            }
        }

    private fun close() {
        activity.setBackPressInterceptor(null)
        onClose()
    }

    private fun dp(value: Int): Int =
        (value * activity.resources.displayMetrics.density).toInt()
}
