using System;

namespace HydraulicSimulator.Models
{
    /// <summary>
    /// Tubería con ecuación de Darcy-Weisbach y factor de fricción por Swamee-Jain
    /// </summary>
    public class Pipe : Element
    {
        public double L { get; set; } // m - longitud
        public double D { get; set; } // m - diámetro
        public double Rough { get; set; } = 4.5e-5; // m - rugosidad (acero comercial ~45 micrones)

        public Pipe(double length, double diameter, double roughness = 4.5e-5)
        {
            L = length;
            D = diameter;
            Rough = roughness;
        }

        private double Area => Math.PI * (D * D) / 4.0;

        private double FrictionFactor(double q, Fluid fluid)
        {
            var area = Area;
            var v = Math.Abs(q) / area;
            var re = Math.Max(4000.0, fluid.Rho * v * D / fluid.Mu); // forzamos turbulento
            var epsRel = Rough / D;
            // Swamee-Jain
            var f = 0.25 / Math.Pow(Math.Log10(epsRel / 3.7 + 5.74 / Math.Pow(re, 0.9)), 2);
            return f;
        }

        public override double Dp(double q, Fluid fluid)
        {
            var area = Area;
            var f = FrictionFactor(q, fluid);
            var k = f * (L / D) * 0.5 * fluid.Rho / (area * area);
            return k * q * Math.Abs(q); // signo
        }

        public override double DdpDq(double q, Fluid fluid)
        {
            // Ignoramos df/dq para estabilidad/simplicidad (funciona muy bien).
            var area = Area;
            var qAbs = Math.Max(Math.Abs(q), 1e-9);
            var qSign = q >= 0 ? 1 : -1;
            var f = FrictionFactor(qAbs * qSign, fluid);
            var k = f * (L / D) * 0.5 * fluid.Rho / (area * area);
            return 2.0 * k * Math.Abs(q) + 1e-12; // evita 0
        }
    }
}
