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

using Volpe.Cafe.MarketData;
using Volpe.Cafe.MarketData.Design;
using Volpe.Cafe.TechKeys;

namespace Volpe.Cafe.EffectsModels
{
    /// <summary>
    /// Provides aggregate data for one or more vehicle models, for use during effects modeling.
    /// </summary>
    public class AggregateEffectsVehicle : IEffectsVehicle
    {
        #region <<< Constructors >>>

        /// <summary>
        /// Initializes a new instance of the <see cref="AggregateEffectsVehicle"/> class, using the specified
        /// regulatory class and vehicle style, and for a given model year.
        /// </summary>
        /// <param name="regClass">The aggregate vehicle's CAFE regulatory class assignment.</param>
        /// <param name="vehStyle">The aggregate vehicle's style.</param>
        /// <param name="year">The model year representing the aggregate vehicle's revision.</param>
        public AggregateEffectsVehicle(RegulatoryClass regClass, VehicleStyle vehStyle, int year)
        {
            this.RegClass = regClass;
            this.Style = vehStyle;
            this.VehicleClass = vehStyle.ToVehicleClass();
            this.RevisionYear = year;
        }

        #endregion

        #region <<< Properties >>>

        //----- general vehicle info -----
        public int Code => (int)this.RegClass * 1000 + (int)this.Style;
        public string ManufacturerName { get; set; }
        public int RevisionYear { get; }

        //----- 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; }
        public SafetyClass SafetyClass { get; set; }
        public VehicleClass VehicleClass { get; }

        public TechnologyClass TechnologyClass { get; set; }
        public EngineTechnologyClass EngineTechnologyClass { get; set; }

        //----- vehicle characteristics -----
        public VehicleStyle Style { get; }

        public double Footprint { get; set; }
        public double CurbWeightMR0 { get; set; }
        public double CurbWeight { get; set; }
        public double GVWR { get; set; }
        public double GCWR { get; set; }

        public double FuelCapacity { get; set; }

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

        //----- technology utilization -----
        public TechKey128 TechKey { get; set; }

        //----- IEffectsVehicle -----
        public FuelValue RatedFE { get; set; }
        public FuelValue OnRoadFE { get; set; }

        public FuelValue InitFuelEconomy { get; set; }
        public FuelValue InitRatedFE { get; set; }
        public FuelValue InitOnRoadFE { get; set; }
        public FuelValue InitFuelShare { get; set; }
        public FuelType InitFuelType => this.InitFuelShare.FuelType;
        public double InitCurbWeight { get; set; }

        #endregion

        #region <<< Explicitly Defined Properties >>>

        //----- general vehicle info -----
        ModelYearKey IOEMProductInfo.RefreshYears => ModelYearKey.Empty;
        ModelYearKey IOEMProductInfo.RedesignYears => ModelYearKey.Empty;

        string IVehicleInfo.Brand => string.Empty;
        string IVehicleInfo.Model => string.Empty;
        string IVehicleInfo.Nameplate => string.Empty;

        int IVehicleInfo.PlatformCode => 0;
        int IVehicleInfo.EngineCode => 0;
        int IVehicleInfo.TransmissionCode => 0;

        //----- regulatory classification -----
        bool IVehicleInfo.IsZevCandidate => false;
        int? IVehicleInfo.ZEVCandidate => null;
        int IVehicleInfo.ZevApplicationYear => 0;
        int IVehicleInfo.ZevReferenceVehicleCode => 0;
        bool IVehicleInfo.CARBAgreement => false;

        //----- vehicle characteristics -----
        Origin IVehicleInfo.Origin => Origin.Domestic;
        VehicleFrame IVehicleInfo.Structure => VehicleFrame.None;
        DriveType IVehicleInfo.Drive => DriveType.None;

        //----- IEffectsVehicle -----
        double IEffectsVehicle.FleetShare => 1;
        bool IEffectsVehicle.IsHistoric => false;

        #endregion
    }
}
