package com.example.godeye.utils

import android.content.Context
import android.content.SharedPreferences
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraManager
import android.util.Log
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import java.util.*

/**
 * Расширения для Context
 */
fun Context.getPreferences(): SharedPreferences {
    return getSharedPreferences("godeye_prefs", Context.MODE_PRIVATE)
}

fun Context.generateDeviceId(): String {
    val prefs = getPreferences()
    var deviceId = prefs.getString(Constants.PreferenceKeys.DEVICE_ID, null)
    if (deviceId == null) {
        deviceId = "android_${UUID.randomUUID().toString().take(8)}"
        prefs.edit().putString(Constants.PreferenceKeys.DEVICE_ID, deviceId).apply()
    }
    return deviceId
}

/**
 * Расширения для CameraManager
 */
fun CameraManager.getAvailableCameraTypes(): List<String> {
    val cameras = mutableListOf<String>()
    try {
        for (cameraId in cameraIdList) {
            val characteristics = getCameraCharacteristics(cameraId)
            val facing = characteristics.get(CameraCharacteristics.LENS_FACING)

            when (facing) {
                CameraCharacteristics.LENS_FACING_BACK -> {
                    // Проверяем на широкоугольный и телеобъектив
                    val focalLengths = characteristics.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS)
                    if (focalLengths != null && focalLengths.isNotEmpty()) {
                        val minFocalLength = focalLengths.minOrNull() ?: 0f
                        val maxFocalLength = focalLengths.maxOrNull() ?: 0f

                        when {
                            minFocalLength < 2.8f -> cameras.add(Constants.CameraTypes.WIDE)
                            maxFocalLength > 5.5f -> cameras.add(Constants.CameraTypes.TELEPHOTO)
                            else -> cameras.add(Constants.CameraTypes.BACK)
                        }
                    } else {
                        cameras.add(Constants.CameraTypes.BACK)
                    }
                }
                CameraCharacteristics.LENS_FACING_FRONT -> cameras.add(Constants.CameraTypes.FRONT)
            }
        }
    } catch (e: Exception) {
        Log.e("CameraExtensions", "Error getting cameras", e)
        // Добавляем базовые камеры как fallback
        cameras.add(Constants.CameraTypes.BACK)
        cameras.add(Constants.CameraTypes.FRONT)
    }
    return cameras.distinct()
}

fun CameraManager.getCameraIdForType(cameraType: String): String? {
    return try {
        for (cameraId in cameraIdList) {
            val characteristics = getCameraCharacteristics(cameraId)
            val facing = characteristics.get(CameraCharacteristics.LENS_FACING)

            when (cameraType) {
                Constants.CameraTypes.FRONT -> {
                    if (facing == CameraCharacteristics.LENS_FACING_FRONT) {
                        return cameraId
                    }
                }
                Constants.CameraTypes.BACK,
                Constants.CameraTypes.WIDE,
                Constants.CameraTypes.TELEPHOTO -> {
                    if (facing == CameraCharacteristics.LENS_FACING_BACK) {
                        // Для простоты используем первую найденную заднюю камеру
                        // В реальном проекте здесь была бы более сложная логика
                        return cameraId
                    }
                }
            }
        }
        null
    } catch (e: Exception) {
        Log.e("CameraExtensions", "Error finding camera for type $cameraType", e)
        null
    }
}

/**
 * Compose расширения для Flow
 */
@Composable
fun <T> Flow<T>.collectAsEffect(
    key: Any? = null,
    action: suspend (T) -> Unit
) {
    val lifecycleOwner = LocalLifecycleOwner.current
    LaunchedEffect(key) {
        lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
            collect(action)
        }
    }
}

/**
 * Логирование
 */
object Logger {
    private const val TAG = "GodEye"

    fun d(message: String, tag: String = TAG) {
        Log.d(tag, message)
    }

    fun e(message: String, throwable: Throwable? = null, tag: String = TAG) {
        Log.e(tag, message, throwable)
    }

    fun i(message: String, tag: String = TAG) {
        Log.i(tag, message)
    }

    fun w(message: String, tag: String = TAG) {
        Log.w(tag, message)
    }
}
