package com.hikoncont.manager

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.ImageFormat
import android.graphics.Matrix
import android.graphics.Rect
import android.graphics.YuvImage
import android.hardware.camera2.*
import android.hardware.camera2.CameraManager
import android.media.Image
import android.media.ImageReader
import android.os.Handler
import android.os.HandlerThread
import android.util.Log
import android.util.Size
import android.view.Surface
import com.hikoncont.service.AccessibilityRemoteService
import kotlinx.coroutines.*
import java.io.ByteArrayOutputStream
import java.nio.ByteBuffer
import java.util.concurrent.Semaphore
import java.util.concurrent.TimeUnit

/**
 * 摄像头管理器 - 使用无障碍权限调用摄像头
 * 
 * 负责摄像头数据捕获和传输功能
 */
class CameraManager(private val service: AccessibilityRemoteService) {
    
    companion object {
        private const val TAG = "CameraManager"
        private const val CAMERA_FPS = 5 // 摄像头帧率，与发送频率保持一致
        private const val IMAGE_QUALITY = 70 // JPEG压缩质量
        private const val MAX_WIDTH = 640 // 最大宽度
        private const val MAX_HEIGHT = 480 // 最大高度
    }
    
    private var cameraDevice: CameraDevice? = null
    private var imageReader: ImageReader? = null
    private var captureSession: CameraCaptureSession? = null
    private var backgroundThread: HandlerThread? = null
    private var backgroundHandler: Handler? = null
    
    private val cameraManager = service.getSystemService(Context.CAMERA_SERVICE) as android.hardware.camera2.CameraManager
    private var currentCameraId: String? = null
    private var availableCameraIds: List<String> = emptyList()
    private var currentCameraIndex = 0
    
    private val cameraOpenCloseLock = Semaphore(1)
    private var isCapturing = false
    
    private val captureScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
    
    // 摄像头数据回调
    private var onFrameCaptured: ((ByteArray) -> Unit)? = null
    
    init {
        initializeCameraList()
    }
    
    /**
     * 设置摄像头数据回调
     */
    fun setOnFrameCaptured(callback: (ByteArray) -> Unit) {
        onFrameCaptured = callback
    }
    
    /**
     * 初始化可用摄像头列表
     */
    private fun initializeCameraList() {
        try {
            availableCameraIds = cameraManager.cameraIdList.toList()
            Log.d(TAG, "发现 ${availableCameraIds.size} 个摄像头: $availableCameraIds")
            
            // 优先选择前置摄像头
            for (i in availableCameraIds.indices) {
                val id = availableCameraIds[i]
                val characteristics = cameraManager.getCameraCharacteristics(id)
                val facing = characteristics.get(CameraCharacteristics.LENS_FACING)
                if (facing == CameraCharacteristics.LENS_FACING_FRONT) {
                    currentCameraIndex = i
                    currentCameraId = id
                    Log.d(TAG, "选择前置摄像头: $id")
                    return
                }
            }
            
            // 如果没有前置摄像头，使用第一个可用摄像头
            if (availableCameraIds.isNotEmpty()) {
                currentCameraIndex = 0
                currentCameraId = availableCameraIds[0]
                Log.d(TAG, "选择默认摄像头: $currentCameraId")
            }
        } catch (e: Exception) {
            Log.e(TAG, "初始化摄像头列表失败", e)
        }
    }
    
    /**
     * 获取当前摄像头ID
     */
    private fun getCurrentCameraId(): String? {
        return currentCameraId
    }
    
    /**
     * 切换到下一个摄像头
     */
    fun switchToNextCamera() {
        if (availableCameraIds.size <= 1) {
            Log.w(TAG, "只有一个或没有可用摄像头，无法切换")
            return
        }
        
        try {
            // 停止当前摄像头
            stopCamera()
            
            // 切换到下一个摄像头
            currentCameraIndex = (currentCameraIndex + 1) % availableCameraIds.size
            currentCameraId = availableCameraIds[currentCameraIndex]
            
            val characteristics = cameraManager.getCameraCharacteristics(currentCameraId!!)
            val facing = characteristics.get(CameraCharacteristics.LENS_FACING)
            val cameraType = when (facing) {
                CameraCharacteristics.LENS_FACING_FRONT -> "前置"
                CameraCharacteristics.LENS_FACING_BACK -> "后置"
                else -> "未知"
            }
            
            Log.d(TAG, "切换到 $cameraType 摄像头: $currentCameraId")
            
            // 重新启动摄像头
            startCamera()
        } catch (e: Exception) {
            Log.e(TAG, "切换摄像头失败", e)
        }
    }
    
    /**
     * 获取当前摄像头信息
     */
    fun getCurrentCameraInfo(): String {
        return try {
            if (currentCameraId == null) {
                "无可用摄像头"
            } else {
                val characteristics = cameraManager.getCameraCharacteristics(currentCameraId!!)
                val facing = characteristics.get(CameraCharacteristics.LENS_FACING)
                val cameraType = when (facing) {
                    CameraCharacteristics.LENS_FACING_FRONT -> "前置"
                    CameraCharacteristics.LENS_FACING_BACK -> "后置"
                    else -> "未知"
                }
                "$cameraType 摄像头 ($currentCameraId)"
            }
        } catch (e: Exception) {
            "获取摄像头信息失败: ${e.message}"
        }
    }
    
    /**
     * 启动摄像头并开始捕获
     */
    fun startCamera() {
        val cameraId = getCurrentCameraId()
        if (cameraId == null) {
            Log.e(TAG, "没有可用的摄像头")
            return
        }
        
        startBackgroundThread()
        
        try {
            if (!cameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
                throw RuntimeException("等待摄像头超时")
            }
            
            cameraManager.openCamera(cameraId, stateCallback, backgroundHandler)
            
            // 启动摄像头后自动开始捕获
            startCapturing()
        } catch (e: SecurityException) {
            Log.e(TAG, "摄像头权限被拒绝", e)
        } catch (e: Exception) {
            Log.e(TAG, "启动摄像头失败", e)
            cameraOpenCloseLock.release()
        }
    }
    
    /**
     * 停止摄像头并停止捕获
     */
    fun stopCamera() {
        // 先停止捕获
        stopCapturing()
        
        try {
            cameraOpenCloseLock.acquire()
            closeCamera()
        } catch (e: InterruptedException) {
            throw RuntimeException("中断异常", e)
        } finally {
            cameraOpenCloseLock.release()
        }
        
        stopBackgroundThread()
    }
    
    /**
     * 开始捕获
     */
    fun startCapturing() {
        isCapturing = true
        Log.i(TAG, "开始摄像头捕获")
    }
    
    /**
     * 停止捕获
     */
    fun stopCapturing() {
        isCapturing = false
        Log.i(TAG, "停止摄像头捕获")
    }
    
    /**
     * 摄像头状态回调
     */
    private val stateCallback = object : CameraDevice.StateCallback() {
        override fun onOpened(camera: CameraDevice) {
            cameraOpenCloseLock.release()
            cameraDevice = camera
            createCameraPreviewSession()
        }
        
        override fun onDisconnected(camera: CameraDevice) {
            cameraOpenCloseLock.release()
            camera.close()
            cameraDevice = null
        }
        
        override fun onError(camera: CameraDevice, error: Int) {
            cameraOpenCloseLock.release()
            camera.close()
            cameraDevice = null
            Log.e(TAG, "摄像头错误: $error")
        }
    }
    
    /**
     * 创建摄像头预览会话
     */
    private fun createCameraPreviewSession() {
        try {
            val cameraDevice = this.cameraDevice ?: return
            
            // 创建ImageReader
            val currentCameraId = getCurrentCameraId()
            if (currentCameraId == null) {
                Log.e(TAG, "当前摄像头ID为null")
                return
            }
            val characteristics = cameraManager.getCameraCharacteristics(currentCameraId)
            val map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
            val largest = map?.getOutputSizes(ImageFormat.JPEG)?.maxByOrNull { it.width * it.height }
            
            val size = if (largest != null) {
                Size(
                    minOf(largest.width, MAX_WIDTH),
                    minOf(largest.height, MAX_HEIGHT)
                )
            } else {
                Size(MAX_WIDTH, MAX_HEIGHT)
            }
            
            imageReader = ImageReader.newInstance(
                size.width, size.height,
                ImageFormat.JPEG, 1
            ).apply {
                setOnImageAvailableListener(imageAvailableListener, backgroundHandler)
            }
            
            val surface = imageReader!!.surface
            
            // 创建捕获请求
            val captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
            captureRequestBuilder.addTarget(surface)
            
            // 创建捕获会话
            cameraDevice.createCaptureSession(
                listOf(surface),
                object : CameraCaptureSession.StateCallback() {
                    override fun onConfigured(session: CameraCaptureSession) {
                        if (cameraDevice == null) return
                        
                        captureSession = session
                        try {
                            val captureRequest = captureRequestBuilder.build()
                            session.setRepeatingRequest(captureRequest, null, backgroundHandler)
                        } catch (e: CameraAccessException) {
                            Log.e(TAG, "创建捕获请求失败", e)
                        }
                    }
                    
                    override fun onConfigureFailed(session: CameraCaptureSession) {
                        Log.e(TAG, "摄像头会话配置失败")
                    }
                },
                backgroundHandler
            )
            
        } catch (e: CameraAccessException) {
            Log.e(TAG, "创建摄像头预览会话失败", e)
        }
    }
    
    /**
     * 图像可用监听器
     */
    private val imageAvailableListener = ImageReader.OnImageAvailableListener { reader ->
        if (!isCapturing) return@OnImageAvailableListener
        
        val image = reader.acquireLatestImage()
        image?.let { processImage(it) }
    }
    
    /**
     * 处理图像数据
     */
    private fun processImage(image: Image) {
        try {
            val buffer = image.planes[0].buffer
            val bytes = ByteArray(buffer.remaining())
            buffer.get(bytes)
            
            // 将JPEG字节数组转换为Bitmap
            val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
            
            // 如果需要旋转图像（前置摄像头通常需要镜像）
            val currentCameraId = getCurrentCameraId()
            val rotatedBitmap = if (currentCameraId != null) {
                val characteristics = cameraManager.getCameraCharacteristics(currentCameraId)
                val facing = characteristics.get(CameraCharacteristics.LENS_FACING)
                if (facing == CameraCharacteristics.LENS_FACING_FRONT) {
                    rotateBitmap(bitmap, 180f) // 前置摄像头镜像
                } else {
                    bitmap
                }
            } else {
                bitmap
            }
            
            // 压缩图像
            val compressedBytes = compressBitmap(rotatedBitmap)
            
            // 通过回调发送数据
            onFrameCaptured?.invoke(compressedBytes)
            
        } catch (e: Exception) {
            Log.e(TAG, "处理图像失败", e)
        } finally {
            image.close()
        }
    }
    
    /**
     * 旋转Bitmap
     */
    private fun rotateBitmap(bitmap: Bitmap, degrees: Float): Bitmap {
        val matrix = Matrix()
        matrix.postRotate(degrees)
        return Bitmap.createBitmap(
            bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true
        )
    }
    
    /**
     * 压缩Bitmap为JPEG字节数组
     */
    private fun compressBitmap(bitmap: Bitmap): ByteArray {
        val outputStream = ByteArrayOutputStream()
        bitmap.compress(Bitmap.CompressFormat.JPEG, IMAGE_QUALITY, outputStream)
        return outputStream.toByteArray()
    }
    
    /**
     * 启动后台线程
     */
    private fun startBackgroundThread() {
        backgroundThread = HandlerThread("CameraBackground").also { it.start() }
        backgroundHandler = Handler(backgroundThread!!.looper)
    }
    
    /**
     * 停止后台线程
     */
    private fun stopBackgroundThread() {
        backgroundThread?.quitSafely()
        try {
            backgroundThread?.join()
            backgroundThread = null
            backgroundHandler = null
        } catch (e: InterruptedException) {
            Log.e(TAG, "停止后台线程失败", e)
        }
    }
    
    /**
     * 关闭摄像头
     */
    private fun closeCamera() {
        captureSession?.close()
        captureSession = null
        
        cameraDevice?.close()
        cameraDevice = null
        
        imageReader?.close()
        imageReader = null
    }
    
    /**
     * 检查是否正在捕获
     */
    fun isCapturing(): Boolean {
        return isCapturing
    }
    
    /**
     * 释放资源
     */
    fun release() {
        stopCamera()
        captureScope.cancel()
    }
}
