using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NAudio;
using NAudio.Wave;

namespace Whisper
{
    internal class NAudioClass
    {
        // Fields for managing audio recording
        private WaveInEvent waveIn;
        private WaveFileWriter waveWriter;
        private readonly int deviceNumber;      // The selected audio input device
        private readonly string outputFilePath; // The path where the recorded audio will be saved

        // Constructor to initialize the class
        public NAudioClass(int deviceNumber, string outputFilePath)
        {
            this.deviceNumber = deviceNumber;
            this.outputFilePath = outputFilePath;
        }

        // Method to start audio recording
        public void StartRecording()
        {
            // Create a WaveInEvent instance with specified settings
            waveIn = new WaveInEvent
            {
                DeviceNumber = deviceNumber,
                WaveFormat = new WaveFormat(rate: 44100, bits: 16, channels: 1),
                //sample rate , bit depth, audio chanell
                BufferMilliseconds = 20
            };

            // Create a WaveFileWriter to save the recorded audio
            waveWriter = new WaveFileWriter(outputFilePath, waveIn.WaveFormat);

            // Subscribe to the DataAvailable event to capture audio data and save it
            waveIn.DataAvailable += WaveIn_DataAvailable;

            // Start recording and notify the user
            waveIn.StartRecording();
            Console.WriteLine("Recording started. Press Enter to stop and save the file.");
        }

        // Method to stop audio recording and clean up resources
        public void StopRecording()
        {
            waveIn.StopRecording();
            waveIn.Dispose();
            waveWriter.Dispose();
            Console.WriteLine($"Audio recorded and saved as '{outputFilePath}'");
        }

        // Event handler to process audio data and display a level meter
        static void WaveIn_DataAvailable(object? sender, NAudio.Wave.WaveInEventArgs e)
        {
            // Convert the audio buffer to an array of 16-bit integers
            Int16[] values = new Int16[e.Buffer.Length / 2];
            Buffer.BlockCopy(e.Buffer, 0, values, 0, e.Buffer.Length);

            // Determine the highest audio level as a fraction of the maximum possible value
            float fraction = (float)values.Max() / 32768;

            // Create a level meter bar and display it in the console
            string bar = new('#', (int)(fraction * 70));
            string meter = "[" + bar.PadRight(60, '-') + "]";
            Console.CursorLeft = 0;
            Console.CursorVisible = false;
            Console.Write($"{meter} {fraction * 100:00.0}%");
        }
    }
}