package com.convenient.android.lib.ui.sample.media

import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Icon
import androidx.compose.material.RadioButton
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material3.*
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.constraintlayout.compose.Dimension
import androidx.core.content.ContextCompat
import androidx.lifecycle.viewmodel.compose.viewModel
import com.convenient.android.common.extension.lengthToFitMemorySize
import com.convenient.android.common.extension.spSave
import com.convenient.android.common.extension.toFile
import com.convenient.android.common.media.config.MediaSortOrder
import com.convenient.android.common.media.config.MediaSortType
import com.convenient.android.common.utils.date.DateUtils
import com.convenient.android.lib.R
import com.convenient.android.lib.ui.theme.SampleTheme

/**
 * @classname:
 * @author: LiuXiaoLong
 * @date: 2022/8/4
 * description:
 */

@Composable
fun MediaPage() {
    val context = LocalContext.current
    var rememberPermission by remember {
        mutableStateOf(ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
    }
    if (rememberPermission) {
        MediaFilesPage()
    } else {
        PermissionPage {
            rememberPermission = true
        }
    }

}

@Composable
fun MediaFilesPage() {
    val viewModel: MediaFilesViewModel = viewModel()
    val result = viewModel.result.collectAsState()

    LazyColumn {

        item {
            QueryInfoPage(viewModel = viewModel)
        }

        item {
            ResultInfoPage(viewModel = viewModel)
        }

        items(result.value){item->
            Row(
                modifier = Modifier
                    .padding(vertical = 8.dp)
                    .fillMaxWidth(), verticalAlignment = Alignment.CenterVertically
            ) {
                Image(
                    imageVector = ImageVector.vectorResource(id = if (item.isFile) R.drawable.ic_icons8_file else R.drawable.ic_icons8_folder),
                    modifier = Modifier.padding(top = 8.dp, bottom = 8.dp),
                    contentDescription = null
                )

                Column {
                    Text(text = item.name, style = TextStyle(color = Color.Black, fontWeight = FontWeight.Bold, fontSize = 14.sp))
                    Row {
                        Text(text = DateUtils.getFormatDate(item.lastModified), fontSize = 12.sp)
                        Spacer(modifier = Modifier.padding(horizontal = 8.dp))
                        Text(text = item.mediaPath.toFile()?.lengthToFitMemorySize() ?: "", fontSize = 12.sp)
                    }
                }
            }
        }
    }
}


@Composable
fun QueryInfoPage(viewModel: MediaFilesViewModel) {
    val context = LocalContext.current
    val config = viewModel.config.collectAsState()
    val dir = viewModel.dir.collectAsState()
    val queryType = viewModel.queryType.collectAsState()

    val addIgnoreFolderLauncher = rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult(), onResult = {
        it.data?.data?.let {
            val folder = resolveContentUri(context, it)
            viewModel.addConfigIgnoreChildFiles(folder.toFile())
        }
    })


    val addIgnoreFileLauncher = rememberLauncherForActivityResult(contract = ActivityResultContracts.GetContent(), onResult = {
        it?.let { uri ->
            val folder = UriTofilePath.getFilePathByUri(context, uri)
            viewModel.addConfigIgnoreChildFiles(folder.toFile())
        }
    })

    val chooseDirLauncher = rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult(), onResult = {
        it.data?.data?.let {
            val path = resolveContentUri(context, it)
            context.spSave("dir", path)
            viewModel.changeQueryDir(path)
        }
    })

    ConstraintLayout(
        modifier = Modifier
            .fillMaxWidth()
    ) {
        val (btnFromFiles, btnFromMediaStore, btnChooseDir) = createRefs()

        ElevatedButton(
            onClick = { chooseDirLauncher.launch(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)) },
            modifier = Modifier
                .fillMaxWidth()
                .constrainAs(btnChooseDir) {
                    top.linkTo(parent.top)
                    start.linkTo(parent.start)
                    end.linkTo(parent.end)
                }) {
            Text(text = "选择文件夹")
        }

        ElevatedButton(onClick = { viewModel.changeQueryType(MediaQueryType.FILES) }, modifier = Modifier
            .padding(end = 8.dp)
            .constrainAs(btnFromFiles) {
                top.linkTo(btnChooseDir.bottom)
                start.linkTo(parent.start)
                end.linkTo(btnFromMediaStore.start)
                width = Dimension.fillToConstraints
            }) {
            Text(text = "从FilesMedia获取")

        }

        ElevatedButton(onClick = { viewModel.changeQueryType(MediaQueryType.MEDIA_STORE) },
            modifier = Modifier
                .padding(start = 8.dp)
                .constrainAs(btnFromMediaStore) {
                    top.linkTo(btnFromFiles.top)
                    start.linkTo(btnFromFiles.end)
                    end.linkTo(parent.end)
                    width = Dimension.fillToConstraints
                }) {
            Text(text = "从MediaStore获取")
        }
    }


    Column() {
        InfoItem(title = "目录:", info = dir.value, infoPosition = InfoPosition.END)
        InfoItem(title = "获取方式:", info = queryType.value.name, infoPosition = InfoPosition.END)

        InfoItem(title = "查询的文件格式:", info = config.value.supportMimeTypes.toString(), infoPosition = InfoPosition.END)
        TextField(
            keyboardOptions = KeyboardOptions(autoCorrect = false, capitalization = KeyboardCapitalization.None),
            value = viewModel.getSupportMimeTypesFiledTextValue(config.value),
            singleLine = true,
            shape = RoundedCornerShape(4.dp),
            onValueChange = {
                val a = it.replace("[", "").replace("]", "").trim().lowercase()
                val supportMimeTypes = a.split(",").toMutableList()
                viewModel.changeConfig(config = config.value.copy(supportMimeTypes = supportMimeTypes))
            }, placeholder = {
                Text(text = "png,jpg 以,分割")
            })
        Row {
            val includeFolder = config.value.includeFolder
            RadioButton(selected = includeFolder, onClick = {
                viewModel.changeConfigIncludeFolder(includeFolder.not())
            })
            InfoItem(title = "结果是否包含文件夹:", info = config.value.includeFolder.toString())
        }
        Row {
            val recursively = config.value.recursively
            RadioButton(selected = recursively, onClick = {
                viewModel.changeConfig(config.value.copy(recursively = recursively.not()))
            })
            InfoItem(title = "遍历子文件夹:", info = config.value.recursively.toString())
        }
        InfoItem(title = "排序类型:", info = "")
        SortTypeButton(viewModel = viewModel)
        InfoItem(title = "排序方式:", info = "")
        OrderTypeButton(viewModel = viewModel)

        InfoItem(title = "忽略的文件:", info = "")
        Row {
            ElevatedButton(onClick = { addIgnoreFolderLauncher.launch(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)) }) {
                Text(text = "选择忽略的文件夹")
            }

            ElevatedButton(onClick = { addIgnoreFileLauncher.launch("*/*") }) {
                Text(text = "选择忽略的文件")
            }
        }
        for (ignoreChildFile in config.value.ignoreChildFiles) {
            Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
                Text(modifier = Modifier.weight(3F), text = ignoreChildFile.absolutePath)
                IconButton(modifier = Modifier.weight(1F), onClick = {
                    viewModel.removeConfigIgnoreChildFiles(ignoreChildFile)
                }) {
                    Icon(imageVector = Icons.Default.Delete, contentDescription = null)
                }
            }
        }
        Spacer(
            modifier = Modifier
                .fillMaxWidth()
                .height(1.dp)
                .background(color = Color.LightGray)
        )

    }
}

@Composable
fun SortTypeButton(viewModel: MediaFilesViewModel) {
    val sortType = viewModel.config.collectAsState()

    val types = listOf(MediaSortType.DATE, MediaSortType.SIZE, MediaSortType.NAME)

    Row {
        types.forEach {
            FilledTonalButton(
                colors = ButtonDefaults.filledTonalButtonColors(
                    containerColor = if (it == sortType.value.sortType) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.primary.copy(0.1F)
                )
                ,onClick = {
                viewModel.changeSortType(it)
            }) {
                Text(text = it.name, color = Color.White)
            }
        }
    }
}

@Composable
fun OrderTypeButton(viewModel: MediaFilesViewModel) {
    val orderType = viewModel.config.collectAsState()

    val types = listOf(MediaSortOrder.ASC, MediaSortOrder.DESC)

    Row {
        types.forEach {
            FilledTonalButton(
                colors = ButtonDefaults.filledTonalButtonColors(
                    containerColor = if (it == orderType.value.order) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.primary.copy(0.1F)
                )
                ,onClick = {
                    viewModel.changeOrder(it)
                }) {
                Text(text = it.name, color = Color.White)
            }
        }
    }
}

enum class InfoPosition {
    TOP, BOTTOM, START, END
}

@Composable
fun InfoItem(title: String, info: String, infoPosition: InfoPosition = InfoPosition.BOTTOM) {


    Column(verticalArrangement = Arrangement.Center) {
        if (infoPosition == InfoPosition.TOP) {
            info(info)
        }
        Row {
            if (infoPosition == InfoPosition.START) {
                info(info)
            }
            Text(text = title, style = TextStyle(fontSize = 14.sp, color = Color.Black, fontWeight = FontWeight.Bold))
            if (infoPosition == InfoPosition.END) {
                info(info)
            }
        }
        if (infoPosition == InfoPosition.BOTTOM) {
            info(info)
        }
        Spacer(modifier = Modifier.padding(top = 8.dp))
    }
}

@Composable
fun info(info: String) {
    if (info.isNotEmpty() && info.equals("[]").not()) {
        Text(text = info, style = TextStyle(fontSize = 12.sp), modifier = Modifier.padding(horizontal = 8.dp))
    }
}

@Composable
fun ResultInfoPage(viewModel: MediaFilesViewModel) {

    InfoItem(title = "查询结果", info = "")

    val result = viewModel.result.collectAsState()
    val count = result.value.size
    val mimeTypes = result.value.distinctBy {
        it.extension
    }.map {
        it.extension
    }

    InfoItem(title = "数量", info = count.toString())
    InfoItem(title = "结果文件格式", info = mimeTypes.toString())

}


@Preview(showSystemUi = true)
@Composable
fun MediaFilesPagePreview() {
    SampleTheme {
        MediaFilesPage()
    }
}

