using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Effects;
using System.Windows.Documents;
using System.Globalization;
using System.IO;
using System.Text;
using System.Windows.Media.Imaging;
using AutoTrackR2.LogEventHandlers;
using System.Timers;
using System.Linq;


namespace AutoTrackR2;

public partial class HomePage : UserControl
{

    private LogHandler? _logHandler;
    private KillHistoryManager _killHistoryManager;
    private bool _UIEventsRegistered = false;
    private System.Timers.Timer _statusCheckTimer;
    private bool _isLogHandlerRunning = false;

    public HomePage()
    {
        InitializeComponent();

        if (string.IsNullOrEmpty(ConfigManager.KillHistoryFile))
        {
            throw new InvalidOperationException("KillHistoryFile path is not configured.");
        }
        _killHistoryManager = new KillHistoryManager(ConfigManager.KillHistoryFile);

        // Set the TextBlock text
        KillTallyTitle.Text = $"Kill Tally - {DateTime.Now.ToString("MMMM")}";
        KillTallyTextBox.Text = _killHistoryManager.GetKillsInCurrentMonth().Count.ToString();
        AdjustFontSize(KillTallyTextBox);
        AddKillHistoryKillsToUI();

        // Initialize and start the status check timer
        _statusCheckTimer = new System.Timers.Timer(1000); // Check every second
        _statusCheckTimer.Elapsed += CheckStarCitizenStatus;
        _statusCheckTimer.Start();

        // Check if Star Citizen is already running and initialize accordingly
        if (IsStarCitizenRunning())
        {
            Dispatcher.Invoke(() =>
            {
                UpdateStatusIndicator(true);
                InitializeLogHandler(); // Then initialize the log handler
            });
        }
    }

    private void CheckStarCitizenStatus(object? sender, ElapsedEventArgs e)
    {
        bool isRunning = IsStarCitizenRunning();
        Dispatcher.Invoke(() =>
        {
            UpdateStatusIndicator(isRunning);

            if (isRunning)
            {
                if (!_isLogHandlerRunning)
                {
                    // Game is running, start log monitoring and read initial states
                    InitializeLogHandler();
                }
            }
            else
            {
                // Game is not running, set everything to Unknown
                GameModeTextBox.Text = "Unknown";
                PlayerShipTextBox.Text = "Unknown";
                PilotNameTextBox.Text = "Unknown";
                LocationTextBox.Text = "Unknown";
                LocalPlayerData.CurrentGameMode = GameMode.Unknown;
                LocalPlayerData.PlayerShip = string.Empty;
                LocalPlayerData.Username = string.Empty;
                LocalPlayerData.LastSeenVehicleLocation = "Unknown";

                // Stop log monitoring if it's running
                if (_isLogHandlerRunning)
                {
                    _logHandler?.StopMonitoring();
                    _isLogHandlerRunning = false;
                }
            }
        });
    }

    private void UpdateStatusIndicator(bool isRunning)
    {
        if (isRunning)
        {
            StatusLight.Fill = new SolidColorBrush(Colors.Green);
            StatusText.Text = "TrackR\nActive";
        }
        else
        {
            StatusLight.Fill = new SolidColorBrush(Colors.Red);
            StatusText.Text = "TrackR\nStandby";
        }
    }

    private void AddKillHistoryKillsToUI()
    {
        var kills = _killHistoryManager.GetKills();
        foreach (var kill in kills)
        {
            Dispatcher.Invoke(() => { AddKillToScreen(kill); });
        }
    }

    private void RegisterUIEventHandlers()
    {
        if (_UIEventsRegistered)
            return;

        // Username
        TrackREventDispatcher.PlayerLoginEvent += (username) =>
        {
            Dispatcher.Invoke(() =>
            {
                PilotNameTextBox.Text = username;
                AdjustFontSize(PilotNameTextBox);
                LocalPlayerData.Username = username;
            });
        };

        // Ship
        TrackREventDispatcher.JumpDriveStateChangedEvent += (data) =>
        {
            Dispatcher.Invoke(() =>
            {
                PlayerShipTextBox.Text = data.ShipName;
                AdjustFontSize(PlayerShipTextBox);
                LocalPlayerData.PlayerShip = data.ShipName;
                LocalPlayerData.LastSeenVehicleLocation = data.Location;
                LocationTextBox.Text = data.Location;
                AdjustFontSize(LocationTextBox);
            });
        };

        // Game Mode
        TrackREventDispatcher.PlayerChangedGameModeEvent += (mode) =>
        {
            Dispatcher.Invoke(() =>
            {
                GameModeTextBox.Text = mode == GameMode.PersistentUniverse ? mode.ToString() : GameMode.Unknown.ToString();
                AdjustFontSize(GameModeTextBox);
                LocalPlayerData.CurrentGameMode = mode;
            });
        };

        // Game Version
        TrackREventDispatcher.GameVersionEvent += (version) =>
        {
            LocalPlayerData.GameVersion = version;
        };

        // Actor Death
        TrackREventDispatcher.ActorDeathEvent += async (actorDeathData) =>
        {
            if (actorDeathData.VictimPilot != LocalPlayerData.Username)
            {
                var playerData = await WebHandler.GetPlayerData(actorDeathData.VictimPilot);
                if (playerData != null)
                {
                    var killData = new KillData
                    {
                        EnemyPilot = actorDeathData.VictimPilot,
                        EnemyShip = actorDeathData.VictimShip,
                        Location = LocalPlayerData.LastSeenVehicleLocation,
                        OrgAffiliation = playerData?.OrgName,
                        Weapon = actorDeathData.Weapon,
                        Ship = LocalPlayerData.PlayerShip ?? "Unknown",
                        Method = actorDeathData.DamageType,
                        RecordNumber = playerData?.UEERecord,
                        GameVersion = LocalPlayerData.GameVersion ?? "Unknown",
                        TrackRver = "2.10",
                        Enlisted = playerData?.JoinDate,
                        KillTime = DateTime.UtcNow.ToString("dd MMM yyyy HH:mm"),
                        PFP = playerData?.PFPURL ?? "https://cdn.robertsspaceindustries.com/static/images/account/avatar_default_big.jpg"
                    };

                    switch (LocalPlayerData.CurrentGameMode)
                    {
                        case GameMode.PersistentUniverse:
                            killData.Mode = "pu";
                            break;
                        case GameMode.ArenaCommander:
                            killData.Mode = "ac";
                            break;
                    }

                    // Add kill to UI
                    Dispatcher.Invoke(() =>
                    {
                        AddKillToScreen(killData);
                    });

                    // Only submit kill data if not in offline mode
                    if (ConfigManager.OfflineMode == 0)
                    {
                        await WebHandler.SubmitKill(killData);
                    }

                    _killHistoryManager.AddKill(killData);
                    VisorWipe();
                    VideoRecord();
                }
            }
        };

        // Vehicle Destruction
        TrackREventDispatcher.VehicleDestructionEvent += (data) =>
        {
            Dispatcher.Invoke(() =>
            {
                LocalPlayerData.LastSeenVehicleLocation = data.VehicleZone;
                LocationTextBox.Text = data.VehicleZone;
                AdjustFontSize(LocationTextBox);
            });
        };

        _UIEventsRegistered = true;
    }

    private void AddKillToScreen(KillData killData)
    {
        // Fetch the dynamic resource for AltTextColor
        var altTextColorBrush = new SolidColorBrush((Color)Application.Current.Resources["AltTextColor"]);
        var accentColorBrush = new SolidColorBrush((Color)Application.Current.Resources["AccentColor"]);

        // Fetch the Orbitron FontFamily from resources
        var orbitronFontFamily = (FontFamily)Application.Current.Resources["Orbitron"];
        var gemunuFontFamily = (FontFamily)Application.Current.Resources["Gemunu"];

        // Create a new TextBlock for each kill
        var killTextBlock = new TextBlock
        {
            Margin = new Thickness(0, 10, 0, 10),
            Style = (Style)Application.Current.Resources["RoundedTextBlock"], // Apply style for text
            FontSize = 14,
            FontWeight = FontWeights.Bold,
            FontFamily = gemunuFontFamily,
        };

        // Add styled content using Run elements
        killTextBlock.Inlines.Add(new Run("Victim Name: ")
        {
            Foreground = altTextColorBrush,
            FontFamily = orbitronFontFamily,
        });
        killTextBlock.Inlines.Add(new Run($"{killData.EnemyPilot}\n"));

        // Repeat for other lines
        killTextBlock.Inlines.Add(new Run("Victim Ship: ")
        {
            Foreground = altTextColorBrush,
            FontFamily = orbitronFontFamily,
        });
        killTextBlock.Inlines.Add(new Run($"{killData.EnemyShip}\n"));

        killTextBlock.Inlines.Add(new Run("Victim Org: ")
        {
            Foreground = altTextColorBrush,
            FontFamily = orbitronFontFamily,
        });
        killTextBlock.Inlines.Add(new Run($"{killData.OrgAffiliation}\n"));

        killTextBlock.Inlines.Add(new Run("Join Date: ")
        {
            Foreground = altTextColorBrush,
            FontFamily = orbitronFontFamily,
        });
        killTextBlock.Inlines.Add(new Run($"{killData.Enlisted}\n"));

        killTextBlock.Inlines.Add(new Run("UEE Record: ")
        {
            Foreground = altTextColorBrush,
            FontFamily = orbitronFontFamily,
        });

        killTextBlock.Inlines.Add(new Run($"{killData.RecordNumber}\n"));

        killTextBlock.Inlines.Add(new Run("Kill Time: ")
        {
            Foreground = altTextColorBrush,
            FontFamily = orbitronFontFamily,
        });
        killTextBlock.Inlines.Add(new Run($"{killData.KillTime}"));

        // Create a Border and apply the RoundedTextBlockWithBorder style
        var killBorder = new Border
        {
            Style = (Style)Application.Current.Resources["RoundedTextBlockWithBorder"], // Apply border style
        };

        // Create a Grid to hold the TextBlock and the Image
        var killGrid = new Grid
        {
            Width = 400, // Adjust the width of the Grid
            Height = 130, // Adjust the height as needed
        };

        // Define two columns in the Grid: one for the text and one for the image
        killGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(3, GridUnitType.Star) }); // Text column
        killGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) }); // Image column

        // Add the TextBlock to the first column of the Grid
        Grid.SetColumn(killTextBlock, 0);
        killGrid.Children.Add(killTextBlock);

        if (killData.PFP == "")
        {
            killData.PFP = "https://cdn.robertsspaceindustries.com/static/images/account/avatar_default_big.jpg";
        }

        // Create the Image for the profile
        var profileImage = new Image
        {
            Source = new BitmapImage(new Uri(killData.PFP ?? "https://cdn.robertsspaceindustries.com/static/images/account/avatar_default_big.jpg")),
            Width = 90,
            Height = 90,
            Stretch = Stretch.Fill, // Adjust how the image fits
        };

        // Create a Border around the Image
        var imageBorder = new Border();
        imageBorder.SetResourceReference(Border.BorderBrushProperty, "AccentBrush");
        imageBorder.BorderThickness = new Thickness(2);
        imageBorder.Padding = new Thickness(0);
        imageBorder.CornerRadius = new CornerRadius(5);
        imageBorder.Margin = new Thickness(10, 18, 15, 18);
        imageBorder.Child = profileImage;

        // Add the Border (with the image inside) to the Grid
        Grid.SetColumn(imageBorder, 1);
        killGrid.Children.Add(imageBorder);

        // Set the Grid as the child of the Border
        killBorder.Child = killGrid;

        // Add the new Border to the StackPanel inside the Border
        Dispatcher.Invoke(() =>
        {
            KillFeedStackPanel.Children.Insert(0, killBorder);
        });
    }

    public void StopButton_Click(object sender, RoutedEventArgs e)
    {
        _logHandler?.StopMonitoring();
    }

    private void AdjustFontSize(TextBlock textBlock)
    {
        // Set a starting font size
        double fontSize = 14;
        double maxWidth = textBlock.Width;

        if (string.IsNullOrEmpty(textBlock.Text) || double.IsNaN(maxWidth))
            return;

        // Measure the rendered width of the text
        FormattedText formattedText = new FormattedText(
            textBlock.Text,
            CultureInfo.CurrentCulture,
            FlowDirection.LeftToRight,
            new Typeface(textBlock.FontFamily, textBlock.FontStyle, textBlock.FontWeight, textBlock.FontStretch),
            fontSize,
            textBlock.Foreground,
            VisualTreeHelper.GetDpi(this).PixelsPerDip
        );

        // Reduce font size until text fits within the width
        while (formattedText.Width > maxWidth && fontSize > 6)
        {
            fontSize -= 0.5;
            formattedText = new FormattedText(
                textBlock.Text,
                CultureInfo.CurrentCulture,
                FlowDirection.LeftToRight,
                new Typeface(textBlock.FontFamily, textBlock.FontStyle, textBlock.FontWeight, textBlock.FontStretch),
                fontSize,
                textBlock.Foreground,
                VisualTreeHelper.GetDpi(this).PixelsPerDip
            );
        }
        // Apply the adjusted font size
        textBlock.FontSize = fontSize;
    }

    public static void RunAHKScript(string? path)
    {
        if (string.IsNullOrEmpty(path) || string.IsNullOrEmpty(ConfigManager.AHKScriptFolder))
        {
            return;
        }

        string scriptPath = Path.Combine(ConfigManager.AHKScriptFolder, path);

        if (!File.Exists(scriptPath))
        {
            return;
        }

        // Run the script using powershell
        using var ahkProcess = new Process();

        // Runs the script via Explorer, ensuring it uses whatever the
        // default binary for AHK is. Skips having to find a specific path to AHK
        ahkProcess.StartInfo.FileName = "explorer";
        ahkProcess.StartInfo.Arguments = "\"" + scriptPath + "\"";
        ahkProcess.Start();
    }

    private void VisorWipe()
    {
        if (ConfigManager.VisorWipe == 1)
        {
            RunAHKScript(ConfigManager.VisorWipeScript);
        }
    }

    private void VideoRecord()
    {
        if (ConfigManager.VideoRecord == 1)
        {
            RunAHKScript(ConfigManager.VideoRecordScript);
        }
    }

    public void InitializeLogHandler()
    {
        if (_logHandler == null)
        {
            RegisterUIEventHandlers();
            _logHandler = new LogHandler(ConfigManager.LogFile);
            _logHandler.Initialize();
            _isLogHandlerRunning = true;
        }
        else if (!_isLogHandlerRunning)
        {
            _logHandler.Initialize();
            _isLogHandlerRunning = true;
        }
    }
    

    public void Cleanup()
    {
        // Stop and dispose the status check timer
        _statusCheckTimer?.Stop();
        _statusCheckTimer?.Dispose();

        // Stop the log handler if it's running
        _logHandler?.StopMonitoring();
    }

    private bool IsStarCitizenRunning()
    {
        return Process.GetProcessesByName("StarCitizen").Length > 0;
    }
}