using System.Diagnostics;
using NixUniversalSDK;

namespace NixExampleWinUI.Models;
/// <summary>
/// Holds a single instance of the <see cref="DeviceScanner"/> and selected <see cref="IDeviceCompat"/> for shared access between the various view models.
/// </summary>
internal class DeviceModel
{
    private const string LogPrefix = nameof(DeviceModel) + "/";

    #region Constructor
    public DeviceModel()
    {
        // Create DeviceScanner instance and set up its events
        _Scanner = new DeviceScanner();
        Scanner.ScannerCreated += OnScannerCreated;
        Scanner.ScannerStarted += OnScannerStarted;
        Scanner.ScannerStopped += OnScannerStopped;
        Scanner.ScanResult += OnScanResult;

        // Initialize (async)
        ScannerInitTask = Scanner.InitializeAsync();
    }    
    #endregion

    #region IDeviceScanner instance
    private readonly IDeviceScanner _Scanner;
    public IDeviceScanner Scanner => _Scanner;
    public readonly Task<DeviceScannerState> ScannerInitTask;
    
    private void OnScannerCreated(
        object? sender, 
        ScannerCreatedEventArgs args)
    {
        Debug.WriteLine($"{LogPrefix}OnScannerCreated with state {args.State}");
    }

    private void OnScannerStarted(
        object? sender, 
        EventArgs args)
    {
        Debug.WriteLine($"{LogPrefix}OnScannerStarted");
    }

    private void OnScannerStopped(
        object? sender, 
        EventArgs args)
    {
        Debug.WriteLine($"{LogPrefix}OnScannerStopped");
    }

    private void OnScanResult(
        object? sender, 
        ScanResultEventArgs args)
    {
        if (args.Device is IDeviceCompat device)
        {
            Debug.WriteLine($"{LogPrefix}Found {device?.Id} ({device?.Name}) at RSSI {device?.Rssi}");
        }        
    }
    #endregion

    #region IDeviceCompat instance
    private IDeviceCompat? _Device;
    public IDeviceCompat? Device
    {    
        get => _Device;
        set
        {
            // Remove device handlers from old value
            RemoveDeviceEvents();

            // Update the stored value
            _Device = value;

            // Add device handlers to new value
            AddDeviceEvents();
        }
    }

    private void AddDeviceEvents()
    {
        if (Device is not null)
        {
            Device.Connected += OnConnected;
            Device.Disconnected += OnDisconnected;
            Device.BatteryStateChanged += OnBatteryStateChanged;
            Device.ExtPowerStateChanged += OnExtPowerStateChanged;
        }
    }

    private void RemoveDeviceEvents()
    {
        if (Device is not null)
        {
            Device.Connected -= OnConnected;
            Device.Disconnected -= OnDisconnected;
            Device.BatteryStateChanged -= OnBatteryStateChanged;
            Device.ExtPowerStateChanged -= OnExtPowerStateChanged;
        }
    }

    private void OnConnected(
        object? sender, 
        EventArgs args)
    {
        Debug.WriteLine($"{LogPrefix}OnConnected()");
    }

    private void OnDisconnected(
        object? sender, 
        DeviceStatusArgs args)
    {
        Debug.WriteLine($"{LogPrefix}OnDisconnected() with status {args.Status}");
    }

    private void OnBatteryStateChanged(
        object? sender, 
        BatteryStateEventArgs args)
    {
        Debug.WriteLine($"{LogPrefix}OnBatteryStateChanged to {args.NewState}");
    }

    private void OnExtPowerStateChanged(
        object? sender, 
        ExtPowerStateEventArgs args)
    {
        Debug.WriteLine($"{LogPrefix}OnExtPowerStateChanged to {args.NewState}");
    }
    #endregion
}
