package com.example.kasirapp

import android.graphics.Color
import android.os.Bundle
import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Spinner
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.example.kasirapp.data.AppDatabase
import com.example.kasirapp.data.Transaction
import com.github.mikephil.charting.charts.LineChart
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.data.LineData
import com.github.mikephil.charting.data.LineDataSet
import com.github.mikephil.charting.formatter.ValueFormatter
import kotlinx.coroutines.launch
import java.text.SimpleDateFormat
import java.util.*

class SalesTrafficActivity : AppCompatActivity() {

    private lateinit var lineChart: LineChart
    private lateinit var spinnerDateFilter: Spinner
    private val db by lazy { AppDatabase.getDatabase(this) }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sales_traffic)

        lineChart = findViewById(R.id.line_chart)
        spinnerDateFilter = findViewById(R.id.spinner_date_filter)

        setupFilterSpinner()
        loadTransactionsAndSetupChart(FilterOption.LAST_7_DAYS) // Default to last 7 days
    }

    private fun setupFilterSpinner() {
        val filterOptions = FilterOption.values().map { it.displayName }
        val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, filterOptions)
        spinnerDateFilter.adapter = adapter
        spinnerDateFilter.setSelection(FilterOption.LAST_7_DAYS.ordinal) // Set default selection

        spinnerDateFilter.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
                val selectedFilter = FilterOption.values()[position]
                loadTransactionsAndSetupChart(selectedFilter)
            }
            override fun onNothingSelected(parent: AdapterView<*>?) {}
        }
    }

    private fun loadTransactionsAndSetupChart(filter: FilterOption) {
        lifecycleScope.launch {
            val (startDate, endDate) = filter.getStartAndEndTimestamps()
            val transactions = db.transactionDao().getAllTransactions().filter {
                it.timestamp in startDate..endDate
            }
            setupLineChart(transactions, filter)
        }
    }

    private fun setupLineChart(transactions: List<Transaction>, filter: FilterOption) {
        val salesData = getSalesDataForChart(transactions, filter)

        val entries = ArrayList<Entry>()
        salesData.values.forEachIndexed { index, sales ->
            entries.add(Entry(index.toFloat(), sales.toFloat()))
        }

        val dataSet = LineDataSet(entries, "Penjualan").apply {
            color = Color.BLUE
            valueTextColor = Color.BLACK
            lineWidth = 2f
            setCircleColor(Color.BLUE)
            circleRadius = 4f
        }

        val lineData = LineData(dataSet)
        lineChart.data = lineData

        lineChart.description.text = filter.displayName
        lineChart.xAxis.valueFormatter = DateAxisFormatter(salesData.keys.toList())
        lineChart.invalidate() // Refresh chart
    }

    private fun getSalesDataForChart(transactions: List<Transaction>, filter: FilterOption): Map<String, Int> {
        val salesByDay = LinkedHashMap<String, Int>()
        val (startDate, _) = filter.getStartAndEndTimestamps()
        val calendar = Calendar.getInstance().apply { timeInMillis = startDate }
        val endCalendar = Calendar.getInstance()

        val sdf = if (filter == FilterOption.THIS_MONTH) {
            SimpleDateFormat("dd", Locale.getDefault())
        } else {
            SimpleDateFormat("dd/MM", Locale.getDefault())
        }

        // Initialize map with all days/dates in the range
        while (calendar.timeInMillis <= endCalendar.timeInMillis) {
            salesByDay[sdf.format(calendar.time)] = 0
            calendar.add(Calendar.DAY_OF_YEAR, 1)
        }

        // Populate with transaction data
        transactions.forEach { transaction ->
            val dateString = sdf.format(Date(transaction.timestamp))
            if (salesByDay.containsKey(dateString)) {
                salesByDay[dateString] = (salesByDay[dateString] ?: 0) + transaction.total
            }
        }

        return salesByDay
    }

    enum class FilterOption(val displayName: String) {
        TODAY("Hari Ini"),
        LAST_7_DAYS("7 Hari Terakhir"),
        THIS_MONTH("Bulan Ini"),
        ALL("Semua"); // Although 'All' is less meaningful for a traffic chart, we keep it for consistency

        fun getStartAndEndTimestamps(): Pair<Long, Long> {
            val calendar = Calendar.getInstance()
            val endDate = calendar.timeInMillis

            when (this) {
                TODAY -> {
                    calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0)
                }
                LAST_7_DAYS -> {
                    calendar.add(Calendar.DAY_OF_YEAR, -6)
                    calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0)
                }
                THIS_MONTH -> {
                    calendar.set(Calendar.DAY_OF_MONTH, 1)
                    calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0)
                }
                ALL -> return Pair(0, Long.MAX_VALUE)
            }
            val startDate = calendar.timeInMillis
            return Pair(startDate, endDate)
        }
    }

    class DateAxisFormatter(private val dates: List<String>) : ValueFormatter() {
        override fun getFormattedValue(value: Float):
                String = dates.getOrNull(value.toInt()) ?: ""
    }
}
