import { findComponentsByKeyValue } from "./helpers"

export const cameraXML = () => {
    return `
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <androidx.camera.view.PreviewView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/cameraPreview"/>

    <ImageButton
        android:layout_width="60sp"
        android:layout_height="60sp"
        android:layout_centerHorizontal="true"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="40sp"
        android:id="@+id/capture"
        android:src="@android:drawable/ic_menu_camera"
        android:scaleType="centerCrop"
        android:background="?attr/selectableItemBackgroundBorderless"
        app:tint="#fff" />

    <ImageButton
        android:layout_width="40sp"
        android:layout_height="40sp"
        android:layout_alignParentEnd="true"
        android:layout_margin="10sp"
        android:src="@android:drawable/star_big_on"
        app:tint="#fff"
        android:id="@+id/toggleFlash"
        android:background="?attr/selectableItemBackgroundBorderless"/>

    <ImageButton
        android:layout_width="40sp"
        android:layout_height="40sp"
        android:layout_below="@id/toggleFlash"
        android:layout_marginEnd="10sp"
        android:layout_alignParentEnd="true"
        android:id="@+id/flipCamera"
        android:src="@android:drawable/ic_menu_rotate"
        android:background="?attr/selectableItemBackgroundBorderless"
        app:tint="#fff" />


</RelativeLayout>
    `
}


export const cameraFragmentFunctions = (fragment) => {
    if (findComponentsByKeyValue(fragment, "name", "CameraView").length == 0) return "";

    return `
    private val activityResultLauncher =
        registerForActivityResult(ActivityResultContracts.RequestPermission()) { result ->
            if (result) {
                startCamera(cameraFacing)
            }
        }

    private fun startCamera(cameraFacing: Int) {
        val aspectRatio = aspectRatio(previewView.width, previewView.height)
        val cameraProviderFuture: ListenableFuture<ProcessCameraProvider> =
            ProcessCameraProvider.getInstance(requireContext())

        cameraProviderFuture.addListener({
            try {
                val cameraProvider = cameraProviderFuture.get()
                val preview = Preview.Builder()
                    .setTargetAspectRatio(aspectRatio)
                    .build()

                val imageCapture = ImageCapture.Builder()
                    .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
                    .setTargetRotation(requireActivity().windowManager.defaultDisplay.rotation)
                    .build()

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

                cameraProvider.unbindAll()

                val camera = cameraProvider.bindToLifecycle(
                    this,
                    cameraSelector,
                    preview,
                    imageCapture
                )

                capture.setOnClickListener {
                    takePicture(imageCapture)
                }

                toggleFlash.setOnClickListener {
                    setFlashIcon(camera)
                }

                preview.setSurfaceProvider(previewView.surfaceProvider)
            } catch (e: ExecutionException) {
                e.printStackTrace()
            } catch (e: InterruptedException) {
                e.printStackTrace()
            }
        }, ContextCompat.getMainExecutor(requireContext()))
    }

    private fun takePicture(imageCapture: ImageCapture) {
        println("Capturing")
        val file = File(requireContext().getExternalFilesDir(null), "\${System.currentTimeMillis()}.jpg")
        val outputFileOptions = ImageCapture.OutputFileOptions.Builder(file).build()

        imageCapture.takePicture(
            outputFileOptions,
            Executors.newCachedThreadPool(),
            object : ImageCapture.OnImageSavedCallback {
                override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
                    println("saved image")
                    requireActivity().runOnUiThread {
                        Toast.makeText(
                            requireContext(),
                            "Image saved at: \${file.path}",
                            Toast.LENGTH_SHORT
                        ).show()
                    }
                    startCamera(cameraFacing)
                }

                override fun onError(exception: ImageCaptureException) {
                    println("could not capture")
                    requireActivity().runOnUiThread {
                        Toast.makeText(
                            requireContext(),
                            "Failed to save: \${exception.message}",
                            Toast.LENGTH_SHORT
                        ).show()
                    }
                    startCamera(cameraFacing)
                }
            })
    }

    private fun setFlashIcon(camera: Camera) {
        if (camera.cameraInfo.hasFlashUnit()) {
            val torchState = camera.cameraInfo.torchState.value
            if (torchState == 0) {
                camera.cameraControl.enableTorch(true)
                toggleFlash.setImageResource(android.R.drawable.star_big_off)
            } else {
                camera.cameraControl.enableTorch(false)
                toggleFlash.setImageResource(android.R.drawable.star_big_on)
            }
        } else {
            requireActivity().runOnUiThread {
                Toast.makeText(
                    requireContext(),
                    "Flash is not available currently",
                    Toast.LENGTH_SHORT
                ).show()
            }
        }
    }

    private fun aspectRatio(width: Int, height: Int): Int {
        val previewRatio = maxOf(width, height).toDouble() / minOf(width, height).toDouble()
        return if (Math.abs(previewRatio - 4.0 / 3.0) <= Math.abs(previewRatio - 16.0 / 9.0)) {
            AspectRatio.RATIO_4_3
        } else {
            AspectRatio.RATIO_16_9
        }
    }
    `
}


export const generateCameraViewImports = (fragment) => {
    if (findComponentsByKeyValue(fragment, "name", "CameraView").length == 0) return "";

    return `
    import android.Manifest
import android.content.pm.PackageManager
import android.widget.ImageButton
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.camera.core.*
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.core.content.ContextCompat
import com.google.common.util.concurrent.ListenableFuture
import java.io.File
import java.util.concurrent.ExecutionException
import java.util.concurrent.Executors
    `

}

export const getCameraFragmentFields = (fragment) => {
    if (findComponentsByKeyValue(fragment, "name", "CameraView").length == 0) return "";

    return `
    private lateinit var capture: ImageButton
    private lateinit var toggleFlash: ImageButton
    private lateinit var flipCamera: ImageButton
    private lateinit var previewView: PreviewView
    private var cameraFacing = CameraSelector.LENS_FACING_BACK
    `
}

export const generateCameraViewInteractions = (fragment) => {
    if (findComponentsByKeyValue(fragment, "name", "CameraView").length == 0) return "";
    
    return `
    previewView = view.findViewById(R.id.cameraPreview)
    capture = view.findViewById(R.id.capture)
    toggleFlash = view.findViewById(R.id.toggleFlash)
    flipCamera = view.findViewById(R.id.flipCamera)

    if (ContextCompat.checkSelfPermission(
            requireContext(),
            Manifest.permission.CAMERA
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        activityResultLauncher.launch(Manifest.permission.CAMERA)
    } else {
        startCamera(cameraFacing)
    }

    flipCamera.setOnClickListener {
        cameraFacing =
            if (cameraFacing == CameraSelector.LENS_FACING_BACK) CameraSelector.LENS_FACING_FRONT else CameraSelector.LENS_FACING_BACK
        startCamera(cameraFacing)
    }
    `
}