using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Input;

namespace XLAB
{
    internal sealed class VerificationEditWindowViewModel : ObservableObject
    {
        private string _rejectionReason;
        private DocumentFormReference _selectedDocumentForm;
        private int? _selectedVerifierId;
        private string _stickerNumber;
        private string _validationMessage;
        private DateTime? _verificationDate;
        private string _verificationDocumentNumber;

        public VerificationEditWindowViewModel(
            VerificationEditSeed seed,
            IReadOnlyList<PersonReference> verifiers,
            IReadOnlyList<DocumentFormReference> documentForms)
        {
            if (seed == null)
            {
                throw new ArgumentNullException("seed");
            }

            IsPassed = seed.IsPassed;
            Verifiers = new ObservableCollection<PersonReference>(verifiers ?? new List<PersonReference>());
            DocumentForms = new ObservableCollection<DocumentFormReference>(documentForms ?? new List<DocumentFormReference>());

            VerificationDate = seed.VerificationDate ?? DateTime.Today;
            SelectedVerifierId = seed.VerifierId;
            StickerNumber = seed.StickerNumber ?? string.Empty;
            VerificationDocumentNumber = seed.VerificationDocumentNumber ?? string.Empty;
            RejectionReason = seed.RejectionReason ?? string.Empty;

            if (seed.DocumentForm != null)
            {
                SelectedDocumentForm = DocumentForms.FirstOrDefault(delegate(DocumentFormReference item)
                {
                    return item.DocumentFormId == seed.DocumentForm.DocumentFormId;
                });
            }

            if (SelectedDocumentForm == null && DocumentForms.Count > 0)
            {
                SelectedDocumentForm = DocumentForms[0];
            }

            ConfirmCommand = new RelayCommand(Confirm);
            CancelCommand = new RelayCommand(Cancel);
        }

        public event EventHandler<bool?> CloseRequested;

        public ICommand CancelCommand { get; private set; }

        public ICommand ConfirmCommand { get; private set; }

        public ObservableCollection<DocumentFormReference> DocumentForms { get; private set; }

        public string DocumentNumberCaption
        {
            get { return IsPassed ? "Номер свидетельства" : "Номер извещения"; }
        }

        public string DocumentFormCaption
        {
            get { return IsPassed ? "Форма свидетельства" : "Форма извещения"; }
        }

        public bool IsPassed { get; private set; }

        public Visibility RejectionReasonVisibility
        {
            get { return IsPassed ? Visibility.Collapsed : Visibility.Visible; }
        }

        public string RejectionReason
        {
            get { return _rejectionReason; }
            set { SetProperty(ref _rejectionReason, value); }
        }

        public DocumentFormReference SelectedDocumentForm
        {
            get { return _selectedDocumentForm; }
            set { SetProperty(ref _selectedDocumentForm, value); }
        }

        public int? SelectedVerifierId
        {
            get { return _selectedVerifierId; }
            set { SetProperty(ref _selectedVerifierId, value); }
        }

        public Visibility StickerVisibility
        {
            get { return IsPassed ? Visibility.Visible : Visibility.Collapsed; }
        }

        public string StickerNumber
        {
            get { return _stickerNumber; }
            set { SetProperty(ref _stickerNumber, value); }
        }

        public string Title
        {
            get { return IsPassed ? "Результат поверки: годен" : "Результат поверки: забракован"; }
        }

        public string ValidationMessage
        {
            get { return _validationMessage; }
            private set { SetProperty(ref _validationMessage, value); }
        }

        public DateTime? VerificationDate
        {
            get { return _verificationDate; }
            set { SetProperty(ref _verificationDate, value); }
        }

        public string VerificationDocumentNumber
        {
            get { return _verificationDocumentNumber; }
            set { SetProperty(ref _verificationDocumentNumber, value); }
        }

        public ObservableCollection<PersonReference> Verifiers { get; private set; }

        public VerificationEditResult ToResult()
        {
            var verifier = Verifiers.FirstOrDefault(delegate(PersonReference item)
            {
                return item.PersonId == SelectedVerifierId;
            });

            return new VerificationEditResult
            {
                DocumentFormId = SelectedDocumentForm == null ? 0 : SelectedDocumentForm.DocumentFormId,
                DocumentLinkTypeId = SelectedDocumentForm == null ? 0 : SelectedDocumentForm.LinkTypeId,
                IsPassed = IsPassed,
                RejectionReason = string.IsNullOrWhiteSpace(RejectionReason) ? string.Empty : RejectionReason.Trim(),
                StickerNumber = string.IsNullOrWhiteSpace(StickerNumber) ? string.Empty : StickerNumber.Trim(),
                VerificationDate = VerificationDate.HasValue ? VerificationDate.Value : DateTime.Today,
                VerificationDocumentNumber = string.IsNullOrWhiteSpace(VerificationDocumentNumber) ? string.Empty : VerificationDocumentNumber.Trim(),
                VerifierId = SelectedVerifierId.GetValueOrDefault(),
                VerifierName = verifier == null ? string.Empty : verifier.FullName
            };
        }

        private void Cancel(object parameter)
        {
            RaiseCloseRequested(false);
        }

        private void Confirm(object parameter)
        {
            if (!VerificationDate.HasValue)
            {
                ValidationMessage = "Укажите дату поверки.";
                return;
            }

            if (!SelectedVerifierId.HasValue)
            {
                ValidationMessage = "Выберите поверителя.";
                return;
            }

            if (!string.IsNullOrWhiteSpace(VerificationDocumentNumber) && SelectedDocumentForm == null)
            {
                ValidationMessage = "Выберите форму документа.";
                return;
            }

            if (!IsPassed)
            {
                if (string.IsNullOrWhiteSpace(RejectionReason))
                {
                    ValidationMessage = "Укажите причину непригодности.";
                    return;
                }

                if (string.IsNullOrWhiteSpace(VerificationDocumentNumber))
                {
                    ValidationMessage = "Укажите номер извещения о непригодности.";
                    return;
                }
            }

            ValidationMessage = string.Empty;
            RaiseCloseRequested(true);
        }

        private void RaiseCloseRequested(bool? dialogResult)
        {
            var handler = CloseRequested;
            if (handler != null)
            {
                handler(this, dialogResult);
            }
        }
    }
}
