using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using RevitEstimate.Models;

namespace RevitEstimate.Calculators
{
    public class Item43Calculator : IItemCalculator
    {
        private ProjectLevels _levels;
        public Item43Calculator(ProjectLevels levels = null) => _levels = levels ?? new ProjectLevels();

        public List<EstimateRowModel> Calculate(List<Element> collector, out double totalQty)
        {
            totalQty = 0.0;
            var rows = new List<EstimateRowModel>();
            var windows = collector.Where(e => e is FamilyInstance && e.Category != null && e.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Windows).Cast<FamilyInstance>().ToList();

            foreach (var win in windows)
            {
                int partitions = GetPartitionCount(win);
                double qty = partitions * 1.0; // 1 Lock/Fastener set per partition
                totalQty += qty;

                rows.Add(new EstimateRowModel
                {
                    SNo = "",
                    ItemOfWork = $"   -> Knob and Handle (Lock) for Window: {win.Name} [ID: {win.Id}]",
                    NosOfFlats = "1",
                    NosOfInstance = qty.ToString(),
                    Length = "-",
                    Width = "-",
                    HeightDepth = "-",
                    Qty = qty.ToString("F2"),
                    Unit = "Nos",
                    Remarks = $"Based on {partitions} partition(s) (1 locking set per partition)."
                });
            }
            if (rows.Count == 0) rows.Add(new EstimateRowModel { SNo = "", ItemOfWork = "   -> [No Windows found]", Qty = "0.00", Unit = "Nos" });
            return rows;
        }

        private int GetPartitionCount(FamilyInstance win)
        {
            string[] paramNames = { "Panes", "Lights", "Sashes", "Panels", "Number of Panes", "No. of Panes", "Partitions" };
            foreach (var name in paramNames)
            {
                Parameter param = win.LookupParameter(name) ?? (win.Symbol != null ? win.Symbol.LookupParameter(name) : null);
                if (param != null && param.HasValue)
                {
                    int val = param.AsInteger();
                    if (val > 0) return val;
                }
            }
            return 1;
        }
    }
}