package com.gh.gamecenter.setting.compose.ui.component

import android.os.Handler
import android.os.Looper
import android.view.MotionEvent
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.input.pointer.pointerInteropFilter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.constraintlayout.compose.Dimension
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.rememberLottieAnimatable
import com.airbnb.lottie.compose.rememberLottieComposition
import com.gh.gamecenter.setting.compose.R
import com.gh.gamecenter.setting.compose.ui.theme.HaloTheme
import kotlin.math.abs

@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun SettingItem(
    name: String,
    content: String = "",
    tips: String = "",
    showSelected: Boolean = false,
    selectedStatus: Boolean = false,
    showArrow: Boolean = false,
    showSwitch: Boolean = false,
    switchStatus: Boolean = false,
    showUpdateHint: Boolean = false,
    contentColor: Color = HaloTheme.colors.textSubtitleDesc,
    onLongClick: (() -> Unit)? = null,
    onClick: (() -> Unit)? = null
) {
    var isPressed by remember {
        mutableStateOf(false)
    }
    var isLongPressed by remember {
        mutableStateOf(false)
    }
    var lastX by remember {
        mutableStateOf(0F)
    }
    var lastY by remember {
        mutableStateOf(0F)
    }
    val handler = remember {
        Handler(Looper.getMainLooper())
    }

    ConstraintLayout(
        modifier = Modifier
            .fillMaxWidth()
            .background(if (isPressed) Color(0X0D000000) else HaloTheme.colors.backgroundWhite)
            .pointerInteropFilter {
                when (it.action) {
                    MotionEvent.ACTION_DOWN -> {
                        lastX = it.x
                        lastY = it.y
                        handler.postDelayed({
                            isLongPressed = true
                            onLongClick?.invoke()
                        }, 400)
                        isPressed = true
                    }
                    MotionEvent.ACTION_CANCEL -> {
                        isPressed = false
                        handler.removeCallbacksAndMessages(null)
                    }
                    MotionEvent.ACTION_MOVE -> {
                        val offsetX = abs(it.x - lastX)
                        val offsetY = abs(it.y - lastY)
                        if (offsetX > 10 || offsetY > 10) {
                            isLongPressed = false
                            handler.removeCallbacksAndMessages(null)
                        }
                    }
                    MotionEvent.ACTION_UP -> {
                        isPressed = false
                        if (!isLongPressed) onClick?.invoke()
                        isLongPressed = false
                        handler.removeCallbacksAndMessages(null)
                    }
                }
                true
            }
    ) {
        val (desc, iconArrow, iconSelected, textContent, switchLottie, updateHint) = createRefs()
        val showContent = content.isNotEmpty()
        val showTips = tips.isNotEmpty()

        Column(modifier = Modifier.constrainAs(desc) {
            top.linkTo(parent.top, 15.dp)
            start.linkTo(parent.start, 16.dp)
            end.linkTo(parent.end, 60.dp)
            bottom.linkTo(parent.bottom, 15.dp)
            width = Dimension.fillToConstraints
            height = Dimension.preferredWrapContent
        }) {
            Description(name, tips, showTips)
        }

        if (showArrow) {
            Icon(imageVector = ImageVector.vectorResource(id = (R.drawable.icon_more)),
                contentDescription = null,
                tint = if (isSystemInDarkTheme()) Color(0x3DFFFFFF) else Color(0xFFAAAAAA),
                modifier = Modifier
                    .size(12.dp)
                    .constrainAs(iconArrow) {
                        top.linkTo(parent.top)
                        end.linkTo(parent.end, 16.dp)
                        bottom.linkTo(parent.bottom)
                    })
        }

        if (showContent) {
            Text(
                text = content,
                fontSize = 14.sp,
                color = contentColor,
                modifier = Modifier.constrainAs(textContent) {
                    top.linkTo(parent.top)
                    if (showArrow) end.linkTo(iconArrow.start, margin = 4.dp) else end.linkTo(parent.end, 16.dp)
                    bottom.linkTo(parent.bottom)
                })
        }

        if (showSelected) {
            Icon(imageVector = ImageVector.vectorResource(id = if (selectedStatus) R.drawable.ic_selector_selected_svg else R.drawable.ic_selector_default_svg),
                contentDescription = null,
                tint = if (selectedStatus) Color.Unspecified else if (!selectedStatus && isSystemInDarkTheme()) Color(
                    0X14FFFFFF
                ) else Color(0XFFEEEEEE),
                modifier = Modifier
                    .size(16.dp)
                    .constrainAs(iconSelected) {
                        top.linkTo(parent.top)
                        end.linkTo(parent.end, 16.dp)
                        bottom.linkTo(parent.bottom)
                    })
        }

        if (showSwitch) {
            val lottieTurnOff =
                rememberLottieComposition(LottieCompositionSpec.Asset(if (isSystemInDarkTheme()) "lottie/switch_turnoff_dark.json" else "lottie/switch_turnoff_light.json"))
            val lottieTurnOn =
                rememberLottieComposition(LottieCompositionSpec.Asset(if (isSystemInDarkTheme()) "lottie/switch_turnon_dark.json" else "lottie/switch_turnon_light.json"))
            val animation = rememberLottieAnimatable()
            LaunchedEffect(switchStatus) {
                animation.animate(
                    (if (switchStatus) lottieTurnOn else lottieTurnOff).await(),
                    initialProgress = 0F
                )
            }
            LaunchedEffect(isSystemInDarkTheme()) {
                animation.animate(
                    (if (switchStatus) lottieTurnOn else lottieTurnOff).await(),
                    initialProgress = 1F
                )
            }
            LottieAnimation(composition = animation.composition, progress = {
                animation.progress
            }, modifier = Modifier
                .size(40.dp, 20.dp)
                .constrainAs(switchLottie) {
                    top.linkTo(parent.top)
                    end.linkTo(parent.end, 16.dp)
                    bottom.linkTo(parent.bottom)
                })
        }

        if (showUpdateHint) {
            Text(text = LocalContext.current.getString(R.string.personal_update_hint),
                color = Color.White,
                fontSize = 10.sp,
                modifier = Modifier
                    .background(HaloTheme.colors.themeRed, CircleShape)
                    .padding(horizontal = 6.dp, vertical = (2.5F).dp)
                    .constrainAs(updateHint) {
                        top.linkTo(parent.top)
                        end.linkTo(parent.end, 16.dp)
                        bottom.linkTo(parent.bottom)
                    })
        }
    }
}


@Composable
fun Description(title: String, tips: String = "", showTips: Boolean = false) {
    Text(text = title, fontSize = 14.sp, color = HaloTheme.colors.textTitle)
    if (showTips) {
        Text(
            text = tips,
            fontSize = 12.sp,
            color = HaloTheme.colors.textSubtitleDesc,
            lineHeight = 16.sp,
            modifier = Modifier.padding(top = 8.dp)
        )
    }
}