package com.cloud.hmg_patient_app.penguin

import android.app.Activity
import android.content.Context
import android.content.Context.RECEIVER_EXPORTED
import android.content.IntentFilter
import android.graphics.Color
import android.os.Build
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.widget.RelativeLayout
import android.widget.Toast
import androidx.annotation.RequiresApi
import com.cloud.hmg_patient_app.PermissionManager.PermissionHelper
import com.cloud.hmg_patient_app.PermissionManager.PermissionManager
import com.cloud.hmg_patient_app.PermissionManager.PermissionResultReceiver
import com.ejada.hmg.MainActivity
import com.peng.pennavmap.PlugAndPlayConfiguration
import com.peng.pennavmap.PlugAndPlaySDK
import com.peng.pennavmap.enums.InitializationErrorType
import com.peng.pennavmap.interfaces.PenNavUIDelegate
import com.peng.pennavmap.utils.Languages
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.platform.PlatformView
import com.cloud.hmg_patient_app.penguin.PenguinNavigator
import com.peng.pennavmap.interfaces.PIEventsDelegate
import com.peng.pennavmap.interfaces.PILocationDelegate
import com.peng.pennavmap.interfaces.RefIdDelegate
import com.peng.pennavmap.models.PIReportIssue
/**
 * Custom PlatformView for displaying Penguin UI components within a Flutter app.
 * Implements `PlatformView` for rendering the view, `MethodChannel.MethodCallHandler` for handling method calls,
 * and `PenNavUIDelegate` for handling SDK events.
 */
@RequiresApi(Build.VERSION_CODES.O)
internal class PenguinView(
    context: Context,
    id: Int,
    val creationParams: Map<String, Any>,
    messenger: BinaryMessenger,
    activity: MainActivity,
    val channel: MethodChannel
) : PlatformView, MethodChannel.MethodCallHandler, PenNavUIDelegate {
    // The layout for displaying the Penguin UI
    private val mapLayout: RelativeLayout = RelativeLayout(context)
    private val _context: Context = context

    private val permissionResultReceiver: PermissionResultReceiver
    private val permissionIntentFilter = IntentFilter("PERMISSION_RESULT_ACTION")

    private companion object {
        const val PERMISSIONS_REQUEST_CODE = 1
    }

    private lateinit var permissionManager: PermissionManager

    // Reference to the main activity
    private var _activity: Activity = activity

    private lateinit var mContext: Context

    lateinit var navigator: PenguinNavigator

    init {
        // Set layout parameters for the mapLayout
        mapLayout.layoutParams = ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
        )

        mContext = context


        permissionResultReceiver = PermissionResultReceiver { granted ->
            if (granted) {
                onPermissionsGranted()
            } else {
                onPermissionsDenied()
            }
        }
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            mContext.registerReceiver(
                permissionResultReceiver,
                permissionIntentFilter,
                RECEIVER_EXPORTED
            )
        } else {
            mContext.registerReceiver(
                permissionResultReceiver,
                permissionIntentFilter,
            )
        }

        // Set the background color of the layout
        mapLayout.setBackgroundColor(Color.RED)

        permissionManager = PermissionManager(
            context = mContext,
            listener = object : PermissionManager.PermissionListener {
                override fun onPermissionGranted() {
                    // Handle permissions granted
                    onPermissionsGranted()
                }

                override fun onPermissionDenied() {
                    // Handle permissions denied
                    onPermissionsDenied()
                }
            },
            requestCode = PERMISSIONS_REQUEST_CODE,
            PermissionHelper.getRequiredPermissions().get(0)
        )

        if (!permissionManager.arePermissionsGranted()) {
            permissionManager.requestPermissions(_activity)
        } else {
            // Permissions already granted
            permissionManager.listener.onPermissionGranted()
        }


    }

    private fun onPermissionsGranted() {
        // Handle the actions when permissions are granted
        Log.d("PermissionsResult", "onPermissionsGranted")
        // Register the platform view factory for creating custom views

        // Initialize the Penguin SDK
        initPenguin()


    }

    private fun onPermissionsDenied() {
        // Handle the actions when permissions are denied
        Log.d("PermissionsResult", "onPermissionsDenied")

    }

    /**
     * Returns the view associated with this PlatformView.
     *
     * @return The main view for this PlatformView.
     */
    override fun getView(): View {
        return mapLayout
    }

    /**
     * Cleans up resources associated with this PlatformView.
     */
    override fun dispose() {
        // Cleanup code if needed
    }

    /**
     * Handles method calls from Dart code.
     *
     * @param call The method call from Dart.
     * @param result The result callback to send responses back to Dart.
     */
    override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
        // Handle method calls from Dart code here
    }

    /**
     * Initializes the Penguin SDK with custom configuration and delegates.
     */
    private fun initPenguin() {
        navigator = PenguinNavigator()
        // Configure the PlugAndPlaySDK
        val language = when (creationParams["languageCode"] as String) {
            "ar" -> Languages.ar
            "en" -> Languages.en
            else -> {
                Languages.en
            }
        }
        Log.d(
            "TAG",
            "initPenguin: ${Languages.getLanguageEnum(creationParams["languageCode"] as String)}"
        )
        PlugAndPlaySDK.configuration = PlugAndPlayConfiguration.Builder()
            .setBaseUrl(
                creationParams["dataURL"] as String,
                creationParams["positionURL"] as String
            )
            .setServiceName(
                creationParams["dataServiceName"] as String,
                creationParams["positionServiceName"] as String
            )
            .setClientData(
                creationParams["clientID"] as String,
                creationParams["clientKey"] as String
            )
            .setUserName(creationParams["username"] as String)
//            .setLanguageID(Languages.en)
            .setLanguageID(language)
            .setSimulationModeEnabled(creationParams["isSimulationModeEnabled"] as Boolean)
            .setEnableBackButton(true)
//            .setDeepLinkData("deeplink")
            .setCustomizeColor("#2CA0AF")
            .setDeepLinkSchema("")
            .setIsEnableReportIssue(true)
            .build()

        // Set location delegate to handle location updates
//        PlugAndPlaySDK.setPiLocationDelegate {
            // Example code to handle location updates
            // Uncomment and modify as needed
            // if (location.size() > 0)
            //     Toast.makeText(_context, "Location Info Latitude: ${location[0]}, Longitude: ${location[1]}", Toast.LENGTH_SHORT).show()
//        }

        // Set events delegate for reporting issues
//        PlugAndPlaySDK.setPiEventsDelegate(new PIEventsDelegate() {
//            @Override
//            public void onReportIssue(PIReportIssue issue) {
//                Log.e("Issue Reported: ", issue.getReportType());
//            }
//                // Implement issue reporting logic here         }
//                @Override
//                public void onSharedLocation(String link) {
//                    // Implement  Shared location logic here
//                }
//            })

        // Start the Penguin SDK
        PlugAndPlaySDK.start(mContext, this)
    }


    /**
     * Navigates to the specified reference ID.
     *
     * @param refID The reference ID to navigate to.
     */
    fun navigateTo(refID: String) {
        try {
            if (refID.isBlank()) {
                Log.e("navigateTo", "Invalid refID: The reference ID is blank.")
            }
//                referenceId = refID
            navigator.navigateTo(mContext, refID,object : RefIdDelegate {
                override fun onRefByIDSuccess(PoiId: String?) {
                    Log.e("navigateTo", "PoiId is penguin view+++++++ $PoiId")

//                    channelFlutter.invokeMethod(
//                        PenguinMethod.navigateToPOI.name,
//                        "navigateTo Success"
//                    )
                }

                override fun onGetByRefIDError(error: String?) {
                    Log.e("navigateTo", "error is penguin view+++++++ $error")

//                    channelFlutter.invokeMethod(
//                        PenguinMethod.navigateToPOI.name,
//                        "navigateTo Failed: Invalid refID"
//                    )
                }
            } , creationParams["clientID"] as String, creationParams["clientKey"] as String )

        } catch (e: Exception) {
            Log.e("navigateTo", "Exception occurred during navigation: ${e.message}", e)
//            channelFlutter.invokeMethod(
//                PenguinMethod.navigateToPOI.name,
//                "Failed: Exception - ${e.message}"
//            )
        }
    }

    /**
     * Called when Penguin UI setup is successful.
     *
     * @param warningCode Optional warning code received from the SDK.
     */
    override fun onPenNavSuccess(warningCode: String?) {
        val clinicId = creationParams["clinicID"] as String

        if(clinicId.isEmpty()) return

        navigateTo(clinicId)
    }

    /**
     * Called when there is an initialization error with Penguin UI.
     *
     * @param description Description of the error.
     * @param errorType Type of initialization error.
     */
    override fun onPenNavInitializationError(
        description: String?,
        errorType: InitializationErrorType?
    ) {
        val arguments: Map<String, Any?> = mapOf(
            "description" to description,
            "type" to errorType?.name
        )

        channel.invokeMethod(PenguinMethod.onPenNavInitializationError.name, arguments)
        Toast.makeText(mContext, "Navigation Error: $description", Toast.LENGTH_SHORT).show()
    }

    /**
     * Called when Penguin UI is dismissed.
     */
    override fun onPenNavUIDismiss() {
        // Handle UI dismissal if needed
        try {
            mContext.unregisterReceiver(permissionResultReceiver)
            dispose();
        } catch (e: IllegalArgumentException) {
            Log.e("PenguinView", "Receiver not registered: $e")
        }
    }
}
