package com.example.cmake_project_test

import android.util.Log
import java.nio.ByteBuffer
import java.nio.ByteOrder

/**
 * 信号处理JNI接口类
 * 提供C++信号处理功能的Java封装
 */
class SignalProcessorJNI {
    
    companion object {
        // 加载原生库
        init {
            System.loadLibrary("cmake_project_test")
        }
    }
    
    private var processorId: Long = -1
    
    /**
     * 创建信号处理器实例
     */
    fun createProcessor(): Boolean {
        processorId = createSignalProcessor()
        return processorId != -1L
    }
    
    /**
     * 销毁信号处理器实例
     */
    fun destroyProcessor() {
        if (processorId != -1L) {
            destroySignalProcessor(processorId)
            processorId = -1L
        }
    }
    
    /**
     * 带通滤波
     * @param signal 输入信号数据
     * @param sampleRate 采样率
     * @param lowFreq 低频截止频率
     * @param highFreq 高频截止频率
     * @return 滤波后的信号数据
     */
    fun bandpassFilter(signal: FloatArray, sampleRate: Double, lowFreq: Double, highFreq: Double): FloatArray? {
        if (processorId == -1L) {
            Log.e("SignalProcessorJNI", "Processor not initialized")
            return null
        }
        
        val signalBytes = floatArrayToByteArray(signal)
        val resultBytes = bandpassFilter(processorId, signalBytes, sampleRate, lowFreq, highFreq)
        return resultBytes?.let { byteArrayToFloatArray(it) }
    }
    
    /**
     * 低通滤波
     * @param signal 输入信号数据
     * @param sampleRate 采样率
     * @param cutoffFreq 截止频率
     * @return 滤波后的信号数据
     */
    fun lowpassFilter(signal: FloatArray, sampleRate: Double, cutoffFreq: Double): FloatArray? {
        if (processorId == -1L) {
            Log.e("SignalProcessorJNI", "Processor not initialized")
            return null
        }
        
        val signalBytes = floatArrayToByteArray(signal)
        val resultBytes = lowpassFilter(processorId, signalBytes, sampleRate, cutoffFreq)
        return resultBytes?.let { byteArrayToFloatArray(it) }
    }
    
    /**
     * 高通滤波
     * @param signal 输入信号数据
     * @param sampleRate 采样率
     * @param cutoffFreq 截止频率
     * @return 滤波后的信号数据
     */
    fun highpassFilter(signal: FloatArray, sampleRate: Double, cutoffFreq: Double): FloatArray? {
        if (processorId == -1L) {
            Log.e("SignalProcessorJNI", "Processor not initialized")
            return null
        }
        
        val signalBytes = floatArrayToByteArray(signal)
        val resultBytes = highpassFilter(processorId, signalBytes, sampleRate, cutoffFreq)
        return resultBytes?.let { byteArrayToFloatArray(it) }
    }
    
    /**
     * 陷波滤波
     * @param signal 输入信号数据
     * @param sampleRate 采样率
     * @param notchFreq 陷波频率
     * @param qFactor 品质因数
     * @return 滤波后的信号数据
     */
    fun notchFilter(signal: FloatArray, sampleRate: Double, notchFreq: Double, qFactor: Double = 30.0): FloatArray? {
        if (processorId == -1L) {
            Log.e("SignalProcessorJNI", "Processor not initialized")
            return null
        }
        
        val signalBytes = floatArrayToByteArray(signal)
        val resultBytes = notchFilter(processorId, signalBytes, sampleRate, notchFreq, qFactor)
        return resultBytes?.let { byteArrayToFloatArray(it) }
    }
    
    /**
     * 计算信号质量
     * @param signal 输入信号数据
     * @return 信号质量指数 (0.0 - 1.0)
     */
    fun calculateSignalQuality(signal: FloatArray): Float {
        if (processorId == -1L) {
            Log.e("SignalProcessorJNI", "Processor not initialized")
            return 0.0f
        }
        
        val signalBytes = floatArrayToByteArray(signal)
        return calculateSignalQuality(processorId, signalBytes)
    }
    
    /**
     * 计算ECG信号质量指数
     * @param signal 输入信号数据
     * @param sampleRate 采样率
     * @return ECG信号质量指数 (0.0 - 1.0)
     */
    fun calculateECGSQI(signal: FloatArray, sampleRate: Double): Float {
        if (processorId == -1L) {
            Log.e("SignalProcessorJNI", "Processor not initialized")
            return 0.0f
        }
        
        val signalBytes = floatArrayToByteArray(signal)
        return calculateECGSQI(processorId, signalBytes, sampleRate)
    }
    
    /**
     * 计算两个信号的相关性
     * @param x 第一个信号
     * @param y 第二个信号
     * @return 相关系数 (-1.0 - 1.0)
     */
    fun calculateCorrelation(x: FloatArray, y: FloatArray): Float {
        if (processorId == -1L) {
            Log.e("SignalProcessorJNI", "Processor not initialized")
            return 0.0f
        }
        
        val xBytes = floatArrayToByteArray(x)
        val yBytes = floatArrayToByteArray(y)
        return calculateCorrelation(processorId, xBytes, yBytes)
    }
    
    /**
     * 归一化信号幅度
     * @param signal 输入信号数据（将被修改）
     */
    fun normalizeAmplitude(signal: FloatArray) {
        if (processorId == -1L) {
            Log.e("SignalProcessorJNI", "Processor not initialized")
            return
        }
        
        val signalBytes = floatArrayToByteArray(signal)
        normalizeAmplitude(processorId, signalBytes)
        
        // 将处理后的数据写回原数组
        val processedSignal = byteArrayToFloatArray(signalBytes)
        processedSignal.copyInto(signal)
    }
    
    /**
     * 提取信号特征
     * @param signal 输入信号数据
     * @param sampleRate 采样率
     * @return 特征向量
     */
    fun extractFeatures(signal: FloatArray, sampleRate: Double): FloatArray? {
        if (processorId == -1L) {
            Log.e("SignalProcessorJNI", "Processor not initialized")
            return null
        }
        
        val signalBytes = floatArrayToByteArray(signal)
        val resultBytes = extractFeatures(processorId, signalBytes, sampleRate)
        return resultBytes?.let { byteArrayToFloatArray(it) }
    }
    
    /**
     * 重置滤波器状态
     */
    fun resetFilters() {
        if (processorId == -1L) {
            Log.e("SignalProcessorJNI", "Processor not initialized")
            return
        }
        
        resetFilters(processorId)
    }
    
    /**
     * 实时处理数据块
     * @param chunk 输入数据块
     * @param sampleRate 采样率
     * @return 处理后的数据块
     */
    fun processRealtimeChunk(chunk: FloatArray, sampleRate: Double): FloatArray? {
        if (processorId == -1L) {
            Log.e("SignalProcessorJNI", "Processor not initialized")
            return null
        }
        
        val chunkBytes = floatArrayToByteArray(chunk)
        val resultBytes = processRealtimeChunk(processorId, chunkBytes, sampleRate)
        return resultBytes?.let { byteArrayToFloatArray(it) }
    }
    
    // 辅助方法：FloatArray转ByteArray
    private fun floatArrayToByteArray(floatArray: FloatArray): ByteArray {
        val buffer = ByteBuffer.allocate(floatArray.size * 4)
        buffer.order(ByteOrder.LITTLE_ENDIAN)
        floatArray.forEach { buffer.putFloat(it) }
        return buffer.array()
    }
    
    // 辅助方法：ByteArray转FloatArray
    private fun byteArrayToFloatArray(byteArray: ByteArray): FloatArray {
        val buffer = ByteBuffer.wrap(byteArray)
        buffer.order(ByteOrder.LITTLE_ENDIAN)
        val floatArray = FloatArray(byteArray.size / 4)
        for (i in floatArray.indices) {
            floatArray[i] = buffer.float
        }
        return floatArray
    }
    
    // 原生方法声明
    private external fun createSignalProcessor(): Long
    private external fun destroySignalProcessor(processorId: Long)
    private external fun bandpassFilter(processorId: Long, signal: ByteArray, sampleRate: Double, lowFreq: Double, highFreq: Double): ByteArray?
    private external fun lowpassFilter(processorId: Long, signal: ByteArray, sampleRate: Double, cutoffFreq: Double): ByteArray?
    private external fun highpassFilter(processorId: Long, signal: ByteArray, sampleRate: Double, cutoffFreq: Double): ByteArray?
    private external fun notchFilter(processorId: Long, signal: ByteArray, sampleRate: Double, notchFreq: Double, qFactor: Double): ByteArray?
    private external fun calculateSignalQuality(processorId: Long, signal: ByteArray): Float
    private external fun calculateECGSQI(processorId: Long, signal: ByteArray, sampleRate: Double): Float
    private external fun calculateCorrelation(processorId: Long, x: ByteArray, y: ByteArray): Float
    private external fun normalizeAmplitude(processorId: Long, signal: ByteArray)
    private external fun extractFeatures(processorId: Long, signal: ByteArray, sampleRate: Double): ByteArray?
    private external fun resetFilters(processorId: Long)
    private external fun processRealtimeChunk(processorId: Long, chunk: ByteArray, sampleRate: Double): ByteArray?
}
