package com.rosetta.messenger.ui.chats.components

import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.provider.Settings
import android.util.Log
import android.view.ScaleGestureDetector
import android.view.ViewGroup
import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
import androidx.activity.compose.BackHandler
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.camera.core.Camera
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageCapture
import androidx.camera.core.ImageCaptureException
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.FlipCameraAndroid
import androidx.compose.material.icons.filled.FlashOff
import androidx.compose.material.icons.filled.FlashOn
import androidx.compose.material.icons.filled.FlashAuto
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Remove
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.scale
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.view.WindowCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.io.File
import java.text.SimpleDateFormat
import java.util.*
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
import androidx.compose.ui.platform.LocalView
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.LinearEasing
import androidx.compose.ui.graphics.graphicsLayer
import com.rosetta.messenger.data.PreferencesManager

/**
 * 📷 In-App Camera Screen - как в Telegram
 * Кастомная камера без системного превью, сразу переходит в ImageEditorScreen
 */
@OptIn(androidx.compose.ui.ExperimentalComposeUiApi::class)
@Composable
fun InAppCameraScreen(
    preferencesManager: PreferencesManager,
    onDismiss: () -> Unit,
    onPhotoTaken: (Uri) -> Unit  // Вызывается с URI сделанного фото
) {
    val context = LocalContext.current
    val activity = context as? Activity
    val lifecycleOwner = LocalLifecycleOwner.current
    val scope = rememberCoroutineScope()
    val view = LocalView.current
    val keyboardController = LocalSoftwareKeyboardController.current
    val focusManager = LocalFocusManager.current
    
    // Camera state
    var lensFacing by remember { mutableStateOf(CameraSelector.LENS_FACING_BACK) }
    var flashMode by remember { mutableStateOf(ImageCapture.FLASH_MODE_AUTO) }
    var isCapturing by remember { mutableStateOf(false) }
    var hasCameraPermission by
            remember {
                mutableStateOf(
                        ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) ==
                                PackageManager.PERMISSION_GRANTED
                )
            }
    var hasRequestedCameraPermission by remember { mutableStateOf(false) }
    val cameraPermissionLauncher =
            rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()) {
                    granted ->
                hasRequestedCameraPermission = true
                hasCameraPermission = granted
            }
    val isPermissionPermanentlyDenied =
            remember(hasCameraPermission, hasRequestedCameraPermission, activity) {
                hasRequestedCameraPermission &&
                        !hasCameraPermission &&
                        activity != null &&
                        !ActivityCompat.shouldShowRequestPermissionRationale(
                                activity,
                                Manifest.permission.CAMERA
                        )
            }

    fun requestCameraPermission() {
        cameraPermissionLauncher.launch(Manifest.permission.CAMERA)
    }

    fun openAppSettings() {
        val intent =
                Intent(
                                Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                                Uri.fromParts("package", context.packageName, null)
                        )
                        .apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) }
        runCatching { context.startActivity(intent) }
    }

    LaunchedEffect(preferencesManager) {
        flashMode = preferencesManager.getCameraFlashMode()
    }

    LaunchedEffect(Unit) {
        if (!hasCameraPermission) {
            requestCameraPermission()
        }
    }

    DisposableEffect(lifecycleOwner) {
        val observer = LifecycleEventObserver { _, event ->
            if (event == Lifecycle.Event.ON_RESUME) {
                hasCameraPermission =
                        ContextCompat.checkSelfPermission(
                                context,
                                Manifest.permission.CAMERA
                        ) == PackageManager.PERMISSION_GRANTED
            }
        }
        lifecycleOwner.lifecycle.addObserver(observer)
        onDispose { lifecycleOwner.lifecycle.removeObserver(observer) }
    }
    
    // Camera references
    var imageCapture by remember { mutableStateOf<ImageCapture?>(null) }
    var cameraProvider by remember { mutableStateOf<ProcessCameraProvider?>(null) }
    var camera by remember { mutableStateOf<Camera?>(null) }

    // Zoom state — linear 0..1 progress synced with camera
    var zoomLinearProgress by remember { mutableFloatStateOf(0.5f) }
    
    // ═══════════════════════════════════════════════════════════════
    // 🎬 FADE ANIMATION (как в ImageEditorScreen)
    // ═══════════════════════════════════════════════════════════════
    var isClosing by remember { mutableStateOf(false) }
    val animationProgress = remember { Animatable(0f) }
    
    // Enter animation + hide keyboard
    LaunchedEffect(Unit) {
        val localActivity = context as? Activity
        val localWindow = localActivity?.window
        val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        localWindow?.setSoftInputMode(
            WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN or
                WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING
        )
        repeat(4) {
            imm.hideSoftInputFromWindow(view.windowToken, 0)
            localWindow?.let { win ->
                WindowCompat.getInsetsController(win, view)
                    .hide(androidx.core.view.WindowInsetsCompat.Type.ime())
            }
            view.findFocus()?.clearFocus()
            localActivity?.currentFocus?.clearFocus()
            delay(50)
        }
        keyboardController?.hide()
        focusManager.clearFocus(force = true)
        animationProgress.animateTo(
            targetValue = 1f,
            animationSpec = tween(durationMillis = 200, easing = FastOutSlowInEasing)
        )
    }
    
    // Animated dismiss function
    fun animatedDismiss() {
        if (isClosing) return
        isClosing = true
        scope.launch {
            animationProgress.animateTo(
                targetValue = 0f,
                animationSpec = tween(durationMillis = 150, easing = LinearEasing)
            )
            onDismiss()
        }
    }
    
    // ═══════════════════════════════════════════════════════════════
    // 🎨 Status bar (черный как в ImageEditorScreen)
    // ═══════════════════════════════════════════════════════════════
    val window = activity?.window
    val originalSoftInputMode = remember(window) {
        window?.attributes?.softInputMode ?: WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
    }
    
    val originalStatusBarColor = remember { window?.statusBarColor ?: android.graphics.Color.WHITE }
    val originalNavigationBarColor = remember { window?.navigationBarColor ?: android.graphics.Color.WHITE }
    val insetsController = remember(window, view) { window?.let { WindowCompat.getInsetsController(it, view) } }
    val originalLightStatusBars = remember { insetsController?.isAppearanceLightStatusBars ?: true }
    val originalLightNavigationBars = remember { insetsController?.isAppearanceLightNavigationBars ?: true }
    
    LaunchedEffect(animationProgress.value) {
        if (window == null || insetsController == null) return@LaunchedEffect
        
        val progress = animationProgress.value
        val currentStatusColor = androidx.core.graphics.ColorUtils.blendARGB(
            originalStatusBarColor, android.graphics.Color.TRANSPARENT, progress
        )
        val currentNavColor = androidx.core.graphics.ColorUtils.blendARGB(
            originalNavigationBarColor, android.graphics.Color.BLACK, progress
        )
        
        window.statusBarColor = currentStatusColor
        window.navigationBarColor = currentNavColor
        insetsController.isAppearanceLightStatusBars = progress < 0.5f && originalLightStatusBars
        insetsController.isAppearanceLightNavigationBars = progress < 0.5f && originalLightNavigationBars
    }
    
    DisposableEffect(window) {
        onDispose {
            if (window == null || insetsController == null) return@onDispose
            window.setSoftInputMode(originalSoftInputMode)
            window.statusBarColor = originalStatusBarColor
            insetsController.isAppearanceLightStatusBars = originalLightStatusBars

            window.navigationBarColor = originalNavigationBarColor
            insetsController.isAppearanceLightNavigationBars = originalLightNavigationBars
            insetsController.show(androidx.core.view.WindowInsetsCompat.Type.navigationBars())
        }
    }
    
    BackHandler { animatedDismiss() }
    
    // ═══════════════════════════════════════════════════════════════
    // 📷 CAMERA SETUP
    // ═══════════════════════════════════════════════════════════════
    
    // Shutter button animation
    val shutterScale by animateFloatAsState(
        targetValue = if (isCapturing) 0.85f else 1f,
        animationSpec = tween(100)
    )
    
    // Take photo function
    fun takePhoto() {
        if (!hasCameraPermission) {
            requestCameraPermission()
            return
        }
        val capture = imageCapture ?: return
        if (isCapturing) return
        
        isCapturing = true
        
        // Create output file
        val photoFile = File(
            context.cacheDir,
            "photo_${SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(Date())}.jpg"
        )
        
        val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile).build()
        
        capture.takePicture(
            outputOptions,
            ContextCompat.getMainExecutor(context),
            object : ImageCapture.OnImageSavedCallback {
                override fun onImageSaved(output: ImageCapture.OutputFileResults) {
                    val savedUri = Uri.fromFile(photoFile)
                    // Сразу открываем редактор без промежуточного превью!
                    onPhotoTaken(savedUri)
                }
                
                override fun onError(exc: ImageCaptureException) {
                    isCapturing = false
                }
            }
        )
    }
    
    // ═══════════════════════════════════════════════════════════════
    // 🎨 UI
    // ═══════════════════════════════════════════════════════════════
    
    // PreviewView reference
    var previewView by remember { mutableStateOf<PreviewView?>(null) }
    
    // Bind camera when previewView or lensFacing changes (NOT flashMode — that causes flicker)
    LaunchedEffect(previewView, lensFacing, hasCameraPermission) {
        if (!hasCameraPermission) {
            cameraProvider?.unbindAll()
            cameraProvider = null
            camera = null
            imageCapture = null
            return@LaunchedEffect
        }

        val pv = previewView ?: return@LaunchedEffect

        val provider = context.getCameraProvider()
        cameraProvider = provider

        val preview = Preview.Builder().build().also {
            it.setSurfaceProvider(pv.surfaceProvider)
        }

        val capture = ImageCapture.Builder()
            .setFlashMode(flashMode)
            .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
            .build()
        imageCapture = capture

        val cameraSelector = CameraSelector.Builder()
            .requireLensFacing(lensFacing)
            .build()

        try {
            provider.unbindAll()
            camera = provider.bindToLifecycle(
                lifecycleOwner,
                cameraSelector,
                preview,
                capture
            )
            camera?.cameraControl?.setLinearZoom(zoomLinearProgress)
        } catch (e: Exception) {
        }
    }

    // Apply flash mode directly without rebinding camera (prevents flicker)
    LaunchedEffect(flashMode) {
        imageCapture?.flashMode = flashMode
    }
    
    // Unbind on dispose
    DisposableEffect(Unit) {
        onDispose {
            cameraProvider?.unbindAll()
        }
    }
    
    Box(
        modifier = Modifier
            .fillMaxSize()
            .graphicsLayer { alpha = animationProgress.value }
            .background(Color.Black)
    ) {
        if (hasCameraPermission) {
            // Camera Preview with pinch-to-zoom
            AndroidView(
                factory = { ctx ->
                    PreviewView(ctx).apply {
                        layoutParams = ViewGroup.LayoutParams(
                            ViewGroup.LayoutParams.MATCH_PARENT,
                            ViewGroup.LayoutParams.MATCH_PARENT
                        )
                        scaleType = PreviewView.ScaleType.FILL_CENTER
                        implementationMode = PreviewView.ImplementationMode.COMPATIBLE
                        previewView = this

                        // Pinch-to-zoom via ScaleGestureDetector
                        val scaleGestureDetector = ScaleGestureDetector(ctx,
                            object : ScaleGestureDetector.SimpleOnScaleGestureListener() {
                                override fun onScale(detector: ScaleGestureDetector): Boolean {
                                    val cam = camera ?: return true
                                    val zoomState = cam.cameraInfo.zoomState.value ?: return true
                                    val currentZoom = zoomState.zoomRatio
                                    val newZoom = currentZoom * detector.scaleFactor
                                    cam.cameraControl.setZoomRatio(newZoom)
                                    // Sync slider with pinch: convert ratio to linear 0..1
                                    val minZoom = zoomState.minZoomRatio
                                    val maxZoom = zoomState.maxZoomRatio
                                    val clampedZoom = newZoom.coerceIn(minZoom, maxZoom)
                                    zoomLinearProgress = if (maxZoom > minZoom)
                                        ((clampedZoom - minZoom) / (maxZoom - minZoom)).coerceIn(0f, 1f)
                                    else 0f
                                    return true
                                }
                            }
                        )
                        setOnTouchListener { _, event ->
                            scaleGestureDetector.onTouchEvent(event)
                            true
                        }
                    }
                },
                modifier = Modifier.fillMaxSize()
            )
        } else {
            CameraPermissionContent(
                    permanentlyDenied = isPermissionPermanentlyDenied,
                    onGrantAccess = { requestCameraPermission() },
                    onOpenSettings = { openAppSettings() }
            )
        }
        
        // Top controls (Close + Flash)
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .statusBarsPadding()
                .padding(16.dp),
            horizontalArrangement = Arrangement.SpaceBetween
        ) {
            // Close button
            IconButton(
                onClick = { animatedDismiss() },
                modifier = Modifier
                    .size(44.dp)
                    .background(Color.Black.copy(alpha = 0.3f), CircleShape)
            ) {
                Icon(
                    Icons.Default.Close,
                    contentDescription = "Close",
                    tint = Color.White
                )
            }
            
            // Flash button
            if (hasCameraPermission) {
                IconButton(
                    onClick = {
                        val nextFlashMode = when (flashMode) {
                            ImageCapture.FLASH_MODE_OFF -> ImageCapture.FLASH_MODE_AUTO
                            ImageCapture.FLASH_MODE_AUTO -> ImageCapture.FLASH_MODE_ON
                            else -> ImageCapture.FLASH_MODE_OFF
                        }
                        flashMode = nextFlashMode
                        scope.launch {
                            preferencesManager.setCameraFlashMode(nextFlashMode)
                        }
                    },
                    modifier = Modifier
                        .size(44.dp)
                        .background(Color.Black.copy(alpha = 0.3f), CircleShape)
                ) {
                    Icon(
                        when (flashMode) {
                            ImageCapture.FLASH_MODE_OFF -> Icons.Default.FlashOff
                            ImageCapture.FLASH_MODE_AUTO -> Icons.Default.FlashAuto
                            else -> Icons.Default.FlashOn
                        },
                        contentDescription = "Flash",
                        tint = Color.White
                    )
                }
            } else {
                Spacer(modifier = Modifier.size(44.dp))
            }
        }
        
        // ── Zoom slider with −/+ buttons (Telegram-style) ──
        val zoomState = camera?.cameraInfo?.zoomState?.value
        val currentZoomRatio = zoomState?.zoomRatio ?: 1f
        val minZoomRatio = zoomState?.minZoomRatio ?: 1f
        val maxZoomRatio = zoomState?.maxZoomRatio ?: 1f
        val zoomLabel = "%.1fx".format(currentZoomRatio)

        // Only show slider if camera supports zoom range > 1
        if (hasCameraPermission && maxZoomRatio > minZoomRatio + 0.1f) {
            Column(
                modifier = Modifier
                    .align(Alignment.BottomCenter)
                    .navigationBarsPadding()
                    .padding(bottom = 130.dp),
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                // Zoom ratio label (e.g. "2.3x")
                Text(
                    text = zoomLabel,
                    color = Color.White,
                    fontSize = 13.sp,
                    fontWeight = FontWeight.Medium,
                    textAlign = TextAlign.Center,
                    modifier = Modifier
                        .background(Color.Black.copy(alpha = 0.4f), RoundedCornerShape(10.dp))
                        .padding(horizontal = 8.dp, vertical = 2.dp)
                )

                Spacer(modifier = Modifier.height(6.dp))

                // Slider row: [−] ━━━━━━━━━ [+]
                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(horizontal = 32.dp),
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    // Minus button
                    Box(
                        modifier = Modifier
                            .size(32.dp)
                            .background(Color.Black.copy(alpha = 0.4f), CircleShape)
                            .clip(CircleShape)
                            .clickable(
                                interactionSource = remember { MutableInteractionSource() },
                                indication = null
                            ) {
                                val newProgress = (zoomLinearProgress - 0.1f).coerceIn(0f, 1f)
                                zoomLinearProgress = newProgress
                                camera?.cameraControl?.setLinearZoom(newProgress)
                            },
                        contentAlignment = Alignment.Center
                    ) {
                        Icon(
                            Icons.Default.Remove,
                            contentDescription = "Zoom out",
                            tint = Color.White,
                            modifier = Modifier.size(18.dp)
                        )
                    }

                    // Slider track
                    Slider(
                        value = zoomLinearProgress,
                        onValueChange = { newValue ->
                            zoomLinearProgress = newValue
                            camera?.cameraControl?.setLinearZoom(newValue)
                        },
                        modifier = Modifier
                            .weight(1f)
                            .padding(horizontal = 4.dp),
                        colors = SliderDefaults.colors(
                            thumbColor = Color.White,
                            activeTrackColor = Color.White,
                            inactiveTrackColor = Color.White.copy(alpha = 0.3f)
                        )
                    )

                    // Plus button
                    Box(
                        modifier = Modifier
                            .size(32.dp)
                            .background(Color.Black.copy(alpha = 0.4f), CircleShape)
                            .clip(CircleShape)
                            .clickable(
                                interactionSource = remember { MutableInteractionSource() },
                                indication = null
                            ) {
                                val newProgress = (zoomLinearProgress + 0.1f).coerceIn(0f, 1f)
                                zoomLinearProgress = newProgress
                                camera?.cameraControl?.setLinearZoom(newProgress)
                            },
                        contentAlignment = Alignment.Center
                    ) {
                        Icon(
                            Icons.Default.Add,
                            contentDescription = "Zoom in",
                            tint = Color.White,
                            modifier = Modifier.size(18.dp)
                        )
                    }
                }
            }
        }

        // Bottom controls (Shutter + Flip)
        if (hasCameraPermission) {
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .align(Alignment.BottomCenter)
                    .navigationBarsPadding()
                    .padding(bottom = 32.dp),
                horizontalArrangement = Arrangement.SpaceEvenly,
                verticalAlignment = Alignment.CenterVertically
            ) {
                // Placeholder for symmetry
                Spacer(modifier = Modifier.size(60.dp))

                // Shutter button
                Box(
                    modifier = Modifier
                        .size(80.dp)
                        .scale(shutterScale)
                        .clip(CircleShape)
                        .background(Color.White.copy(alpha = 0.2f))
                        .border(4.dp, Color.White, CircleShape)
                        .clickable(
                            interactionSource = remember { MutableInteractionSource() },
                            indication = null
                        ) { takePhoto() },
                    contentAlignment = Alignment.Center
                ) {
                    Box(
                        modifier = Modifier
                            .size(64.dp)
                            .clip(CircleShape)
                            .background(Color.White)
                    )
                }

                // Flip camera button
                IconButton(
                    onClick = {
                        lensFacing = if (lensFacing == CameraSelector.LENS_FACING_BACK) {
                            CameraSelector.LENS_FACING_FRONT
                        } else {
                            CameraSelector.LENS_FACING_BACK
                        }
                    },
                    modifier = Modifier
                        .size(60.dp)
                        .background(Color.Black.copy(alpha = 0.3f), CircleShape)
                ) {
                    Icon(
                        Icons.Default.FlipCameraAndroid,
                        contentDescription = "Flip camera",
                        tint = Color.White,
                        modifier = Modifier.size(28.dp)
                    )
                }
            }
        }
    }
}

@Composable
private fun CameraPermissionContent(
        permanentlyDenied: Boolean,
        onGrantAccess: () -> Unit,
        onOpenSettings: () -> Unit
) {
    Column(
            modifier = Modifier.fillMaxSize().padding(horizontal = 28.dp),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(
                text = "Camera access is required",
                color = Color.White,
                fontSize = 20.sp,
                fontWeight = FontWeight.SemiBold,
                textAlign = TextAlign.Center
        )
        Spacer(modifier = Modifier.height(10.dp))
        Text(
                text =
                        if (permanentlyDenied)
                                "Permission is denied permanently. Open settings and allow camera access."
                        else "Allow camera permission to use in-app camera.",
                color = Color.White.copy(alpha = 0.78f),
                fontSize = 14.sp,
                textAlign = TextAlign.Center
        )
        Spacer(modifier = Modifier.height(20.dp))
        Button(
                onClick = if (permanentlyDenied) onOpenSettings else onGrantAccess,
                shape = RoundedCornerShape(24.dp)
        ) {
            Text(if (permanentlyDenied) "Open settings" else "Grant access")
        }
    }
}

/**
 * Получить CameraProvider с suspend
 */
private suspend fun Context.getCameraProvider(): ProcessCameraProvider {
    return suspendCoroutine { continuation ->
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
        cameraProviderFuture.addListener({
            continuation.resume(cameraProviderFuture.get())
        }, ContextCompat.getMainExecutor(this))
    }
}
