package com.iscs.bozzys.ui.pages.compose

import android.Manifest
import android.content.pm.PackageManager
import android.os.Build
import android.util.Log
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Checkbox
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshots.SnapshotStateList
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathEffect
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.AsyncImage
import coil.compose.rememberAsyncImagePainter
import com.iscs.bozzys.R
import com.iscs.bozzys.api.FormField
import com.iscs.bozzys.api.FormOption
import com.iscs.bozzys.api.Job
import com.iscs.bozzys.api.UploadFile
import com.iscs.bozzys.ui.common.PageBase
import com.iscs.bozzys.ui.pages.vm.VMFormUploadFile
import com.iscs.bozzys.ui.theme.Main
import com.iscs.bozzys.ui.theme.Text
import com.iscs.bozzys.utils.DateUtil.dateToTimestamp
import com.iscs.bozzys.utils.DateUtil.format
import com.iscs.bozzys.utils.SystemUtil
import com.iscs.bozzys.utils.SystemUtil.uriToFile
import com.loper7.date_time_picker.DateTimeConfig
import com.loper7.date_time_picker.dialog.CardDatePickerDialog
import kotlinx.serialization.json.Json


/**
 * 表单容器，可以根据后台配置的表单格式进行解析各种表单
 */
@Composable
fun FormBox(forms: List<FormField>, onValueChange: (FormField) -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true) {
    Column(modifier = modifier) {
        forms.forEach { form ->
            key(form.id) {
                when (form.type) {
                    // 单行文本输入
                    "input" -> FormInput(
                        form.label,
                        form.value,
                        {
                            form.value = it
                            onValueChange(form)
                        },
                        form.placeholder,
                        required = form.required,
                        enable = form.enabled && enabled
                    )
                    // 多行文本输入
                    "textarea" -> FormTextarea(
                        form.label,
                        form.value,
                        {
                            form.value = it
                            onValueChange(form)
                        },
                        form.placeholder,
                        required = form.required,
                        enable = form.enabled && enabled
                    )
                    // 选择器
                    "select" -> FormSelect(
                        form.label,
                        form.value,
                        form.options,
                        {
                            form.value = it
                            onValueChange(form)
                        },
                        required = form.required,
                        enable = form.enabled && enabled,
                        multiSelect = form.multiSelect,
                        placeholder = form.placeholder
                    )
                    // 日期选择
                    "date" -> FormDateSelect(
                        form.label,
                        form.value,
                        {
                            form.value = it
                            onValueChange(form)
                        },
                        required = form.required,
                        enable = form.enabled && enabled,
                        placeholder = form.placeholder
                    )
                    // 起止日期选择
                    "daterange" -> FormDateRangeSelect(
                        form.label,
                        form.value,
                        {
                            form.value = it
                            onValueChange(form)
                        },
                        required = form.required,
                        placeholder = form.placeholder,
                        enable = form.enabled && enabled
                    )
                    // 时间选择器
                    "timepicker" -> FormTimeSelect(
                        form.label,
                        form.value,
                        {
                            form.value = it
                            onValueChange(form)
                        },
                        required = form.required,
                        enable = form.enabled && enabled,
                        placeholder = form.placeholder
                    )
                    // 单选
                    "radio" -> FormRadio(
                        form.label,
                        form.value,
                        form.options,
                        {
                            form.value = it
                            onValueChange(form)
                        },
                        required = form.required,
                        enable = form.enabled && enabled
                    )
                    // 多选
                    "checkbox" -> FormCheckbox(
                        form.label,
                        form.value,
                        form.options,
                        {
                            form.value = it
                            onValueChange(form)
                        },
                        required = form.required,
                        enable = form.enabled && enabled
                    )
                    // 上传文件
                    "upload" -> FormUpload(
                        form.label,
                        form.value,
                        form.options,
                        {
                            form.value = it
                            onValueChange(form)
                        },
                        required = form.required,
                        enable = form.enabled && enabled,
                        maxCount = form.maxCount ?: 1,
                        uploadType = form.uploadType ?: "file"
                    )
                }
            }
        }
    }
}

/**
 * 表单输入框
 *
 * @param label         表单的标题
 * @param value         表单的内容
 * @param onValueChange 表单内容发生变化
 */
@Composable
fun FormInput(
    label: String,
    value: List<String>,
    onValueChange: (List<String>) -> Unit,
    placeholder: List<String> = listOf(),
    required: Boolean = false,
    enable: Boolean = true,
) {
    var text by remember { mutableStateOf(value.getOrNull(0) ?: "") }
    Column(
        Modifier
            .fillMaxWidth()
            .heightIn(max = 90.dp)
    ) {
        Row(
            Modifier
                .fillMaxWidth()
                .height(40.dp), verticalAlignment = Alignment.CenterVertically
        ) {
            Text(
                label,
                fontSize = 14.sp,
                fontWeight = FontWeight.Bold,
                color = Text.copy(alpha = if (enable) 1f else 0.6f)
            )
            if (required) Text(
                "*",
                fontSize = 14.sp,
                color = Color(0xFFFF4D4F).copy(alpha = if (enable) 1f else 0.6f),
                modifier = Modifier.padding(start = 3.dp)
            )
        }
        BasicTextField(
            text,
            onValueChange = {
                text = it
                onValueChange(listOf(text))
            },
            enabled = enable,
            modifier = Modifier
                .fillMaxWidth()
                .height(46.dp)
                .border(1.dp, shape = RoundedCornerShape(6.dp), color = Color(0xFFE5E6EB))
                .padding(horizontal = 10.dp),
            singleLine = true,
            textStyle = LocalTextStyle.current.copy(fontSize = 14.sp, lineHeight = 18.sp, color = Text.copy(alpha = if (enable) 1f else 0.6f)),
            decorationBox = { innerTextField ->
                Box(contentAlignment = Alignment.CenterStart) {
                    innerTextField()
                    if (text.isEmpty()) {
                        val ph = (placeholder.getOrNull(0) ?: "").ifEmpty { "请输入$label" }
                        Text(ph, color = Color(0xFF9CA3AF), fontSize = 14.sp, lineHeight = 18.sp)
                    }
                }
            },
            cursorBrush = SolidColor(Main),
            keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
        )
    }
}

/**
 * 表单多行文本输入
 *
 * @param label         标题
 * @param value         输入的内容
 * @param onValueChange 输入内容发生变化
 * @param placeholder   占位内容
 * @param enable        是否使能
 */
@Composable
fun FormTextarea(
    label: String,
    value: List<String>,
    onValueChange: (List<String>) -> Unit,
    placeholder: List<String> = listOf(""),
    required: Boolean = false,
    enable: Boolean = true,
) {
    var text by remember { mutableStateOf(value.getOrNull(0) ?: "") }
    Column(
        Modifier
            .fillMaxWidth()
            .heightIn(max = 160.dp)
    ) {
        Row(
            Modifier
                .fillMaxWidth()
                .height(40.dp), verticalAlignment = Alignment.CenterVertically
        ) {
            Text(
                label,
                fontSize = 14.sp,
                fontWeight = FontWeight.Bold,
                color = Text.copy(alpha = if (enable) 1f else 0.6f)
            )
            if (required) Text(
                "*",
                fontSize = 14.sp,
                color = Color(0xFFFF4D4F).copy(alpha = if (enable) 1f else 0.6f),
                modifier = Modifier.padding(start = 3.dp)
            )
        }
        BasicTextField(
            text,
            onValueChange = {
                text = it
                onValueChange(listOf(it))
            },
            enabled = enable,
            modifier = Modifier
                .fillMaxWidth()
                .heightIn(min = 120.dp)
                .border(1.dp, shape = RoundedCornerShape(6.dp), color = Color(0xFFE5E6EB))
                .padding(10.dp)
                .verticalScroll(rememberScrollState()),
            textStyle = LocalTextStyle.current.copy(fontSize = 14.sp, lineHeight = 18.sp, color = Text.copy(alpha = if (enable) 1f else 0.6f)),
            decorationBox = { innerTextField ->
                Box(contentAlignment = Alignment.TopStart) {
                    innerTextField()
                    if (text.isEmpty()) {
                        val ph = (placeholder.getOrNull(0) ?: "").ifEmpty { "请输入$label" }
                        Text(ph, color = Color(0xFF9CA3AF), fontSize = 14.sp, lineHeight = 18.sp)
                    }
                }
            },
            cursorBrush = SolidColor(Main),
            keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
        )
    }
}


/**
 * 表单选择器
 *
 * @param label             标题
 * @param value             当前选中
 * @param options           选择列表
 * @param onSelectChange    选择变化监听
 */
@Composable
fun FormSelect(
    label: String,
    value: List<String>,
    options: List<FormOption>,
    onSelectChange: (List<String>) -> Unit,
    placeholder: List<String> = listOf(),
    required: Boolean = false,
    enable: Boolean = true,
    multiSelect: Boolean = false,
) {
    var expanded by remember { mutableStateOf(false) }
    var width by remember { mutableStateOf(0) }
    val density = LocalDensity.current
    // 当前表单中的状态
    val values = remember { mutableStateListOf<String>() }
    LaunchedEffect(value) {
        values.clear()
        values.addAll(value)
    }

    /**
     * 转换数组列表
     */
    fun SnapshotStateList<String>.data2String(): String {
        var datas = ""
        this.forEachIndexed { index, value ->
            val find = options.find { it.value == value }?.label ?: ""
            datas += if (index == (this.size - 1)) find else "$find, "
        }
        return datas
    }

    Column(
        Modifier
            .fillMaxWidth()
            .heightIn(max = 90.dp)
            .onSizeChanged({ width = it.width })
    ) {
        Row(
            Modifier
                .fillMaxWidth()
                .height(40.dp), verticalAlignment = Alignment.CenterVertically
        ) {
            Text(
                label,
                fontSize = 14.sp,
                fontWeight = FontWeight.Bold,
                color = Text.copy(alpha = if (enable) 1f else 0.6f)
            )
            if (required) Text(
                "*",
                fontSize = 14.sp,
                color = Color(0xFFFF4D4F).copy(alpha = if (enable) 1f else 0.6f),
                modifier = Modifier.padding(start = 3.dp)
            )
        }
        Row(
            Modifier
                .fillMaxWidth()
                .height(46.dp)
                .border(1.dp, shape = RoundedCornerShape(6.dp), color = Color(0xFFE5E6EB))
                .clip(RoundedCornerShape(6.dp))
                .clickable(onClick = { expanded = true }, enabled = enable)
                .padding(horizontal = 10.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(
                values.data2String()
                    .ifEmpty { (placeholder.getOrNull(0) ?: "").ifEmpty { "请选择$label" } },
                color = Text.copy(alpha = if (enable && values.data2String().isNotEmpty()) 1f else 0.6f),
                fontSize = 14.sp,
                lineHeight = 18.sp,
                modifier = Modifier.weight(1f),
            )
            Icon(
                painter = painterResource(R.drawable.back),
                contentDescription = "",
                modifier = Modifier
                    .rotate(if (expanded) -90f else 180f)
                    .size(12.dp),
                tint = Text.copy(alpha = if (enable) 1f else 0.6f)
            )
        }
        val widthDp = with(density) { width.toDp() }
        DropdownMenu(
            expanded = expanded, onDismissRequest = { expanded = false },
            modifier = Modifier.width(widthDp),
            offset = DpOffset(x = 0.dp, y = 5.dp)
        ) {
            Column(
                modifier = Modifier
                    .heightIn(max = 240.dp)
                    .verticalScroll(rememberScrollState())
            ) {
                options.forEach { option ->
                    DropdownMenuItem(
                        modifier = Modifier.fillMaxWidth(),
                        text = {
                            Text(
                                option.label,
                                color = if (values.contains(option.value)) MaterialTheme.colorScheme.primary else Text
                            )
                        },
                        onClick = {
                            if (multiSelect) {
                                if (values.contains(option.value)) {
                                    values.remove(option.value)
                                } else {
                                    values.add(option.value)
                                }
                            } else {
                                values.clear()
                                values.add(option.value)
                            }
                            onSelectChange(ArrayList(values))
                            if (!multiSelect) expanded = false
                        }
                    )
                }
            }
        }
    }
}

/**
 * 表单单选组件
 *
 * @param label             标题
 * @param value             当前选中
 * @param options           可选列表
 * @param onSelectChange    当前选中
 */
@OptIn(ExperimentalLayoutApi::class)
@Composable
fun FormRadio(
    label: String,
    value: List<String>,
    options: List<FormOption>,
    onSelectChange: (List<String>) -> Unit,
    required: Boolean = false,
    enable: Boolean = true,
) {
    var text by remember { mutableStateOf(value.getOrNull(0) ?: "") }
    Column(
        Modifier
            .fillMaxWidth()
            .heightIn(max = 160.dp)
    ) {
        Row(
            Modifier
                .fillMaxWidth()
                .height(40.dp), verticalAlignment = Alignment.CenterVertically
        ) {
            Text(
                label,
                fontSize = 14.sp,
                fontWeight = FontWeight.Bold,
                color = Text.copy(alpha = if (enable) 1f else 0.6f)
            )
            if (required) Text(
                "*",
                fontSize = 14.sp,
                color = Color(0xFFFF4D4F).copy(alpha = if (enable) 1f else 0.6f),
                modifier = Modifier.padding(start = 3.dp)
            )
        }
        FlowRow(
            Modifier
                .fillMaxWidth()
                .heightIn(max = 120.dp)
        ) {
            options.forEach { item ->
                Row(
                    modifier = Modifier
                        .clip(RoundedCornerShape(12.dp))
                        .clickable(onClick = {
                            text = item.value
                            onSelectChange(listOf(item.value))
                        }, enabled = enable)
                        .padding(horizontal = 10.dp, vertical = 5.dp),
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    RadioButton(
                        selected = text == item.value,
                        onClick = null,
                        modifier = Modifier.size(14.dp),
                        enabled = enable
                    )
                    Text(
                        text = item.label,
                        fontSize = 15.sp,
                        modifier = Modifier.padding(start = 10.dp),
                        color = Text.copy(alpha = if (enable) 1f else 0.6f)
                    )
                }
            }
        }
    }
}

/**
 * 表单单选组件
 *
 * @param label             标题
 * @param value             当前选中
 * @param options           可选列表
 * @param onSelectChange    当前选中
 */
@OptIn(ExperimentalLayoutApi::class)
@Composable
fun FormCheckbox(
    label: String,
    value: List<String>,
    options: List<FormOption>,
    onSelectChange: (List<String>) -> Unit,
    required: Boolean = false,
    enable: Boolean = true,
) {
    val values = remember { mutableStateListOf<String>() }
    LaunchedEffect(Unit) {
        values.clear()
        values.addAll(value)
    }
    Column(
        Modifier
            .fillMaxWidth()
            .heightIn(max = 160.dp)
    ) {
        Row(
            Modifier
                .fillMaxWidth()
                .height(40.dp), verticalAlignment = Alignment.CenterVertically
        ) {
            Text(
                label,
                fontSize = 14.sp,
                fontWeight = FontWeight.Bold,
                color = Text.copy(alpha = if (enable) 1f else 0.6f)
            )
            if (required) Text(
                "*",
                fontSize = 14.sp,
                color = Color(0xFFFF4D4F).copy(alpha = if (enable) 1f else 0.6f),
                modifier = Modifier.padding(start = 3.dp)
            )
        }
        FlowRow(
            Modifier
                .fillMaxWidth()
                .heightIn(max = 120.dp)
        ) {
            options.forEach { item ->
                Row(
                    modifier = Modifier
                        .clip(RoundedCornerShape(12.dp))
                        .clickable(onClick = {
                            if (values.contains(item.value))
                                values.remove(item.value)
                            else values.add(item.value)
                            onSelectChange(values)
                        }, enabled = enable)
                        .padding(horizontal = 10.dp, vertical = 5.dp),
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    Checkbox(
                        checked = values.contains(item.value),
                        onCheckedChange = null,
                        modifier = Modifier.size(14.dp),
                        enabled = enable
                    )
                    Text(
                        text = item.label,
                        fontSize = 15.sp,
                        modifier = Modifier.padding(start = 10.dp),
                        color = Text.copy(alpha = if (enable) 1f else 0.6f)
                    )
                }
            }
        }
    }
}

/**
 * 文件上传组件
 *
 * @param label             标题
 * @param value             当前选中
 * @param options           可选列表
 * @param onSelectChange    当前选中
 * @param maxCount          上传最大限制
 * @param uploadType        上传类型
 */
@OptIn(ExperimentalLayoutApi::class)
@Composable
fun FormUpload(
    label: String,
    value: List<String>,
    options: List<FormOption>,
    onSelectChange: (List<String>) -> Unit,
    required: Boolean = false,
    enable: Boolean = true,
    maxCount: Int = 1,
    uploadType: String = "file",
    vm: VMFormUploadFile = viewModel()
) {
    val ctx = LocalContext.current
    val state by vm.state.collectAsState()
    val type = if (uploadType == "image") "image" else "*"
    LaunchedEffect(Unit) {
        if (ctx is PageBase) {
            ctx.apply {
                vm.toast.initToast()
                vm.loading.initLoading()
            }
        }
    }
    // 启动页面
    val activityLauncher = rememberLauncherForActivityResult(contract = ActivityResultContracts.GetContent()) { uri ->
        if (uri != null) {
            val file = ctx.uriToFile(uri)
            val fileType = ctx.contentResolver.getType(uri) ?: ""
            vm.uploadFile(UploadFile(file = file, type = fileType)) { onSelectChange(it) }
        }
    }
    // 权限请求
    val permissionLauncher = rememberLauncherForActivityResult(contract = ActivityResultContracts.RequestPermission()) {
        if (it) {
            activityLauncher.launch("${type}/*")
        }
    }
    LaunchedEffect(Unit) {
        vm.init(value)
    }
    Column(
        Modifier
            .fillMaxWidth()
            .heightIn(max = 160.dp)
    ) {
        Row(
            Modifier
                .fillMaxWidth()
                .height(40.dp), verticalAlignment = Alignment.CenterVertically
        ) {
            Text(
                label,
                fontSize = 14.sp,
                fontWeight = FontWeight.Bold,
                color = Text.copy(alpha = if (enable) 1f else 0.6f)
            )
            if (required) Text(
                "*",
                fontSize = 14.sp,
                color = Color(0xFFFF4D4F).copy(alpha = if (enable) 1f else 0.6f),
                modifier = Modifier.padding(start = 3.dp)
            )
        }

        Column(
            modifier = Modifier
                .fillMaxWidth()
                .heightIn(max = 120.dp)
                .border(1.dp, shape = RoundedCornerShape(6.dp), color = Color(0xFFE5E6EB))
                .padding(vertical = 10.dp)
                .verticalScroll(rememberScrollState()),
            verticalArrangement = Arrangement.Top,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            if (state.files.isEmpty()) Column(
                horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier
                    .fillMaxSize()
                    .padding(horizontal = 10.dp)
                    .clip(RoundedCornerShape(6.dp))
                    .clickable(enabled = enable) {
                        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
                            if (ctx.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                                permissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
                            } else {
                                activityLauncher.launch("${type}/*")
                            }
                        } else {
                            activityLauncher.launch("${type}/*")
                        }
                    }
                    .padding(vertical = 10.dp)) {
                Icon(
                    painter = painterResource(R.drawable.upload),
                    contentDescription = null,
                    modifier = Modifier
                        .size(50.dp),
                    tint = Text.copy(alpha = if (enable) 0.3f else 0.1f)
                )
                Text(if (enable) "点击上传" else "暂无上传内容", fontSize = 14.sp, color = Text.copy(alpha = if (enable) 0.3f else 0.1f))
            }
            FlowRow(
                modifier = Modifier
                    .padding(horizontal = 10.dp)
                    .fillMaxWidth()
            ) {
                // 显示添加的文件列表
                state.files.forEach { item ->
                    Box(
                        modifier = Modifier
                            .fillMaxWidth(1 / 4f)
                            .aspectRatio(1f)
                            .padding(5.dp),
                        contentAlignment = Alignment.Center
                    ) {
                        val src = SystemUtil.getFileTypeIconBySuffix(item.url.ifEmpty { item.file?.name ?: "" })
                        AsyncImage(
                            model = item.url.ifEmpty { item.file },
                            placeholder = rememberAsyncImagePainter(model = item.file),
                            contentDescription = null,
                            modifier = Modifier
                                .fillMaxSize()
                                .clip(RoundedCornerShape(10))
                                .alpha(if (enable) 1f else 0.5f),
                            contentScale = ContentScale.Crop
                        )
                        if (!listOf("jpg", "png").contains(src.second)) {
                            Box(
                                Modifier
                                    .fillMaxSize()
                                    .background(MaterialTheme.colorScheme.primary.copy(alpha = 0.3f), shape = RoundedCornerShape(10.dp))
                                    .alpha(if (enable) 1f else 0.5f)
                            ) {
                                Spacer(
                                    modifier = Modifier
                                        .padding(20.dp)
                                        .fillMaxSize()
                                        .background(Color.White)
                                )
                                Icon(
                                    painter = painterResource(src.first),
                                    contentDescription = null,
                                    modifier = Modifier
                                        .padding(15.dp)
                                        .fillMaxSize(),
                                    tint = MaterialTheme.colorScheme.primary
                                )
                            }
                        }
                        // 右上角删除操作
                        if (enable) Icon(
                            painterResource(R.drawable.delete_all),
                            contentDescription = null,
                            modifier = Modifier
                                .align(Alignment.TopEnd)
                                .offset(x = 6.dp, y = (-3).dp)
                                .size(20.dp)
                                .background(Color.Black.copy(alpha = 0.6f), shape = RoundedCornerShape(6.dp))
                                .clickable { vm.delete(item) }
                                .padding(3.dp),
                            tint = MaterialTheme.colorScheme.primary
                        )
                    }
                }
                // 上传按钮
                if (state.files.isNotEmpty() && enable) Box(
                    modifier = Modifier
                        .fillMaxWidth(1 / 4f)
                        .aspectRatio(1f)
                        .padding(5.dp)
                        .clip(RoundedCornerShape(10.dp))
                        .clickable {
                            if (!vm.checkCanSelect(maxCount)) return@clickable
                            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
                                if (ctx.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                                    permissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
                                } else {
                                    activityLauncher.launch("${type}/*")
                                }
                            } else {
                                activityLauncher.launch("${type}/*")
                            }
                        },
                    contentAlignment = Alignment.Center
                ) {
                    Icon(
                        painter = painterResource(R.drawable.upload),
                        contentDescription = null,
                        modifier = Modifier
                            .padding(2.dp)
                            .fillMaxSize()
                            .drawBehind {
                                val strokeWidth = 2.dp.toPx()
                                val dashWidth = 6.dp.toPx()
                                val dashGap = 4.dp.toPx()
                                val radius = 10.dp.toPx()

                                drawRoundRect(
                                    color = Text.copy(alpha = 0.5f),
                                    cornerRadius = CornerRadius(radius),
                                    style = Stroke(
                                        width = strokeWidth,
                                        pathEffect = PathEffect.dashPathEffect(floatArrayOf(dashWidth, dashGap))
                                    )
                                )
                            }
                            .padding(12.dp),
                        tint = Text.copy(alpha = 0.5f)
                    )
                }
            }
        }
    }
}

/**
 * 表单日期时间选择组件
 *
 * @param label             标题
 * @param value             当前选中
 * @param onSelectChange    当前选中
 */
@Composable
fun FormDateSelect(
    label: String,
    value: List<String>,
    onSelectChange: (List<String>) -> Unit,
    placeholder: List<String> = listOf(),
    required: Boolean = false,
    enable: Boolean = true
) {
    var date by remember {
        mutableStateOf((value.getOrNull(0) ?: "").dateToTimestamp("yyyy/MM/dd HH:mm:ss"))
    }
    val picker = CardDatePickerDialog.builder(LocalContext.current)
        .setTitle("请选择日期")
        .setDefaultTime(date)
        .setDisplayType(
            mutableListOf(
                DateTimeConfig.YEAR,
                DateTimeConfig.MONTH,
                DateTimeConfig.DAY,
                DateTimeConfig.HOUR,
                DateTimeConfig.MIN
            )
        )
        .setPickerLayout(R.layout.date_picker)
        .showBackNow(false)
        .showFocusDateInfo(false)
        .showDateLabel(false)
        .setOnChoose { timestamp ->
            date = timestamp
            onSelectChange(listOf(timestamp.toString()))
        }.build()

    Column(
        Modifier
            .fillMaxWidth()
            .heightIn(max = 90.dp)
    ) {
        Row(
            Modifier
                .fillMaxWidth()
                .height(40.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(
                label,
                fontSize = 14.sp,
                fontWeight = FontWeight.Bold,
                color = Text.copy(alpha = if (enable) 1f else 0.6f)
            )
            if (required) Text(
                "*",
                fontSize = 14.sp,
                color = Color(0xFFFF4D4F).copy(alpha = if (enable) 1f else 0.6f),
                modifier = Modifier.padding(start = 3.dp)
            )
        }

        Text(
            if (date <= 0) {
                if (placeholder.getOrNull(0).isNullOrEmpty()) "请选择$label" else placeholder.getOrNull(0) ?: ""
            } else date.format("yyyy/MM/dd HH:mm"),
            modifier = Modifier
                .fillMaxWidth()
                .height(46.dp)
                .border(1.dp, shape = RoundedCornerShape(6.dp), color = Color(0xFFE5E6EB))
                .clip(RoundedCornerShape(6.dp))
                .clickable(onClick = { picker.show() }, enabled = enable)
                .padding(10.dp),
            fontSize = 14.sp,
            lineHeight = 26.sp,
            color = if (date <= 0) Color(0xFF9CA3AF) else Text.copy(alpha = if (enable) 1f else 0.6f)
        )
    }
}

/**
 * 表单日期范围选择组件
 *
 * @param label             标题
 * @param value             当前选中
 * @param onSelectChange    当前选中
 */
@Composable
fun FormDateRangeSelect(
    label: String,
    value: List<String>,
    onSelectChange: (List<String>) -> Unit,
    placeholder: List<String> = listOf(),
    required: Boolean = false,
    enable: Boolean = true
) {
    val ctx = LocalContext.current
    val startTs = (value.getOrNull(0) ?: "").dateToTimestamp("yyyy/MM/dd HH:mm:ss")
    val endTs = (value.getOrNull(1) ?: "").dateToTimestamp("yyyy/MM/dd HH:mm:ss")
    var start by remember { mutableStateOf(startTs) }
    var end by remember { mutableStateOf(endTs) }

    Column(
        Modifier
            .fillMaxWidth()
            .heightIn(max = 90.dp)
    ) {
        Row(
            Modifier
                .fillMaxWidth()
                .height(40.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(
                label,
                fontSize = 14.sp,
                fontWeight = FontWeight.Bold,
                color = Text.copy(alpha = if (enable) 1f else 0.6f)
            )
            if (required) Text(
                "*",
                fontSize = 14.sp,
                color = Color(0xFFFF4D4F).copy(alpha = if (enable) 1f else 0.6f),
                modifier = Modifier.padding(start = 3.dp)
            )
        }

        Row(
            modifier = Modifier
                .fillMaxWidth()
                .height(46.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(
                if (start <= 0) {
                    if ((placeholder.getOrNull(0) ?: "").isEmpty()) {
                        "请选择开始日期"
                    } else placeholder.getOrNull(0) ?: ""
                } else start.format("yyyy/MM/dd"),
                modifier = Modifier
                    .weight(1f)
                    .height(46.dp)
                    .border(1.dp, shape = RoundedCornerShape(6.dp), color = Color(0xFFE5E6EB))
                    .clip(RoundedCornerShape(6.dp))
                    .clickable(onClick = {
                        CardDatePickerDialog.builder(ctx)
                            .setTitle("请选择开始日期")
                            .setDefaultTime(start)
                            .setDisplayType(
                                mutableListOf(
                                    DateTimeConfig.YEAR,
                                    DateTimeConfig.MONTH,
                                    DateTimeConfig.DAY
                                )
                            )
                            .setPickerLayout(R.layout.date_range_picker)
                            .showBackNow(false)
                            .showFocusDateInfo(false)
                            .showDateLabel(false)
                            .setOnChoose { timestamp ->
                                start = timestamp
                                onSelectChange(listOf(start.toString(), end.toString()))
                            }.build().show()
                    }, enabled = enable)
                    .padding(10.dp),
                fontSize = 14.sp,
                lineHeight = 26.sp,
                color = if (start <= 0) Color(0xFF9CA3AF) else Text.copy(alpha = if (enable) 1f else 0.6f)
            )
            Text(
                "-",
                modifier = Modifier.padding(horizontal = 5.dp),
                color = Text.copy(alpha = if (enable) 1f else 0.6f)
            )
            Text(
                if (end <= 0) {
                    if ((placeholder.getOrNull(1) ?: "").isEmpty()) {
                        "请选择结束日期"
                    } else placeholder.getOrNull(1) ?: ""
                } else end.format("yyyy/MM/dd"),
                modifier = Modifier
                    .weight(1f)
                    .height(46.dp)
                    .border(1.dp, shape = RoundedCornerShape(6.dp), color = Color(0xFFE5E6EB))
                    .clip(RoundedCornerShape(6.dp))
                    .clickable(onClick = {
                        CardDatePickerDialog.builder(ctx)
                            .setTitle("请选择结束日期")
                            .setDefaultTime(end)
                            .setDisplayType(
                                mutableListOf(
                                    DateTimeConfig.YEAR,
                                    DateTimeConfig.MONTH,
                                    DateTimeConfig.DAY
                                )
                            )
                            .setPickerLayout(R.layout.date_range_picker)
                            .showBackNow(false)
                            .showFocusDateInfo(false)
                            .showDateLabel(false)
                            .setOnChoose { timestamp ->
                                end = timestamp
                                onSelectChange(listOf(start.toString(), end.toString()))
                            }.build().show()
                    }, enabled = enable)
                    .padding(10.dp),
                fontSize = 14.sp,
                lineHeight = 26.sp,
                color = if (end <= 0) Color(0xFF9CA3AF) else Text.copy(alpha = if (enable) 1f else 0.6f)
            )
        }

    }
}

/**
 * 表单时间选择组件
 *
 * @param label             标题
 * @param value             当前选中
 * @param onSelectChange    当前选中
 */
@Composable
fun FormTimeSelect(
    label: String,
    value: List<String>,
    onSelectChange: (List<String>) -> Unit,
    required: Boolean = false,
    enable: Boolean = true,
    placeholder: List<String> = listOf(),
) {
    val timestamp = (value.getOrNull(0) ?: "0").toLong()
    var date by remember { mutableStateOf(timestamp) }
    val picker = CardDatePickerDialog.builder(LocalContext.current)
        .setTitle("请选择时间")
        .setDefaultTime(date)
        .setDisplayType(mutableListOf(DateTimeConfig.HOUR, DateTimeConfig.MIN, DateTimeConfig.SECOND))
        .setPickerLayout(R.layout.timer_picker)
        .showBackNow(false)
        .showFocusDateInfo(false)
        .showDateLabel(false)
        .setOnChoose { timestamp ->
            date = timestamp
            onSelectChange(listOf(timestamp.toString()))
        }.build()

    Column(
        Modifier
            .fillMaxWidth()
            .heightIn(max = 90.dp)
    ) {
        Row(
            Modifier
                .fillMaxWidth()
                .height(40.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(
                label,
                fontSize = 14.sp,
                fontWeight = FontWeight.Bold,
                color = Text.copy(alpha = if (enable) 1f else 0.6f)
            )
            if (required) Text(
                "*",
                fontSize = 14.sp,
                color = Color(0xFFFF4D4F).copy(alpha = if (enable) 1f else 0.6f),
                modifier = Modifier.padding(start = 3.dp)
            )
        }

        Text(
            if (date <= 0) {
                if (placeholder.getOrNull(0).isNullOrEmpty()) {
                    "请选择$label"
                } else {
                    placeholder.getOrNull(0) ?: ""
                }
            } else date.format("HH:mm:ss"),
            modifier = Modifier
                .fillMaxWidth()
                .height(46.dp)
                .border(1.dp, shape = RoundedCornerShape(6.dp), color = Color(0xFFE5E6EB))
                .clip(RoundedCornerShape(6.dp))
                .clickable(onClick = { picker.show() }, enabled = enable)
                .padding(10.dp),
            fontSize = 14.sp,
            lineHeight = 26.sp,
            color = if (date <= 0) Color(0xFF9CA3AF) else Text.copy(alpha = if (enable) 1f else 0.6f)
        )
    }
}


/**
 * 将服务端返回的表单String JSON数组转化为可用的表单数据
 */
fun List<String>.getFormListByJsonList(): List<FormField> {
    val list = ArrayList<FormField>()
    this.forEach { form ->
        Log.d("FormCompose", form)
        val forms = form.getFormListByJsonObject()
        list.addAll(forms)
    }
    return list
}

/**
 * 转换表单列表
 */
fun String.getFormListByJsonList(job: Job?): List<FormField> {
    val json = Json { ignoreUnknownKeys = true }
    val fields = json.decodeFromString<List<FormField>>(this)
    val list = ArrayList<FormField>()

    fun List<FormField>.forEach() {
        this.forEach { ch ->
            if (ch.children.isNotEmpty()) ch.children.forEach()
            else {
                job?.let {
                    // 默认赋值操作
                    when (ch.id) {
                        "job_name" -> ch.value = listOf(it.name)
                        "job_sop" -> ch.value = listOf(it.designId.toString())
                        "job_type" -> ch.value = listOf(it.type)
                        "job_content" -> ch.value = listOf(it.description)
                        "job_urgency_level" -> ch.value = listOf(it.urgencyLevel)
                    }
                }
                list.add(ch)
            }
        }
    }

    // 执行递归遍历
    fields.forEach()

    return list
}

/**
 * 转换表单列表
 */
fun String.getFormListByJsonObject(): List<FormField> {
    val json = Json { ignoreUnknownKeys = true }
    val form = json.decodeFromString<FormField>(this)
    val list = ArrayList<FormField>()

    fun List<FormField>.forEach() {
        this.forEach { ch ->
            if (ch.children.isNotEmpty()) ch.children.forEach()
            else list.add(ch)
        }
    }

    // 处理表单
    if (form.children.isNotEmpty()) {
        form.children.forEach()
    } else {
        list.add(form)
    }

    return list
}

/**
 * 校验是否可以提交，并返回提示信息
 */
fun List<FormField>.checkCanCommitReturnTips(): String {
    this.forEach {
        if (it.required) {
            if (it.value.isEmpty() || it.value.getOrNull(0).isNullOrEmpty()) {
                return if (it.placeholder.isEmpty()) "请输入${it.label}" else (it.placeholder.getOrNull(0) ?: "").ifEmpty { "请输入${it.label}" }
            }
        }
    }
    return ""
}
