using System;
using Android.Bluetooth;
using Android.Content;
using Android.Gms.Common.Apis;
using Android.Gms.Location;
using Android.Provider;
using Android.Net.Wifi;
using Android.OS;
using CommunityToolkit.Mvvm.Messaging;
using Sample.Platforms.Android;
using SII.SDK.Maui.Printer;

namespace Sample
{
    partial class Function
    {
        // Gets the current language setting set on the device.
        public partial String GetCurrentLanguage()
        {
            // 
            return Java.Util.Locale.Default.Language;
        }

        // Check the Storage permissions required to use the SDK on Android
        public async partial Task CheckStoragePermissions()
        {
            // Request storage permission for Android 9 and earlier.
            if (Android.OS.Build.VERSION.SdkInt <= Android.OS.BuildVersionCodes.P)
            {
                var storagePermissionStatus = await Permissions.CheckStatusAsync<Permissions.StorageRead>();
                if (storagePermissionStatus != PermissionStatus.Granted)
                {
                    storagePermissionStatus = await Permissions.RequestAsync<Permissions.StorageRead>();
                }
            }
            return;
        }

        // Check the Bluetooth permissions required to use the SDK on Android
        private async partial Task CheckBluetoothPermissions(PortType portType)
        {
            if (portType == PortType.PORT_TYPE_BLUETOOTH)
            {
                // Request Bluetooth permissions for Android 12 or higher.
                if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.S)
                {
                    var bluetoothPermissionStatus = await Permissions.CheckStatusAsync<MyBluetoothPermission>();
                    if (bluetoothPermissionStatus != PermissionStatus.Granted)
                    {
                        bluetoothPermissionStatus = await Permissions.RequestAsync<MyBluetoothPermission>();
                        if (bluetoothPermissionStatus != PermissionStatus.Granted)
                        {
                            return;
                        }
                    }
                }

                // If Bluetooth is disabled, enable it.
                var result = await CheckBluetoothEnabled();
                if (!result)
                {
                    return;
                }

                // Enable location permission to discover Bluetooth devices.
                var locationPermissionStatus = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();
                if (locationPermissionStatus != PermissionStatus.Granted)
                {
                    await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
                }
                // for Android 10 or higher
                if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Q)
                {
                    await CheckLocationRequest();
                }
            }
            else if (portType == PortType.PORT_TYPE_TCP)
            {
                // If Wi-Fi is disabled, enable it.
                await CheckWifiEnabled();
            }

            return;
        }

        // If Wi-Fi is disabled, enable it.
        public async Task<bool> CheckWifiEnabled()
        {
            using (WifiManager wifiManager = (WifiManager)Platform.CurrentActivity.ApplicationContext.GetSystemService(Context.WifiService))
            {
                if (wifiManager != null && !wifiManager.IsWifiEnabled)
                {
                    var tcs = new TaskCompletionSource<bool>();
                    if (Build.VERSION.SdkInt >= BuildVersionCodes.Q)
                    {
                        WeakReferenceMessenger.Default.Register<ActivityResultMessage>(this, (r, m) =>
                        {
                            tcs.SetResult(true);
                        });

                        Intent panelIntent = new Intent(Settings.Panel.ActionWifi);
                        panelIntent.AddFlags(ActivityFlags.NoHistory);
                        Platform.CurrentActivity.StartActivityForResult(panelIntent, ActivityResultMessage.WifiEnabledRequestCode);
                    }
                    else
                    {
                        wifiManager.SetWifiEnabled(true);
                        tcs.SetResult(true);
                    }

                    bool result = await tcs.Task;
                    WeakReferenceMessenger.Default.Unregister<ActivityResultMessage>(this);
                    return result;
                }
            }

            return true;
        }

        // If Bluetooth is disabled, enable it.
        public async Task<bool> CheckBluetoothEnabled()
        {
            BluetoothManager bluetoothManager = (BluetoothManager)Android.App.Application.Context.GetSystemService(Android.Content.Context.BluetoothService);
            BluetoothAdapter bluetoothAdapter = bluetoothManager?.Adapter;
            if (bluetoothAdapter == null)
            {
                return false;
            }

            if (!bluetoothAdapter.IsEnabled)
            {
                var tcs = new TaskCompletionSource<bool>();
                WeakReferenceMessenger.Default.Register<ActivityResultMessage>(this, (r, m) =>
                {
                    tcs.SetResult(Android.App.Result.Ok == (Android.App.Result)m.ResultCode ? true : false);
                });

                Intent enableBluetoothIntent = new Intent(BluetoothAdapter.ActionRequestEnable);
                Platform.CurrentActivity.StartActivityForResult(enableBluetoothIntent, ActivityResultMessage.BluetoothEnabledRequestCode);

                bool result = await tcs.Task;
                WeakReferenceMessenger.Default.Unregister<ActivityResultMessage>(this);

                return result;
            }

            return true;
        }

        // Enable LocationServices to discover Bluetooth devices.
        public async Task<bool> CheckLocationRequest()
        {
            var tcs = new TaskCompletionSource<bool>();
            try
            {
                LocationRequest locationRequest = LocationRequest.Create();
                locationRequest.SetPriority(LocationRequest.PriorityHighAccuracy);
                LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().AddLocationRequest(locationRequest);
                var response = await LocationServices.GetSettingsClient(Platform.CurrentActivity).CheckLocationSettingsAsync(builder.Build());
                tcs.SetResult(true);
            }
            catch (ApiException exception)
            {
                switch (exception.StatusCode)
                {
                    case LocationSettingsStatusCodes.ResolutionRequired:
                        WeakReferenceMessenger.Default.Register<ActivityResultMessage>(this, (r, m) =>
                        {
                            tcs.SetResult(Android.App.Result.Ok == (Android.App.Result)m.ResultCode ? true : false);
                        });
                        try
                        {
                            // Request for location information setting
                            ResolvableApiException resolvable = (ResolvableApiException)exception;
                            resolvable.StartResolutionForResult(Platform.CurrentActivity, ActivityResultMessage.LocationRequestCode);
                        }
                        catch
                        {
                            tcs.SetResult(false);
                        }

                        break;
                    default:
                        break;
                }

            }

            bool result = await tcs.Task;
            WeakReferenceMessenger.Default.Unregister<ActivityResultMessage>(this);

            return result;
        }

        // Get Android.Graphics.Bitmap instance from stream.
        private partial object GetPlatformImageData(string filePath)
        {
            try
            {

                using (FileStream fs = System.IO.File.OpenRead(filePath))
                {
                    Android.Graphics.Bitmap bitmap = Android.Graphics.BitmapFactory.DecodeStream(fs);
                    return bitmap;
                }
            }
            catch
            {
                return null;
            }
        }

        // Dispose Android.Graphics.Bitmap instance.
        private partial bool DisposePlatformImageData(object imageObject)
        {
            try
            {
                if (imageObject is Android.Graphics.Bitmap bitmap)
                {
                    bitmap.Dispose();
                }
                return true;
            }
            catch
            {
                return false;
            }
        }
    }
}

