//

//  BlueGpsView.swift

//  Runner

//

//  Created by Penguin.

//



import Foundation
import UIKit
import Flutter
import PenNavUI

import Foundation
import Flutter
import UIKit



/**

 * A custom Flutter platform view for displaying Penguin UI components.

 * This class integrates with the Penguin navigation SDK and handles UI events.

 */

class PenguinView: NSObject, FlutterPlatformView, PIEventsDelegate, PenNavInitializationDelegate

{
    // The main view displayed within the platform view

    private var _view: UIView

    private var model: PenguinModel?

    private var methodChannel: FlutterMethodChannel

    var onSuccess: (() -> Void)?



    

    

    /**

     * Initializes the PenguinView with the provided parameters.

     *

     * @param frame The frame of the view, specifying its size and position.

     * @param viewId A unique identifier for this view instance.

     * @param args Optional arguments provided for creating the view.

     * @param messenger The [FlutterBinaryMessenger] used for communication with Dart.

     */

    init(

        frame: CGRect,

        viewIdentifier viewId: Int64,

        arguments args: Any?,

        binaryMessenger messenger: FlutterBinaryMessenger?

    ) {

        _view = UIView()

        methodChannel = FlutterMethodChannel(name: "launch_penguin_ui", binaryMessenger: messenger!)



        super.init()

        

        // Get the screen's width and height to set the view's frame

        let screenWidth = UIScreen.main.bounds.width

        let screenHeight = UIScreen.main.bounds.height

        

        // Uncomment to set the background color of the view

        // _view.backgroundColor = UIColor.red

        

        // Set the frame of the view to cover the entire screen

        _view.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)

        print("========Inside Penguin View ========")

        print(args)

        guard let arguments = args as? [String: Any] else {

            print("Error: Arguments are not in the expected format.")

            return

        }

        print("===== i got tha Args=======")

        

        // Initialize the model from the arguments

        if let penguinModel = PenguinModel(from: arguments) {

            self.model = penguinModel

            initPenguin(args: penguinModel)

        } else {

            print("Error: Failed to initialize PenguinModel from arguments ")

        }

        // Initialize the Penguin SDK with required configurations

        // initPenguin( arguments: args)

    }

    

    /**

     * Initializes the Penguin SDK with custom configuration settings.

     */

    func initPenguin(args: PenguinModel) {

//         Set the initialization delegate to handle SDK initialization events

        PenNavUIManager.shared.initializationDelegate = self

        // Configure the Penguin SDK with necessary parameters

        PenNavUIManager.shared

            .setClientKey(args.clientKey)

            .setClientID(args.clientID)

            .setUsername(args.username)

            .setSimulationModeEnabled(isEnable: args.isSimulationModeEnabled)

            .setBaseURL(dataURL: args.dataURL, positionURL: args.positionURL)

            .setServiceName(dataServiceName: args.dataServiceName, positionServiceName: args.positionServiceName)

            .setIsShowUserName(args.isShowUserName)

            .setIsUpdateUserLocationSmoothly(args.isUpdateUserLocationSmoothly)

            .setEnableReportIssue(enable: args.isEnableReportIssue)

            .setLanguage(args.languageCode)

            .setBackButtonVisibility(true)

            .build()

    }

    

    

    /**

     * Returns the main view associated with this platform view.

     *

     * @return The UIView instance that represents this platform view.

     */

    func view() -> UIView {

        return _view

    }

    

    // MARK: - PIEventsDelegate Methods

    

    

    

    

    /**

     * Called when the Penguin UI is dismissed.

     */

    func onPenNavUIDismiss() {

        // Handle UI dismissal if needed

        print("====== onPenNavUIDismiss =========")

     

        

        self.view().removeFromSuperview()

    }

    

    /**

     * Called when a report issue is generated.

     *

     * @param issue The type of issue reported.

     */

    func onReportIssue(_ issue: PenNavUI.IssueType) {

        // Handle report issue events if needed

        print("====== onReportIssueError =========")

        methodChannel.invokeMethod("onReportIssue", arguments: ["issueType": issue])



    }

    

    /**

     * Called when the Penguin UI setup is successful.

     */

    func onPenNavSuccess() {

        print("====== onPenNavSuccess =========")

        onSuccess?()

         methodChannel.invokeMethod("onPenNavSuccess", arguments: nil)

        // Obtain the FlutterViewController instance

        let controller: FlutterViewController = UIApplication.shared.windows.first?.rootViewController as! FlutterViewController

        

        print("====== after controller onPenNavSuccess =========")

        

        // Set the events delegate to handle SDK events

        PenNavUIManager.shared.eventsDelegate = self

        

        print("====== after eventsDelegate onPenNavSuccess =========")

        

        // Present the Penguin UI on top of the Flutter view controller

        PenNavUIManager.shared.present(root: controller, view: _view)

        

        

        print("====== after present onPenNavSuccess =========")

        print(model?.clinicID)

        print("====== after present onPenNavSuccess =========")

        

        guard let config = self.model else {

            print("Error: Config Model is nil")

            return

        }

        

        guard let clinicID = self.model?.clinicID,

              let clientID = self.model?.clientID, !clientID.isEmpty else {

            print("Error: Config Client ID is nil or empty")

            return

        }

        

        let navigator = PenguinNavigator(config: config)

        

        PenNavUIManager.shared.getToken(clientID: config.clientID, clientKey: config.clientKey) { [weak self] token, error in

            if let error = error {

                let errorMessage = "Token error while getting the for Navigate to method"

                print("Failed to get token: \(errorMessage)")

                return

            }

            

            guard let token = token else {

                print("Token is nil")

                return

            }

            print("Token Generated")

            print(token);

            

            self?.handleNavigation(clinicID: clinicID, token: token) { success, errorMessage in

                if success {

                    print("Navigation successful")

                } else {

                    print("Navigation failed: \(errorMessage ?? "Unknown error")")

                }

                

            }

            

            print("====== after Token onPenNavSuccess =========")

        }

        

    }

    

    

    

    private func handleNavigation(clinicID: String, token: String, completion: @escaping (Bool, String?) -> Void) {

        DispatchQueue.main.async {

            PenNavUIManager.shared.setToken(token: token)

            PenNavUIManager.shared.navigate(to: clinicID)

            completion(true,nil)

        }

    }



    

    

    

    /**

     * Called when there is an initialization error with the Penguin UI.

     *

     * @param errorType The type of initialization error.

     * @param errorDescription A description of the error.

     */

    func onPenNavInitializationError(errorType: PenNavUI.PenNavUIError, errorDescription: String) {

        // Handle initialization errors if needed

        print("onPenNavInitializationErrorType: \(errorType.rawValue)")

        print("onPenNavInitializationError: \(errorDescription)")
    }
}
