using System.Collections.Generic;
using System.Windows;

namespace XLAB2
{
    internal interface IDialogService
    {
        DocumentEditorResult ShowCreateDocumentDialog(DocumentEditorResult seed);

        IReadOnlyList<AvailableInstrumentItem> ShowInstrumentPickerDialog(string customerName, IReadOnlyList<AvailableInstrumentItem> instruments);

        InstrumentTypeSelectionResult ShowInstrumentTypeDialog(string customerName, IReadOnlyList<AvailableInstrumentItem> instrumentTypes);

        IReadOnlyList<string> ShowCloneVerificationDialog(CloneVerificationSeed seed);

        SpoiDirectoryItem ShowSpoiEditDialog(SpoiDirectoryItem seed, bool isNew, IReadOnlyList<SpoiDirectoryItem> existingItems);

        SpnmtpDirectoryItem ShowSpnmtpEditDialog(SpnmtpDirectoryItem seed, bool isNew, IReadOnlyList<SpnmtpDirectoryItem> existingItems);

        VerificationEditResult ShowVerificationDialog(
            VerificationEditSeed seed,
            IReadOnlyList<PersonReference> verifiers,
            IReadOnlyList<DocumentFormReference> documentForms);

        bool Confirm(string message);

        void ShowError(string message);

        void ShowInfo(string message);

        void ShowWarning(string message);
    }

    internal sealed class DialogService : IDialogService
    {
        public DialogService()
        {
        }

        public DialogService(Window owner)
        {
            Owner = owner;
        }

        public Window Owner { get; set; }

        public DocumentEditorResult ShowCreateDocumentDialog(DocumentEditorResult seed)
        {
            var viewModel = new CreateDocumentWindowViewModel(seed);
            var window = new CreateDocumentWindow(viewModel);
            AttachOwner(window);

            var result = window.ShowDialog();
            return result.HasValue && result.Value ? viewModel.ToResult() : null;
        }

        public IReadOnlyList<AvailableInstrumentItem> ShowInstrumentPickerDialog(string customerName, IReadOnlyList<AvailableInstrumentItem> instruments)
        {
            var viewModel = new SelectInstrumentsWindowViewModel(customerName, instruments);
            var window = new SelectInstrumentsWindow(viewModel);
            AttachOwner(window);

            var result = window.ShowDialog();
            return result.HasValue && result.Value ? viewModel.GetSelectedItems() : null;
        }

        public InstrumentTypeSelectionResult ShowInstrumentTypeDialog(string customerName, IReadOnlyList<AvailableInstrumentItem> instrumentTypes)
        {
            var viewModel = new SelectInstrumentTypeWindowViewModel(customerName, instrumentTypes);
            var window = new SelectInstrumentTypeWindow(viewModel);
            AttachOwner(window);

            var result = window.ShowDialog();
            return result.HasValue && result.Value ? viewModel.GetResult() : null;
        }

        public IReadOnlyList<string> ShowCloneVerificationDialog(CloneVerificationSeed seed)
        {
            var viewModel = new CloneVerificationWindowViewModel(seed);
            var window = new CloneVerificationWindow(viewModel);
            AttachOwner(window);

            var result = window.ShowDialog();
            return result.HasValue && result.Value ? viewModel.GetSerialNumbers() : null;
        }

        public SpoiDirectoryItem ShowSpoiEditDialog(SpoiDirectoryItem seed, bool isNew, IReadOnlyList<SpoiDirectoryItem> existingItems)
        {
            var viewModel = new SpoiEditWindowViewModel(seed, isNew, existingItems);
            var window = new SpoiEditWindow(viewModel);
            AttachOwner(window);

            var result = window.ShowDialog();
            return result.HasValue && result.Value ? viewModel.ToResult() : null;
        }

        public SpnmtpDirectoryItem ShowSpnmtpEditDialog(SpnmtpDirectoryItem seed, bool isNew, IReadOnlyList<SpnmtpDirectoryItem> existingItems)
        {
            var viewModel = new SpnmtpEditWindowViewModel(seed, isNew, existingItems);
            var window = new SpnmtpEditWindow(viewModel);
            AttachOwner(window);

            var result = window.ShowDialog();
            return result.HasValue && result.Value ? viewModel.ToResult() : null;
        }

        public VerificationEditResult ShowVerificationDialog(
            VerificationEditSeed seed,
            IReadOnlyList<PersonReference> verifiers,
            IReadOnlyList<DocumentFormReference> documentForms)
        {
            var viewModel = new VerificationEditWindowViewModel(seed, verifiers, documentForms);
            var window = new VerificationEditWindow(viewModel);
            AttachOwner(window);

            var result = window.ShowDialog();
            return result.HasValue && result.Value ? viewModel.ToResult() : null;
        }

        public bool Confirm(string message)
        {
            return Owner == null
                ? MessageBox.Show(message, "ПСВ", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes
                : MessageBox.Show(Owner, message, "ПСВ", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes;
        }

        public void ShowError(string message)
        {
            ShowMessage(message, MessageBoxImage.Error);
        }

        public void ShowInfo(string message)
        {
            ShowMessage(message, MessageBoxImage.Information);
        }

        public void ShowWarning(string message)
        {
            ShowMessage(message, MessageBoxImage.Warning);
        }

        private void AttachOwner(Window window)
        {
            if (Owner != null)
            {
                window.Owner = Owner;
            }
        }

        private void ShowMessage(string message, MessageBoxImage image)
        {
            if (Owner == null)
            {
                MessageBox.Show(message, "ПСВ", MessageBoxButton.OK, image);
                return;
            }

            MessageBox.Show(Owner, message, "ПСВ", MessageBoxButton.OK, image);
        }
    }
}
