using CareFusion.Mosaic.Interfaces.Types.Stock;
using System;
using System.Runtime.Serialization;

namespace CareFusion.Mosaic.Interfaces.Types.Packs
{
    /// <summary>
    /// Class which represents a pack which is stored in a storage system.
    /// </summary>
    [DataContract]
    public class RobotPack
    {
        #region Properties

        /// <summary>
        /// Gets or sets the identifier of the pack.
        /// </summary>
        [DataMember]
        public long ID { get; set; }

        /// <summary>
        /// Gets or sets the identifier of the according article.
        /// </summary>
        [DataMember]
        public int RobotArticleID { get; set; }

        /// <summary>
        /// Gets or sets the identifier of the storage system which stores the pack.
        /// </summary>
        [DataMember]
        public int ComponentID { get; set; }

        /// <summary>
        /// Gets or sets the it system internal article code.
        /// </summary>
        [DataMember]
        //!Warning: Remove that!!!
        public string PISArticleCode { get; set; }

        /// <summary>
        /// Gets or sets the robot used article code.
        /// </summary>
        [DataMember]
        public string RobotArticleCode { get; set; }

        /// <summary>
        /// Gets or sets the batch number which was used during pack input.
        /// </summary>
        [DataMember]
        public string BatchNumber { get; set; }

        /// <summary>
        /// Gets or sets/// </summary>
        [DataMember]/// </summary>
        public string DeliveryNumber { get; set; }

        /// <summary>
        /// Gets or sets the ExpiryDate of the pack.
        /// </summary>
        [DataMember]
        public DateTime ExpiryDate { get; set; }

        /// <summary>
        /// Gets or sets the  source of ExpiryDate.
        /// </summary>
        [DataMember]
        public ExpiryDateSource ExpiryDateSource { get; set; }

        /// <summary>
        /// Gets or sets the external identifier which was assigned during pack input.
        /// </summary>
        [DataMember]
        public string ExternalID { get; set; }

        /// <summary>
        /// Gets or sets the optional serial number of this stock output order item.
        /// </summary>
        [DataMember]
        public string SerialNumber { get; set; }

        /// <summary>
        /// Gets or sets a flag indicating whether this pack is in fridge.
        /// </summary>
        [DataMember]
        public bool IsInFridge { get; set; }

        /// <summary>
        /// Gets or sets the shape of the pack.
        /// </summary>
        [DataMember]
        public PackShape Shape { get; set; }

        /// <summary>
        /// Gets or sets the amount of pills in the pack.
        /// </summary>
        [DataMember]
        public int SubItemQuantity { get; set; }

        /// <summary>
        /// Gets or sets the raw scancode of the pack.
        /// </summary>
        [DataMember]
        public string ScanCode { get; set; }

        /// <summary>
        /// Gets or sets the date when the pack was input into the storage system.
        /// </summary>
        [DataMember]
        public DateTime StockInDate { get; set; }

        /// <summary>
        /// Gets or sets the depth of the pack in millimeters.
        /// </summary>
        [DataMember]
        public int Depth { get; set; }

        /// <summary>
        /// Gets or sets the height of the pack in millimeters.
        /// </summary>
        [DataMember]
        public int Height { get; set; }

        /// <summary>
        /// Gets or sets the width of the pack in millimeters.
        /// </summary>
        [DataMember]
        public int Width { get; set; }

        /// <summary>
        /// Gets or sets a flag whether the pack is available for output.
        /// </summary>
        [DataMember]
        public bool IsAvailable { get; set; }

        /// <summary>
        /// Gets or sets a flag whether the pack is blocked -> no output is possible.
        /// </summary>
        [DataMember]
        public bool IsBlocked { get; set; }

        /// <summary>
        /// Gets or sets a flag whether the pack is online -> storage system is generally connected.
        /// </summary>
        [DataMember]
        public bool IsOnline { get; set; }

        /// <summary>
        /// Gets or sets the stock location identifier of the pack.
        /// </summary>
        [DataMember]
        public string StockLocationID { get; set; }

        /// <summary>
        /// Gets or sets the tenant identifier of the pack.
        /// </summary>
        [DataMember]
        public string TenantID { get; set; }

        /// <summary>
        /// Gets or sets the machine location of the pack.
        /// </summary>
        [DataMember]
        public string MachineLocation { get; set; }

        [DataMember]
        public Guid Guid { get; set; }

        /// <summary>
        /// Gets an array of the property names of this object.
        /// These names are required to serialize this object to the database.
        /// </summary>
        public string[] PropertyNames
        {
            get
            {
                return new string[]
                {
                    "ID", "RobotArticleID", "ComponentID", "RobotArticleCode",
                    "BatchNumber", "DeliveryNumber", "ExpiryDate", "ExpiryDateSource", "ExternalID",
                    "IsInFridge", "Shape", "SubItemQuantity", "ScanCode",
                    "StockInDate", "Depth", "Height", "Width",
                    "IsAvailable", "IsBlocked", "IsOnline", "StockLocationID",
                    "TenantID", "MachineLocation", nameof(Guid)
                };
            }
        }

        /// <summary>
        /// Gets an array of the raw property values of this object.
        /// These values are required to serialize this object to the database.
        /// </summary>
        public object[] PropertyValues
        {
            get
            {
                return new object[]
                {
                    (int)this.ID,
                    this.RobotArticleID,
                    this.ComponentID,
                    this.RobotArticleCode,
                    this.BatchNumber,
                    this.DeliveryNumber,
                    this.ExpiryDate,
                    this.ExpiryDateSource.ToString(),
                    this.ExternalID,
                    this.IsInFridge,
                    this.Shape.ToString(),
                    this.SubItemQuantity,
                    this.ScanCode,
                    this.StockInDate,
                    this.Depth,
                    this.Height,
                    this.Width,
                    this.IsAvailable,
                    this.IsBlocked,
                    this.IsOnline,
                    this.StockLocationID,
                    this.TenantID,
                    this.MachineLocation
                };
            }
        }

        /// <summary>
        /// Gets an array of the property names which define the unique key of this object.
        /// These names are required to delete this object from the database.
        /// </summary>
        public string[] KeyPropertyNames
        {
            get
            {
                return new string[] { "ID", "RobotArticleID", "ComponentID" };
            }
        }

        /// <summary>
        /// Gets an array of the raw property values which define the unique key of this object.
        /// These names are required to delete this object from the database.
        /// </summary>
        public object[] KeyPropertyValues
        {
            get
            {
                return new object[] { (int)this.ID, this.RobotArticleID, this.ComponentID };
            }
        }

        #endregion

        /// <summary>
        /// Initializes a new instance of the <see cref="RobotPack"/> class.
        /// </summary>
        public RobotPack()
        {
            this.IsBlocked = false;
            this.IsOnline = true;
            this.IsAvailable = true;

            this.RobotArticleCode = string.Empty;
            this.BatchNumber = string.Empty;
            this.DeliveryNumber = string.Empty;
            this.ExternalID = string.Empty;
            this.ScanCode = string.Empty;
            this.MachineLocation = string.Empty;
            this.StockLocationID = string.Empty;
            this.TenantID = string.Empty;
        }
    }
}
