using Microsoft.Extensions.Logging;
using Moq;
using PowderCoating.Application.DTOs.Quote;
using PowderCoating.Application.Services;
using PowderCoating.Core.Entities;
using PowderCoating.Core.Interfaces;
using PowderCoating.Core.Interfaces.Repositories;
using Xunit;

namespace PowderCoating.UnitTests;

public class PricingCalculationServiceTests
{
    [Fact]
    public async Task CalculateCoatPriceAsync_CustomPowder_ChargesFullOrderQuantity()
    {
        var costs = CreateOperatingCosts();
        var unitOfWork = CreateUnitOfWorkMock(costs);
        var tenantContext = new Mock<ITenantContext>();
        tenantContext.Setup(x => x.UseMetricSystemAsync()).ReturnsAsync(false);

        var service = new PricingCalculationService(
            unitOfWork.Object,
            Mock.Of<ILogger<PricingCalculationService>>(),
            new MeasurementConversionService(),
            tenantContext.Object);

        var coat = new CreateQuoteItemCoatDto
        {
            CoatName = "Custom Red",
            PowderCostPerLb = 10m,
            PowderToOrder = 3m,
            CoverageSqFtPerLb = 30m,
            TransferEfficiency = 65m
        };

        var result = await service.CalculateCoatPriceAsync(
            coat,
            itemSurfaceAreaSqFt: 5m,
            quantity: 2m,
            coatIndex: 0,
            estimatedMinutesBase: 15,
            companyId: 1);

        Assert.Equal(30m, result.CoatMaterialCost);
        Assert.Equal(30m, result.CoatLaborCost);
        Assert.Equal(60m, result.CoatTotalCost);
    }

    [Fact]
    public async Task CalculateQuoteItemPriceAsync_LaborItem_UsesStandardLaborRate()
    {
        var costs = CreateOperatingCosts();
        costs.StandardLaborRate = 80m;

        var unitOfWork = CreateUnitOfWorkMock(costs);
        var tenantContext = new Mock<ITenantContext>();
        tenantContext.Setup(x => x.UseMetricSystemAsync()).ReturnsAsync(false);

        var service = new PricingCalculationService(
            unitOfWork.Object,
            Mock.Of<ILogger<PricingCalculationService>>(),
            new MeasurementConversionService(),
            tenantContext.Object);

        var item = new CreateQuoteItemDto
        {
            Description = "Shop labor",
            IsLaborItem = true,
            Quantity = 2.5m
        };

        var result = await service.CalculateQuoteItemPriceAsync(item, companyId: 1);

        Assert.Equal(0m, result.MaterialCost);
        Assert.Equal(200m, result.LaborCost);
        Assert.Equal(80m, result.UnitPrice);
        Assert.Equal(200m, result.TotalPrice);
    }

    [Fact]
    public async Task CalculateQuoteItemPriceAsync_AiItem_UsesManualUnitPriceWithoutAdditionalCosts()
    {
        var unitOfWork = CreateUnitOfWorkMock(CreateOperatingCosts());
        var tenantContext = new Mock<ITenantContext>();
        tenantContext.Setup(x => x.UseMetricSystemAsync()).ReturnsAsync(false);

        var service = new PricingCalculationService(
            unitOfWork.Object,
            Mock.Of<ILogger<PricingCalculationService>>(),
            new MeasurementConversionService(),
            tenantContext.Object);

        var item = new CreateQuoteItemDto
        {
            Description = "AI wheel estimate",
            IsAiItem = true,
            ManualUnitPrice = 123m,
            Quantity = 2m
        };

        var result = await service.CalculateQuoteItemPriceAsync(item, companyId: 1);

        Assert.Equal(0m, result.MaterialCost);
        Assert.Equal(0m, result.LaborCost);
        Assert.Equal(123m, result.UnitPrice);
        Assert.Equal(246m, result.TotalPrice);
    }

    [Fact]
    public async Task CalculateCoatPriceAsync_InventoryPowder_UsesCalculatedUsageOnly()
    {
        var unitOfWork = CreateUnitOfWorkMock(
            CreateOperatingCosts(),
            inventoryItem: new InventoryItem
            {
                Id = 12,
                CompanyId = 1,
                Name = "Gloss Black",
                UnitCost = 12m
            });

        var tenantContext = new Mock<ITenantContext>();
        tenantContext.Setup(x => x.UseMetricSystemAsync()).ReturnsAsync(false);

        var service = new PricingCalculationService(
            unitOfWork.Object,
            Mock.Of<ILogger<PricingCalculationService>>(),
            new MeasurementConversionService(),
            tenantContext.Object);

        var coat = new CreateQuoteItemCoatDto
        {
            CoatName = "Gloss Black",
            InventoryItemId = 12,
            CoverageSqFtPerLb = 24m,
            TransferEfficiency = 50m
        };

        var result = await service.CalculateCoatPriceAsync(
            coat,
            itemSurfaceAreaSqFt: 10m,
            quantity: 2m,
            coatIndex: 0,
            estimatedMinutesBase: 30,
            companyId: 1);

        Assert.Equal(20m, result.CoatMaterialCost, 2);
        Assert.Equal(60m, result.CoatLaborCost);
        Assert.Equal(80m, result.CoatTotalCost, 2);
    }

    [Fact]
    public async Task CalculateCoatPriceAsync_MetricTenant_ConvertsSurfaceAreaBeforePricing()
    {
        var unitOfWork = CreateUnitOfWorkMock(CreateOperatingCosts());
        var tenantContext = new Mock<ITenantContext>();
        tenantContext.Setup(x => x.UseMetricSystemAsync()).ReturnsAsync(true);

        var service = new PricingCalculationService(
            unitOfWork.Object,
            Mock.Of<ILogger<PricingCalculationService>>(),
            new MeasurementConversionService(),
            tenantContext.Object);

        var coat = new CreateQuoteItemCoatDto
        {
            CoatName = "Metric Blue",
            PowderCostPerLb = 5m,
            CoverageSqFtPerLb = 10m,
            TransferEfficiency = 100m
        };

        var result = await service.CalculateCoatPriceAsync(
            coat,
            itemSurfaceAreaSqFt: 1m,
            quantity: 1m,
            coatIndex: 0,
            estimatedMinutesBase: 0,
            companyId: 1);

        Assert.Equal(5.38m, result.CoatMaterialCost);
        Assert.Equal(0m, result.CoatLaborCost);
        Assert.Equal(5.38m, result.CoatTotalCost);
    }

    [Fact]
    public async Task CalculateCoatPriceAsync_AdditionalCoatWithNoExtraLayerCharge_SkipsLabor()
    {
        var unitOfWork = CreateUnitOfWorkMock(CreateOperatingCosts());
        var tenantContext = new Mock<ITenantContext>();
        tenantContext.Setup(x => x.UseMetricSystemAsync()).ReturnsAsync(false);

        var service = new PricingCalculationService(
            unitOfWork.Object,
            Mock.Of<ILogger<PricingCalculationService>>(),
            new MeasurementConversionService(),
            tenantContext.Object);

        var coat = new CreateQuoteItemCoatDto
        {
            CoatName = "Clear Coat",
            PowderCostPerLb = 4m,
            PowderToOrder = 1m,
            CoverageSqFtPerLb = 20m,
            TransferEfficiency = 100m,
            NoExtraLayerCharge = true
        };

        var result = await service.CalculateCoatPriceAsync(
            coat,
            itemSurfaceAreaSqFt: 0m,
            quantity: 2m,
            coatIndex: 1,
            estimatedMinutesBase: 45,
            companyId: 1);

        Assert.Equal(4m, result.CoatMaterialCost);
        Assert.Equal(0m, result.CoatLaborCost);
        Assert.Equal(4m, result.CoatTotalCost);
    }

    [Fact]
    public async Task CalculateCoatPriceAsync_WhenOperatingCostsMissing_ReturnsZeros()
    {
        var unitOfWork = CreateUnitOfWorkMock(costs: null);
        var tenantContext = new Mock<ITenantContext>();
        tenantContext.Setup(x => x.UseMetricSystemAsync()).ReturnsAsync(false);

        var service = new PricingCalculationService(
            unitOfWork.Object,
            Mock.Of<ILogger<PricingCalculationService>>(),
            new MeasurementConversionService(),
            tenantContext.Object);

        var result = await service.CalculateCoatPriceAsync(
            new CreateQuoteItemCoatDto { CoatName = "Unpriced" },
            itemSurfaceAreaSqFt: 10m,
            quantity: 1m,
            coatIndex: 0,
            estimatedMinutesBase: 30,
            companyId: 1);

        Assert.Equal(0m, result.CoatMaterialCost);
        Assert.Equal(0m, result.CoatLaborCost);
        Assert.Equal(0m, result.CoatTotalCost);
    }

    [Fact]
    public async Task CalculateQuoteItemPriceAsync_CatalogItem_UsesPowderCostOverrideAsBasePrice()
    {
        var unitOfWork = CreateUnitOfWorkMock(
            CreateOperatingCosts(),
            catalogItem: new CatalogItem
            {
                Id = 50,
                CompanyId = 1,
                Name = "Wheel",
                DefaultPrice = 10m
            });
        var tenantContext = new Mock<ITenantContext>();
        tenantContext.Setup(x => x.UseMetricSystemAsync()).ReturnsAsync(false);

        var service = new PricingCalculationService(
            unitOfWork.Object,
            Mock.Of<ILogger<PricingCalculationService>>(),
            new MeasurementConversionService(),
            tenantContext.Object);

        var item = new CreateQuoteItemDto
        {
            Description = "Override catalog item",
            CatalogItemId = 50,
            PowderCostOverride = 77m,
            Quantity = 3m
        };

        var result = await service.CalculateQuoteItemPriceAsync(item, companyId: 1);

        Assert.Equal(0m, result.MaterialCost);
        Assert.Equal(0m, result.LaborCost);
        Assert.Equal(77m, result.UnitPrice);
        Assert.Equal(231m, result.TotalPrice);
    }

    [Fact]
    public async Task CalculateQuoteItemPriceAsync_CatalogItem_AddsPrepCostAndCustomPowder()
    {
        var unitOfWork = CreateUnitOfWorkMock(
            CreateOperatingCosts(),
            catalogItem: new CatalogItem
            {
                Id = 51,
                CompanyId = 1,
                Name = "Bracket",
                DefaultPrice = 50m
            });
        var tenantContext = new Mock<ITenantContext>();
        tenantContext.Setup(x => x.UseMetricSystemAsync()).ReturnsAsync(false);

        var service = new PricingCalculationService(
            unitOfWork.Object,
            Mock.Of<ILogger<PricingCalculationService>>(),
            new MeasurementConversionService(),
            tenantContext.Object);

        var item = new CreateQuoteItemDto
        {
            Description = "Bracket with prep",
            CatalogItemId = 51,
            Quantity = 2m,
            IncludePrepCost = true,
            PrepServices = new List<CreateQuoteItemPrepServiceDto>
            {
                new() { PrepServiceId = 1, EstimatedMinutes = 30 }
            },
            Coats = new List<CreateQuoteItemCoatDto>
            {
                new()
                {
                    CoatName = "Custom Green",
                    PowderCostPerLb = 5m,
                    PowderToOrder = 2m
                }
            }
        };

        var result = await service.CalculateQuoteItemPriceAsync(item, companyId: 1);

        // Custom powder material ($10) is excluded from the item price — it moves to the
        // auto-generated "Custom Powder Order" line item so users can add shipping.
        Assert.Equal(0m, result.MaterialCost);
        Assert.Equal(30m, result.LaborCost);
        Assert.Equal(0m, result.EquipmentCost);
        Assert.Equal(65m, result.UnitPrice);   // catalog $50 + prep $15/unit
        Assert.Equal(130m, result.TotalPrice);
    }

    [Fact]
    public async Task CalculateQuoteItemPriceAsync_MarginMode_AppliesAdditionalCoatAndComplexity()
    {
        var costs = CreateOperatingCosts();
        costs.PricingMode = PowderCoating.Core.Enums.PricingMode.MarginOnTotalCost;
        costs.TargetMarginPercent = 50m;
        costs.CoatingBoothCostPerHour = 0m;
        costs.ComplexityModeratePercent = 5m;

        var unitOfWork = CreateUnitOfWorkMock(costs);
        var tenantContext = new Mock<ITenantContext>();
        tenantContext.Setup(x => x.UseMetricSystemAsync()).ReturnsAsync(false);

        var service = new PricingCalculationService(
            unitOfWork.Object,
            Mock.Of<ILogger<PricingCalculationService>>(),
            new MeasurementConversionService(),
            tenantContext.Object);

        var item = new CreateQuoteItemDto
        {
            Description = "Complex fabricated part",
            Quantity = 1m,
            SurfaceAreaSqFt = 10m,
            EstimatedMinutes = 60,
            Complexity = "Moderate",
            Coats = new List<CreateQuoteItemCoatDto>
            {
                new()
                {
                    CoatName = "Base",
                    PowderCostPerLb = 10m,
                    CoverageSqFtPerLb = 10m,
                    TransferEfficiency = 100m
                },
                new()
                {
                    CoatName = "Top",
                    PowderCostPerLb = 10m,
                    CoverageSqFtPerLb = 10m,
                    TransferEfficiency = 100m
                }
            }
        };

        var result = await service.CalculateQuoteItemPriceAsync(item, companyId: 1);

        Assert.Equal(10.5m, result.MaterialCost);
        Assert.Equal(60m, result.LaborCost);
        Assert.Equal(0m, result.EquipmentCost);
        Assert.Equal(222.075m, result.ItemSubtotal);
        Assert.Equal(222.075m, result.TotalPrice);
    }

    [Fact]
    public async Task CalculateQuoteTotalsAsync_MixedAiAndManualItems_ScalesOvenCostBySurfaceAreaAndUsesManualTax()
    {
        var costs = CreateOperatingCosts();
        costs.OvenOperatingCostPerHour = 30m;
        costs.DefaultOvenCycleMinutes = 60;
        costs.ShopSuppliesRate = 0m;
        costs.TaxPercent = 5m;
        costs.MonthlyRent = 0m;
        costs.MonthlyUtilities = 0m;

        var unitOfWork = CreateUnitOfWorkMock(costs);
        var tenantContext = new Mock<ITenantContext>();
        tenantContext.Setup(x => x.UseMetricSystemAsync()).ReturnsAsync(false);

        var service = new PricingCalculationService(
            unitOfWork.Object,
            Mock.Of<ILogger<PricingCalculationService>>(),
            new MeasurementConversionService(),
            tenantContext.Object);

        var items = new List<CreateQuoteItemDto>
        {
            new()
            {
                Description = "AI estimate",
                IsAiItem = true,
                ManualUnitPrice = 200m,
                Quantity = 1m,
                SurfaceAreaSqFt = 50m,
                Coats = new List<CreateQuoteItemCoatDto> { new() { CoatName = "Base Coat", Sequence = 1 } }
            },
            new()
            {
                Description = "Labor item",
                IsLaborItem = true,
                Quantity = 1m,
                SurfaceAreaSqFt = 50m,
                EstimatedMinutes = 60,
                Coats = new List<CreateQuoteItemCoatDto> { new() { CoatName = "Base Coat", Sequence = 1 } }
            }
        };

        var result = await service.CalculateQuoteTotalsAsync(
            items,
            companyId: 1,
            manualTaxPercent: 8m);

        Assert.Equal(260m, result.ItemsSubtotal);
        Assert.Equal(15m, result.OvenBatchCost);
        Assert.Equal(275m, result.SubtotalBeforeDiscount);
        Assert.Equal(8m, result.TaxPercent);
        Assert.Equal(22m, result.TaxAmount);
        Assert.Equal(297m, result.Total);
    }

    [Fact]
    public async Task CalculateQuoteTotalsAsync_ZeroSurfaceAreaFallback_UsesItemCountForOvenFraction()
    {
        var costs = CreateOperatingCosts();
        costs.OvenOperatingCostPerHour = 20m;
        costs.DefaultOvenCycleMinutes = 60;
        costs.ShopSuppliesRate = 0m;
        costs.TaxPercent = 0m;
        costs.MonthlyRent = 0m;
        costs.MonthlyUtilities = 0m;

        var unitOfWork = CreateUnitOfWorkMock(costs);
        var tenantContext = new Mock<ITenantContext>();
        tenantContext.Setup(x => x.UseMetricSystemAsync()).ReturnsAsync(false);

        var service = new PricingCalculationService(
            unitOfWork.Object,
            Mock.Of<ILogger<PricingCalculationService>>(),
            new MeasurementConversionService(),
            tenantContext.Object);

        var items = new List<CreateQuoteItemDto>
        {
            new()
            {
                Description = "AI item",
                IsAiItem = true,
                ManualUnitPrice = 100m,
                Quantity = 1m,
                Coats = new List<CreateQuoteItemCoatDto> { new() { CoatName = "Base Coat", Sequence = 1 } }
            },
            new()
            {
                Description = "Shelf item",
                IsSalesItem = true,
                ManualUnitPrice = 40m,
                Quantity = 1m,
                Coats = new List<CreateQuoteItemCoatDto> { new() { CoatName = "Base Coat", Sequence = 1 } }
            }
        };

        var result = await service.CalculateQuoteTotalsAsync(items, companyId: 1);

        Assert.Equal(140m, result.ItemsSubtotal);
        Assert.Equal(10m, result.OvenBatchCost);
        Assert.Equal(150m, result.Total);
    }

    [Fact]
    public async Task CalculateQuoteTotalsAsync_FixedRushAndFacilityOverhead_AreAppliedBeforeTotal()
    {
        var costs = CreateOperatingCosts();
        costs.OvenOperatingCostPerHour = 0m;
        costs.MonthlyRent = 1600m;
        costs.MonthlyUtilities = 0m;
        costs.MonthlyBillableHours = 160;
        costs.ShopSuppliesRate = 10m;
        costs.RushChargeType = "FixedAmount";
        costs.RushChargeFixedAmount = 25m;
        costs.TaxPercent = 0m;

        var unitOfWork = CreateUnitOfWorkMock(costs);
        var tenantContext = new Mock<ITenantContext>();
        tenantContext.Setup(x => x.UseMetricSystemAsync()).ReturnsAsync(false);

        var service = new PricingCalculationService(
            unitOfWork.Object,
            Mock.Of<ILogger<PricingCalculationService>>(),
            new MeasurementConversionService(),
            tenantContext.Object);

        var items = new List<CreateQuoteItemDto>
        {
            new()
            {
                Description = "Labor item",
                IsLaborItem = true,
                Quantity = 2m,
                EstimatedMinutes = 60
            }
        };

        var result = await service.CalculateQuoteTotalsAsync(
            items,
            companyId: 1,
            isRushJob: true);

        Assert.Equal(120m, result.ItemsSubtotal);
        Assert.Equal(10m, result.FacilityOverheadRatePerHour);
        Assert.Equal(20m, result.FacilityOverheadCost);
        Assert.Equal(12m, result.ShopSuppliesAmount);
        Assert.Equal(152m, result.SubtotalBeforeDiscount);
        Assert.Equal(25m, result.RushFee);
        Assert.Equal(177m, result.Total);
    }

    [Fact]
    public async Task CalculateQuoteTotalsAsync_AppliesTierDiscount_QuoteDiscount_RushFee_AndTax()
    {
        var costs = CreateOperatingCosts();
        costs.StandardLaborRate = 100m;
        costs.ShopSuppliesRate = 10m;
        costs.RushChargeType = "Percentage";
        costs.RushChargePercentage = 20m;
        costs.TaxPercent = 5m;
        costs.OvenOperatingCostPerHour = 0m;
        costs.MonthlyRent = 0m;
        costs.MonthlyUtilities = 0m;

        var customerRepo = new Mock<ICustomerRepository>();
        customerRepo
            .Setup(x => x.FindAsync(It.IsAny<System.Linq.Expressions.Expression<Func<Customer, bool>>>(), false, It.IsAny<System.Linq.Expressions.Expression<Func<Customer, object>>[]>()))
            .ReturnsAsync(new[]
            {
                new Customer { Id = 1, CompanyId = 1, PricingTierId = 10 }
            });

        var pricingTierRepo = new Mock<IRepository<PricingTier>>();
        pricingTierRepo
            .Setup(x => x.GetByIdAsync(10, false, It.IsAny<System.Linq.Expressions.Expression<Func<PricingTier, object>>[]>()))
            .ReturnsAsync(new PricingTier { Id = 10, CompanyId = 1, DiscountPercent = 10m });

        var unitOfWork = CreateUnitOfWorkMock(costs);
        unitOfWork.SetupGet(x => x.Customers).Returns(customerRepo.Object);
        unitOfWork.SetupGet(x => x.PricingTiers).Returns(pricingTierRepo.Object);

        var tenantContext = new Mock<ITenantContext>();
        tenantContext.Setup(x => x.UseMetricSystemAsync()).ReturnsAsync(false);

        var service = new PricingCalculationService(
            unitOfWork.Object,
            Mock.Of<ILogger<PricingCalculationService>>(),
            new MeasurementConversionService(),
            tenantContext.Object);

        var items = new List<CreateQuoteItemDto>
        {
            new()
            {
                Description = "Labor item",
                IsLaborItem = true,
                Quantity = 2m
            }
        };

        var result = await service.CalculateQuoteTotalsAsync(
            items,
            companyId: 1,
            customerId: 1,
            discountType: "FixedAmount",
            discountValue: 5m,
            isRushJob: true);

        Assert.Equal(200m, result.ItemsSubtotal);
        Assert.Equal(20m, result.ShopSuppliesAmount);
        Assert.Equal(220m, result.SubtotalBeforeDiscount);
        Assert.Equal(22m, result.PricingTierDiscountAmount);
        Assert.Equal(5m, result.QuoteDiscountAmount);
        Assert.Equal(193m, result.SubtotalAfterDiscount);
        Assert.Equal(38.6m, result.RushFee);
        Assert.Equal(11.58m, result.TaxAmount);
        Assert.Equal(243.18m, result.Total);
    }

    private static Mock<IUnitOfWork> CreateUnitOfWorkMock(
        CompanyOperatingCosts? costs,
        InventoryItem? inventoryItem = null,
        CatalogItem? catalogItem = null)
    {
        var unitOfWork = new Mock<IUnitOfWork>();

        var companyOperatingCostsRepo = new Mock<IRepository<CompanyOperatingCosts>>();
        companyOperatingCostsRepo
            .Setup(x => x.FindAsync(It.IsAny<System.Linq.Expressions.Expression<Func<CompanyOperatingCosts, bool>>>(), false, It.IsAny<System.Linq.Expressions.Expression<Func<CompanyOperatingCosts, object>>[]>()))
            .ReturnsAsync(costs != null ? new[] { costs } : Array.Empty<CompanyOperatingCosts>());

        var inventoryRepo = new Mock<IRepository<InventoryItem>>();
        inventoryRepo
            .Setup(x => x.GetByIdAsync(It.IsAny<int>(), false, It.IsAny<System.Linq.Expressions.Expression<Func<InventoryItem, object>>[]>()))
            .ReturnsAsync(inventoryItem);

        var catalogRepo = new Mock<IRepository<CatalogItem>>();
        catalogRepo
            .Setup(x => x.GetByIdAsync(It.IsAny<int>(), false, It.IsAny<System.Linq.Expressions.Expression<Func<CatalogItem, object>>[]>()))
            .ReturnsAsync(catalogItem);

        var customerRepo = new Mock<ICustomerRepository>();
        customerRepo
            .Setup(x => x.FindAsync(It.IsAny<System.Linq.Expressions.Expression<Func<Customer, bool>>>(), false, It.IsAny<System.Linq.Expressions.Expression<Func<Customer, object>>[]>()))
            .ReturnsAsync(Array.Empty<Customer>());

        var pricingTierRepo = new Mock<IRepository<PricingTier>>();
        pricingTierRepo
            .Setup(x => x.GetByIdAsync(It.IsAny<int>(), false, It.IsAny<System.Linq.Expressions.Expression<Func<PricingTier, object>>[]>()))
            .ReturnsAsync((PricingTier?)null);

        unitOfWork.SetupGet(x => x.CompanyOperatingCosts).Returns(companyOperatingCostsRepo.Object);
        unitOfWork.SetupGet(x => x.InventoryItems).Returns(inventoryRepo.Object);
        unitOfWork.SetupGet(x => x.CatalogItems).Returns(catalogRepo.Object);
        unitOfWork.SetupGet(x => x.Customers).Returns(customerRepo.Object);
        unitOfWork.SetupGet(x => x.PricingTiers).Returns(pricingTierRepo.Object);

        return unitOfWork;
    }

    private static CompanyOperatingCosts CreateOperatingCosts()
    {
        return new CompanyOperatingCosts
        {
            Id = 1,
            CompanyId = 1,
            StandardLaborRate = 60m,
            AdditionalCoatLaborPercent = 50m,
            OvenOperatingCostPerHour = 25m,
            SandblasterCostPerHour = 20m,
            CoatingBoothCostPerHour = 10m,
            PowderCoatingCostPerSqFt = 1m,
            PricingMode = PowderCoating.Core.Enums.PricingMode.MarkupOnMaterial,
            GeneralMarkupPercentage = 20m,
            TargetMarginPercent = 40m,
            TaxPercent = 5m,
            ShopSuppliesRate = 10m,
            DefaultOvenCycleMinutes = 60,
            RushChargeType = "Percentage",
            RushChargePercentage = 15m,
            RushChargeFixedAmount = 50m,
            ShopMinimumCharge = 0m,
            ComplexitySimplePercent = 0m,
            ComplexityModeratePercent = 5m,
            ComplexityComplexPercent = 15m,
            ComplexityExtremePercent = 25m,
            MonthlyBillableHours = 160
        };
    }
}
