package org.tensorflow.lite.examples.poseestimation.data
import kotlin.math.abs

class Angle {

    // 站立姿势(正面)
    fun standList(): List<Int> {
        val list = List(8) { 90; 90; 170; 170; 90; 90; 180; 180 }
        return list
    }

    // 硬拉(左侧面)
    fun deadliftList(): List<Int> {
        val list = List(8) { 90; 90; 180; 180; 150; 30; 120; 120 }
        return list
    }

    // 深蹲（侧面观察)
    fun squatList(): List<Int> {
        val list = List(8) { 10; 10; 180; 180; 20; 20; 70; 70 }
        /*左肩膀与右肩膀保持水平
        list[1] = 180 // 右肩膀与左肩膀保持水平
        list[2] = 90  // 左肘部默认弯曲角度为90°
        list[3] = 90  // 右肘部默认弯曲角度为90°
        list[4] = 90  // 左髋部下降，接近平行
        list[5] = 90  // 右髋部下降，接近平行
        list[6] = 90  // 左膝盖弯曲至90°
        list[7] = 90  // 右膝盖弯曲至90°*/
        return list
    }

    // 平板支撑（Plank）- 侧面观察
    fun plankList(): List<Int> {
        val list = List(8) { 90; 90; 90; 90; 180; 180; 180; 180 }
        /*list[0] = 180 // 左肩膀与右肩膀保持水平
        list[1] = 180 // 右肩膀与左肩膀保持水平
        list[2] = 0   // 左肘部保持水平
        list[3] = 0   // 右肘部保持水平
        list[4] = 0   // 左膝盖保持直线
        list[5] = 0   // 右膝盖保持直线
        list[6] = 0   // 左脚踝与脚背成直线
        list[7] = 0   // 右脚踝与脚背成直线*/
        return list
    }

    // 引体向上（正面）
    fun pullUpList(): List<Int> {
        val list = List(8) { 100; 100; 100; 100; 90; 90; 180; 180 }
        return list
    }

    /*
    俯卧撑（Push-up）- 侧面观察
    肩膀（LEFT_SHOULDER, RIGHT_SHOULDER）：肩膀应在肘部正上方，保持稳定，不要耸肩。 -> 左右肩膀的角度应接近180°，保持在肘部上方。
    肘部（LEFT_ELBOW, RIGHT_ELBOW）：肘部弯曲角度大约为90度，且肘部始终保持在肩膀下方。 -> 左右肘部角度为90°，肘部应下沉，不应过度弯曲。
    脚踝（LEFT_ANKLE, RIGHT_ANKLE）：身体应从脚踝到肩膀成一直线，避免臀部上升或下垂。 -> 左右脚踝角度为0°，保持直线。

    */
    fun pushUpList(): List<Int> {
        val list = List(8) { 90 }  // 初始值设置为90°
        /*list[0] = 180 // 左肩膀与右肩膀保持水平
        list[1] = 180 // 右肩膀与左肩膀保持水平
        list[2] = 90  // 左肘部弯曲至90°
        list[3] = 90  // 右肘部弯曲至90°
        list[4] = 0   // 左膝盖保持直线
        list[5] = 0   // 右膝盖保持直线
        list[6] = 0   // 左脚踝角度保持自然
        list[7] = 0   // 右脚踝角度保持自然*/
        return list
    }
}

class AngleDifference(private val angleObj: Angle) {

    // 假设getAngles()方法已经实现并能返回一个List<Double>
    fun getAngles(): List<Double> {
        return listOf(100.0, 95.0, 180.0, 85.0, 90.0, 75.0, 160.0, 170.0)
    }

    // 根据不同的 listType 判断标准
    private fun getStandardForListType(listType: String): List<Double> {
        return when (listType) {
            "1" -> angleObj.standList().map { it.toDouble() }  // 转换为 List<Double>
            "2" -> angleObj.deadliftList().map { it.toDouble() }  // 转换为 List<Double>
            "3" -> angleObj.pushUpList().map { it.toDouble() }  // 转换为 List<Double>
            "4" -> angleObj.squatList().map { it.toDouble() }  // 转换为 List<Double>
            "5" -> angleObj.plankList().map { it.toDouble() }  // 转换为 List<Double>
            else -> throw IllegalArgumentException("未知的列表类型: $listType")  // 无效的输入
        }
    }

    // 计算角度差，并根据角度值判断是否大于10，返回相应的语句
    fun calculateAngleDifference(listType: String): String {
        // 根据传入的参数选择不同的角度列表
        val selectedList = when (listType) {
            "1" -> angleObj.standList()  // 选择站立姿势列表
            "2" -> angleObj.deadliftList()  // 选择硬拉列表
            "3" -> angleObj.pushUpList()  // 选择俯卧撑列表
            "4" -> angleObj.squatList()  // 选择深蹲列表
            "5" -> angleObj.plankList()  // 选择平板支撑列表
            else -> throw IllegalArgumentException("未知的列表类型: $listType")  // 处理无效的输入
        }

        // 获取另一个类中的角度列表
        val angles = getAngles()

        // 获取当前listType对应的标准列表
        val standardList = getStandardForListType(listType)

        // 确保两个列表的大小一致
        if (selectedList.size != angles.size || selectedList.size != standardList.size) {
            throw IllegalArgumentException("三个列表的大小不一致！")
        }

        // 计算差值并检查条件
        val differenceList = mutableListOf<Double>()
        for (i in selectedList.indices) {
            differenceList.add((selectedList[i] - angles[i]).toDouble())
        }

        // 根据listType的不同，提供不同标准的判断
        val absoluteValues = differenceList.map { abs(it) }

        // 检查角度差是否符合标准
        val warningMessages = mutableListOf<String>()

        // 替换角度位置的名称
        val bodyParts = listOf(
            "左肩", "右肩", "左肘", "右肘", "左髋", "右髋", "左膝", "右膝"
        )

        for (i in absoluteValues.indices) {
            val standard = standardList[i]
            val absoluteDifference = absoluteValues[i]
            if (absoluteDifference > 10) {
                // 根据角度差的正负判断提示语
                val direction = if (differenceList[i] > 0) "增大" else "减小"
                // 根据listType提供不同的标准和建议
                warningMessages.add(
                    when (listType) {
                        "1" -> "${bodyParts[i]}的角度差值超出标准(${standard}°)，请$direction 相应位置的角度！"
                        "2" -> "${bodyParts[i]}的角度差值超出标准(${standard}°)，请$direction 相应位置的角度！"
                        "3" -> "${bodyParts[i]}的角度差值超出标准(${standard}°)，请$direction 相应位置的角度！"
                        "4" -> "${bodyParts[i]}的角度差值超出标准(${standard}°)，请$direction 相应位置的角度！"
                        "5" -> "${bodyParts[i]}的角度差值超出标准(${standard}°)，请$direction 相应位置的角度！"
                        else -> "未知类型的角度差值超出标准，请检查！"
                    }
                )
            }
        }

        // 如果没有超出标准的位置
        return if (warningMessages.isEmpty()) {
            "动作标准"
        } else {
            warningMessages.joinToString("\n")
        }
    }
}
