package com.iscs.bozzys.api

import android.util.Log
import com.iscs.bozzys.R
import com.iscs.bozzys.ui.pages.edit.step.compose.NodeUI
import com.iscs.bozzys.utils.StringToListSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json

/**
 * 流程节点
 */
@Serializable
data class Node(
    val id: Int = 0,
    val workId: Int = 0,
    val uuid: String = "",
    val parentUuid: String = "",
    val childrenUuid: String = "",
    val nodeName: String = "",
    val nodeIcon: String = "",
    val type: String = "",
    val position: String = "",
    val data: String = "",
    val description: String? = null,
    val workerUserId: Int = 0,
    val workerGroupId: Int? = null,
    val formId: Int = 0,
    val formData: String? = null,
    val createTime: Long = 0L,
    val approvalStatus: String = "",
    val approvalOpinion: String = "",
    val isolationType: String? = null,          // 隔离类型
    val isolationPoints: String? = null,        // 解除隔离的点位
    val isolationNodeUuid: String? = null,      // 解除隔离关联的节点uuid
    val nodeUserList: List<User>? = null,       // 隔离和解除隔离关联的上锁人和共锁人
    val smsTemplateCode: String? = null,        // 短信通知
    val messageTemplateCode: String? = null,    // 站内信息
    val emailTemplateCode: String? = null,      // 邮件通知
    val appTemplateCode: String? = null,        // app消息推送
    val deviceNumber: String? = null,           // 设备序列号
    val attachments: String? = null,            // 携带的数据
) {

    /**
     * 校验是否可以通过手机进行操作
     */
    fun checkCanOptionByPhone(): Boolean {
        return !(listOf("isolation", "releaseIsolation", "returnLock").contains(type) && !listOf("0", "2").contains(isolationType))
    }

    /**
     * 校验请求参数
     *
     * @param forms 表单数据
     */
    fun checkCanSubmit(forms: List<FormField>): String {
        forms.forEach {
            Log.d("NodeOption", "checkCanSubmit -> $it")
            if (it.required) {
                if ((it.value.getOrNull(0) ?: "").isEmpty()) {
                    return (it.placeholder.getOrNull(0) ?: "").ifEmpty { "请填写${it.label}" }
                }
            }
        }
        return ""
    }

    /**
     * 构建请求参数
     *
     * @param forms 表单数据
     */
    fun buildSubmitParams(forms: List<FormField>, workFormList: List<TaskFormInfo>): MutableMap<String, Any?> {
        val nodeName = forms.find { it.name == "nodeName" }?.value?.getOrNull(0) ?: ""
        val params = mutableMapOf<String, Any?>("nodeId" to id, "nodeName" to nodeName)
        if (type != "createJob") {
            val workerUserId = forms.find { it.name == "workerUserId" }?.value?.getOrNull(0) ?: "0"
            val formId = forms.find { it.name == "formId" }?.value?.getOrNull(0) ?: "0"
            val findWork = workFormList.find { it.id == formId.toInt() }
            val formData = if (findWork != null) Json.encodeToString(findWork) else null
            val noticeType = forms.find { it.name == "noticeType" }?.value ?: emptyList()
            params["workerUserId"] = workerUserId.toInt()
            params["formId"] = formId.toInt()
            params["formData"] = formData
            // 处理隔离点信息表单
            if (listOf("isolation", "releaseIsolation").contains(type)) {
                val isolationType = forms.find { it.name == "isolationType" }?.value?.getOrNull(0) ?: "-1"
                val isolationPoints = forms.find { it.name == "isolationPoints" }?.value ?: emptyList()
                if (isolationType == "1") {
                    // 移除负责人
                    params.remove("workerUserId")
                    // 上锁人和共锁人
                    val locker = forms.find { it.name == "locker" }?.value?.getOrNull(0) ?: "-1"
                    val group = forms.find { it.name == "group" }?.value ?: emptyList()
                    val userList = mutableListOf<MutableMap<String, Any>>()
                    if (locker.toInt() > 0) userList += mutableMapOf("userId" to locker.toInt(), "type" to "jtlocker")
                    group.forEach { userList += mutableMapOf("userId" to it.toInt(), "type" to "jtcolocker") }
                    params["nodeUserDOList"] = userList
                }
                params["isolationType"] = isolationType
                params["isolationPoints"] = isolationPoints.joinToString(
                    prefix = "[",
                    postfix = "]",
                    separator = ","
                )
                if (type == "releaseIsolation") {
                    val isolationNode = forms.find { it.name == "isolationNode" }?.value?.getOrNull(0)
                    // 解除隔离，这里需要填写关联的节点uuid
                    params["isolationNodeUuid"] = isolationNode
                }
            }
            // 通知方式
            // 短信
            params["smsTemplateCode"] = if (noticeType.contains("sms")) "true" else "false"
            // 站内信
            params["messageTemplateCode"] = if (noticeType.contains("message")) "true" else "false"
            // 邮件
            params["emailTemplateCode"] = if (noticeType.contains("email")) "true" else "false"
            // app通知
            params["appTemplateCode"] = if (noticeType.contains("app")) "true" else "false"
        }
        return params
    }

    /**
     * 更新节点信息
     *
     * @param forms
     */
    fun updateNodeInfo(forms: List<FormField>, nodes: List<NodeUI>): Node {
        val nodeName = forms.find { it.name == "nodeName" }?.value?.getOrNull(0) ?: ""
        if (type != "createJob") {
            // 解析关联表单
            val formId = forms.find { it.name == "formId" }?.value?.getOrNull(0) ?: "-1"
            // 解析表单数据
            val formData = forms.find { it.name == "formData" }?.value?.getOrNull(0)
            // 解析负责人
            var workerUserId = forms.find { it.name == "workerUserId" }?.value?.getOrNull(0) ?: "0"
            // 解析隔离方式
            var isolationType = forms.find { it.name == "isolationType" }?.value?.getOrNull(0)
            // 解析点位
            var isolationPoints = forms.find { it.name == "isolationPoints" }?.value ?: emptyList()
            // 解析上锁人
            val locker = forms.find { it.name == "locker" }?.value?.getOrNull(0) ?: "-1"
            // 解析共锁人
            val group = forms.find { it.name == "group" }?.value ?: emptyList()
            // 构建上锁人和共锁人列表
            val userList = mutableListOf<User>()
            if (locker.toInt() > 0) userList += User(userId = locker.toInt(), type = "jtlocker")
            if (group.isNotEmpty()) group.forEach { userList += User(userId = it.toInt(), type = "jtcolocker") }
            // 解析隔离节点
            val isolationNode = forms.find { it.name == "isolationNode" }?.value?.getOrNull(0)
            // 如果是解除隔离操作，隔离方式、隔离点位、负责人（或者上锁人、解锁人）需要从选中的点位中获取
            if (type == "releaseIsolation") {
                nodes.find { it.node?.uuid == isolationNode }?.node?.let {
                    // 从节点中将数据copy到当前节点
                    workerUserId = "${it.workerUserId}"
                    isolationType = it.isolationType
                    isolationPoints = if (it.isolationPoints.isNullOrEmpty()) {
                        emptyList()
                    } else {
                        it.isolationPoints.replace("[", "").replace("]", "").split(",")
                    }
                    userList.addAll(it.nodeUserList ?: emptyList())
                }
            }
            // 通知方式
            val noticeType = forms.find { it.name == "noticeType" }?.value ?: emptyList()
            return Node(
                id = id,
                workId = workId,
                uuid = uuid,
                parentUuid = parentUuid,
                childrenUuid = childrenUuid,
                nodeName = nodeName,
                type = type,
                position = position,
                workerUserId = workerUserId.toInt(),
                formId = formId.toInt(),
                formData = formData,
                isolationType = isolationType,
                isolationPoints = isolationPoints.joinToString(
                    prefix = "[",
                    postfix = "]",
                    separator = ","
                ),
                isolationNodeUuid = isolationNode,
                nodeUserList = if (userList.isEmpty()) null else userList,
                smsTemplateCode = if (noticeType.contains("sms")) "true" else "false",
                messageTemplateCode = if (noticeType.contains("message")) "true" else "false",
                emailTemplateCode = if (noticeType.contains("email")) "true" else "false",
                appTemplateCode = if (noticeType.contains("app")) "true" else "false"
            )
        }
        return Node(
            id = id,
            workId = workId,
            uuid = uuid,
            parentUuid = parentUuid,
            childrenUuid = childrenUuid,
            nodeName = nodeName,
            type = type,
            position = position
        )
    }

    /**
     * 构建表单列表
     *
     * @param workerUserList        负责人列表
     * @param lockerUserList        上锁人列表
     * @param groupUserList         共锁人列表
     * @param workFormList          工作表单列表
     * @param isolationMethodList   获取隔离方式列表
     * @param isolationList         点位列表
     * @param isLocker              是否上锁人
     */
    fun buildFormList(
        workerUserList: List<User>,
        lockerUserList: List<User>,
        groupUserList: List<User>,
        workFormList: List<TaskFormInfo>,
        isolationMethodList: List<Dict>,
        isolationList: List<IsolationPoint>,
        nodes: List<NodeUI> = listOf(),
        isLocker: Boolean = false,
    ): List<FormField> {
        Log.d("NodeOption", "buildFormList -> $this")
        val list = ArrayList<FormField>()
        // 添加节点名称
        list += FormField(
            id.toString(),
            "input",
            "节点名称",
            name = "nodeName",
            true,
            value = listOf(nodeName),
            placeholder = listOf("请输入节点名称")
        )
        if (type == "createJob") return list
        // 添加节点负责人
        list += FormField(
            id.toString(),
            "select",
            "负责人",
            "workerUserId",
            true,
            placeholder = listOf("请选择负责人"),
            options = workerUserList.map { FormOption(it.nickname, it.id.toString()) },
            value = if (workerUserId > 0) listOf(workerUserId.toString()) else listOf()
        )
        // 添加业务表单
        list += FormField(
            id.toString(),
            "select",
            "业务表单",
            name = "formId",
            true,
            placeholder = listOf("请选择业务表单"),
            options = workFormList.map { FormOption(it.name ?: "", it.id.toString()) },
            value = if (formId > 0) listOf(formId.toString()) else listOf()
        )
        // 隔离配置
        if (listOf("isolation", "releaseIsolation").contains(type)) {
            // 先移除负责人，需要在后面进行添加
            list.removeIf { it.name == "workerUserId" }
            // 而且业务表单非必填
            val formField = list.find { it.name == "formId" }?.copy(required = false)
            list.removeIf { it.name == "formId" }
            formField?.let { list.add(it) }
            val isolations = nodes.map { it.node }.filter { it != null && it.type == "isolation" }
            var enabled = true
            var isLockerTemp = isLocker
            // 如果是解除隔离操作，这里只能选择当前流程中已经存在的隔离点位
            if (type == "releaseIsolation") {
                enabled = false
                // 增加隔离点选择列表
                list += FormField(
                    id.toString(),
                    type = "select",
                    label = "选择隔离节点",
                    name = "isolationNode",
                    required = true,
                    placeholder = listOf("请选择隔离节点"),
                    options = isolations.map { FormOption(it?.nodeName ?: "", value = it?.uuid ?: "") },
                    value = if (isolationNodeUuid.isNullOrEmpty()) listOf() else listOf(isolationNodeUuid)
                )
                // 如果是解除隔离的操作，这里需要先校验选择的节点是否是拆除
                isLockerTemp = isolationType == "1"
            }
            // 抽取隔离方式value值
            val valueOfIsolationType = if (isolationType.isNullOrEmpty()) {
                listOf()
//                val type = dataMap["isolationMethod"]
//                if (type == null) listOf() else listOf("$type")
            } else listOf(isolationType)
            // 隔离方式
            list += FormField(
                id.toString(),
                "select",
                "隔离方式",
                "isolationType",
                true,
                placeholder = listOf("请选择隔离方式"),
                options = isolationMethodList.map { FormOption(it.label, it.value) },
                value = valueOfIsolationType,
                enabled = enabled
            )
            // 抽取隔离点位value值
            val points = if (isolationPoints.isNullOrEmpty()) "" else isolationPoints.replace("[", "").replace("]", "")
            val valueOfIsolationPoints = if (points.isNotEmpty()) {
                points.split(",")
            } else {
                listOf()
//                when (val value = dataMap["isolationPoints"]) {
//                    // 如果是数组
//                    is List<*> -> value.map { "$it".toFloat().toInt().toString() }
//                    // 如果是String
//                    is String -> {
//                        value.replace("[", "").replace("]", "").split(",")
//                    }
//                    // 其他不处理
//                    else -> listOf()
//                }
            }
            // 隔离点选择，可多选
            list += FormField(
                id.toString(),
                "select",
                "隔离点选择（可多选）",
                "isolationPoints",
                true,
                listOf("请选择隔离点"),
                multiSelect = true,
                options = isolationList.map { FormOption(it.pointName, it.id.toString()) },
                value = valueOfIsolationPoints,
                enabled = enabled
            )
            if (isLockerTemp) {
                val locker = nodeUserList?.find { it.type == "jtlocker" }
                val group = nodeUserList?.filter { it.type == "jtcolocker" } ?: emptyList()
                // 上锁人
                list += FormField(
                    id.toString(),
                    "select",
                    "上锁人",
                    "locker",
                    true,
                    placeholder = listOf("请选择上锁人"),
                    options = lockerUserList.map { FormOption(it.nickname, it.id.toString()) },
                    value = if (locker != null) listOf(locker.userId.toString()) else listOf(),
                    enabled = enabled
                )
                // 共锁人
                list += FormField(
                    id.toString(),
                    "select",
                    "共锁人（可多选）",
                    "group",
                    false,
                    placeholder = listOf("请选择共锁人"),
                    options = groupUserList.map { FormOption(it.nickname, it.id.toString()) },
                    value = if (group.isNotEmpty()) group.map { it.userId.toString() } else listOf(),
                    multiSelect = true,
                    enabled = enabled
                )
            } else {
                // 负责人
                list += FormField(
                    id.toString(),
                    "select",
                    "负责人",
                    "workerUserId",
                    true,
                    placeholder = listOf("请选择负责人"),
                    options = workerUserList.map { FormOption(it.nickname, it.id.toString()) },
                    value = if (workerUserId > 0) listOf(workerUserId.toString()) else listOf(),
                    enabled = enabled
                )
            }
        }
        val notices = arrayListOf<String>()
        if (smsTemplateCode == "true") notices += "sms"
        if (messageTemplateCode == "true") notices += "message"
        if (emailTemplateCode == "true") notices += "email"
        if (appTemplateCode == "true") notices += "app"
        // 通知方式
        list += FormField(
            id.toString(), "checkbox", "通知方式", "noticeType", false, listOf(), notices,
            options = listOf(
                FormOption("短信", "sms"),
                FormOption("站内信", "message"),
                FormOption("邮件", "email"),
                FormOption("App通知", "app"),
            )
        )
//        // 通知人
//        list += FormField(
//            id.toString(), "select", "通知人", nodeName, false, listOf(), options = listOf(
//                FormOption("任务负责人", "p1"),
//                FormOption("任务参与人", "p2"),
//                FormOption("任务负责和参与人", "all"),
//                FormOption("指定人", "custom"),
//            )
//        )
//        // 通知时间
//        list += FormField(
//            id.toString(), "select", "通知时间", nodeName, false, listOf(), options = listOf(
//                FormOption("任务开始前30分钟", "0.5"),
//                FormOption("任务开始前1小时", "1"),
//                FormOption("任务开始前2小时", "2"),
//                FormOption("任务开始前5小时", "5"),
//            )
//        )
        return list
    }

    /**
     * 获取node图标，暂时本地通过type获取
     */
    fun getIcon(): Int {
        return when (type) {
            // 开始/创建
            "createJob" -> R.drawable.node_icon_create_job
            // 审核
            "review" -> R.drawable.node_icon_review
            // 确认
            "confirm" -> R.drawable.node_icon_confirm
            // 录入信息
            "inputInfo" -> R.drawable.node_icon_input_info
            // 隔离
            "isolation" -> R.drawable.node_icon_isolation
            // 解除隔离
            "releaseIsolation" -> R.drawable.node_icon_release_isolation
            // 还锁
            "returnLock" -> R.drawable.node_icon_return_lock
            // 结束
            "complete" -> R.drawable.node_icon_complete
            else -> R.drawable.tips
        }
    }

}

/**
 * 表单需要的组件
 *
 * @param id
 * @param type
 * @param label
 * @param name
 * @param required
 * @param placeholder
 * @param options
 * @param cardTitle
 * @param gridColumns
 * @param children
 */
@Serializable
data class FormField(
    val id: String = "",
    val type: String = "",
    val label: String = "",
    val name: String = "",
    val required: Boolean = false,
    @Serializable(with = StringToListSerializer::class)
    val placeholder: List<String> = listOf(),
    @Serializable(with = StringToListSerializer::class)
    var value: List<String> = listOf(),
    var options: List<FormOption> = listOf(),
    val cardTitle: String = "",
    val gridColumns: Int = 0,
    val enabled: Boolean = true,
    val multiSelect: Boolean = false,
    val children: List<FormField> = listOf(),
    val maxCount: Int? = null,          // 文件上传的最大限制个数
    val uploadType: String? = "file"    // 上传文件类型
)


/**
 * 表单Option字段
 *
 * @param label 标题
 * @param value 数值
 */
@Serializable
data class FormOption(val label: String = "", val value: String = "")

/**
 * 节点位置信息
 */
@Serializable
data class NodePositon(val x: Float, val y: Float)

/**
 * 节点信息
 */
@Serializable
data class NodeInfo(val edgeCount: Int, val edges: List<NodeConnection>)

/**
 * 节点连接线信息
 */
@Serializable
data class NodeConnection(
    val id: String,
    val source: String,
    val target: String,
    val sourceHandle: String,
    val targetHandle: String,
    val type: String
)

/**
 * 拆除盲板需要的字段
 */
@Serializable
data class Attachment(val name: String = "", val url: String = "")