package com.example.livingai.camera

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Matrix
import android.util.Log
import android.util.Size
import android.widget.Toast
import androidx.camera.core.AspectRatio
import androidx.camera.core.ImageAnalysis
import androidx.camera.core.ImageCapture
import androidx.camera.core.ImageCaptureException
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.core.content.ContextCompat
import androidx.lifecycle.LifecycleOwner
import com.example.livingai.R
import com.example.livingai.analysis.Analyzer
import com.example.livingai.storage.StorageUtils
import java.io.File
import java.io.FileOutputStream
import java.util.concurrent.Executors
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min

/**
 * Responsible only for fetching camera frames and capturing images.
 */
class CameraProcessor(
    private val context: Context,
    private val previewView: PreviewView,
    private val analysisListener: Analyzer.AnalysisListener
) {

    private var imageCapture: ImageCapture? = null
    private val cameraExecutor = Executors.newSingleThreadExecutor()
    var analysisSize: Size? = null
        private set

    fun startCamera(onAnalysisSizeReady: (Int, Int) -> Unit = { _, _ -> }) {
        val providerFuture = ProcessCameraProvider.getInstance(context)

        providerFuture.addListener({
            val cameraProvider = providerFuture.get()

            val preview = androidx.camera.core.Preview.Builder().build()
            preview.surfaceProvider = previewView.surfaceProvider

            imageCapture = ImageCapture.Builder()
                .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
                .build()
            
            val metrics = context.resources.displayMetrics
            val screenAspectRatio = aspectRatio(metrics.widthPixels, metrics.heightPixels)

            val analyzer = ImageAnalysis.Builder()
                .setTargetAspectRatio(screenAspectRatio)
                .setBackpressureStrategy(
                    ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST
                )
                .build()
                .also {
                    it.setAnalyzer(cameraExecutor, Analyzer(analysisListener))
                }

            cameraProvider.unbindAll()
            
            if (context is LifecycleOwner) {
                cameraProvider.bindToLifecycle(
                    context,
                    androidx.camera.core.CameraSelector.DEFAULT_BACK_CAMERA,
                    preview,
                    imageCapture,
                    analyzer
                )
                
                // Get analysis resolution
                analyzer.resolutionInfo?.resolution?.let { size ->
                    analysisSize = size
                    onAnalysisSizeReady(size.width, size.height)
                } ?: run {
                     // Fallback: if resolution info is not available immediately
                }
            }

        }, ContextCompat.getMainExecutor(context))
    }
    
    private fun aspectRatio(width: Int, height: Int): Int {
        val previewRatio = max(width, height).toDouble() / min(width, height)
        if (abs(previewRatio - 4.0 / 3.0) <= abs(previewRatio - 16.0 / 9.0)) {
            return AspectRatio.RATIO_4_3
        }
        return AspectRatio.RATIO_16_9
    }

    fun takePhoto(cowName: String?, orientation: String?, silhouetteId: Int, retakePath: String? = null) {
        val imageCapture = imageCapture ?: return

        val name = cowName ?: "unknown"
        val side = orientation ?: "unknown"

        // Find current count for this cow and orientation
        val cowFolder = StorageUtils.getCowImageFolder(name)
        
        val existingFiles = cowFolder.listFiles { _, fname ->
            fname.startsWith("${name}_${side}_") && fname.endsWith(".jpg")
        }
        val count = (existingFiles?.size ?: 0) + 1

        if (!cowFolder.exists()) {
            cowFolder.mkdirs()
        }

        val filename = "${name}_${side}_${count}.jpg"
        val file = File(cowFolder, filename)

        val outputOptions = ImageCapture.OutputFileOptions.Builder(file).build()

        imageCapture.takePicture(
            outputOptions,
            ContextCompat.getMainExecutor(context),
            object : ImageCapture.OnImageSavedCallback {
                override fun onError(exc: ImageCaptureException) {
                    Log.e("CameraProcessor", "Photo capture failed: ${exc.message}", exc)
                    Toast.makeText(context, context.getString(R.string.toast_capture_failed), Toast.LENGTH_SHORT).show()
                }

                override fun onImageSaved(output: ImageCapture.OutputFileResults) {
                    try {
                        val bitmap = BitmapFactory.decodeFile(file.absolutePath)
                        val matrix = Matrix()

                        val rotation = if (orientation == "front" || orientation == "back") 90f else 0f

                        if (rotation != 0f) {
                            matrix.postRotate(rotation)
                            val rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
                            FileOutputStream(file).use { out ->
                                rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out)
                            }
                        }
                        
                        if (!retakePath.isNullOrEmpty()) {
                            val oldFile = File(retakePath)
                            if (oldFile.exists()) {
                                oldFile.delete()
                            }
                        }

                        val msg = "${context.getString(R.string.toast_saved_as)} $filename"
                        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show()
                        
                        // Navigate to FullScreenImageActivity
                        val intent = android.content.Intent(context, com.example.livingai.ui.page.FullScreenImageActivity::class.java)
                        intent.putExtra("IMAGE_PATH", file.absolutePath)
                        intent.putExtra("ALLOW_RETAKE", true)
                        intent.putExtra("COW_NAME", cowName)
                        intent.putExtra("ORIENTATION", orientation)
                        intent.putExtra("SILHOUETTE_ID", silhouetteId)
                        context.startActivity(intent)
                        
                        if (context is android.app.Activity) {
                            context.finish()
                        }

                    } catch (e: Exception) {
                        Log.e("CameraProcessor", "Error saving image", e)
                        Toast.makeText(context, context.getString(R.string.toast_error_saving_image), Toast.LENGTH_SHORT).show()
                    }
                }
            }
        )
    }
}
