package de.sebse.fuplanner2.ui.courses

import android.content.res.Configuration
import android.util.Log
import androidx.annotation.StringRes
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.Card
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material.icons.outlined.Person
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner
import de.sebse.fuplanner2.MenuItem
import de.sebse.fuplanner2.R
import de.sebse.fuplanner2.Tools
import de.sebse.fuplanner2.database.Course
import de.sebse.fuplanner2.ui.theme.*
import de.sebse.fuplanner2.ui.tools.previews.CoursePreviewProvider
import de.sebse.fuplanner2.ui.tools.viewmodels.CoursesViewModel
import de.sebse.fuplanner2.utils.color.getColor

@Composable
fun CoursesScreen(tools: Tools) {
    val viewModelStoreOwner = checkNotNull(LocalViewModelStoreOwner.current) {
        "No ViewModelStoreOwner was provided via LocalViewModelStoreOwner"
    }
    val coursesViewModel = ViewModelProvider(viewModelStoreOwner)[CoursesViewModel::class.java]
    val courses = coursesViewModel.list.observeAsState(listOf()).value
    val groups =
        courses.groupBy { (if (it.isSummerSemester) "+" else "-") + (it.year ?: 0) }

    val title = stringResource(R.string.menu_courses)
    LaunchedEffect(title) {
        tools.setTitle(title)
    }
    AppTheme {
        GroupedCourseList(groups = groups) { course ->
            course.uid?.let {
                Log.d("WHERE TO GO", "${MenuItem.Courses.route}/$it")
                tools.navTo("${MenuItem.Courses.route}/$it")
            }
        }
    }
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun GroupedCourseList(groups: Map<String, List<Course>>, onclick: (course: Course) -> Unit) {
    val headerBg =
        if (MaterialTheme.colors.isLight) md_theme_light_secondaryContainer
        else md_theme_dark_secondaryContainer
    val headerColor =
        if (MaterialTheme.colors.isLight) md_theme_light_onSecondaryContainer
        else md_theme_dark_onSecondaryContainer
    LazyColumn {
        for ((key, value) in groups.entries) {
            stickyHeader(key = key) {
                Text(
                    text = key,
                    color = headerColor,
                    modifier = Modifier
                        .fillMaxWidth()
                        .background(headerBg)
                        .padding()
                )
            }
            items(value) { course ->
                CourseItem(course) { onclick(course) }
            }
        }
    }
}

@Composable
fun CourseList(courses: List<Course>, onclick: () -> Unit) {
    LazyColumn {
        items(courses) { course -> CourseItem(course, onclick) }
    }
}

@Composable
fun CourseItem(course: Course, onclick: () -> Unit) {
    @Suppress("SimplifiableCallChain")
    CourseItem(
        id = course.uid,
        title = course.title,
        lecturers = course.lecturers
            .filter { lecturer -> lecturer.isResponsible }
            .map { lecturer ->
                stringResource(
                    R.string.full_name,
                    lecturer.firstName.substring(0, 1) + ".",
                    lecturer.lastName
                )
            }
            .joinToString(),
        type = course.type,
        onclick = onclick
    )
}

@Composable
fun CourseItem(id: Long?, title: String, lecturers: String, type: String, onclick: () -> Unit) {
    val color = Color(getColor(LocalContext.current, id ?: 0, highContrast = true))
    Card(
        modifier = Modifier
            .fillMaxWidth()
            .clickable(onClick = onclick)
            .padding(dimensionResource(R.dimen.card_view_margin)),
        elevation = dimensionResource(R.dimen.card_view_elevation)
    ) {
        Column(
            modifier = Modifier
                .height(1.5.dp)
                .background(Brush.horizontalGradient(
                    colors = listOf(color, MaterialTheme.colors.surface)
                ))
        ) {}
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .padding(dimensionResource(R.dimen.card_view_padding))
        ) {
            Text(
                text = title,
                color = MaterialTheme.colors.primaryVariant,
                style = MaterialTheme.typography.h6
            )
            CourseItemHint(
                icon = Icons.Outlined.Person,
                imageAltRes = R.string.lecturers,
                text = lecturers
            )
            CourseItemHint(
                icon = Icons.Outlined.Info,
                imageAltRes = R.string.course_type,
                text = type
            )
        }
    }
}

@Composable
fun CourseItemHint(icon: ImageVector, @StringRes imageAltRes: Int, text: String) {
    Row {
        Icon(
            icon,
            contentDescription = stringResource(imageAltRes),
            modifier = Modifier.padding(
                start = dimensionResource(R.dimen.card_view_padding)
            )
        )
        Text(
            text = text,
            style = MaterialTheme.typography.subtitle1,
            modifier = Modifier.padding(
                start = dimensionResource(R.dimen.card_view_padding)
            )
        )
    }
}

@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
fun CourseListPreview() {
    AppTheme {
        CourseList(
            CoursePreviewProvider().values.take(3).toList()
        ) { }
    }
}

@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Preview
@Composable
fun CourseItemPreview(@PreviewParameter(CoursePreviewProvider::class, 1) course: Course) {
    AppTheme {
        CourseItem(course) {}
    }
}
