using System;
using System.Net;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Diagnostics;
using NotepadEnhanced.Helpers;
using NotepadEnhanced.Localization;

namespace NotepadEnhanced
{
    class UpdateChecker
    {
        private readonly string _downloadLink; // Page to scan for versioning
        private readonly string _updatePage; // Page to scan for versioning
        private bool _hideNoUpdateMessage;
        public event EventHandler Completed;

        public UpdateChecker(string downloadLink, string updatePage)
        {
            _downloadLink = downloadLink;
            _updatePage = updatePage;
        }

        public void BeginChecking(bool hideNoUpdateMessage)
        {
            _hideNoUpdateMessage = hideNoUpdateMessage;
            Cursor.Current = Cursors.WaitCursor;

            using (WebClient webClient = new WebClient())
            {
                webClient.DownloadStringCompleted += webClient_DownloadStringCompleted;

                try
                {
                    webClient.DownloadStringAsync(new Uri(_updatePage));
                }
                catch (Exception ex)
                {
                    if (!_hideNoUpdateMessage)
                    MsgBox.Show(ex.Message);
                }
            }
        }

        private void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Error != null || string.IsNullOrEmpty(e.Result))
            {
                if (!_hideNoUpdateMessage)
                MsgBox.Show(Strings.MsgCoundNotRetrieveData, MessageBoxIcon.Error);

                return;
            }

            // ex: Notepad Enhanced=[ver]7.4.6.0b[ver]
            string pattern = Application.ProductName + @"=\[ver\](?<version>\d\.\d\.\d\.\d)(?<status>|a|b)\[ver\]";
            Match match = Regex.Match(e.Result, pattern, RegexOptions.IgnoreCase);
            string finding = match.Groups["version"].Value;
            string status = match.Groups["status"].Value;
            char statusChar = ' ';
            if (status.Length > 0) statusChar = status[0];

            if (finding.Length.Equals(0))
            {
                if (!_hideNoUpdateMessage)
                MsgBox.Show(Strings.MsgUpdateInfoError, MessageBoxIcon.Asterisk);
                return;
            }

            int latestVersion = VersionToInt(finding);
            int appVersion = VersionToInt(Application.ProductVersion);

            if (latestVersion.Equals(0))
            {
                if (!_hideNoUpdateMessage)
                MsgBox.Show(Strings.MsgUpdateInfoError, MessageBoxIcon.Asterisk);
                return;
            }

            CheckVersions(appVersion, latestVersion, statusChar);

            if (Completed != null)
                Completed(this, EventArgs.Empty);
        }

        private void CheckVersions(int appVersion, int latestVersion, char status)
        {
            if (appVersion < latestVersion)
            {
                string message = Strings.MsgNewVersion;

                if (status == 'b')
                {
                    message += "\n\n" + Strings.MsgBetaDownload;
                }
                else if (status == 'a')
                {
                    message += "\n\n" + Strings.AlphaDownload;
                }

                DialogResult result = MsgBox.Show(message, MessageBoxIcon.Asterisk, MessageBoxButtons.OKCancel);

                if (result == DialogResult.OK)
                {
                    GoToDownloadLocation();
                }
            }
            else if (!_hideNoUpdateMessage)
            {
                    string message = string.Format(Strings.MsgUpToDate, Application.ProductName);

                    if (!_hideNoUpdateMessage)
                    MsgBox.Show(message, MessageBoxIcon.Asterisk);
            }
        }

        private void GoToDownloadLocation()
        {
            try
            {
                Process.Start(_downloadLink);
            }
            catch
            {
                if (!_hideNoUpdateMessage)
                MsgBox.Show(Strings.MsgDownloadLinkErrorMsg);
            }
        }

        /// <summary>
        /// Converts a version string with periods to an integer which we can test for greatness later
        /// </summary>
        private static int VersionToInt(string version)
        {
            version = version.Replace(".", string.Empty);
            int versionNum;
            int.TryParse(version, out versionNum);
            return versionNum;
        }
    }
}
