/*
 *   Copyright (c) 2020 Project CHIP Authors
 *   All rights reserved.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 *
 */

package com.google.chip.chiptool.setuppayloadscanner

import android.Manifest
import android.annotation.SuppressLint
import android.content.pm.PackageManager
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.DisplayMetrics
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.camera.core.*
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.content.ContextCompat
import androidx.core.content.ContextCompat.checkSelfPermission
import androidx.fragment.app.Fragment
import chip.setuppayload.SetupPayload
import chip.setuppayload.SetupPayloadParser
import chip.setuppayload.SetupPayloadParser.SetupPayloadException
import chip.setuppayload.SetupPayloadParser.InvalidEntryCodeFormatException
import chip.setuppayload.SetupPayloadParser.UnrecognizedQrCodeException
import com.google.chip.chiptool.R
import com.google.chip.chiptool.SelectActionFragment
import com.google.chip.chiptool.databinding.BarcodeFragmentBinding
import com.google.chip.chiptool.util.FragmentUtil
import com.google.mlkit.vision.barcode.BarcodeScanner
import com.google.mlkit.vision.barcode.BarcodeScanning
import com.google.mlkit.vision.barcode.common.Barcode
import com.google.mlkit.vision.common.InputImage
import java.util.concurrent.Executors
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min

/** Launches the camera to scan for QR code. */
class BarcodeFragment : Fragment() {
    private var _binding: BarcodeFragmentBinding? = null
    private val binding get() = _binding!!

    private fun aspectRatio(width: Int, height: Int): Int {
        val previewRatio = max(width, height).toDouble() / min(width, height)
        if (abs(previewRatio - RATIO_4_3_VALUE) <= abs(previewRatio - RATIO_16_9_VALUE)) {
            return AspectRatio.RATIO_4_3
        }
        return AspectRatio.RATIO_16_9
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (!hasCameraPermission()) {
            requestCameraPermission()
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = BarcodeFragmentBinding.inflate(inflater, container, false)

        startCamera()
        binding.inputAddressBtn.setOnClickListener {
            FragmentUtil.getHost(
                this@BarcodeFragment,
                SelectActionFragment.Callback::class.java
            )?.onShowDeviceAddressInput()
        }

        return binding.root
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }

    @SuppressLint("UnsafeOptInUsageError")
    private fun startCamera() {
        val cameraProviderFuture = ProcessCameraProvider.getInstance(requireActivity())
        cameraProviderFuture.addListener({
            val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
            val metrics = DisplayMetrics().also { binding.cameraView.display?.getRealMetrics(it) }
            val screenAspectRatio = aspectRatio(metrics.widthPixels, metrics.heightPixels)
            // Preview
            val preview: Preview = Preview.Builder()
                .setTargetAspectRatio(screenAspectRatio)
                .setTargetRotation(binding.cameraView.display.rotation)
                .build()
            preview.setSurfaceProvider(binding.cameraView.surfaceProvider)

            // Setup barcode scanner
            val imageAnalysis = ImageAnalysis.Builder()
                .setTargetAspectRatio(screenAspectRatio)
                .setTargetRotation(binding.cameraView.display.rotation)
                .build()
            val cameraExecutor = Executors.newSingleThreadExecutor()
            val barcodeScanner: BarcodeScanner = BarcodeScanning.getClient()
            imageAnalysis.setAnalyzer(cameraExecutor) { imageProxy ->
                processImageProxy(barcodeScanner, imageProxy)
            }
            // Select back camera as a default
            val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
            try {
                // Unbind use cases before rebinding
                cameraProvider.unbindAll()

                // Bind use cases to camera
                cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageAnalysis)

            } catch (exc: Exception) {
                Log.e(TAG, "Use case binding failed", exc)
            }
        }, ContextCompat.getMainExecutor(requireActivity()))

        //workaround: can not use gms to scan the code in China, added a EditText to debug
        binding.manualCodeBtn.setOnClickListener {
            val qrCode = binding.manualCodeEditText.text.toString()
            Log.d(TAG, "Submit Code:$qrCode")
            handleInputQrCode(qrCode)
        }
    }

    @ExperimentalGetImage
    private fun processImageProxy(
        barcodeScanner: BarcodeScanner,
        imageProxy: ImageProxy
    ) {
        val inputImage =
            InputImage.fromMediaImage(imageProxy.image!!, imageProxy.imageInfo.rotationDegrees)

        barcodeScanner.process(inputImage)
            .addOnSuccessListener { barcodes ->
                barcodes.forEach {
                    handleScannedQrCode(it)
                }
            }
            .addOnFailureListener {
                Log.e(TAG, it.message ?: it.toString())
            }.addOnCompleteListener {
                // When the image is from CameraX analysis use case, must call image.close() on received
                // images when finished using them. Otherwise, new images may not be received or the camera
                // may stall.
                imageProxy.close()
            }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray
    ) {
        if (requestCode == REQUEST_CODE_CAMERA_PERMISSION) {
            if (grantResults.size == 1 && grantResults[0] == PackageManager.PERMISSION_DENIED) {
                showCameraPermissionAlert()
            }
        } else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        }
    }

    private fun handleInputQrCode(qrCode: String) {
        lateinit var payload: SetupPayload
        var isShortDiscriminator = false
        try {
            payload = SetupPayloadParser().parseQrCode(qrCode)
        } catch (ex: SetupPayloadException) {
            try {
                payload = SetupPayloadParser().parseManualEntryCode(qrCode)
                isShortDiscriminator = true
            } catch (ex: Exception) {
                Log.e(TAG, "Unrecognized Manual Pairing Code", ex)
                Toast.makeText(requireContext(), "Unrecognized Manual Pairing Code", Toast.LENGTH_SHORT).show()
            }
        } catch (ex: UnrecognizedQrCodeException) {
            Log.e(TAG, "Unrecognized QR Code", ex)
            Toast.makeText(requireContext(), "Unrecognized QR Code", Toast.LENGTH_SHORT).show()
        }
        FragmentUtil.getHost(this@BarcodeFragment, Callback::class.java)
            ?.onCHIPDeviceInfoReceived(CHIPDeviceInfo.fromSetupPayload(payload, isShortDiscriminator))
    }

    private fun handleScannedQrCode(barcode: Barcode) {
        Handler(Looper.getMainLooper()).post {
            lateinit var payload: SetupPayload
            try {
                payload = SetupPayloadParser().parseQrCode(barcode.displayValue)
            } catch (ex: UnrecognizedQrCodeException) {
                Log.e(TAG, "Unrecognized QR Code", ex)
                Toast.makeText(requireContext(), "Unrecognized QR Code", Toast.LENGTH_SHORT).show()
                return@post
            }
            FragmentUtil.getHost(this@BarcodeFragment, Callback::class.java)
                ?.onCHIPDeviceInfoReceived(CHIPDeviceInfo.fromSetupPayload(payload))
        }
    }

    private fun showCameraPermissionAlert() {
        AlertDialog.Builder(requireContext())
            .setTitle(R.string.camera_permission_missing_alert_title)
            .setMessage(R.string.camera_permission_missing_alert_subtitle)
            .setPositiveButton(R.string.camera_permission_missing_alert_try_again) { _, _ ->
                requestCameraPermission()
            }
            .setCancelable(false)
            .create()
            .show()
    }

    private fun showCameraUnavailableAlert() {
        AlertDialog.Builder(requireContext())
            .setTitle(R.string.camera_unavailable_alert_title)
            .setMessage(R.string.camera_unavailable_alert_subtitle)
            .setPositiveButton(R.string.camera_unavailable_alert_exit) { _, _ ->
                requireActivity().finish()
            }
            .setCancelable(false)
            .create()
            .show()
    }

    private fun hasCameraPermission(): Boolean {
        return (PackageManager.PERMISSION_GRANTED
                == checkSelfPermission(requireContext(), Manifest.permission.CAMERA))
    }

    private fun requestCameraPermission() {
        val permissions = arrayOf(Manifest.permission.CAMERA)
        requestPermissions(permissions, REQUEST_CODE_CAMERA_PERMISSION)
    }

    /** Interface for notifying the host. */
    interface Callback {
        /** Notifies host of the [CHIPDeviceInfo] from the scanned QR code. */
        fun onCHIPDeviceInfoReceived(deviceInfo: CHIPDeviceInfo)
    }

    companion object {
        private const val TAG = "BarcodeFragment"
        private const val REQUEST_CODE_CAMERA_PERMISSION = 100;

        @JvmStatic
        fun newInstance() = BarcodeFragment()

        private const val RATIO_4_3_VALUE = 4.0 / 3.0
        private const val RATIO_16_9_VALUE = 16.0 / 9.0
    }
}