using CareFusion.Mosaic.Converters.Wwks2.Types;
using CareFusion.Mosaic.Interfaces.Converters;
using CareFusion.Mosaic.Interfaces.Messages;
using Rowa.Mosaic.Shared.Converters;
using System.Collections.Generic;
using System.Xml.Serialization;

namespace CareFusion.Mosaic.Converters.Wwks2.Messages.Stock
{
    /// <summary>
    /// Class which represents the WWKS 2.0 StockUpdateRequest message envelope.
    /// </summary>
    [XmlType(TypeName = "WWKS")]

    public class StockUpdateRequestEnvelope : EnvelopeBase, IMessageConversion
    {
        [XmlElement]
        public StockUpdateRequest StockUpdateRequest { get; set; }

        /// <summary>
        /// Translates this object instance into a Mosaic message.
        /// </summary>
        /// <param name="converterStream">The converter stream instance which request the message conversion.</param>
        /// <returns>
        /// The Mosaic message representation of this object.
        /// </returns>
        public MosaicMessage ToMosaicMessage(IConverterStream converterStream)
        {
            return StockUpdateRequest.ToMosaicMessage(converterStream);
        }
    }

    /// <summary>
    /// Class which represents the WWKS 2.0 StockUpdateRequest message.
    /// </summary>
    public class StockUpdateRequest : MessageBase, IMessageConversion
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="StockUpdateRequest"/> class.
        /// </summary>
        public StockUpdateRequest()
        {

        }

        /// <summary>
        /// Initializes a new instance of the <see cref="StockUpdateRequest"/> class.
        /// </summary>
        /// <param name="message">The message to use for initialization.</param>
        public StockUpdateRequest(MosaicMessage mosaicMessage)
        {
            var request = (CareFusion.Mosaic.Interfaces.Messages.Stock.StockUpdateRequest) mosaicMessage;
            Criteria = request.Criteria;
            Pack = request.Pack;
            Id = mosaicMessage.ID;
            Destination = mosaicMessage.Destination;
            Source = mosaicMessage.Source;
        }

        /// <summary>
        /// Translates this object instance into a Mosaic message.
        /// </summary>
        /// <param name="converterStream">The converter stream instance which request the message conversion.</param>
        /// <returns>
        /// The Mosaic message representation of this object.
        /// </returns>
        public MosaicMessage ToMosaicMessage(IConverterStream converterStream)
        {
            var request = new CareFusion.Mosaic.Interfaces.Messages.Stock.StockUpdateRequest(converterStream);
            request.ID = Id;
            request.Source = Source;
            request.Destination = Destination;
            request.Criteria = new List<Criteria>();
            foreach (var criterion in Criteria ?? new List<Criteria>())
            {
                request.Criteria.Add(new Criteria
                {
                    ArticleId = TextConverter.UnescapeInvalidXmlChars(criterion.ArticleId),
                    BatchNumber = TextConverter.UnescapeInvalidXmlChars(criterion.BatchNumber),
                    SerialNumber = TextConverter.UnescapeInvalidXmlChars(criterion.SerialNumber),
                    PackId = TextConverter.UnescapeInvalidXmlChars(criterion.PackId),
                    StockLocationId = TextConverter.UnescapeInvalidXmlChars(criterion.StockLocationId),
                    MachineLocation = TextConverter.UnescapeInvalidXmlChars(criterion.MachineLocation),
                    ExternalId = TextConverter.UnescapeInvalidXmlChars(criterion.ExternalId),
                    
                });
            }

            request.Pack = new Pack
            {
                BatchNumber = TextConverter.UnescapeInvalidXmlChars(Pack?.BatchNumber)
            };

            return request;
        }

        /// <summary>
        /// The filter criteria to which articles and packs the update applies.
        /// </summary>
        [XmlElement]
        public List<Criteria> Criteria { get; set; }

        /// <summary>
        /// The new information that should be applied to the stock
        /// </summary>
        [XmlElement]
        public Pack Pack { get; set; }
    }
}
