using Plugin.NFC;
using System.Collections.ObjectModel;
using System.Text;
using System.Windows.Input;
using System.Linq;

namespace WorkFlowCheck.MAUI.Pages.NFC;

public partial class NFCTestPage : ContentPage
{
    public NFCTestPage()
    {
        InitializeComponent();
    }

    public ObservableCollection<NFCData> NFCDataList { get; set; }
    public ICommand RefreshCommand { get; set; }

    public const string ALERT_TITLE = "NFC";
    bool _eventsAlreadySubscribed = false;
    public bool IsRefreshing { get; set; }

    protected override async void OnAppearing()
    {
        base.OnAppearing();

        CrossNFC.Legacy = false;
        if (CrossNFC.IsSupported)
        {
            if (!CrossNFC.Current.IsAvailable)
                await ShowAlert("NFC is not available");

            if (!CrossNFC.Current.IsEnabled)
                await ShowAlert("NFC is disabled");

            await AutoStartAsync().ConfigureAwait(false);
        }
        else
        {
            await ShowAlert("NFC is not available");
        }
        RefreshCommand = new Command(async () => await LoadNFCDataList());
        BindingContext = this;
    }
    Task ShowAlert(string message, string title = null) => DisplayAlert(string.IsNullOrWhiteSpace(title) ? ALERT_TITLE : title, message, "OK");
    async Task AutoStartAsync()
    {
        // Some delay to prevent Java.Lang.IllegalStateException "Foreground dispatch can only be enabled when your activity is resumed" on Android
        await Task.Delay(500);
        await StartListeningIfNotiOS();
    }
    async Task StartListeningIfNotiOS()
    {

        await BeginListening();
    }
    async Task BeginListening()
    {
        try
        {
            MainThread.BeginInvokeOnMainThread(() =>
            {
                SubscribeEvents();
                CrossNFC.Current.StartListening();
            });
        }
        catch (Exception ex)
        {
            await ShowAlert(ex.Message);
        }
    }
    void SubscribeEvents()
    {
        if (_eventsAlreadySubscribed)
            UnsubscribeEvents();

        _eventsAlreadySubscribed = true;

        CrossNFC.Current.OnMessageReceived += Current_OnMessageReceived_NFCData;
        //CrossNFC.Current.OnMessagePublished += Current_OnMessagePublished;
        //CrossNFC.Current.OnTagDiscovered += Current_OnTagDiscovered;
        //CrossNFC.Current.OnNfcStatusChanged += Current_OnNfcStatusChanged;
        //CrossNFC.Current.OnTagListeningStatusChanged += Current_OnTagListeningStatusChanged;


    }
    void UnsubscribeEvents()
    {
        CrossNFC.Current.OnMessageReceived -= Current_OnMessageReceived_NFCData;
        //CrossNFC.Current.OnMessagePublished -= Current_OnMessagePublished;
        //CrossNFC.Current.OnTagDiscovered -= Current_OnTagDiscovered;
        //CrossNFC.Current.OnNfcStatusChanged -= Current_OnNfcStatusChanged;
        //CrossNFC.Current.OnTagListeningStatusChanged -= Current_OnTagListeningStatusChanged;



        _eventsAlreadySubscribed = false;
    }
    async void Current_OnMessageReceived(ITagInfo tagInfo)
    {
        if (tagInfo == null)
        {
            await ShowAlert("No tag found");
            return;
        }

        // Customized serial number
        var identifier = tagInfo.Identifier;
        var serialNumber = NFCUtils.ByteArrayToHexString(identifier, ":");
        var title = !string.IsNullOrWhiteSpace(serialNumber) ? $"Tag [{serialNumber}]" : "Tag Info";

        if (!tagInfo.IsSupported)
        {
            await ShowAlert("Unsupported tag (app)", title);
        }
        else if (tagInfo.IsEmpty)
        {
            await ShowAlert("Empty tag", title);
        }
        else
        {
            var first = tagInfo.Records[0];
            await ShowAlert(GetMessage(first), title);
        }
    }
    async void Current_OnMessageReceived_NFCData(ITagInfo tagInfo)
    {

        if (tagInfo == null)
        {
            await ShowAlert("No tag found");
            return;
        }

        // Customized serial number
        var identifier = tagInfo.Identifier;
        var serialNumber = NFCUtils.ByteArrayToHexString(identifier, ":");

        if (NFCDataList == null)
        {
            NFCDataList = new ObservableCollection<NFCData>();
        }


        NFCDataList.Add(new NFCData()
        {
            SerialNumber = serialNumber,
            DateReceived = $"{DateTime.Now.Date.ToShortDateString()}  {DateTime.Now.ToLongTimeString()}"
        });

        NFCDataListCollection.ItemsSource = NFCDataList.OrderByDescending(o => o.DateReceived);
        await LoadNFCDataList();
    }

    private async Task LoadNFCDataList()
    {
        IsRefreshing = true;
        IsRefreshing = false;
        OnPropertyChanged(nameof(IsRefreshing));
        OnPropertyChanged(nameof(NFCDataList));
    }
    string GetMessage(NFCNdefRecord record)
    {
        var message = $"Message: {record.Message}";
        message += Environment.NewLine;
        message += $"RawMessage: {Encoding.UTF8.GetString(record.Payload)}";
        message += Environment.NewLine;
        message += $"Type: {record.TypeFormat}";

        if (!string.IsNullOrWhiteSpace(record.MimeType))
        {
            message += Environment.NewLine;
            message += $"MimeType: {record.MimeType}";
        }

        return message;
    }
    protected override bool OnBackButtonPressed()
    {
        Shell.Current.GoToAsync("//MainPage");
        return true;
    }
}