/*
 * Created by sweetbread
 * Copyright (c) 2025. All rights reserved.
 */

package ru.sweetbread.unn.ui.composes

import android.graphics.drawable.Drawable
import android.text.Html
import android.text.method.LinkMovementMethod
import android.text.util.Linkify
import android.util.Log
import android.widget.TextView
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.NonRestartableComposable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewmodel.compose.viewModel
import coil.ImageLoader
import coil.compose.AsyncImage
import coil.request.ImageRequest
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import ru.sweetbread.unn.AvatarSet
import ru.sweetbread.unn.Post
import ru.sweetbread.unn.R
import ru.sweetbread.unn.Type
import ru.sweetbread.unn.User
import ru.sweetbread.unn.getBlogposts
import ru.sweetbread.unn.getUserByBitrixId
import ru.sweetbread.unn.portalURL
import ru.sweetbread.unn.ui.theme.UNNTheme
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle


val defUser = User(
    null,
    123,
    123,
    Type.Student,
    "cool.email@domain.com",
    "Джон Сигма Омегович",
    "Jon Sigma Omega",
    true,
    LocalDate.now(),
    AvatarSet(
        "https://upload.wikimedia.org/wikipedia/ru/thumb/9/94/%D0%93%D0%B8%D0%B3%D0%B0%D1%87%D0%B0%D0%B4.jpg/500px-%D0%93%D0%B8%D0%B3%D0%B0%D1%87%D0%B0%D0%B4.jpg",
        "https://upload.wikimedia.org/wikipedia/ru/thumb/9/94/%D0%93%D0%B8%D0%B3%D0%B0%D1%87%D0%B0%D0%B4.jpg/500px-%D0%93%D0%B8%D0%B3%D0%B0%D1%87%D0%B0%D0%B4.jpg",
        "https://upload.wikimedia.org/wikipedia/ru/thumb/9/94/%D0%93%D0%B8%D0%B3%D0%B0%D1%87%D0%B0%D0%B4.jpg/500px-%D0%93%D0%B8%D0%B3%D0%B0%D1%87%D0%B0%D0%B4.jpg"
    )
)


@Composable
fun Blogposts(viewModel: PostViewModel = viewModel()) {
    val posts by viewModel.posts.collectAsState()
    var extended by remember { mutableIntStateOf(0) }

    LaunchedEffect(Unit) {
        viewModel.loadPosts()
    }

    if (posts.isNotEmpty()) {
        Log.d("Another fuck", posts.size.toString())
        LazyColumn {
            items(posts) {
                PostItem(
                    Modifier
                        .padding(8.dp)
                        .clip(RoundedCornerShape(16.dp))
                        .background(MaterialTheme.colorScheme.secondaryContainer)
                        .clickable {
                            extended = if (extended == it.id) 0 else it.id
                        },
                    post = it,
                    extended == it.id
                )
            }
        }
    } else {
        LinearProgressIndicator(
            modifier = Modifier
                .fillMaxWidth()
                .padding(8.dp),
            color = MaterialTheme.colorScheme.surfaceVariant,
            trackColor = MaterialTheme.colorScheme.secondary,
        )
    }
}


class PostRepository {
    suspend fun loadPosts(): List<Post> {
        return getBlogposts()
    }
}

class PostViewModel : ViewModel() {
    private val repository = PostRepository()
    private val _posts = MutableStateFlow<List<Post>>(emptyList())
    val posts: StateFlow<List<Post>> = _posts.asStateFlow()

    suspend fun loadPosts() {
        _posts.value = repository.loadPosts()
    }
}


@Composable
@NonRestartableComposable
fun UserItem(modifier: Modifier = Modifier, user: User, info: String? = null) {
    Row(
        modifier.padding(16.dp),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.SpaceBetween
    ) {
        AsyncImage(
            modifier = Modifier
                .padding(end = 8.dp)
                .size(48.dp)
                .clip(RoundedCornerShape(50)),
            model = portalURL + user.avatar.thumbnail,
            contentDescription = user.nameEn
        )

        Column {
            Text(user.nameRu, fontWeight = FontWeight.Bold)
            if (!info.isNullOrBlank())
                Text(
                    text = info,
                    fontStyle = FontStyle.Italic,
                    fontSize = MaterialTheme.typography.labelLarge.fontSize
                )
        }
    }
}

@Composable
@NonRestartableComposable
fun PostItem(modifier: Modifier = Modifier, post: Post, extended: Boolean = false) {
    var user: User? by remember { mutableStateOf(null) }
    var html: String by remember { mutableStateOf("") }


    LaunchedEffect(post) {
        html = post.content
        user = getUserByBitrixId(post.authorId)
    }

    Column(modifier.padding(16.dp)) {
        if (user != null)
            UserItem(user = user!!)
        else
            LinearProgressIndicator(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(8.dp),
                color = MaterialTheme.colorScheme.surfaceVariant,
                trackColor = MaterialTheme.colorScheme.secondary,
            )

        val textColor = MaterialTheme.colorScheme.onBackground.toArgb()
        val linkColor = MaterialTheme.colorScheme.primary.toArgb()

        AndroidView(
            modifier = Modifier,
            factory = {
                TextView(it).apply {
                    movementMethod = LinkMovementMethod.getInstance()
                    autoLinkMask = Linkify.WEB_URLS
                    linksClickable = true
                    setTextColor(textColor)
                    setLinkTextColor(linkColor)
                }
            },
            update = {
                it.maxLines = if (extended) Int.MAX_VALUE else 5
                it.text = Html.fromHtml(
                    html,
                    Html.FROM_HTML_MODE_LEGACY,
                    CoilImageGetter(it),
                    null
                )
            }
        )

        HorizontalDivider(
            modifier = Modifier.padding(vertical = 16.dp),
            thickness = 1.dp,
            color = MaterialTheme.colorScheme.onBackground
        )

        Text(text = post.date.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)))
    }
}


@Preview
@Composable
fun UserItemPreview() {
    UNNTheme {
        Surface {
            UserItem(
                Modifier
                    .width(300.dp)
                    .clip(RoundedCornerShape(8.dp))
                    .background(MaterialTheme.colorScheme.primaryContainer), defUser, Type.Student.s
            )
        }
    }
}

@Preview
@Composable
fun PostItemPreview() {
    val post = Post(
        id = 154923,
        authorId = 165945,
        enableComments = true,
        numComments = 0,
        date = LocalDateTime.of(2024, 3, 20, 18, 55, 20),
        content = stringResource(id = R.string.lorem)
    )

    UNNTheme {
        Surface {
            PostItem(
                Modifier
                    .clip(RoundedCornerShape(8.dp))
                    .background(MaterialTheme.colorScheme.primaryContainer), post
            )
        }
    }
}


class CoilImageGetter(
    private val textView: TextView,
    private val maxImageWidth: Int = textView.width
) : Html.ImageGetter {

    override fun getDrawable(source: String): Drawable {
        val urlDrawable = UrlDrawable()

        if (maxImageWidth <= 0)
            textView.post { updateImage(source, urlDrawable, textView.width) }
        else
            updateImage(source, urlDrawable, maxImageWidth)

        return urlDrawable
    }

    private fun updateImage(source: String, urlDrawable: UrlDrawable, maxWidth: Int) {
        val imageLoader = ImageLoader.Builder(textView.context)
            .build()

        val request = ImageRequest.Builder(textView.context)
            .data(source)
            .target { drawable ->
                val (scaledWidth, scaledHeight) = calculateScaledSize(
                    drawable.intrinsicWidth,
                    drawable.intrinsicHeight,
                    maxWidth
                )

                drawable.setBounds(0, 0, scaledWidth, scaledHeight)
                urlDrawable.drawable = drawable
                urlDrawable.setBounds(0, 0, scaledWidth, scaledHeight)

                textView.text = textView.text
            }
            .build()

        imageLoader.enqueue(request)
    }

    private fun calculateScaledSize(
        originalWidth: Int,
        originalHeight: Int,
        maxWidth: Int
    ): Pair<Int, Int> {
        if (originalWidth <= maxWidth)
            return Pair(originalWidth, originalHeight)

        val ratio = maxWidth.toFloat() / originalWidth.toFloat()
        return Pair(
            maxWidth,
            (originalHeight * ratio).toInt()
        )
    }
}

class UrlDrawable() : Drawable() {
    var drawable: Drawable? = null
        set(value) {
            field = value
            invalidateSelf()
        }

    override fun draw(canvas: android.graphics.Canvas) {
        drawable?.draw(canvas)
    }

    override fun setAlpha(alpha: Int) {}
    override fun setColorFilter(colorFilter: android.graphics.ColorFilter?) {}
    override fun getOpacity(): Int = android.graphics.PixelFormat.TRANSLUCENT
}