using System;
using System.Windows.Input;
using Chernobyl.App.Core;
using Chernobyl.Creation;
using GalaSoft.MvvmLight.CommandWpf;

namespace Chernobyl.App.Creation
{
    /// <summary>
    /// View model representing an instance that can create objects.
    /// </summary>
    public abstract class FactoryViewModel : ViewModel
    {
        /// <inheritdoc />
        protected FactoryViewModel(Action create, string creationName)
        {
            _create = create;
            CreationName = creationName;
            CreateCommand = new RelayCommand(_create);
        }

        /// <summary>
        /// Invoked when an items must be created.
        /// </summary>
        public ICommand CreateCommand { get; }

        /// <summary>
        /// The action being taken.
        /// </summary>
        public string CreateCommandText => $"Create {CreationName}";

        /// <summary>
        /// The name of the item getting created.
        /// </summary>
        public string CreationName { get; }

        // RelayCommand holds the Action as a weak reference, so we have to hold onto it to prevent
        // it from getting garbage collected.
        // ReSharper disable PrivateFieldCanBeConvertedToLocalVariable
        readonly Action _create;
        // ReSharper restore PrivateFieldCanBeConvertedToLocalVariable
    }

    /// <summary>
    /// A generic version of <see cref="FactoryViewModel"/>.
    /// </summary>
    public class FactoryViewModel<T> : FactoryViewModel
    {
        /// <inheritdoc />
        public FactoryViewModel(IFactory<T> factory, string creationName)
            : base(() => factory.Create(), creationName ?? "")
        {
            Factory = factory;
        }

        /// <summary>
        /// The instance used for construction.
        /// </summary>
        public IFactory<T> Factory { get; }
    }
}