using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using Autodesk.Revit.DB;
using RevitEstimate.Models;
using WpfGrid = System.Windows.Controls.Grid;

namespace RevitEstimate
{
    // Static storage to persist level configurations across window re-opens during session
    public static class LevelSetupState
    {
        public static bool IsConfigured { get; set; } = false;

        public static object BotFoundSelection { get; set; }
        public static string BotFoundCustom { get; set; }

        public static object TopFoundSelection { get; set; }
        public static string TopFoundCustom { get; set; }

        public static object GLSelection { get; set; }
        public static string GLCustom { get; set; }

        public static object BotPlinthSelection { get; set; }
        public static string BotPlinthCustom { get; set; }

        public static object TopPlinthSelection { get; set; }
        public static string TopPlinthCustom { get; set; }

        // GF
        public static object GFLintelBotSelection { get; set; }
        public static string GFLintelBotCustom { get; set; }
        public static object GFLintelTopSelection { get; set; }
        public static string GFLintelTopCustom { get; set; }
        public static object GFBotSelection { get; set; }
        public static string GFBotCustom { get; set; }
        public static object GFTopSelection { get; set; }
        public static string GFTopCustom { get; set; }

        // FF
        public static bool FFChecked { get; set; } = true;
        public static object FFLintelBotSelection { get; set; }
        public static string FFLintelBotCustom { get; set; }
        public static object FFLintelTopSelection { get; set; }
        public static string FFLintelTopCustom { get; set; }
        public static object FFBotSelection { get; set; }
        public static string FFBotCustom { get; set; }
        public static object FFTopSelection { get; set; }
        public static string FFTopCustom { get; set; }

        // SF
        public static bool SFChecked { get; set; } = false;
        public static object SFLintelBotSelection { get; set; }
        public static string SFLintelBotCustom { get; set; }
        public static object SFLintelTopSelection { get; set; }
        public static string SFLintelTopCustom { get; set; }
        public static object SFBotSelection { get; set; }
        public static string SFBotCustom { get; set; }
        public static object SFTopSelection { get; set; }
        public static string SFTopCustom { get; set; }

        // TF
        public static bool TFChecked { get; set; } = false;
        public static object TFLintelBotSelection { get; set; }
        public static string TFLintelBotCustom { get; set; }
        public static object TFLintelTopSelection { get; set; }
        public static string TFLintelTopCustom { get; set; }
        public static object TFBotSelection { get; set; }
        public static string TFBotCustom { get; set; }
        public static object TFTopSelection { get; set; }
        public static string TFTopCustom { get; set; }

        // Terrace
        public static bool TerChecked { get; set; } = false;
        public static object TerBotSelection { get; set; }
        public static string TerBotCustom { get; set; }
        public static object TerTopSelection { get; set; }
        public static string TerTopCustom { get; set; }
    }

    public partial class LevelSetupWindow : Window
    {
        public ProjectLevels Levels { get; private set; }
        private Document _doc;
        private List<RevitLevelData> _revitLevels;

        // Substructure Controls
        private ComboBox cmbBotFound, cmbTopFound, cmbGL, cmbBotPlinth, cmbTopPlinth;
        private TextBox txtBotFound, txtTopFound, txtGL, txtBotPlinth, txtTopPlinth;

        // Ground Floor Controls
        private ComboBox cmbGF_LintelBot, cmbGF_LintelTop, cmbGF_Bot, cmbGF_Top;
        private TextBox txtGF_LintelBot, txtGF_LintelTop, txtGF_Bot, txtGF_Top;

        // First Floor Controls & Checkbox
        private CheckBox chkFF;
        private ComboBox cmbFF_LintelBot, cmbFF_LintelTop, cmbFF_Bot, cmbFF_Top;
        private TextBox txtFF_LintelBot, txtFF_LintelTop, txtFF_Bot, txtFF_Top;

        // Second Floor Controls & Checkbox
        private CheckBox chkSF;
        private ComboBox cmbSF_LintelBot, cmbSF_LintelTop, cmbSF_Bot, cmbSF_Top;
        private TextBox txtSF_LintelBot, txtSF_LintelTop, txtSF_Bot, txtSF_Top;

        // Third Floor Controls & Checkbox
        private CheckBox chkTF;
        private ComboBox cmbTF_LintelBot, cmbTF_LintelTop, cmbTF_Bot, cmbTF_Top;
        private TextBox txtTF_LintelBot, txtTF_LintelTop, txtTF_Bot, txtTF_Top;

        // Terrace Controls & Checkbox
        private CheckBox chkTer;
        private ComboBox cmbTer_Bot, cmbTer_Top;
        private TextBox txtTer_Bot, txtTer_Top;

        public LevelSetupWindow(Document doc)
        {
            _doc = doc;
            Title = "Configure Project Levels with Floor Checkboxes";
            Width = 640;
            Height = 720;
            WindowStartupLocation = WindowStartupLocation.CenterScreen;
            Levels = new ProjectLevels();

            LoadRevitLevels();
            BuildUI();
            RestoreState();
        }

        private void LoadRevitLevels()
        {
            _revitLevels = new List<RevitLevelData>();

            FilteredElementCollector collector = new FilteredElementCollector(_doc)
                .OfClass(typeof(Autodesk.Revit.DB.Level));

            foreach (Element elem in collector)
            {
                if (elem is Autodesk.Revit.DB.Level lvl)
                {
                    double elevMeters = UnitUtils.ConvertFromInternalUnits(lvl.Elevation, UnitTypeId.Meters);
                    _revitLevels.Add(new RevitLevelData { Name = lvl.Name, Elevation = elevMeters });
                }
            }

            _revitLevels = _revitLevels.OrderBy(l => l.Elevation).ToList();
            _revitLevels.Insert(0, new RevitLevelData { Name = "-- Custom / Manual Entry --", Elevation = -9999 });

            if (_revitLevels.Count <= 1)
            {
                _revitLevels.Add(new RevitLevelData { Name = "Default Level (0.0m)", Elevation = 0.0 });
            }
        }

        private void BuildUI()
        {
            WpfGrid mainGrid = new WpfGrid { Margin = new Thickness(15) };
            mainGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
            mainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
            mainGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });

            TextBlock header = new TextBlock
            {
                Text = "Tick the floor checkboxes to enable fields. Sequence: Lintel Bottom -> Top -> Slab Bottom -> Top",
                FontWeight = FontWeights.Bold,
                FontSize = 12,
                Margin = new Thickness(0, 0, 0, 10)
            };
            WpfGrid.SetRow(header, 0);
            mainGrid.Children.Add(header);

            ScrollViewer scroll = new ScrollViewer { VerticalScrollBarVisibility = ScrollBarVisibility.Auto };
            StackPanel panel = new StackPanel();

            // Substructure
            AddCategoryHeader(panel, "=== Substructure Levels ===");
            AddLevelControlRow(panel, "Bottom of Foundation:", -1.5, out cmbBotFound, out txtBotFound);
            AddLevelControlRow(panel, "Top of Foundation (PCC/RCC):", -1.1, out cmbTopFound, out txtTopFound);
            AddLevelControlRow(panel, "Ground Level (GL):", 0.0, out cmbGL, out txtGL);
            AddLevelControlRow(panel, "Bottom of Plinth:", 0.0, out cmbBotPlinth, out txtBotPlinth);
            AddLevelControlRow(panel, "Top of Plinth (FFL):", 0.6, out cmbTopPlinth, out txtTopPlinth);

            // Ground Floor (Always enabled by default)
            AddCategoryHeader(panel, "=== Ground Floor (GF) ===");
            AddLevelControlRow(panel, "Ground floor lintel bottom:", 2.1, out cmbGF_LintelBot, out txtGF_LintelBot);
            AddLevelControlRow(panel, "Ground floor lintel top:", 2.25, out cmbGF_LintelTop, out txtGF_LintelTop);
            AddLevelControlRow(panel, "Ground floor slab bottom:", 3.0, out cmbGF_Bot, out txtGF_Bot);
            AddLevelControlRow(panel, "Ground floor slab top:", 3.15, out cmbGF_Top, out txtGF_Top);

            // First Floor (With Checkbox)
            chkFF = AddFloorHeaderWithCheckbox(panel, "=== First Floor (FF) ===", true);
            var ffRow1 = AddLevelControlRow(panel, "First floor lintel bottom:", 5.1, out cmbFF_LintelBot, out txtFF_LintelBot);
            var ffRow2 = AddLevelControlRow(panel, "First floor lintel top:", 5.25, out cmbFF_LintelTop, out txtFF_LintelTop);
            var ffRow3 = AddLevelControlRow(panel, "First floor slab bottom:", 6.0, out cmbFF_Bot, out txtFF_Bot);
            var ffRow4 = AddLevelControlRow(panel, "First floor slab top:", 6.15, out cmbFF_Top, out txtFF_Top);
            BindCheckboxToPanel(chkFF, new UIElement[] { ffRow1, ffRow2, ffRow3, ffRow4 }, true);

            // Second Floor (With Checkbox)
            chkSF = AddFloorHeaderWithCheckbox(panel, "=== Second Floor (SF) ===", false);
            var sfRow1 = AddLevelControlRow(panel, "Second floor lintel bottom:", 8.1, out cmbSF_LintelBot, out txtSF_LintelBot);
            var sfRow2 = AddLevelControlRow(panel, "Second floor lintel top:", 8.25, out cmbSF_LintelTop, out txtSF_LintelTop);
            var sfRow3 = AddLevelControlRow(panel, "Second floor slab bottom:", 9.0, out cmbSF_Bot, out txtSF_Bot);
            var sfRow4 = AddLevelControlRow(panel, "Second floor slab top:", 9.15, out cmbSF_Top, out txtSF_Top);
            BindCheckboxToPanel(chkSF, new UIElement[] { sfRow1, sfRow2, sfRow3, sfRow4 }, false);

            // Third Floor (With Checkbox)
            chkTF = AddFloorHeaderWithCheckbox(panel, "=== Third Floor (TF) ===", false);
            var tfRow1 = AddLevelControlRow(panel, "Third floor lintel bottom:", 11.1, out cmbTF_LintelBot, out txtTF_LintelBot);
            var tfRow2 = AddLevelControlRow(panel, "Third floor lintel top:", 11.25, out cmbTF_LintelTop, out txtTF_LintelTop);
            var tfRow3 = AddLevelControlRow(panel, "Third floor slab bottom:", 12.0, out cmbTF_Bot, out txtTF_Bot);
            var tfRow4 = AddLevelControlRow(panel, "Third floor slab top:", 12.15, out cmbTF_Top, out txtTF_Top);
            BindCheckboxToPanel(chkTF, new UIElement[] { tfRow1, tfRow2, tfRow3, tfRow4 }, false);

            // Terrace (With Checkbox)
            chkTer = AddFloorHeaderWithCheckbox(panel, "=== Terrace Roof ===", false);
            var terRow1 = AddLevelControlRow(panel, "Terrace roof bottom:", 15.0, out cmbTer_Bot, out txtTer_Bot);
            var terRow2 = AddLevelControlRow(panel, "Terrace roof top:", 15.15, out cmbTer_Top, out txtTer_Top);
            BindCheckboxToPanel(chkTer, new UIElement[] { terRow1, terRow2 }, false);

            scroll.Content = panel;
            WpfGrid.SetRow(scroll, 1);
            mainGrid.Children.Add(scroll);

            StackPanel btnPanel = new StackPanel { Orientation = Orientation.Horizontal, HorizontalAlignment = HorizontalAlignment.Right, Margin = new Thickness(0, 15, 0, 0) };
            Button btnSave = new Button
            {
                Content = "Save & Generate Estimate",
                Width = 180,
                Height = 30,
                Background = System.Windows.Media.Brushes.DodgerBlue,
                Foreground = System.Windows.Media.Brushes.White,
                FontWeight = FontWeights.Bold
            };
            btnSave.Click += BtnSave_Click;
            btnPanel.Children.Add(btnSave);

            WpfGrid.SetRow(btnPanel, 2);
            mainGrid.Children.Add(btnPanel);

            Content = mainGrid;
        }

        private void AddCategoryHeader(StackPanel parent, string headerText)
        {
            TextBlock lbl = new TextBlock
            {
                Text = headerText,
                FontWeight = FontWeights.Bold,
                Foreground = System.Windows.Media.Brushes.DarkBlue,
                Margin = new Thickness(0, 10, 0, 5)
            };
            parent.Children.Add(lbl);
        }

        private CheckBox AddFloorHeaderWithCheckbox(StackPanel parent, string headerText, bool defaultChecked)
        {
            DockPanel dock = new DockPanel { Margin = new Thickness(0, 10, 0, 5) };
            TextBlock lbl = new TextBlock
            {
                Text = headerText,
                FontWeight = FontWeights.Bold,
                Foreground = System.Windows.Media.Brushes.DarkBlue
            };
            CheckBox chk = new CheckBox
            {
                Content = "Enable Floor",
                IsChecked = defaultChecked,
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Center,
                FontWeight = FontWeights.SemiBold
            };

            dock.Children.Add(chk);
            dock.Children.Add(lbl);
            parent.Children.Add(dock);
            return chk;
        }

        private DockPanel AddLevelControlRow(StackPanel parent, string labelText, double defaultTargetElevation, out ComboBox cmbOut, out TextBox txtOut)
        {
            DockPanel dock = new DockPanel { Margin = new Thickness(0, 3, 0, 3) };
            TextBlock lbl = new TextBlock { Text = labelText, Width = 210, VerticalAlignment = VerticalAlignment.Center };

            TextBox txtCustom = new TextBox
            {
                Width = 55,
                Text = defaultTargetElevation.ToString("F2"),
                VerticalAlignment = VerticalAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Right,
                Margin = new Thickness(0, 0, 5, 0),
                Visibility = System.Windows.Visibility.Collapsed
            };

            ComboBox cmb = new ComboBox
            {
                Width = 160,
                HorizontalAlignment = HorizontalAlignment.Right,
                ItemsSource = _revitLevels,
                DisplayMemberPath = "DisplayText"
            };

            var closestLevel = _revitLevels.Where(l => l.Elevation != -9999)
                                       .OrderBy(l => Math.Abs(l.Elevation - defaultTargetElevation))
                                       .FirstOrDefault();
            if (closestLevel != null)
            {
                cmb.SelectedItem = closestLevel;
            }

            cmb.SelectionChanged += (s, e) =>
            {
                if (cmb.SelectedItem is RevitLevelData selected && selected.Elevation == -9999)
                {
                    txtCustom.Visibility = System.Windows.Visibility.Visible;
                    cmb.Width = 100;
                }
                else
                {
                    txtCustom.Visibility = System.Windows.Visibility.Collapsed;
                    cmb.Width = 160;
                }
            };

            dock.Children.Add(lbl);
            dock.Children.Add(txtCustom);
            dock.Children.Add(cmb);
            parent.Children.Add(dock);

            cmbOut = cmb;
            txtOut = txtCustom;
            return dock;
        }

        private void BindCheckboxToPanel(CheckBox chk, UIElement[] rows, bool initialState)
        {
            foreach (var row in rows) row.IsEnabled = initialState;
            chk.Checked += (s, e) => { foreach (var row in rows) row.IsEnabled = true; };
            chk.Unchecked += (s, e) => { foreach (var row in rows) row.IsEnabled = false; };
        }

        private void RestoreState()
        {
            if (!LevelSetupState.IsConfigured) return;

            // Substructure
            RestoreRowState(cmbBotFound, txtBotFound, LevelSetupState.BotFoundSelection, LevelSetupState.BotFoundCustom);
            RestoreRowState(cmbTopFound, txtTopFound, LevelSetupState.TopFoundSelection, LevelSetupState.TopFoundCustom);
            RestoreRowState(cmbGL, txtGL, LevelSetupState.GLSelection, LevelSetupState.GLCustom);
            RestoreRowState(cmbBotPlinth, txtBotPlinth, LevelSetupState.BotPlinthSelection, LevelSetupState.BotPlinthCustom);
            RestoreRowState(cmbTopPlinth, txtTopPlinth, LevelSetupState.TopPlinthSelection, LevelSetupState.TopPlinthCustom);

            // GF
            RestoreRowState(cmbGF_LintelBot, txtGF_LintelBot, LevelSetupState.GFLintelBotSelection, LevelSetupState.GFLintelBotCustom);
            RestoreRowState(cmbGF_LintelTop, txtGF_LintelTop, LevelSetupState.GFLintelTopSelection, LevelSetupState.GFLintelTopCustom);
            RestoreRowState(cmbGF_Bot, txtGF_Bot, LevelSetupState.GFBotSelection, LevelSetupState.GFBotCustom);
            RestoreRowState(cmbGF_Top, txtGF_Top, LevelSetupState.GFTopSelection, LevelSetupState.GFTopCustom);

            // FF
            chkFF.IsChecked = LevelSetupState.FFChecked;
            RestoreRowState(cmbFF_LintelBot, txtFF_LintelBot, LevelSetupState.FFLintelBotSelection, LevelSetupState.FFLintelBotCustom);
            RestoreRowState(cmbFF_LintelTop, txtFF_LintelTop, LevelSetupState.FFLintelTopSelection, LevelSetupState.FFLintelTopCustom);
            RestoreRowState(cmbFF_Bot, txtFF_Bot, LevelSetupState.FFBotSelection, LevelSetupState.FFBotCustom);
            RestoreRowState(cmbFF_Top, txtFF_Top, LevelSetupState.FFTopSelection, LevelSetupState.FFTopCustom);

            // SF
            chkSF.IsChecked = LevelSetupState.SFChecked;
            RestoreRowState(cmbSF_LintelBot, txtSF_LintelBot, LevelSetupState.SFLintelBotSelection, LevelSetupState.SFLintelBotCustom);
            RestoreRowState(cmbSF_LintelTop, txtSF_LintelTop, LevelSetupState.SFLintelTopSelection, LevelSetupState.SFLintelTopCustom);
            RestoreRowState(cmbSF_Bot, txtSF_Bot, LevelSetupState.SFBotSelection, LevelSetupState.SFBotCustom);
            RestoreRowState(cmbSF_Top, txtSF_Top, LevelSetupState.SFTopSelection, LevelSetupState.SFTopCustom);

            // TF
            chkTF.IsChecked = LevelSetupState.TFChecked;
            RestoreRowState(cmbTF_LintelBot, txtTF_LintelBot, LevelSetupState.TFLintelBotSelection, LevelSetupState.TFLintelBotCustom);
            RestoreRowState(cmbTF_LintelTop, txtTF_LintelTop, LevelSetupState.TFLintelTopSelection, LevelSetupState.TFLintelTopCustom);
            RestoreRowState(cmbTF_Bot, txtTF_Bot, LevelSetupState.TFBotSelection, LevelSetupState.TFBotCustom);
            RestoreRowState(cmbTF_Top, txtTF_Top, LevelSetupState.TFTopSelection, LevelSetupState.TFTopCustom);

            // Terrace
            chkTer.IsChecked = LevelSetupState.TerChecked;
            RestoreRowState(cmbTer_Bot, txtTer_Bot, LevelSetupState.TerBotSelection, LevelSetupState.TerBotCustom);
            RestoreRowState(cmbTer_Top, txtTer_Top, LevelSetupState.TerTopSelection, LevelSetupState.TerTopCustom);
        }

        private void RestoreRowState(ComboBox cmb, TextBox txt, object selectedItem, string customText)
        {
            if (selectedItem != null)
            {
                // Match item name from stored level data
                if (selectedItem is RevitLevelData savedData)
                {
                    var matching = _revitLevels.FirstOrDefault(l => l.Name == savedData.Name);
                    if (matching != null) cmb.SelectedItem = matching;
                }
            }
            if (!string.IsNullOrEmpty(customText))
            {
                txt.Text = customText;
            }
        }

        private double GetFinalValue(ComboBox cmb, TextBox txt, double fallback, bool isEnabled)
        {
            if (!isEnabled) return -8888; // Disabled means N/A
            if (cmb.SelectedItem is RevitLevelData selected)
            {
                if (selected.Elevation == -9999)
                {
                    if (double.TryParse(txt.Text, out double customVal)) return customVal;
                }
                else return selected.Elevation;
            }
            return fallback;
        }

        private void BtnSave_Click(object sender, RoutedEventArgs e)
        {
            LevelSetupState.IsConfigured = true;

            // Save Substructure selections
            LevelSetupState.BotFoundSelection = cmbBotFound.SelectedItem;
            LevelSetupState.BotFoundCustom = txtBotFound.Text;
            LevelSetupState.TopFoundSelection = cmbTopFound.SelectedItem;
            LevelSetupState.TopFoundCustom = txtTopFound.Text;
            LevelSetupState.GLSelection = cmbGL.SelectedItem;
            LevelSetupState.GLCustom = txtGL.Text;
            LevelSetupState.BotPlinthSelection = cmbBotPlinth.SelectedItem;
            LevelSetupState.BotPlinthCustom = txtBotPlinth.Text;
            LevelSetupState.TopPlinthSelection = cmbTopPlinth.SelectedItem;
            LevelSetupState.TopPlinthCustom = txtTopPlinth.Text;

            // GF
            LevelSetupState.GFLintelBotSelection = cmbGF_LintelBot.SelectedItem;
            LevelSetupState.GFLintelBotCustom = txtGF_LintelBot.Text;
            LevelSetupState.GFLintelTopSelection = cmbGF_LintelTop.SelectedItem;
            LevelSetupState.GFLintelTopCustom = txtGF_LintelTop.Text;
            LevelSetupState.GFBotSelection = cmbGF_Bot.SelectedItem;
            LevelSetupState.GFBotCustom = txtGF_Bot.Text;
            LevelSetupState.GFTopSelection = cmbGF_Top.SelectedItem;
            LevelSetupState.GFTopCustom = txtGF_Top.Text;

            // FF
            LevelSetupState.FFChecked = chkFF.IsChecked == true;
            LevelSetupState.FFLintelBotSelection = cmbFF_LintelBot.SelectedItem;
            LevelSetupState.FFLintelBotCustom = txtFF_LintelBot.Text;
            LevelSetupState.FFLintelTopSelection = cmbFF_LintelTop.SelectedItem;
            LevelSetupState.FFLintelTopCustom = txtFF_LintelTop.Text;
            LevelSetupState.FFBotSelection = cmbFF_Bot.SelectedItem;
            LevelSetupState.FFBotCustom = txtFF_Bot.Text;
            LevelSetupState.FFTopSelection = cmbFF_Top.SelectedItem;
            LevelSetupState.FFTopCustom = txtFF_Top.Text;

            // SF
            LevelSetupState.SFChecked = chkSF.IsChecked == true;
            LevelSetupState.SFLintelBotSelection = cmbSF_LintelBot.SelectedItem;
            LevelSetupState.SFLintelBotCustom = txtSF_LintelBot.Text;
            LevelSetupState.SFLintelTopSelection = cmbSF_LintelTop.SelectedItem;
            LevelSetupState.SFLintelTopCustom = txtSF_LintelTop.Text;
            LevelSetupState.SFBotSelection = cmbSF_Bot.SelectedItem;
            LevelSetupState.SFBotCustom = txtSF_Bot.Text;
            LevelSetupState.SFTopSelection = cmbSF_Top.SelectedItem;
            LevelSetupState.SFTopCustom = txtSF_Top.Text;

            // TF
            LevelSetupState.TFChecked = chkTF.IsChecked == true;
            LevelSetupState.TFLintelBotSelection = cmbTF_LintelBot.SelectedItem;
            LevelSetupState.TFLintelBotCustom = txtTF_LintelBot.Text;
            LevelSetupState.TFLintelTopSelection = cmbTF_LintelTop.SelectedItem;
            LevelSetupState.TFLintelTopCustom = txtTF_LintelTop.Text;
            LevelSetupState.TFBotSelection = cmbTF_Bot.SelectedItem;
            LevelSetupState.TFBotCustom = txtTF_Bot.Text;
            LevelSetupState.TFTopSelection = cmbTF_Top.SelectedItem;
            LevelSetupState.TFTopCustom = txtTF_Top.Text;

            // Terrace
            LevelSetupState.TerChecked = chkTer.IsChecked == true;
            LevelSetupState.TerBotSelection = cmbTer_Bot.SelectedItem;
            LevelSetupState.TerBotCustom = txtTer_Bot.Text;
            LevelSetupState.TerTopSelection = cmbTer_Top.SelectedItem;
            LevelSetupState.TerTopCustom = txtTer_Top.Text;

            // Substructure
            Levels.BottomOfFoundation = GetFinalValue(cmbBotFound, txtBotFound, -1.5, true);
            Levels.TopOfFoundation = GetFinalValue(cmbTopFound, txtTopFound, -1.1, true);
            Levels.GroundLevel = GetFinalValue(cmbGL, txtGL, 0.0, true);
            Levels.BottomOfPlinth = GetFinalValue(cmbBotPlinth, txtBotPlinth, 0.0, true);
            Levels.TopOfPlinth = GetFinalValue(cmbTopPlinth, txtTopPlinth, 0.6, true);

            // Ground Floor (Always active)
            Levels.SlabBottom = GetFinalValue(cmbGF_Bot, txtGF_Bot, 3.0, true);
            Levels.SlabTop = GetFinalValue(cmbGF_Top, txtGF_Top, 3.15, true);
            Levels.LintelBottom = GetFinalValue(cmbGF_LintelBot, txtGF_LintelBot, 2.1, true);
            Levels.LintelTop = GetFinalValue(cmbGF_LintelTop, txtGF_LintelTop, 2.25, true);

            // First Floor
            bool ffActive = chkFF.IsChecked == true;
            Levels.FirstFloorSlabBottom = GetFinalValue(cmbFF_Bot, txtFF_Bot, 6.0, ffActive);
            Levels.FirstFloorSlabTop = GetFinalValue(cmbFF_Top, txtFF_Top, 6.15, ffActive);

            // Second Floor
            bool sfActive = chkSF.IsChecked == true;
            Levels.SecondFloorSlabBottom = GetFinalValue(cmbSF_Bot, txtSF_Bot, 9.0, sfActive);
            Levels.SecondFloorSlabTop = GetFinalValue(cmbSF_Top, txtSF_Top, 9.15, sfActive);

            // Third Floor
            bool tfActive = chkTF.IsChecked == true;
            Levels.ThirdFloorSlabBottom = GetFinalValue(cmbTF_Bot, txtTF_Bot, 12.0, tfActive);
            Levels.ThirdFloorSlabTop = GetFinalValue(cmbTF_Top, txtTF_Top, 12.15, tfActive);

            // Terrace Roof
            bool terActive = chkTer.IsChecked == true;
            Levels.TerraceRoofBottom = GetFinalValue(cmbTer_Bot, txtTer_Bot, 15.0, terActive);
            Levels.TerraceRoofTop = GetFinalValue(cmbTer_Top, txtTer_Top, 15.15, terActive);

            DialogResult = true;
            Close();
        }
    }

    public class RevitLevelData
    {
        public string Name { get; set; }
        public double Elevation { get; set; }
        public string DisplayText => Elevation == -9999 ? "-- Custom --" : $"{Name} ({Elevation:F2} m)";
    }
}