using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Structure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;

namespace RevitEstimate
{
    public partial class SteelEstimateWindow : Window
    {
        private Document _doc;
        private const double DensityOfSteel = 7850.0; // Kg/Cum

        public SteelEstimateWindow(Document doc)
        {
            InitializeComponent();
            _doc = doc;
            CalculateSteelData();
        }

        private void CalculateSteelData()
        {
            var detailedList = new List<DetailedSteelRow>();
            var summaryDict = new Dictionary<string, SummarySteelRow>();

            // Setup Categories for Summary
            summaryDict["Foundation"] = new SummarySteelRow { CategoryName = "Foundation", ThumbRulePercent = 0.8 };
            summaryDict["Column"] = new SummarySteelRow { CategoryName = "Column", ThumbRulePercent = 2.0 };
            summaryDict["Beam"] = new SummarySteelRow { CategoryName = "Beam", ThumbRulePercent = 1.5 };
            summaryDict["Slab"] = new SummarySteelRow { CategoryName = "Slab", ThumbRulePercent = 1.0 };
            summaryDict["Stairs"] = new SummarySteelRow { CategoryName = "Stairs", ThumbRulePercent = 1.2 };

            // 1. COLLECT ACTUAL REBARS
            var rebars = new FilteredElementCollector(_doc).OfClass(typeof(Rebar)).Cast<Rebar>().ToList();

            foreach (var rebar in rebars)
            {
                ElementId hostId = rebar.GetHostId();
                Element host = _doc.GetElement(hostId);

                string categoryMapped = GetMappedCategory(host);

                // Volume in CFT converted to Cum
                double volCum = UnitUtils.ConvertFromInternalUnits(rebar.Volume, UnitTypeId.CubicMeters);
                double weightKg = volCum * DensityOfSteel;

                double barDia = UnitUtils.ConvertFromInternalUnits(
                    rebar.LookupParameter("Bar Diameter")?.AsDouble() ?? 0, UnitTypeId.Millimeters);

                double length = UnitUtils.ConvertFromInternalUnits(
                    rebar.LookupParameter("Total Bar Length")?.AsDouble() ?? 0, UnitTypeId.Meters);

                detailedList.Add(new DetailedSteelRow
                {
                    RebarId = rebar.Id.IntegerValue.ToString(),
                    HostName = host?.Name ?? "Unknown",
                    HostCategory = categoryMapped,
                    BarDiameter = barDia,
                    TotalLength = length,
                    Weight = weightKg
                });

                if (summaryDict.ContainsKey(categoryMapped))
                {
                    summaryDict[categoryMapped].ActualWeight += weightKg;
                }
            }

            // 2. CALCULATE CONCRETE VOLUME FOR THUMB RULE
            CalculateConcreteVolume(BuiltInCategory.OST_StructuralFoundation, summaryDict["Foundation"]);
            CalculateConcreteVolume(BuiltInCategory.OST_StructuralColumns, summaryDict["Column"]);
            CalculateConcreteVolume(BuiltInCategory.OST_StructuralFraming, summaryDict["Beam"]);
            CalculateConcreteVolume(BuiltInCategory.OST_Floors, summaryDict["Slab"]);
            CalculateConcreteVolume(BuiltInCategory.OST_Stairs, summaryDict["Stairs"]);

            // Bind to UI
            GridDetailed.ItemsSource = detailedList;
            GridSummary.ItemsSource = summaryDict.Values.ToList();
        }

        private void CalculateConcreteVolume(BuiltInCategory category, SummarySteelRow summaryRow)
        {
            var elements = new FilteredElementCollector(_doc).OfCategory(category).WhereElementIsNotElementType().ToList();
            double totalVolumeCum = 0;

            foreach (var elem in elements)
            {
                Parameter volParam = elem.get_Parameter(BuiltInParameter.HOST_VOLUME_COMPUTED);
                if (volParam != null && volParam.HasValue)
                {
                    totalVolumeCum += UnitUtils.ConvertFromInternalUnits(volParam.AsDouble(), UnitTypeId.CubicMeters);
                }
            }

            summaryRow.ConcreteVolume = totalVolumeCum;
            // Thumb Rule Weight calculation: Volume * (%/100) * 7850
            summaryRow.ThumbRuleWeight = totalVolumeCum * (summaryRow.ThumbRulePercent / 100.0) * DensityOfSteel;
        }

        private string GetMappedCategory(Element host)
        {
            if (host == null || host.Category == null) return "Other";
            int catId = host.Category.Id.IntegerValue;

            if (catId == (int)BuiltInCategory.OST_StructuralFoundation) return "Foundation";
            if (catId == (int)BuiltInCategory.OST_StructuralColumns || catId == (int)BuiltInCategory.OST_Columns) return "Column";
            if (catId == (int)BuiltInCategory.OST_StructuralFraming) return "Beam";
            if (catId == (int)BuiltInCategory.OST_Floors) return "Slab";
            if (catId == (int)BuiltInCategory.OST_Stairs) return "Stairs";

            return "Other";
        }
    }

    public class DetailedSteelRow
    {
        public string RebarId { get; set; }
        public string HostName { get; set; }
        public string HostCategory { get; set; }
        public double BarDiameter { get; set; }
        public double TotalLength { get; set; }
        public double Weight { get; set; }
    }

    public class SummarySteelRow
    {
        public string CategoryName { get; set; }
        public double ConcreteVolume { get; set; }
        public double ThumbRulePercent { get; set; }
        public double ThumbRuleWeight { get; set; }
        public double ActualWeight { get; set; }
        public double Variance => ActualWeight - ThumbRuleWeight;
    }
}