using System;
using System.Collections.ObjectModel;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using Valg.EVA.Skanning.Resources.Language;
using Prism.Commands;

namespace Valg.EVA.Skanning.UserInterfaceElements.MessageBox
{
    public class MessageBoxViewModel : ViewModelBase, IMessageBoxViewModel
    {
        private string titleText;
        private string messageText;
        private string possibleSolutionText;
        private MessageBoxType messageBoxType;
        private string technicalErrorMessage;
        private bool showTechnicalErrorMessage;
        private string showTechnicalDetailButtonText;
        private ICommand[] possibleSolutionCommands;

        public MessageBoxViewModel()
        {
            ToggleViewTechnicalDataCommand = new DelegateCommand(ToggleTechnicalDataView);
            ShowTechnicalDetailButtonText = LanguageString.MessageBox_ShowTechnicalDataButtonText_View;
            CancelCommandButtonText = LanguageString.Button_Close;
        }

        public string TitleText
        {
            get { return titleText; }
            set
            {
                if (titleText != value)
                {
                    titleText = value;
                    OnPropertyChanged();
                }
            }
        }

        public MessageBoxType MessageBoxType
        {
            get { return messageBoxType; }
            set
            {
                messageBoxType = value;
                OnPropertyChanged();
            }
        }

        public string MessageText
        {
            get { return messageText; }
            set
            {
                if (messageText != value)
                {
                    messageText = value;
                    OnPropertyChanged();
                }
            }
        }

        public bool HasPossibleSolutions => PossibleSolutionList.Count > 0;

        public bool ShowConfirmButton => ConfirmCommand != null;

        public bool ShowTechnicalDetails => !string.IsNullOrWhiteSpace(TechnicalErrorMessage);

        public Collection<object> PossibleSolutionList
        {
            get
            {
                if (string.IsNullOrEmpty(possibleSolutionText))
                {
                    return new Collection<object>();
                }


                return CreateSolutionsCollection();
            }
        }

        private Collection<object> CreateSolutionsCollection()
        {
            var allSolutions = new Collection<object>();

            var commandCount = 0;
            foreach (var solution in possibleSolutionText.Split('#'))
            {
                if (!solution.Contains("<command>"))
                {
                    allSolutions.Add(solution);
                }
                else
                {
                    allSolutions.Add(new ErrorSolutionWithCommand(solution, possibleSolutionCommands[commandCount]));

                    commandCount++;
                }
            }

            return new Collection<object>(allSolutions);
        }

        public BitmapImage ImageSource { get; set; }

        public string TechnicalErrorMessage
        {
            get { return technicalErrorMessage; }
            set
            {
                if (technicalErrorMessage != value)
                {
                    technicalErrorMessage = value;
                    OnPropertyChanged();
                }
            }
        }

        public bool ShowTechnicalErrorMessage
        {
            get { return showTechnicalErrorMessage; }
            set
            {
                if (showTechnicalErrorMessage != value)
                {
                    showTechnicalErrorMessage = value;
                    OnPropertyChanged();
                }
            }
        }

        public string ShowTechnicalDetailButtonText
        {
            get { return showTechnicalDetailButtonText; }
            set
            {
                if (showTechnicalDetailButtonText != value)
                {
                    showTechnicalDetailButtonText = value;
                    OnPropertyChanged();
                }
            }
        }

        public DelegateCommand ToggleViewTechnicalDataCommand { get; }
        public DelegateCommand ConfirmCommand { get; private set ; }
        public DelegateCommand CancelCommand { get; private set; }
        public string CancelCommandButtonText { get; private set; }
        public string ConfirmCommandButtonText { get; private set; }

        public void Initialize(string messageBoxTitle, string messageBoxMessage, string possibleSolutionMessage,
            MessageBoxType boxType, Exception[] errorException, DelegateCommand cancelCommand, ICommand[] solutionCommands)
        {
            possibleSolutionCommands = solutionCommands;
            TitleText = messageBoxTitle;
            MessageText = messageBoxMessage;
            possibleSolutionText = possibleSolutionMessage;
            MessageBoxType = boxType;
            LoadImage();
            if (errorException != null && errorException.Length > 0)
            {
                foreach (var exception in errorException)
                {
                    TechnicalErrorMessage += exception.Message + Environment.NewLine + exception.StackTrace;
                    TechnicalErrorMessage += Environment.NewLine;
                    TechnicalErrorMessage += "------ END OF EXCEPTION DETAILS -----";
                    TechnicalErrorMessage += Environment.NewLine;
                }
            }
            CancelCommand = cancelCommand;
        }

        public void Initialize(string messageBoxTitle, string messageBoxMessage, MessageBoxType msgBoxType, 
            DelegateCommand confirmCommand, DelegateCommand cancelCommand)
        {
            TitleText = messageBoxTitle;
            MessageText = messageBoxMessage;
            MessageBoxType = msgBoxType;
            LoadImage();
            ConfirmCommand = confirmCommand;
            CancelCommand = cancelCommand;
            CancelCommandButtonText = LanguageString.Button_Cancel;
            ConfirmCommandButtonText = LanguageString.Button_Ok;
        }

        private void ToggleTechnicalDataView()
        {
            if (ShowTechnicalErrorMessage)
            {
                ShowTechnicalErrorMessage = false;
                ShowTechnicalDetailButtonText = LanguageString.MessageBox_ShowTechnicalDataButtonText_View;
            }
            else
            {
                ShowTechnicalErrorMessage = true;
                ShowTechnicalDetailButtonText = LanguageString.MessageBox_ShowTechnicalDataButtonText_Hide;
            }
        }

        private void LoadImage()
        {
            switch (MessageBoxType)
            {
                case MessageBoxType.Error:
                    LoadImage("Error.png");
                    break;

                case MessageBoxType.Warning:
                    LoadImage("Warning.png");
                    break;

                case MessageBoxType.Information:
                    LoadImage("Information.png");
                    break;

                default:
                    throw new NotImplementedException($"The selected MessageBoxType {messageBoxType} is not implemented.");
            }
        }

        private void LoadImage(string imageName)
        {
            const string imageLocation = @"pack://application:,,,/Valg.EVA.Skanning.Assets;component/Images/Icons/";
            ImageSource = new BitmapImage(new Uri($"{imageLocation}{imageName}"));
        }
    }
}
