using BarRaider.SdTools;
using BarRaider.SdTools.Wrappers;
using ClipTrimDotNet.Client;
using NAudio.CoreAudioApi.Interfaces;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ClipTrimDotNet
{
    [PluginActionId("com.michal-courson.cliptrim.player")]
    public class Player : KeypadBase
    {

        private ClipMetadata? metadata;
        private KeyCoordinates coordinates;
        private class PluginSettings
        {
            public static PluginSettings CreateDefaultSettings()
            {
                PluginSettings instance = new PluginSettings();
                instance.Path = null;
                instance.PlayType = "Play/Overlap";
                instance.Index = 0;
                instance.Volume = 1;
                return instance;
            }

            [FilenameProperty]
            [JsonProperty(PropertyName = "path")]
            public string? Path { get; set; }

            [JsonProperty(PropertyName = "index")]
            public int? Index { get; set; }
            [JsonProperty(PropertyName = "playtype")]
            public string PlayType { get; set; }

            [JsonProperty(PropertyName = "volume")]
            public double Volume { get; set; }
        }

        #region Private Members

        private PluginSettings settings;

        #endregion
        public Player(SDConnection connection, InitialPayload payload) : base(connection, payload)
        {
            if (payload.Settings == null || payload.Settings.Count == 0)
            {
                this.settings = PluginSettings.CreateDefaultSettings();
                SaveSettings();
            }
            else
            {
                this.settings = payload.Settings.ToObject<PluginSettings>();
            }
            this.coordinates = payload.Coordinates;
            GlobalSettingsManager.Instance.RequestGlobalSettings();
            CheckFile();
        }

        private void Instance_OnReceivedGlobalSettings(object sender, ReceivedGlobalSettingsPayload e)
        {
            Tools.AutoPopulateSettings(GlobalSettings.Instance, e.Settings);
        }

        public int GetIndex()
        {
            return Math.Max((coordinates.Row - 1) * 5 + coordinates.Column, 0);
        }   

        private async void CheckFile()
        {
            
            //if (settings == null || GlobalSettings.Instance.ProfileName ==null) return;
            metadata = ClipTrimClient.Instance.GetClipByPagedIndex(GetIndex());
            await Connection.SetTitleAsync($"{metadata?.Name ?? ""}");
            
            return;

            //var files = Directory.GetFiles(Path.Combine(Path.GetDirectoryName(GlobalSettings.Instance.BasePath), GlobalSettings.Instance.ProfileName), "*.wav", SearchOption.TopDirectoryOnly)
            //                .OrderBy(file => File.GetCreationTime(file))
            //                .ToArray();
            //int? i = this.settings.Index;
            //string new_path = "";
            //if (i != null && i >= 0 && i < files.Length)
            //{
            //    new_path = files[i ?? 0];
            //}


            //await Connection.SetTitleAsync(Path.GetFileNameWithoutExtension(new_path));
            //if (new_path != settings.Path)
            //{
            //    settings.Path = new_path;
            //    if(new_path != "")
            //    {
            //        FileEntry opts = GlobalSettings.Instance.GetFileOptionsInCurrentProfile(new_path);
            //        settings.Volume = opts.Volume;
            //        settings.PlayType = opts.Playtype;
            //    }
            //    await SaveSettings();
            //}
        }


        private async void Connection_OnApplicationDidLaunch(object sender, BarRaider.SdTools.Wrappers.SDEventReceivedEventArgs<BarRaider.SdTools.Events.ApplicationDidLaunch> e)
        {
         
        }

        private void Connection_OnTitleParametersDidChange(object sender, SDEventReceivedEventArgs<BarRaider.SdTools.Events.TitleParametersDidChange> e)
        {
            //titleParameters = e.Event?.Payload?.TitleParameters;
            //userTitle = e.Event?.Payload?.Title;
        }

        public override void Dispose()
        {
            Connection.OnTitleParametersDidChange -= Connection_OnTitleParametersDidChange;
            Connection.OnApplicationDidLaunch -= Connection_OnApplicationDidLaunch;
            //Logger.Instance.LogMessage(TracingLevel.INFO, $"Destructor called");
        }

        public override void KeyPressed(KeyPayload payload)
        {
            //Logger.Instance.LogMessage(TracingLevel.INFO, "Key Pressedd");
            Tools.AutoPopulateSettings(settings, payload.Settings);
            // Logger.Instance.LogMessage(TracingLevel.INFO, JsonConvert.SerializeObject(settings));
            ClipTrimClient.Instance.PlayClip(metadata);
            //try
            //{
            //    WavPlayer.Instance.Play(settings.Path, GlobalSettings.Instance.OutputDevice, settings.Volume, settings.PlayType == "Play/Overlap" ? WavPlayer.PlayMode.PlayOverlap : WavPlayer.PlayMode.PlayStop);
            //}
            //catch
            //{

            //}
            
        }

        public override void KeyReleased(KeyPayload payload) { 
            
        }

        public override void OnTick() {
            CheckFile();
        }

        public override async void ReceivedSettings(ReceivedSettingsPayload payload)
        {
            Logger.Instance.LogMessage(TracingLevel.INFO, "Player rec settings");
            Tools.AutoPopulateSettings(settings, payload.Settings);
            GlobalSettings.Instance.SetFileOptionsCurrentProfile(settings.Path, new FileEntry() { Playtype = settings.PlayType, Volume = settings.Volume });
            await Connection.SetGlobalSettingsAsync(JObject.FromObject(GlobalSettings.Instance));
            //SaveSettings();
            //CheckFile();
        }

        public override void ReceivedGlobalSettings(ReceivedGlobalSettingsPayload payload) {
            //Logger.Instance.LogMessage(TracingLevel.INFO, "ReceivedGlobalSettings");

            if (payload.Settings == null || payload.Settings.Count == 0)
            {
                var inst = GlobalSettings.Instance;
                //GlobalSettingsManager.Instance.SetGlobalSettings(JObject.FromObject(inst));
            }
            else
            {
                GlobalSettings.Instance = payload.Settings.ToObject<GlobalSettings>();
            }
            
            //CheckFile();
        }

        #region Private Methods

        private Task SaveSettings()
        {
            return Connection.SetSettingsAsync(JObject.FromObject(settings));
        }

        #endregion
    }
}