package com.example.godeye.managers

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.SurfaceTexture
import android.hardware.camera2.*
import android.media.MediaRecorder
import android.os.Handler
import android.os.HandlerThread
import android.util.Size
import android.view.Surface
import com.example.godeye.models.AppError
import com.example.godeye.utils.Constants
import com.example.godeye.utils.Logger
import com.example.godeye.utils.getCameraIdForType
import com.example.godeye.utils.getAvailableCameraTypes
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow

/**
 * Менеджер для управления камерами устройства
 */
class CameraManager(private val context: Context) {

    private val cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as android.hardware.camera2.CameraManager
    private var currentCameraId: String? = null
    private var captureSession: CameraCaptureSession? = null
    private var cameraDevice: CameraDevice? = null
    private var backgroundThread: HandlerThread? = null
    private var backgroundHandler: Handler? = null

    private val _isRecording = MutableStateFlow(false)
    val isRecording: StateFlow<Boolean> = _isRecording.asStateFlow()

    private val _currentCameraType = MutableStateFlow<String?>(null)
    val currentCameraType: StateFlow<String?> = _currentCameraType.asStateFlow()

    private val _error = MutableStateFlow<AppError?>(null)
    val error: StateFlow<AppError?> = _error.asStateFlow()

    /**
     * Инициализация фонового потока для камеры
     */
    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) {
            Logger.e("Error stopping background thread", e)
        }
    }

    /**
     * Получить список доступных типов камер
     */
    fun getAvailableCameraTypes(): List<String> {
        return cameraManager.getAvailableCameraTypes()
    }

    /**
     * Открыть камеру указанного типа
     */
    @SuppressLint("MissingPermission")
    fun openCamera(cameraType: String, surface: Surface, onSuccess: () -> Unit = {}, onError: (AppError) -> Unit = {}) {
        try {
            val cameraId = cameraManager.getCameraIdForType(cameraType)
            if (cameraId == null) {
                val error = AppError.CameraError("Camera type $cameraType not available")
                _error.value = error
                onError(error)
                return
            }

            startBackgroundThread()

            cameraManager.openCamera(cameraId, object : CameraDevice.StateCallback() {
                override fun onOpened(camera: CameraDevice) {
                    Logger.d("Camera opened: $cameraId")
                    cameraDevice = camera
                    currentCameraId = cameraId
                    _currentCameraType.value = cameraType
                    createCameraPreviewSession(surface, onSuccess, onError)
                }

                override fun onDisconnected(camera: CameraDevice) {
                    Logger.d("Camera disconnected: $cameraId")
                    camera.close()
                    cameraDevice = null
                    currentCameraId = null
                    _currentCameraType.value = null
                }

                override fun onError(camera: CameraDevice, error: Int) {
                    Logger.e("Camera error: $error")
                    camera.close()
                    cameraDevice = null
                    currentCameraId = null
                    _currentCameraType.value = null
                    val appError = AppError.CameraError("Camera error: $error")
                    _error.value = appError
                    onError(appError)
                }
            }, backgroundHandler)

        } catch (e: Exception) {
            Logger.e("Error opening camera", e)
            val error = AppError.CameraError("Failed to open camera: ${e.message}")
            _error.value = error
            onError(error)
        }
    }

    /**
     * Создать сессию предварительного просмотра камеры
     */
    private fun createCameraPreviewSession(surface: Surface, onSuccess: () -> Unit, onError: (AppError) -> Unit) {
        try {
            val cameraDevice = this.cameraDevice ?: run {
                val error = AppError.CameraError("Camera device is null")
                _error.value = error
                onError(error)
                return
            }

            val captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
            captureRequestBuilder.addTarget(surface)

            // Используем совместимый подход для всех версий Android
            @Suppress("DEPRECATION")
            cameraDevice.createCaptureSession(
                listOf(surface),
                object : CameraCaptureSession.StateCallback() {
                    override fun onConfigured(session: CameraCaptureSession) {
                        captureSession = session
                        try {
                            captureRequestBuilder.set(
                                CaptureRequest.CONTROL_AF_MODE,
                                CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE
                            )

                            val captureRequest = captureRequestBuilder.build()
                            session.setRepeatingRequest(captureRequest, null, backgroundHandler)
                            _isRecording.value = true
                            Logger.d("Camera preview session created successfully")
                            onSuccess()
                        } catch (e: Exception) {
                            Logger.e("Error starting camera preview", e)
                            val error = AppError.CameraError("Failed to start preview: ${e.message}")
                            _error.value = error
                            onError(error)
                        }
                    }

                    override fun onConfigureFailed(session: CameraCaptureSession) {
                        Logger.e("Camera capture session configuration failed")
                        val error = AppError.CameraError("Failed to configure capture session")
                        _error.value = error
                        onError(error)
                    }
                },
                backgroundHandler
            )
        } catch (e: Exception) {
            Logger.e("Error creating camera preview session", e)
            val error = AppError.CameraError("Failed to create preview session: ${e.message}")
            _error.value = error
            onError(error)
        }
    }

    /**
     * Переключить на другой тип камеры
     */
    fun switchCamera(newCameraType: String, surface: Surface, onSuccess: () -> Unit = {}, onError: (AppError) -> Unit = {}) {
        Logger.d("Switching camera from ${_currentCameraType.value} to $newCameraType")
        closeCamera()
        openCamera(newCameraType, surface, onSuccess, onError)
    }

    /**
     * Получить оптимальный размер для предварительного просмотра
     */
    fun getOptimalPreviewSize(cameraType: String): Size? {
        return try {
            val cameraId = cameraManager.getCameraIdForType(cameraType) ?: return null
            val characteristics = cameraManager.getCameraCharacteristics(cameraId)
            val map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
            val outputSizes = map?.getOutputSizes(SurfaceTexture::class.java)

            // Выбираем размер близкий к 1080p, но не превышающий его
            outputSizes?.find { it.width <= 1920 && it.height <= 1080 }
                ?: outputSizes?.minByOrNull { it.width * it.height }
        } catch (e: Exception) {
            Logger.e("Error getting optimal preview size", e)
            null
        }
    }

    /**
     * Закрыть текущую камеру
     */
    fun closeCamera() {
        try {
            captureSession?.close()
            captureSession = null

            cameraDevice?.close()
            cameraDevice = null

            currentCameraId = null
            _currentCameraType.value = null
            _isRecording.value = false

            stopBackgroundThread()
            Logger.d("Camera closed successfully")
        } catch (e: Exception) {
            Logger.e("Error closing camera", e)
        }
    }

    /**
     * Проверить, открыта ли камера
     */
    fun isCameraOpen(): Boolean {
        return cameraDevice != null
    }

    /**
     * Очистить ошибку
     */
    fun clearError() {
        _error.value = null
    }
}
