using System.ComponentModel.DataAnnotations;
using PowderCoating.Core.Enums;

namespace PowderCoating.Core.Entities
{
    public class CompanyOperatingCosts : BaseEntity
    {
        // Navigation
        public new int CompanyId { get; set; }
        public virtual Company Company { get; set; } = null!;

        // Labor Rates (per hour, in currency)
        [Range(0, 10000)]
        public decimal StandardLaborRate { get; set; }

        /// <summary>
        /// Actual labor cost per hour (wages + burden) used exclusively for internal job costing and profit/margin display.
        /// This is NOT the billing rate — it should reflect what you actually pay workers.
        /// When null, the costing engine defaults to 20% of StandardLaborRate.
        /// </summary>
        [Range(0, 10000)]
        public decimal? LaborCostPerHour { get; set; }

        // Additional Coat Labor Percentage (percentage of base labor for each additional coat beyond the first)
        [Range(0, 100)]
        public decimal AdditionalCoatLaborPercent { get; set; } = 30m;

        // Equipment Operating Costs (per hour)
        [Range(0, 10000)]
        public decimal OvenOperatingCostPerHour { get; set; }

        [Range(0, 10000)]
        public decimal SandblasterCostPerHour { get; set; }

        [Range(0, 10000)]
        public decimal CoatingBoothCostPerHour { get; set; }

        // Material Costs
        [Range(0, 1000)]
        public decimal PowderCoatingCostPerSqFt { get; set; }  // per square foot

        // Markup / Margin
        /// <summary>Whether markup is applied to material only, or margin is applied to total item cost.</summary>
        public PricingMode PricingMode { get; set; } = PricingMode.MarkupOnMaterial;

        /// <summary>Markup % added on top of material costs (used when PricingMode = MarkupOnMaterial).</summary>
        [Range(0, 100)]
        public decimal GeneralMarkupPercentage { get; set; }

        /// <summary>Target gross margin % applied to total item cost (used when PricingMode = MarginOnTotalCost).</summary>
        [Range(0, 99)]
        public decimal TargetMarginPercent { get; set; }

        // Tax Percentage
        [Range(0, 100)]
        public decimal TaxPercent { get; set; }

        // Shop Supplies Rate (percentage applied to materials/labor)
        [Range(0, 100)]
        public decimal ShopSuppliesRate { get; set; }

        // Oven batch defaults
        [Range(1, 1440)]
        public int DefaultOvenCycleMinutes { get; set; } = 45;

        // Rush Charge
        public string RushChargeType { get; set; } = "Percentage"; // "Percentage" or "FixedAmount"

        [Range(0, 100)]
        public decimal RushChargePercentage { get; set; }

        [Range(0, 100000)]
        public decimal RushChargeFixedAmount { get; set; }

        // Shop Minimum
        [Range(0, 100000)]
        public decimal ShopMinimumCharge { get; set; }

        // Part Complexity Multipliers (% added to calculated item price)
        [Range(0, 500)]
        public decimal ComplexitySimplePercent { get; set; } = 0m;

        [Range(0, 500)]
        public decimal ComplexityModeratePercent { get; set; } = 5m;

        [Range(0, 500)]
        public decimal ComplexityComplexPercent { get; set; } = 15m;

        [Range(0, 500)]
        public decimal ComplexityExtremePercent { get; set; } = 25m;

        /// <summary>
        /// Free-text description of this shop's specialties, typical item types, and pricing style.
        /// Injected into the AI system prompt so the model can calibrate estimates for this company.
        /// Example: "We specialize in automotive restoration parts — wheels, frames, brackets.
        /// We charge premium rates and rarely work on items over 20 sqft."
        /// </summary>
        [StringLength(2000)]
        public string? AiContextProfile { get; set; }

        // ── Shop Capability / Quoting Calibration ─────────────────────────────────────
        // These fields drive the derived BlastRateSqFtPerHour used in AI photo quoting
        // and calculated item time suggestions. The Override field lets a shop bypass the
        // formula and enter their real-world number directly.

        /// <summary>Broad capability tier chosen in Setup Wizard; sets sensible defaults for all fields below.</summary>
        public ShopCapabilityTier ShopCapabilityTier { get; set; } = ShopCapabilityTier.Small;

        /// <summary>Type of blasting setup — biggest single factor in blast throughput.</summary>
        public BlastSetupType BlastSetupType { get; set; } = BlastSetupType.SiphonCabinet;

        /// <summary>Compressor CFM available for the blast setup.</summary>
        [Range(0, 2000)]
        public decimal CompressorCfm { get; set; } = 0m;

        /// <summary>Blast nozzle size (#3 – #8). Larger nozzle = more media flow.</summary>
        [Range(3, 8)]
        public int BlastNozzleSize { get; set; } = 4;

        /// <summary>Primary substrate being removed; affects passes required per sqft.</summary>
        public BlastSubstrateType PrimaryBlastSubstrate { get; set; } = BlastSubstrateType.Mixed;

        /// <summary>
        /// Manual blast rate override (sqft/hr). When set, the formula is bypassed entirely.
        /// Useful for dialed-in shops who know their exact throughput.
        /// </summary>
        [Range(0, 5000)]
        public decimal? BlastRateSqFtPerHourOverride { get; set; }

        /// <summary>Coating gun technology — affects application speed on complex parts.</summary>
        public CoatingGunType CoatingGunType { get; set; } = CoatingGunType.Corona;

        /// <summary>
        /// Manual coating application rate override (sqft/hr). When set, bypasses the formula.
        /// </summary>
        [Range(0, 5000)]
        public decimal? CoatingRateSqFtPerHourOverride { get; set; }

        // ── Facility Overhead ─────────────────────────────────────────────────────
        // Monthly fixed costs divided by billable hours to derive a per-hour overhead
        // rate, which is then applied to each quote based on estimated labor time.

        /// <summary>Monthly shop lease / rent payment.</summary>
        [Range(0, 1000000)]
        public decimal MonthlyRent { get; set; } = 0m;

        /// <summary>Monthly utilities combined (electricity, gas, water, internet).</summary>
        [Range(0, 1000000)]
        public decimal MonthlyUtilities { get; set; } = 0m;

        /// <summary>
        /// Estimated billable shop hours per month used to amortise facility overhead.
        /// Defaults to 160 (4 weeks × 40 hrs). Must be at least 1 to avoid division by zero.
        /// </summary>
        [Range(1, 10000)]
        public int MonthlyBillableHours { get; set; } = 160;
    }
}
