package com.example.cmake_project_test

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

class ECGChartView @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 = 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 = 30f
        isAntiAlias = true
    }

    private val buttonPaint = Paint().apply {
        color = Color.GRAY
        style = Paint.Style.FILL
        alpha = 150
    }

    private val buttonTextPaint = Paint().apply {
        color = Color.WHITE
        textSize = 20f
        isAntiAlias = true
        textAlign = Paint.Align.CENTER
    }

    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 scaleX = 1.0f // X轴缩放因子
    private var scaleY = 1.0f // Y轴缩放因子
    private var offsetX = 0f // X轴偏移
    private var offsetY = 0f // Y轴偏移
    
    // 自动居中控制
    private var autoCenter = true // 自动居中模式
    private var lockToCenter = true // 锁定到屏幕中央
    
    // 手势检测器
    private val gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
        override fun onDoubleTap(e: MotionEvent): Boolean {
            // 双击重置缩放并锁定到中央
            resetZoom()
            lockToCenter = true
            invalidate()
            return true
        }
        
        override fun onScroll(e1: MotionEvent?, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean {
            // 只有在非锁定模式下才允许平移
            if (!lockToCenter) {
                offsetX -= distanceX
                offsetY -= distanceY
                invalidate()
            }
            return true
        }
    })

    // 按钮区域
    private val buttonSize = 60f
    private val buttonMargin = 20f
    
    // 缩放按钮区域
    private val zoomInXButtonRect = RectF()
    private val zoomOutXButtonRect = RectF()
    private val zoomInYButtonRect = RectF()
    private val zoomOutYButtonRect = RectF()
    private val resetButtonRect = RectF()
    private val lockButtonRect = RectF()

    fun updateData(newData: List<Float>) {
        // 快速累积数据
        dataPoints.addAll(newData)
        
        // 限制数据点数量（避免内存溢出）
        if (dataPoints.size > maxDataPoints) {
            dataPoints = dataPoints.takeLast(maxDataPoints).toMutableList()
        }
        
        // 快速计算数据范围（减少计算量）
        if (dataPoints.isNotEmpty()) {
            // 只计算最近的数据范围，提高性能
            val recentData = dataPoints.takeLast(minOf(1000, dataPoints.size))
            minValue = recentData.minOrNull() ?: 0f
            maxValue = recentData.maxOrNull() ?: 0f
            
            // 确保有足够的显示范围
            val range = maxValue - minValue
            if (range < 0.1f) {
                val center = (maxValue + minValue) / 2
                minValue = center - 0.05f
                maxValue = center + 0.05f
            } else {
                // 添加10%的上下边距（减少边距，提高响应速度）
                val margin = range * 0.1f
                minValue -= margin
                maxValue += margin
            }
        }
        
        // 如果启用自动居中，重置偏移
        if (autoCenter) {
            offsetX = 0f
            offsetY = 0f
        }
        
        // 立即重绘
        invalidate()
    }
    
    fun clearData() {
        dataPoints.clear()
        invalidate()
    }

    // 缩放控制方法
    fun zoomInX() {
        scaleX = min(scaleX * 1.2f, 5.0f)
        invalidate()
    }
    
    fun zoomOutX() {
        scaleX = max(scaleX / 1.2f, 0.2f)
        invalidate()
    }
    
    fun zoomInY() {
        scaleY = min(scaleY * 1.2f, 5.0f)
        invalidate()
    }
    
    fun zoomOutY() {
        scaleY = max(scaleY / 1.2f, 0.2f)
        invalidate()
    }
    
    fun resetZoom() {
        scaleX = 1.0f
        scaleY = 1.0f
        offsetX = 0f
        offsetY = 0f
        lockToCenter = true
        invalidate()
    }
    
    // 切换锁定模式
    fun toggleLockMode() {
        lockToCenter = !lockToCenter
        if (lockToCenter) {
            offsetX = 0f
            offsetY = 0f
        }
        invalidate()
    }
    
    // 获取锁定状态
    fun isLockedToCenter(): Boolean = lockToCenter

    override fun onTouchEvent(event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                // 检查是否点击了按钮
                val x = event.x
                val y = event.y
                
                if (zoomInXButtonRect.contains(x, y)) {
                    zoomInX()
                    return true
                } else if (zoomOutXButtonRect.contains(x, y)) {
                    zoomOutX()
                    return true
                } else if (zoomInYButtonRect.contains(x, y)) {
                    zoomInY()
                    return true
                } else if (zoomOutYButtonRect.contains(x, y)) {
                    zoomOutY()
                    return true
                } else if (resetButtonRect.contains(x, y)) {
                    resetZoom()
                    return true
                } else if (lockButtonRect.contains(x, y)) {
                    toggleLockMode()
                    return true
                }
            }
        }
        
        // 处理手势
        return gestureDetector.onTouchEvent(event) || super.onTouchEvent(event)
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        
        val width = width.toFloat()
        val height = height.toFloat()
        
        // 更新按钮位置
        updateButtonPositions(width, height)
        
        // 绘制网格
        drawGrid(canvas, width, height)
        
        // 绘制标题
        canvas.drawText("ECG Channel 1 (滤波后)", 20f, 40f, textPaint)
        
        // 绘制缩放信息
        canvas.drawText("X缩放: ${String.format("%.1f", scaleX)}x", 20f, 70f, textPaint)
        canvas.drawText("Y缩放: ${String.format("%.1f", scaleY)}x", 20f, 100f, textPaint)
        
        // 绘制锁定状态
        val lockStatus = if (lockToCenter) "🔒 已锁定" else "🔓 已解锁"
        canvas.drawText(lockStatus, 20f, 130f, textPaint)
        
        // 绘制数据点数量
        canvas.drawText("数据点: ${dataPoints.size}", 20f, height - 20f, textPaint)
        
        // 绘制数据范围
        if (dataPoints.isNotEmpty()) {
            canvas.drawText("范围: ${String.format("%.3f", minValue)} - ${String.format("%.3f", maxValue)}", 
                          20f, height - 50f, textPaint)
        }
        
        // 绘制控制按钮
        drawControlButtons(canvas)
        
        // 绘制曲线
        if (dataPoints.size > 1) {
            drawCurve(canvas, width, height)
        }
    }

    private fun updateButtonPositions(width: Float, height: Float) {
        val buttonY = height - buttonSize - buttonMargin
        
        // X轴缩放按钮
        zoomInXButtonRect.set(
            width - buttonSize * 6 - buttonMargin * 6,
            buttonY,
            width - buttonSize * 5 - buttonMargin * 5,
            buttonY + buttonSize
        )
        
        zoomOutXButtonRect.set(
            width - buttonSize * 5 - buttonMargin * 5,
            buttonY,
            width - buttonSize * 4 - buttonMargin * 4,
            buttonY + buttonSize
        )
        
        // Y轴缩放按钮
        zoomInYButtonRect.set(
            width - buttonSize * 4 - buttonMargin * 4,
            buttonY,
            width - buttonSize * 3 - buttonMargin * 3,
            buttonY + buttonSize
        )
        
        zoomOutYButtonRect.set(
            width - buttonSize * 3 - buttonMargin * 3,
            buttonY,
            width - buttonSize * 2 - buttonMargin * 2,
            buttonY + buttonSize
        )
        
        // 重置按钮
        resetButtonRect.set(
            width - buttonSize * 2 - buttonMargin * 2,
            buttonY,
            width - buttonSize - buttonMargin,
            buttonY + buttonSize
        )
        
        // 锁定按钮
        lockButtonRect.set(
            width - buttonSize - buttonMargin,
            buttonY,
            width - buttonMargin,
            buttonY + buttonSize
        )
    }

    private fun drawControlButtons(canvas: Canvas) {
        // 绘制X轴缩放按钮
        canvas.drawRoundRect(zoomInXButtonRect, 10f, 10f, buttonPaint)
        canvas.drawText("X+", zoomInXButtonRect.centerX(), zoomInXButtonRect.centerY() + 7f, buttonTextPaint)
        
        canvas.drawRoundRect(zoomOutXButtonRect, 10f, 10f, buttonTextPaint)
        canvas.drawText("X-", zoomOutXButtonRect.centerX(), zoomOutXButtonRect.centerY() + 7f, buttonTextPaint)
        
        // 绘制Y轴缩放按钮
        canvas.drawRoundRect(zoomInYButtonRect, 10f, 10f, buttonPaint)
        canvas.drawText("Y+", zoomInYButtonRect.centerX(), zoomInYButtonRect.centerY() + 7f, buttonTextPaint)
        
        canvas.drawRoundRect(zoomOutYButtonRect, 10f, 10f, buttonPaint)
        canvas.drawText("Y-", zoomOutYButtonRect.centerX(), zoomOutYButtonRect.centerY() + 7f, buttonTextPaint)
        
        // 绘制重置按钮
        canvas.drawRoundRect(resetButtonRect, 10f, 10f, buttonPaint)
        canvas.drawText("重置", resetButtonRect.centerX(), resetButtonRect.centerY() + 7f, buttonTextPaint)
        
        // 绘制锁定按钮
        val lockButtonColor = if (lockToCenter) Color.GREEN else Color.RED
        buttonPaint.color = lockButtonColor
        canvas.drawRoundRect(lockButtonRect, 10f, 10f, buttonPaint)
        canvas.drawText(if (lockToCenter) "🔒" else "🔓", lockButtonRect.centerX(), lockButtonRect.centerY() + 7f, buttonTextPaint)
        buttonPaint.color = Color.GRAY // 恢复默认颜色
    }

    private fun drawGrid(canvas: Canvas, width: Float, height: Float) {
        // 绘制垂直线
        val verticalSpacing = width / 10
        for (i in 0..10) {
            val x = i * verticalSpacing
            canvas.drawLine(x, 0f, x, height, gridPaint)
        }
        
        // 绘制水平线
        val horizontalSpacing = height / 8
        for (i in 0..8) {
            val y = i * horizontalSpacing
            canvas.drawLine(0f, y, width, y, gridPaint)
        }
    }

    private fun drawCurve(canvas: Canvas, width: Float, height: Float) {
        path.reset()
        
        val padding = 60f
        val drawWidth = width - 2 * padding
        val drawHeight = height - 2 * padding
        
        // 应用缩放和偏移
        val scaledWidth = drawWidth * scaleX
        val scaledHeight = drawHeight * scaleY
        
        // 如果锁定到中央，强制偏移为0
        val effectiveOffsetX = if (lockToCenter) 0f else offsetX
        val effectiveOffsetY = if (lockToCenter) 0f else offsetY
        
        val xStep = scaledWidth / (dataPoints.size - 1)
        
        for (i in dataPoints.indices) {
            val x = padding + i * xStep + effectiveOffsetX
            val normalizedValue = (dataPoints[i] - minValue) / (maxValue - minValue)
            // 使用0.1到0.9的范围，确保曲线在中间80%的区域显示
            val y = padding + (0.1f + normalizedValue * 0.8f) * scaledHeight + effectiveOffsetY
            
            // 确保点在可见区域内
            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 = 800
        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)
    }
}
