package com.example.cmake_project_test

import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.view.ScaleGestureDetector
import kotlin.math.max
import kotlin.math.min

/**
 * 可调节的通用生理信号图表视图
 * 支持多种设备类型和通道数量的动态显示，具有缩放、平移、时间窗口调节等功能
 */
class DynamicChartView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    private val paint = Paint().apply {
        color = Color.BLUE
        strokeWidth = 2f
        style = Paint.Style.STROKE
        isAntiAlias = false // 关闭抗锯齿，提高绘制性能
    }

    private val gridPaint = Paint().apply {
        color = Color.LTGRAY
        strokeWidth = 1f
        style = Paint.Style.STROKE
        alpha = 80
    }

    private val textPaint = Paint().apply {
        color = Color.BLACK
        textSize = 20f
        isAntiAlias = true
    }

    private val controlPaint = Paint().apply {
        color = Color.RED
        strokeWidth = 3f
        style = Paint.Style.STROKE
        isAntiAlias = true
    }

    private val path = Path()
    private var dataPoints = mutableListOf<Float>()
    private var maxDataPoints = 1000 // 默认数据点数量
    private var minValue = Float.MAX_VALUE
    private var maxValue = Float.MIN_VALUE
    private var isDataAvailable = false

    // 图表配置
    private var chartTitle = "通道"
    private var channelIndex = 0
    private var deviceType = "未知设备"
    private var sampleRate = 250f // 默认采样率
    private var timeWindow = 4f // 默认时间窗口（秒）

    // 性能优化：真正的逐点绘制
    private val dataBuffer = mutableListOf<Float>()

    // 多通道数据支持（用于PPG等设备）
    private val multiChannelDataPoints = mutableListOf<MutableList<Float>>()
    private val multiChannelDataBuffers = mutableListOf<MutableList<Float>>()
    private var isMultiChannelMode = false
    private val channelColors = listOf(Color.RED, Color.BLUE) // 通道颜色
    private var lastUpdateTime = 0L
    private val updateInterval = 2L // 2ms更新间隔，实现500Hz显示
    private var lastDrawTime = 0L
    private val drawInterval = 1L // 1ms绘制间隔，实现1000Hz绘制频率

    // 交互控制参数
    private var scaleFactor = 1.0f
    private var translateX = 0f
    private var translateY = 0f
    private var viewportStart = 0f
    private var viewportEnd = 1.0f
    private var isDragging = false
    private var lastTouchX = 0f
    private var lastTouchY = 0f
    
    // 手势检测器
    private val scaleGestureDetector = ScaleGestureDetector(context, ScaleListener())
    
    // 控制按钮区域
    private val controlButtonRect = RectF()
    private val fullscreenButtonRect = RectF()

    // 全屏模式相关
    private var isFullscreenMode = false
    private var originalLayoutParams: android.view.ViewGroup.LayoutParams? = null

    /**
     * 设置图表配置
     */
    fun setChartConfig(
        title: String,
        channelIdx: Int,
        device: String,
        maxPoints: Int,
        sampleRateHz: Float,
        timeWindowSec: Float
    ) {
        chartTitle = title
        channelIndex = channelIdx
        deviceType = device
        maxDataPoints = maxPoints
        sampleRate = sampleRateHz
        timeWindow = timeWindowSec
        resetViewport()
        invalidate()
    }

    /**
     * 设置多通道模式（用于PPG等设备）
     */
    fun setMultiChannelMode(channelCount: Int) {
        isMultiChannelMode = true
        multiChannelDataPoints.clear()
        multiChannelDataBuffers.clear()

        // 初始化每个通道的数据结构
        for (i in 0 until channelCount) {
            multiChannelDataPoints.add(mutableListOf())
            multiChannelDataBuffers.add(mutableListOf())
        }
    }

    fun updateData(newData: List<Float>) {
        if (newData.isEmpty()) return

        isDataAvailable = true

        // 批量添加到缓冲区
        dataBuffer.addAll(newData)

        val currentTime = System.currentTimeMillis()

        // 批量处理 - 每次处理更多点，提高数据累积速度
        if (currentTime - lastUpdateTime >= updateInterval) {
            if (dataBuffer.isNotEmpty()) {
                // 每次处理多个点，提高效率
                val batchSize = minOf(10, dataBuffer.size) // 每次最多处理10个点
                val batch = dataBuffer.take(batchSize)
                dataBuffer.removeAll(batch)

                dataPoints.addAll(batch)

                // 限制数据点数量
                if (dataPoints.size > maxDataPoints) {
                    dataPoints = dataPoints.takeLast(maxDataPoints).toMutableList()
                }

                // 更新数据范围 - 使用批量数据
                updateDataRange(batch)

                lastUpdateTime = currentTime
            }
        }

        // 超高频绘制
        if (currentTime - lastDrawTime >= drawInterval) {
            invalidate()
            lastDrawTime = currentTime
        }
    }

    /**
     * 更新多通道数据（用于PPG等设备）
     */
    fun updateMultiChannelData(channelData: List<List<Float>>) {
        if (channelData.isEmpty() || !isMultiChannelMode) {
            Log.d("DynamicChartView", "跳过多通道更新: channelData.isEmpty=${channelData.isEmpty()}, isMultiChannelMode=$isMultiChannelMode")
            return
        }

        Log.d("DynamicChartView", "多通道数据更新: 通道数=${channelData.size}, 每个通道数据点=${channelData.map { it.size }}")
        isDataAvailable = true

        val currentTime = System.currentTimeMillis()

        // 更新每个通道的数据
        for (channelIndex in channelData.indices) {
            if (channelIndex >= multiChannelDataBuffers.size) {
                Log.w("DynamicChartView", "通道索引超出范围: $channelIndex >= ${multiChannelDataBuffers.size}")
                continue
            }

            val channelBuffer = multiChannelDataBuffers[channelIndex]
            channelBuffer.addAll(channelData[channelIndex])
            Log.d("DynamicChartView", "通道$channelIndex 添加了${channelData[channelIndex].size}个数据点")
        }

        // 批量处理数据
        if (currentTime - lastUpdateTime >= updateInterval) {
            var hasDataToProcess = false

            for (channelIndex in multiChannelDataBuffers.indices) {
                val buffer = multiChannelDataBuffers[channelIndex]
                if (buffer.isNotEmpty()) {
                    // 每次处理多个点
                    val batchSize = minOf(10, buffer.size)
                    val batch = buffer.take(batchSize)
                    buffer.removeAll(batch)

                    multiChannelDataPoints[channelIndex].addAll(batch)

                    // 限制数据点数量
                    if (multiChannelDataPoints[channelIndex].size > maxDataPoints) {
                        multiChannelDataPoints[channelIndex] = multiChannelDataPoints[channelIndex].takeLast(maxDataPoints).toMutableList()
                    }

                    hasDataToProcess = true
                }
            }

            if (hasDataToProcess) {
                // 更新数据范围 - 计算所有通道的数据范围
                updateMultiChannelDataRange()
                lastUpdateTime = currentTime

                Log.d("DynamicChartView", "多通道数据处理完成: 通道数据点=${multiChannelDataPoints.map { it.size }}, 范围=${minValue}-${maxValue}")
            }
        }

        // 超高频绘制
        if (currentTime - lastDrawTime >= drawInterval) {
            invalidate()
            lastDrawTime = currentTime
        }
    }
    
    private fun updateDataRange(batch: List<Float>) {
        // 使用全部数据点计算范围，提供更准确的范围
        if (dataPoints.isEmpty()) return

        // 计算全部数据点的范围
        minValue = dataPoints.minOrNull() ?: 0f
        maxValue = dataPoints.maxOrNull() ?: 0f

        // 确保有足够的显示范围
        val range = maxValue - minValue
        if (range < 0.1f) {
            val center = (maxValue + minValue) / 2
            minValue = center - 0.05f
            maxValue = center + 0.05f
        } else {
            val margin = range * 0.1f
            minValue -= margin
            maxValue += margin
        }
    }

    /**
     * 更新多通道数据范围
     */
    private fun updateMultiChannelDataRange() {
        if (multiChannelDataPoints.isEmpty()) {
            Log.w("DynamicChartView", "多通道数据点为空，无法计算范围")
            return
        }

        // 计算所有通道的最小值和最大值
        var globalMin = Float.MAX_VALUE
        var globalMax = Float.MIN_VALUE
        var hasValidData = false

        for (channelIndex in multiChannelDataPoints.indices) {
            val channelData = multiChannelDataPoints[channelIndex]
            if (channelData.isNotEmpty()) {
                val channelMin = channelData.minOrNull() ?: 0f
                val channelMax = channelData.maxOrNull() ?: 0f
                globalMin = minOf(globalMin, channelMin)
                globalMax = maxOf(globalMax, channelMax)
                hasValidData = true
                Log.d("DynamicChartView", "通道$channelIndex: 范围=${channelMin}-${channelMax}, 数据点=${channelData.size}")
            }
        }

        if (!hasValidData) {
            Log.w("DynamicChartView", "没有有效的多通道数据")
            return
        }

        minValue = globalMin
        maxValue = globalMax

        Log.d("DynamicChartView", "多通道全局范围: ${minValue}-${maxValue}")

        // 确保有足够的显示范围
        val range = maxValue - minValue
        if (range < 0.1f) {
            val center = (maxValue + minValue) / 2
            minValue = center - 0.05f
            maxValue = center + 0.05f
        } else {
            val margin = range * 0.1f
            minValue -= margin
            maxValue += margin
        }

        Log.d("DynamicChartView", "多通道显示范围: ${minValue}-${maxValue}")
    }
    
    fun clearData() {
        dataPoints.clear()
        dataBuffer.clear()
        // 清除多通道数据
        for (channelData in multiChannelDataPoints) {
            channelData.clear()
        }
        for (channelBuffer in multiChannelDataBuffers) {
            channelBuffer.clear()
        }
        isDataAvailable = false
        resetViewport()
        invalidate()
    }

    /**
     * 重置视口到默认状态
     */
    fun resetViewport() {
        scaleFactor = 1.0f
        translateX = 0f
        translateY = 0f
        viewportStart = 0f
        viewportEnd = 1.0f
        invalidate()
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        scaleGestureDetector.onTouchEvent(event)
        
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                val x = event.x
                val y = event.y
                
                // 开始拖拽
                isDragging = true
                lastTouchX = x
                lastTouchY = y
                return true
            }
            
            MotionEvent.ACTION_MOVE -> {
                if (isDragging) {
                    val deltaX = event.x - lastTouchX
                    val deltaY = event.y - lastTouchY
                    
                    translateX += deltaX
                    translateY += deltaY
                    
                    // 限制平移范围
                    val maxTranslate = width * 0.5f
                    translateX = translateX.coerceIn(-maxTranslate, maxTranslate)
                    translateY = translateY.coerceIn(-maxTranslate, maxTranslate)
                    
                    lastTouchX = event.x
                    lastTouchY = event.y
                    invalidate()
                    return true
                }
            }
            
            MotionEvent.ACTION_UP -> {
                isDragging = false
                return true
            }
        }
        
        return super.onTouchEvent(event)
    }

    private inner class ScaleListener : ScaleGestureDetector.SimpleOnScaleGestureListener() {
        override fun onScale(detector: ScaleGestureDetector): Boolean {
            scaleFactor *= detector.scaleFactor
            scaleFactor = scaleFactor.coerceIn(0.2f, 5.0f)
            invalidate()
            return true
        }
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        
        val width = width.toFloat()
        val height = height.toFloat()
        
        // 应用变换
        canvas.save()
        canvas.translate(translateX, translateY)
        canvas.scale(scaleFactor, scaleFactor, width / 2, height / 2)
        
        // 绘制网格
        drawGrid(canvas, width, height)
        
        // 绘制标题和通道信息
        drawTitle(canvas, width, height)
        
        // 绘制数据统计
        drawStats(canvas, width, height)

        // 绘制全屏按钮
        drawFullscreenButton(canvas, width, height)

        // 如果没有数据，显示默认内容
        if (!isDataAvailable) {
            drawDefaultContent(canvas, width, height)
        } else {
            // 绘制曲线 - 检查单通道或多通道数据
            val hasDataToDraw = if (isMultiChannelMode) {
                multiChannelDataPoints.any { it.size > 1 }
            } else {
                dataPoints.size > 1
            }

            if (hasDataToDraw) {
                drawCurve(canvas, width, height)
            }
        }
        
        canvas.restore()
    }

    private fun drawGrid(canvas: Canvas, width: Float, height: Float) {
        val padding = 60f
        val drawWidth = width - 2 * padding
        val drawHeight = height - 2 * padding
        
        // 绘制水平网格线
        val gridLines = 5
        for (i in 0..gridLines) {
            val y = padding + (drawHeight * i / gridLines)
            canvas.drawLine(padding, y, width - padding, y, gridPaint)
        }
        
        // 绘制垂直网格线
        for (i in 0..gridLines) {
            val x = padding + (drawWidth * i / gridLines)
            canvas.drawLine(x, padding, x, height - padding, gridPaint)
        }
    }

    private fun drawTitle(canvas: Canvas, width: Float, height: Float) {
        val title = "$chartTitle $channelIndex"
        canvas.drawText(title, 10f, 25f, textPaint)
        
        val deviceInfo = "$deviceType (${sampleRate.toInt()}Hz)"
        canvas.drawText(deviceInfo, 10f, 50f, textPaint)
        
        // 显示当前缩放和时间窗口信息
        val scaleInfo = "缩放: ${String.format("%.1f", scaleFactor)}x"
        canvas.drawText(scaleInfo, width - 150f, 25f, textPaint)
        
        val timeInfo = "时间窗口: ${timeWindow.toInt()}秒"
        canvas.drawText(timeInfo, width - 150f, 50f, textPaint)
    }

    private fun drawStats(canvas: Canvas, width: Float, height: Float) {
        val totalDataPoints = if (isMultiChannelMode) {
            multiChannelDataPoints.sumOf { it.size }
        } else {
            dataPoints.size
        }

        val statsText = if (isMultiChannelMode) {
            "数据点: ${totalDataPoints} (${multiChannelDataPoints.size}通道)"
        } else {
            "数据点: ${dataPoints.size}"
        }
        canvas.drawText(statsText, 10f, height - 35f, textPaint)

        if (totalDataPoints > 0) {
            val rangeText = "范围: ${String.format("%.2f", minValue)} - ${String.format("%.2f", maxValue)}"
            canvas.drawText(rangeText, 10f, height - 15f, textPaint)
        }
    }

    private fun drawDefaultContent(canvas: Canvas, width: Float, height: Float) {
        val centerX = width / 2
        val centerY = height / 2
        
        val hintPaint = Paint().apply {
            color = Color.GRAY
            textSize = 16f
            textAlign = Paint.Align.CENTER
            isAntiAlias = true
        }
        
        canvas.drawText("等待数据...", centerX, centerY - 20f, hintPaint)
        canvas.drawText("请先连接蓝牙设备", centerX, centerY + 20f, hintPaint)
        canvas.drawText("然后点击'启动程序'显示数据", centerX, centerY + 60f, hintPaint)
    }

    private fun drawCurve(canvas: Canvas, width: Float, height: Float) {
        val padding = 60f
        val drawWidth = width - 2 * padding
        val drawHeight = height - 2 * padding

        if (isMultiChannelMode && multiChannelDataPoints.isNotEmpty()) {
            Log.d("DynamicChartView", "多通道绘制: 通道数=${multiChannelDataPoints.size}, 数据点=${multiChannelDataPoints.map { it.size }}")
            // 多通道绘制模式
            for (channelIndex in multiChannelDataPoints.indices) {
                val channelData = multiChannelDataPoints[channelIndex]
                if (channelData.isEmpty()) {
                    Log.d("DynamicChartView", "通道$channelIndex 数据为空，跳过绘制")
                    continue
                }

                path.reset()

                // 设置通道颜色
                val channelPaint = Paint(paint).apply {
                    color = channelColors.getOrElse(channelIndex) { Color.GRAY }
                    strokeWidth = 2f
                }

                val xStep = if (channelData.size > 1) drawWidth / (channelData.size - 1) else drawWidth

                for (i in channelData.indices) {
                    val x = padding + i * xStep
                    val normalizedValue = (channelData[i] - minValue) / (maxValue - minValue)
                    val y = padding + (0.1f + normalizedValue * 0.8f) * drawHeight

                    if (i == 0) {
                        path.moveTo(x, y)
                    } else {
                        path.lineTo(x, y)
                    }
                }

                canvas.drawPath(path, channelPaint)
            }
        } else {
            // 单通道绘制模式
            if (dataPoints.isEmpty()) return

            path.reset()
            val xStep = if (dataPoints.size > 1) drawWidth / (dataPoints.size - 1) else drawWidth

            for (i in dataPoints.indices) {
                val x = padding + i * xStep
                val normalizedValue = (dataPoints[i] - minValue) / (maxValue - minValue)
                val y = padding + (0.1f + normalizedValue * 0.8f) * drawHeight

                if (i == 0) {
                    path.moveTo(x, y)
                } else {
                    path.lineTo(x, y)
                }
            }

            canvas.drawPath(path, paint)
        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        
        val desiredHeight = 200 // 每个图表的高度
        val height = resolveSize(desiredHeight, heightMeasureSpec)
        setMeasuredDimension(widthMeasureSpec, height)
    }
    
    /**
     * 获取当前图表数据
     */
    fun getCurrentData(): List<Float> {
        return dataPoints.toList()
    }
    
    /**
     * 获取数据统计信息
     */
    fun getDataStats(): Map<String, Any> {
        val totalDataPoints = if (isMultiChannelMode) {
            multiChannelDataPoints.sumOf { it.size }
        } else {
            dataPoints.size
        }

        return mapOf(
            "dataPoints" to totalDataPoints,
            "multiChannelMode" to isMultiChannelMode,
            "channelCount" to if (isMultiChannelMode) multiChannelDataPoints.size else 1,
            "minValue" to minValue,
            "maxValue" to maxValue,
            "range" to (maxValue - minValue),
            "isDataAvailable" to isDataAvailable,
            "scaleFactor" to scaleFactor,
            "timeWindow" to timeWindow
        )
    }
}
