#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member

using System;
using Volpe.Cafe.MarketData.BaselineInfo;
using Volpe.Cafe.MarketData.Design;

namespace Volpe.Cafe.MarketData
{
    /// <summary>
    /// Represents a revision of a vehicle, with descriptions of its engineering characteristics and compliance
    /// attributes for a specific model year.
    /// </summary>
    /// <seealso cref="MarketData.Vehicle"/>
    /// <seealso cref="BaselineVehicle"/>
    [Serializable]
    public class VehicleRevision : ProductRevision, IVehicleRevision
    {
        #region <<< Constructors >>>

        /// <summary>
        /// Initializes a new instance of the <see cref="VehicleRevision"/> class for the specified model year, using
        /// the baseline values from the specified <see cref="IVehicle"/>.
        /// </summary>
        /// <param name="year">The model year associated with this vehicle revision.</param>
        /// <param name="veh">The underlying <see cref="IVehicle"/> associated with this vehicle revision.</param>
        public VehicleRevision(int year, IVehicle veh) : base(year, veh) { }

        /// <summary>
        /// Initializes a new instance of the <see cref="VehicleRevision"/> class for the specified model year, using
        /// the property values from the specified <see cref="IVehicleRevision"/>.
        /// </summary>
        /// <param name="year">The model year associated with this vehicle revision.</param>
        /// <param name="revision">
        ///     The vehicle revision to use for initializing this instance. This value should represent the vehicle's
        ///     revision for a preceding model year.
        /// </param>
        public VehicleRevision(int year, IVehicleRevision revision) : base(year, revision) { }

        #endregion

        #region <<< Properties >>>

        public IVehicle Vehicle => (IVehicle)this.Product;
        public new BaselineVehicle BaselineInfo => this.Vehicle.BaselineInfo;

        //----- general vehicle info -----
        public string Brand => this.BaselineInfo.Brand;
        public string Model => this.BaselineInfo.Model;
        public string Nameplate => this.BaselineInfo.Nameplate;

        public int PlatformCode { get; set; }
        public int EngineCode { get; set; }
        public int TransmissionCode { get; set; }

        //----- fuel-economy values -----
        public FuelValue FuelEconomy { get; set; }
        public FuelValue FuelShare { get; set; }
        public FuelType FuelType => this.FuelShare.FuelType;

        //----- sales/msrp -----
        public double Sales { get; set; }
        public double Msrp { get; set; }

        //----- regulatory classification -----
        public RegulatoryClass RegClass { get; set; }
        public SafetyClass SafetyClass => this.BaselineInfo.SafetyClass;
        public VehicleClass VehicleClass => this.BaselineInfo.VehicleClass;

        public TechnologyClass TechnologyClass => this.BaselineInfo.TechnologyClass;
        public EngineTechnologyClass EngineTechnologyClass => this.BaselineInfo.EngineTechnologyClass;

        public bool IsZevCandidate => this.BaselineInfo.IsZevCandidate;
        public int? ZEVCandidate => this.BaselineInfo.ZEVCandidate;
        public int ZevApplicationYear => this.BaselineInfo.ZevApplicationYear;
        public int ZevReferenceVehicleCode => this.BaselineInfo.ZevReferenceVehicleCode;

        public bool CARBAgreement => this.BaselineInfo.CARBAgreement;

        //----- vehicle characteristics -----
        public Origin Origin => this.BaselineInfo.Origin;

        public VehicleStyle Style => this.BaselineInfo.Style;
        public VehicleFrame Structure => this.BaselineInfo.Structure;
        public DriveType Drive => this.BaselineInfo.Drive;

        public double Footprint { get; set; }

        public double CurbWeightMR0 => this.BaselineInfo.CurbWeightMR0;
        public double CurbWeight { get; set; }
        public double GVWR { get; set; }
        public double GCWR { get; set; }

        public double FuelCapacity => this.BaselineInfo.FuelCapacity;

        //----- vehicle powertrain -----
        public HEVType HevType { get; set; }

        //----- values updated at end of model year -----
        public ComplianceCosts ComplianceCosts { get; set; }

        public AuxiliaryHEVCosts InitAuxiliaryHevCosts { get; set; }
        public AuxiliaryHEVCosts AuxiliaryHevCosts { get; set; }

        public OwnershipCosts InitOwnershipCosts { get; set; }
        public OwnershipCosts OwnershipCosts { get; set; }

        public double Payback { get; set; }
        public double PaybackTCO { get; set; }

        public double ZEVCredits { get; set; }

        #endregion

        #region <<< Methods >>>

        protected override void InitializeInternal(IOEMProductInfo productInfo)
        {
            base.InitializeInternal(productInfo);

            IVehicleInfo vehInfo = (IVehicleInfo)productInfo;

            this.PlatformCode     = vehInfo.PlatformCode;
            this.EngineCode       = vehInfo.EngineCode;
            this.TransmissionCode = vehInfo.TransmissionCode;

            this.FuelEconomy = vehInfo.FuelEconomy;
            this.FuelShare   = vehInfo.FuelShare;
            this.HevType     = vehInfo.HevType;
            this.Sales       = vehInfo.Sales;
            this.Msrp        = vehInfo.Msrp;
            this.RegClass    = vehInfo.RegClass;
            this.Footprint   = vehInfo.Footprint;
            this.CurbWeight  = vehInfo.CurbWeight;
            this.GVWR        = vehInfo.GVWR;
            this.GCWR        = vehInfo.GCWR;
            this.TechKey     = vehInfo.TechKey;

            this.ComplianceCosts       = new ComplianceCosts();
            this.InitAuxiliaryHevCosts = new AuxiliaryHEVCosts();
            this.AuxiliaryHevCosts     = new AuxiliaryHEVCosts();
            this.InitOwnershipCosts    = new OwnershipCosts();
            this.OwnershipCosts        = new OwnershipCosts();
        }

        #endregion
    }
}
