package com.example.cmake_project_test

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

/**
 * ECG波形视图
 * 显示2.5秒（625点）的放大信号，用于精确测量波形形态和间期
 */
class ECGWaveformView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

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

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

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

    private val path = Path()
    private var dataPoints = mutableListOf<Float>()
    private var maxDataPoints = 625 // 2.5秒数据（250Hz采样率）
    private var minValue = Float.MAX_VALUE
    private var maxValue = Float.MIN_VALUE
    private var isDataAvailable = false // 标记是否有数据
    
    // 简化的数据管理：直接显示新数据

    // 缩放控制参数
    private var scaleX = 1.0f
    private var scaleY = 1.0f
    private var offsetX = 0f
    private var offsetY = 0f
    
    // 手势检测器
    private val gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
        override fun onDoubleTap(e: MotionEvent): Boolean {
            resetZoom()
            return true
        }
        
        override fun onScroll(e1: MotionEvent?, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean {
            offsetX -= distanceX
            offsetY -= distanceY
            invalidate()
            return true
        }
    })
    
    // 缩放手势检测器
    private val scaleGestureDetector = android.view.ScaleGestureDetector(context, 
        object : android.view.ScaleGestureDetector.SimpleOnScaleGestureListener() {
            override fun onScale(detector: android.view.ScaleGestureDetector): Boolean {
                scaleX *= detector.scaleFactor
                scaleY *= detector.scaleFactor
                
                // 限制缩放范围
                scaleX = scaleX.coerceIn(0.1f, 5.0f)
                scaleY = scaleY.coerceIn(0.1f, 5.0f)
                
                invalidate()
                return true
            }
        })
    
    // 触摸事件处理
    private var lastTouchX = 0f
    private var lastTouchY = 0f
    private var isDragging = false

    fun updateData(newData: List<Float>) {
        if (newData.isEmpty()) return
        
        isDataAvailable = true
        
        // 直接添加新数据，来多少显示多少
        dataPoints.addAll(newData)
        
        // 限制数据点数量，保持滚动显示
        if (dataPoints.size > maxDataPoints) {
            dataPoints = dataPoints.takeLast(maxDataPoints).toMutableList()
        }
        
        // 更新数据范围
        updateDataRange(newData)
        
        // 立即重绘
        invalidate()
    }
    
    private fun updateDataRange(newData: 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 {
            // 添加15%的上下边距
            val margin = range * 0.15f
            minValue -= margin
            maxValue += margin
        }
    }
    
    fun clearData() {
        dataPoints.clear()
        invalidate()
    }
    
    /**
     * 获取当前图表数据
     */
    fun getCurrentData(): List<Float> {
        return dataPoints.toList()
    }
    
    /**
     * 获取数据统计信息
     */
    fun getDataStats(): Map<String, Any> {
        return mapOf(
            "dataPoints" to dataPoints.size,
            "minValue" to minValue,
            "maxValue" to maxValue,
            "range" to (maxValue - minValue),
            "isDataAvailable" to isDataAvailable
        )
    }

    fun resetZoom() {
        scaleX = 1.0f
        scaleY = 1.0f
        offsetX = 0f
        offsetY = 0f
        invalidate()
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                lastTouchX = event.x
                lastTouchY = event.y
                isDragging = false
            }
            MotionEvent.ACTION_MOVE -> {
                if (event.pointerCount == 1) {
                    // 单指拖拽
                    val deltaX = event.x - lastTouchX
                    val deltaY = event.y - lastTouchY
                    offsetX += deltaX
                    offsetY += deltaY
                    lastTouchX = event.x
                    lastTouchY = event.y
                    isDragging = true
                    invalidate()
                }
            }
            MotionEvent.ACTION_UP -> {
                if (!isDragging) {
                    // 如果没有拖拽，可能是点击事件
                    return gestureDetector.onTouchEvent(event)
                }
            }
        }
        
        // 处理缩放手势
        scaleGestureDetector.onTouchEvent(event)
        
        return true
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        
        val width = width.toFloat()
        val height = height.toFloat()
        
        // 绘制网格
        drawGrid(canvas, width, height)
        
        // 绘制标题
        canvas.drawText("ECG波形视图 (2.5秒)", 20f, 35f, textPaint)
        
        // 绘制时间轴标签
        canvas.drawText("0s", 20f, height - 10f, textPaint)
        canvas.drawText("1.25s", width / 2 - 25f, height - 10f, textPaint)
        canvas.drawText("2.5s", width - 60f, height - 10f, textPaint)
        
        // 绘制数据点数量
        canvas.drawText("数据点: ${dataPoints.size}", 20f, height - 40f, textPaint)
        
        // 绘制数据范围
        if (dataPoints.isNotEmpty()) {
            canvas.drawText("范围: ${String.format("%.3f", minValue)} - ${String.format("%.3f", maxValue)}", 
                          20f, height - 70f, textPaint)
        }
        
        // 绘制缩放信息
        canvas.drawText("X缩放: ${String.format("%.1f", scaleX)}x", width - 150f, 35f, textPaint)
        canvas.drawText("Y缩放: ${String.format("%.1f", scaleY)}x", width - 150f, 65f, textPaint)
        
        // 如果没有数据，显示默认内容
        if (!isDataAvailable) {
            drawDefaultContent(canvas, width, height)
        } else {
            // 绘制曲线
            if (dataPoints.size > 1) {
                drawCurve(canvas, width, height)
            }
        }
    }

    private fun drawGrid(canvas: Canvas, width: Float, height: Float) {
        // 绘制垂直线（时间轴）- 更密集的网格用于精确测量
        val verticalSpacing = width / 25 // 25条垂直线，每0.1秒一条
        for (i in 0..25) {
            val x = i * verticalSpacing
            canvas.drawLine(x, 0f, x, height, gridPaint)
        }
        
        // 绘制水平线（幅度轴）
        val horizontalSpacing = height / 12 // 12条水平线，更密集
        for (i in 0..12) {
            val y = i * horizontalSpacing
            canvas.drawLine(0f, y, width, y, gridPaint)
        }
    }

    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 = 28f
            isAntiAlias = true
            textAlign = Paint.Align.CENTER
        }
        
        canvas.drawText("等待数据...", centerX, centerY - 20f, hintPaint)
        canvas.drawText("请先连接蓝牙设备", centerX, centerY + 20f, hintPaint)
        canvas.drawText("然后点击'启动程序'显示原始数据", centerX, centerY + 60f, hintPaint)
        
        // 绘制一个简单的示例波形
        drawSampleWaveform(canvas, width, height)
    }
    
    private fun drawSampleWaveform(canvas: Canvas, width: Float, height: Float) {
        val samplePaint = Paint().apply {
            color = Color.LTGRAY
            strokeWidth = 1.5f
            style = Paint.Style.STROKE
            isAntiAlias = true
            alpha = 80
        }
        
        val path = Path()
        val padding = 100f
        val drawWidth = width - 2 * padding
        val drawHeight = height - 2 * padding
        val centerY = height / 2
        
        path.moveTo(padding, centerY)
        
        // 绘制一个简单的正弦波示例
        for (i in 0..100) {
            val x = padding + (i * drawWidth / 100)
            val y = centerY + (Math.sin(i * 0.5) * drawHeight / 6).toFloat()
            path.lineTo(x, y)
        }
        
        canvas.drawPath(path, samplePaint)
    }

    private fun drawCurve(canvas: Canvas, width: Float, height: Float) {
        path.reset()
        
        val padding = 100f
        val drawWidth = width - 2 * padding
        val drawHeight = height - 2 * padding
        
        // 应用缩放和偏移
        val scaledWidth = drawWidth * scaleX
        val scaledHeight = drawHeight * scaleY
        
        val xStep = scaledWidth / (dataPoints.size - 1)
        
        for (i in dataPoints.indices) {
            val x = padding + i * xStep + offsetX
            val normalizedValue = (dataPoints[i] - minValue) / (maxValue - minValue)
            // 使用0.1到0.9的范围，确保曲线在中间80%的区域显示
            val y = padding + (0.1f + normalizedValue * 0.8f) * scaledHeight + offsetY
            
            // 确保点在可见区域内
            if (x >= padding && x <= width - padding && y >= padding && y <= height - padding) {
                if (i == 0) {
                    path.moveTo(x, y)
                } else {
                    path.lineTo(x, y)
                }
            }
        }
        
        canvas.drawPath(path, paint)
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val desiredWidth = 1000
        val desiredHeight = 400
        
        val widthMode = MeasureSpec.getMode(widthMeasureSpec)
        val widthSize = MeasureSpec.getSize(widthMeasureSpec)
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)
        val heightSize = MeasureSpec.getSize(heightMeasureSpec)
        
        val width = when (widthMode) {
            MeasureSpec.EXACTLY -> widthSize
            MeasureSpec.AT_MOST -> min(desiredWidth, widthSize)
            else -> desiredWidth
        }
        
        val height = when (heightMode) {
            MeasureSpec.EXACTLY -> heightSize
            MeasureSpec.AT_MOST -> min(desiredHeight, heightSize)
            else -> desiredHeight
        }
        
        setMeasuredDimension(width, height)
    }
}
