using Dalamud.Game.Command;
using Dalamud.IoC;
using Dalamud.Plugin;
using Dalamud.Interface.Windowing;
using Dalamud.Plugin.Services;
using SpotifyHonorific.Windows;
using SpotifyHonorific.Activities;
using SpotifyHonorific.Updaters;
using System;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Xml.Linq;
using System.Numerics;

namespace SpotifyHonorific;

public sealed class Plugin : IDalamudPlugin
{
    [PluginService] internal static IDalamudPluginInterface PluginInterface { get; private set; } = null!;
    [PluginService] internal static ICommandManager CommandManager { get; private set; } = null!;
    [PluginService] internal static IChatGui ChatGui { get; private set; } = null!;
    [PluginService] internal static IPluginLog PluginLog { get; private set; } = null!;
    [PluginService] internal static IFramework Framework { get; private set; } = null!;

    private const string CommandName = "/spotifyhonorific";
    private const string CommandHelpMessage = $"Available subcommands for {CommandName} are config, enable and disable";

    public Config Config { get; init; }

    public readonly WindowSystem WindowSystem = new("SpotifyHonorific");
    private ConfigWindow ConfigWindow { get; init; }
    private Updater Updater { get; init; }
    

    public Plugin()
    {
        Config = PluginInterface.GetPluginConfig() as Config ?? new Config(ActivityConfig.GetDefaults());
        Updater = new(Config, Framework, PluginInterface, PluginLog);
        ConfigWindow = new ConfigWindow(Config, new(), Updater);

        WindowSystem.AddWindow(ConfigWindow);
        CommandManager.AddHandler(CommandName, new CommandInfo(OnCommand)
        {
            HelpMessage = CommandHelpMessage
        });

        PluginInterface.UiBuilder.Draw += DrawUI;
        PluginInterface.UiBuilder.OpenConfigUi += ToggleConfigUI;
        PluginInterface.UiBuilder.OpenMainUi += ToggleConfigUI;
    }

    public void Dispose()
    {
        WindowSystem.RemoveAllWindows();
        CommandManager.RemoveHandler(CommandName);
        Updater.Dispose();
    }

    private void OnCommand(string command, string args)
    {
        var subcommand = args.Split(" ", 2)[0];
        if (subcommand == "config")
        {
            ToggleConfigUI();
        }
        else if (subcommand == "enable")
        {
            Config.Enabled = true;
            Config.Save();
            Updater.Start();
        }
        else if (subcommand == "disable")
        {
            Config.Enabled = false;
            Config.Save();
            Updater.Stop();
        }
        else if (subcommand == "set")
        {
            var splitArgs = args.Trim().Split(' ', 2, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
            if (splitArgs.Length != 2)
            {
                return;
            }
            var setArgs = splitArgs[1].Split('|', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
            bool? prefix = null;
            Vector3? color = null;
            Vector3? glow = null;

            foreach (var a in setArgs)
            {

                var arg = a.ToLower();

                var colorArg = arg.Skip(arg.StartsWith('#') ? 1 : 0).ToArray();

                if (colorArg.Length == 6 && colorArg.All(chr => chr is >= '0' and <= '9' or >= 'a' and <= 'f'))
                {

                    if (color != null && glow != null)
                    {
                        ChatGui.PrintError($"Duplicate Option in Set: '{a}'", "SpotifyHonorific");
                        return;
                    }

                    var rHex = string.Join(null, colorArg.Skip(0).Take(2));
                    var gHex = string.Join(null, colorArg.Skip(2).Take(2));
                    var bHex = string.Join(null, colorArg.Skip(4).Take(2));


                    if (byte.TryParse(rHex, NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo, out var r) &&
                        byte.TryParse(gHex, NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo, out var g) &&
                        byte.TryParse(bHex, NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo, out var b))
                    {

                        var c = new Vector3(r / 255f, g / 255f, b / 255f);
                        if (color == null)
                        {
                            color = c;
                            continue;
                        }

                        glow = c;
                        continue;
                    }
                }

                if (arg is "p" or "prefix" or "pre")
                {
                    if (prefix != null)
                    {
                        ChatGui.PrintError($"Duplicate Option in Set: '{a}'", "SpotifyHonorific");
                        return;
                    }

                    prefix = true;
                    continue;
                }

                if (arg is "s" or "suffix")
                {
                    if (prefix != null)
                    {
                        ChatGui.PrintError($"Duplicate Option in Set: '{a}'", "SpotifyHonorific");
                        return;
                    }
                    prefix = false;
                    continue;
                }
                ChatGui.PrintError($"Invalid Option in Set: '{a}'", "SpotifyHonorific");
                return;
            }

            Config.ActivityConfigs.First().Color = color;
            Config.ActivityConfigs.First().Glow = glow;
            Config.ActivityConfigs.First().IsPrefix = prefix ?? false;
            ChatGui.Print("Updated Title", "SpotifyHonorific");
        }
        else
        {
            ChatGui.Print(CommandHelpMessage);
        }
    }

    private void DrawUI() => WindowSystem.Draw();

    public void ToggleConfigUI() => ConfigWindow.Toggle();
}
