package com.applemand.zmanim.feature.calendar

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.CalendarMonth
import androidx.compose.material.icons.filled.CalendarToday
import androidx.compose.material.icons.filled.CalendarViewDay
import androidx.compose.material.icons.filled.CalendarViewMonth
import androidx.compose.material.icons.filled.CalendarViewWeek
import androidx.compose.material3.windowsizeclass.WindowSizeClass
import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.dp
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.applemand.zmanim.core.ui.AdaptiveDestination
import com.applemand.zmanim.core.ui.AdaptiveScaffold
import com.applemand.zmanim.core.ui.kind
import com.applemand.zmanim.core.ui.keyboardCalendarNav
import com.applemand.zmanim.feature.calendar.components.CalendarHeader
import com.applemand.zmanim.feature.calendar.components.DailyBanner
import kotlinx.datetime.DateTimeUnit
import kotlinx.datetime.LocalDate
import kotlinx.datetime.plus

@Composable
fun CalendarScreen(
    windowSizeClass: WindowSizeClass,
    widthDp: Int,
    onOpenSettings: () -> Unit,
    onOpenLocationPicker: () -> Unit,
    onOpenDafYomi: () -> Unit,
    onOpenIcsExport: () -> Unit,
    modifier: Modifier = Modifier,
    viewModel: CalendarViewModel = hiltViewModel(),
    settingsViewModel: CalendarSettingsViewModel = hiltViewModel(),
    sidePanel: (@Composable () -> Unit)? = null,
) {
    val state by viewModel.state.collectAsStateWithLifecycle()
    val userSettings by settingsViewModel.state.collectAsStateWithLifecycle()
    val todaySummary = state.daySummaries[state.currentDate]
    val layout = windowSizeClass.kind(widthDp)

    val destinations = listOf(
        AdaptiveDestination(
            id = "day", label = "Day", icon = Icons.Filled.CalendarViewDay,
            selected = state.view == CalendarView.DAY,
            onClick = { viewModel.setView(CalendarView.DAY) },
        ),
        AdaptiveDestination(
            id = "week", label = "Week", icon = Icons.Filled.CalendarViewWeek,
            selected = state.view == CalendarView.WEEK,
            onClick = { viewModel.setView(CalendarView.WEEK) },
        ),
        AdaptiveDestination(
            id = "month", label = "Month", icon = Icons.Filled.CalendarMonth,
            selected = state.view == CalendarView.MONTH,
            onClick = { viewModel.setView(CalendarView.MONTH) },
        ),
        AdaptiveDestination(
            id = "year", label = "Year", icon = Icons.Filled.CalendarViewMonth,
            selected = state.view == CalendarView.YEAR,
            onClick = { viewModel.setView(CalendarView.YEAR) },
        ),
    )

    AdaptiveScaffold(
        layout = layout,
        destinations = destinations,
        topBar = {
            CalendarHeader(
                currentDate = state.currentDate,
                hebrewDate = todaySummary?.hebrewDate,
                view = state.view,
                onPrev = { viewModel.setDate(navigate(state.currentDate, state.view, -1)) },
                onNext = { viewModel.setDate(navigate(state.currentDate, state.view, 1)) },
                onToday = { viewModel.goToday() },
                onViewChange = viewModel::setView,
                onOpenLocationPicker = onOpenLocationPicker,
                onOpenSettings = onOpenSettings,
                onOpenDafYomi = onOpenDafYomi,
                onOpenIcsExport = onOpenIcsExport,
            )
        },
        sidePanel = sidePanel,
    ) { inner ->
        Column(
            modifier = modifier
                .fillMaxSize()
                .padding(inner)
                .keyboardCalendarNav(
                    onPrev = { viewModel.setDate(navigate(state.currentDate, state.view, -1)) },
                    onNext = { viewModel.setDate(navigate(state.currentDate, state.view, 1)) },
                    onToday = viewModel::goToday,
                    onSelect = { viewModel.setView(CalendarView.DAY) },
                )
        ) {
            if (todaySummary != null) {
                DailyBanner(today = todaySummary, onDismiss = { /* session-only */ })
            }
            when (state.view) {
                CalendarView.DAY -> {
                    todaySummary?.let { day ->
                        val s = userSettings
                        val zmanimMap = when {
                            s == null -> com.applemand.zmanim.core.zmanim.ZmanKey.entries
                                .associate { it.keyId to true }
                            !s.showZmanim -> com.applemand.zmanim.core.zmanim.ZmanKey.entries
                                .associate { it.keyId to false }
                            else -> s.zmanimVisibleMap
                        }
                        DayScreen(
                            day = day,
                            visibleZmanim = zmanimMap,
                            twelveHour = s?.twelveHourClock ?: true,
                            showSeconds = s?.showZmanimSeconds ?: false,
                            contentPadding = PaddingValues(16.dp),
                        )
                    }
                }
                CalendarView.WEEK -> {
                    WeekScreen(
                        days = state.daySummaries.values.sortedBy { it.date.toEpochDays() },
                        onDaySelect = viewModel::setDate,
                    )
                }
                CalendarView.MONTH -> {
                    MonthScreen(
                        year = state.currentDate.year,
                        month = state.currentDate.monthNumber,
                        days = state.daySummaries.values.sortedBy { it.date.toEpochDays() },
                        today = state.today,
                        onDaySelect = viewModel::setDate,
                    )
                }
                CalendarView.YEAR -> {
                    YearScreen(
                        year = state.currentDate.year,
                        onMonthSelect = { m ->
                            viewModel.setDate(LocalDate(state.currentDate.year, m, 1))
                            viewModel.setView(CalendarView.MONTH)
                        },
                    )
                }
            }
        }
    }
}

private fun navigate(date: LocalDate, view: CalendarView, direction: Int): LocalDate = when (view) {
    CalendarView.DAY -> date.plus(direction, DateTimeUnit.DAY)
    CalendarView.WEEK -> date.plus(direction * 7, DateTimeUnit.DAY)
    CalendarView.MONTH -> date.plus(direction, DateTimeUnit.MONTH)
    CalendarView.YEAR -> date.plus(direction, DateTimeUnit.YEAR)
}
