package com.seatel.mobilehall.ui.yes_member.activity

import android.Manifest
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.PorterDuff
import android.graphics.PorterDuffXfermode
import android.graphics.drawable.BitmapDrawable
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.annotation.OptIn
import androidx.camera.core.CameraSelector
import androidx.camera.core.ExperimentalGetImage
import androidx.camera.core.ImageAnalysis
import androidx.camera.core.ImageProxy
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.android.volley.VolleyError
import com.google.mlkit.vision.barcode.BarcodeScanner
import com.google.mlkit.vision.barcode.BarcodeScanning
import com.google.mlkit.vision.common.InputImage
import com.seatel.mobilehall.data.network.SeatelSuperRequest
import com.seatel.mobilehall.databinding.ActivityOutletScanQrBinding
import com.seatel.mobilehall.ui.base.activity.BaseActivity
import com.seatel.mobilehall.ui.yes_member.interactor.RedeemCodeInteractor
import com.seatel.mobilehall.ui.yes_member.presenter.RedeemCodePresenter
import com.seatel.mobilehall.util.dialogannouncement.RedeemCustomDialog
import org.json.JSONObject
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

class OutLetScanQrActivity : BaseActivity<ActivityOutletScanQrBinding>(),
    RedeemCodeInteractor.View {

    private lateinit var cameraExecutor: ExecutorService
    private var isScanned = false

    companion object {
        fun launch(context: Context) {
            val intent = Intent(context, OutLetScanQrActivity::class.java)
            context.startActivity(intent)
        }
    }

    override fun getViewBinding(): ActivityOutletScanQrBinding {
        return ActivityOutletScanQrBinding.inflate(layoutInflater)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        super.activityEnterRightAnimation()
        binding.overlay.post {
            createTransparentHole()
        }
        binding.ivBack.setOnClickListener {
            onBackPressed()
        }

        binding.btnTypeOutletCode.setOnClickListener {
            RedeemActivity.launch(this)
        }

        cameraExecutor = Executors.newSingleThreadExecutor()
        requestCameraPermission()
    }

    private fun startCamera() {
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)

        cameraProviderFuture.addListener({
            val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

            // Preview
            val preview = Preview.Builder().build().also {
                it.setSurfaceProvider(binding.scanQr.surfaceProvider)
            }

            // Barcode Scanner
            val barcodeScanner = BarcodeScanning.getClient()

            // Image Analysis for QR/Barcode
            val imageAnalysis = ImageAnalysis.Builder()
                .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST).build().also {
                    it.setAnalyzer(cameraExecutor) { imageProxy ->
                        scanBarcode(imageProxy, barcodeScanner)
                    }
                }

            val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

            try {
                cameraProvider.unbindAll()
                cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageAnalysis)
            } catch (e: Exception) {
                Log.e("CameraX", "Use case binding failed", e)
            }
        }, ContextCompat.getMainExecutor(this))
    }


    @OptIn(ExperimentalGetImage::class)
    private fun scanBarcode(imageProxy: ImageProxy, scanner: BarcodeScanner) {
        if (isScanned) {
            imageProxy.close()
            return
        }

        val mediaImage = imageProxy.image ?: return
        val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)

        scanner.process(image)
            .addOnSuccessListener { barcodes ->
                for (barcode in barcodes) {
                    val scannedData = barcode.displayValue
                    Log.d("QR", "Scanned: $scannedData")

                    if (!scannedData.isNullOrEmpty()) {
                        isScanned = true
                        runOnUiThread {
                            RedeemCodePresenter(this, this).onRedeemCode(
                                "qrcode",
                                scannedData,
                                getPhoneLogin()
                            )
                        }
                    }
                }
            }
            .addOnFailureListener { e ->
                Log.e("QR", "Barcode scanning failed: ${e.message}")
            }
            .addOnCompleteListener {
                imageProxy.close()
            }
    }

    private fun requestCameraPermission() {
        if (ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.CAMERA
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), 100)
        } else {
            startCamera() // Start camera if permission is granted
        }
    }


    override fun onRequestPermissionsResult(
        requestCode: Int, permissions: Array<out String>, grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == 100 && grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            startCamera()
        } else {
            Toast.makeText(this, "Camera permission denied", Toast.LENGTH_SHORT).show()
        }
    }

    private fun createTransparentHole() {
        val overlay = binding.overlay
        val frame = binding.frameOverlay

        overlay.post {
            val overlayWidth = overlay.width
            val overlayHeight = overlay.height

            val frameWidth = frame.width
            val frameHeight = frame.height

            val x = (overlayWidth - frameWidth) / 2f
            val y = (overlayHeight - frameHeight) / 2f
            val cornerRadius = 40f  // Adjust for more or less rounding

            val bitmap = Bitmap.createBitmap(overlayWidth, overlayHeight, Bitmap.Config.ARGB_8888)
            val canvas = Canvas(bitmap)

            // 🎨 Pink semi-transparent overlay
            val backgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
                color = Color.parseColor("#80000000") // Soft pink with transparency
            }
            canvas.drawRect(
                0f,
                0f,
                overlayWidth.toFloat(),
                overlayHeight.toFloat(),
                backgroundPaint
            )

            // ✂️ Cut out the transparent hole with rounded corners
            val clearPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
                xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
            }
            canvas.drawRoundRect(
                x,
                y,
                x + frameWidth,
                y + frameHeight,
                cornerRadius,
                cornerRadius,
                clearPaint
            )

            // Set the overlay background
            overlay.background = BitmapDrawable(resources, bitmap)
        }
    }


    override fun onDestroy() {
        super.onDestroy()
        cameraExecutor.shutdown()
        ProcessCameraProvider.getInstance(this).get().unbindAll()
    }

    override fun isDisplayToolbar(): Boolean {
        return false
    }

    override fun onBackPressed() {
        super.onBackPressed()
        super.activityExitLeftAnimation()
    }

    override fun onRedeemCodeSuccess(jsonObject: JSONObject) {

        val status = jsonObject.optString("status")
        val message = jsonObject.optString("message")
        val description = jsonObject.optString("description")

        SuccessRedeemActivity.launch(this, message, description)

    }

    override fun onRedeemCodeFailure(errorMessage: VolleyError) {

        errorMessage.networkResponse.statusCode
        val mErrorMessage = String(errorMessage.networkResponse.data)
        val jsonObject = JSONObject(mErrorMessage)
        val message = jsonObject.optString("message")
        val statusCode = jsonObject.optInt("statusCode")
        RedeemCustomDialog(this, message, statusCode.toString(), "Done").setPositiveButton(
            "Done"
        ) { dialog, which ->
            dialog.dismiss()
        }.show()
        //  SeatelAlertDialog.with(this, SeatelSuperRequest.getErrorMessageFrom(errorMessage)).show()
    }
}