"""
Signal filtering callbacks for vitalDSP webapp.
Handles traditional filtering, advanced filtering, artifact removal, neural filtering, and ensemble filtering.
Uses actual vitalDSP functions for all computations.
"""

import numpy as np
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from dash import Input, Output, State, callback_context, no_update, html
from dash.exceptions import PreventUpdate
from scipy import signal
import dash_bootstrap_components as dbc
import logging

logger = logging.getLogger(__name__)


def register_signal_filtering_callbacks(app):
    """Register all signal filtering callbacks."""

    # Auto-select signal type and set defaults based on uploaded data
    @app.callback(
        [
            Output("filter-signal-type-select", "value"),
            Output("filter-type-select", "value"),
            Output("advanced-filter-method", "value"),
        ],
        [Input("url", "pathname")],
        prevent_initial_call=True,
    )
    def auto_select_signal_type_and_defaults(pathname):
        """Auto-select signal type and set appropriate defaults based on uploaded data."""
        logger.info("=== AUTO-SELECT SIGNAL TYPE CALLBACK TRIGGERED ===")
        logger.info(f"Pathname: {pathname}")

        if pathname != "/filtering":
            logger.info("Not on filtering page, preventing update")
            raise PreventUpdate

        try:
            from vitalDSP_webapp.services.data.data_service import get_data_service

            data_service = get_data_service()
            if not data_service:
                logger.warning("Data service not available")
                return "PPG", "traditional", "convolution"

            # Get the latest data
            all_data = data_service.get_all_data()
            if not all_data:
                logger.info("No data available, using defaults")
                return "PPG", "traditional", "convolution"

            # Get the most recent data
            latest_data_id = max(
                all_data.keys(), key=lambda x: int(x.split("_")[1]) if "_" in x else 0
            )
            data_info = data_service.get_data_info(latest_data_id)

            if not data_info:
                logger.info("No data info available, using defaults")
                return "PPG", "traditional", "convolution"

            # Debug: Log the data_info to see what's stored
            logger.info(
                f"Data info keys: {list(data_info.keys()) if data_info else 'None'}"
            )
            logger.info(f"Full data info: {data_info}")

            # First, check if signal type is stored in data info
            stored_signal_type = data_info.get("signal_type", None)
            logger.info(f"Stored signal type: {stored_signal_type}")

            if stored_signal_type and stored_signal_type.lower() != "auto":
                # Convert stored value to match filtering screen dropdown format
                if stored_signal_type.lower() == "ecg":
                    signal_type = "ECG"
                elif stored_signal_type.lower() == "ppg":
                    signal_type = "PPG"
                elif stored_signal_type.lower() == "other":
                    signal_type = "Other"
                else:
                    signal_type = stored_signal_type.upper()
                logger.info(f"Using stored signal type: {signal_type}")
            else:
                # Auto-detect signal type based on data characteristics
                signal_type = "PPG"  # Default
                logger.info("Auto-detecting signal type from data characteristics")

            filter_type = "traditional"  # Default
            advanced_method = "convolution"  # Default

            # Try to detect signal type from column names or data characteristics if not stored
            if (
                stored_signal_type
                and stored_signal_type.lower() == "auto"
                or not stored_signal_type
            ):
                df = data_service.get_data(latest_data_id)
                if df is not None and not df.empty:
                    column_mapping = data_service.get_column_mapping(latest_data_id)
                    signal_column = column_mapping.get("signal", "")

                    # Check column names for signal type hints
                    if any(
                        keyword in signal_column.lower()
                        for keyword in ["ecg", "electrocardio"]
                    ):
                        signal_type = "ECG"
                        filter_type = "advanced"  # Set ECG default to advanced filters
                        advanced_method = (
                            "convolution"  # Set convolution as default method
                        )
                        logger.info("Auto-detected ECG signal type from column name")
                    elif any(
                        keyword in signal_column.lower()
                        for keyword in ["ppg", "pleth", "photopleth"]
                    ):
                        signal_type = "PPG"
                        logger.info("Auto-detected PPG signal type from column name")
                    else:
                        # Try to detect from data characteristics
                        try:
                            signal_data = (
                                df[signal_column].values
                                if signal_column
                                else df.iloc[:, 1].values
                            )
                            sampling_freq = data_info.get("sampling_freq", 1000)

                            # Simple heuristic: ECG typically has higher frequency content
                            from scipy import signal

                            f, psd = signal.welch(
                                signal_data,
                                fs=sampling_freq,
                                nperseg=min(1024, len(signal_data) // 4),
                            )
                            dominant_freq = f[np.argmax(psd)]

                            if (
                                dominant_freq > 1.0
                            ):  # Higher frequency content suggests ECG
                                signal_type = "ECG"
                                filter_type = "advanced"
                                advanced_method = "convolution"
                                logger.info(
                                    "Auto-detected ECG signal type from frequency analysis"
                                )
                            else:
                                signal_type = "PPG"
                                logger.info(
                                    "Auto-detected PPG signal type from frequency analysis"
                                )
                        except Exception as e:
                            logger.warning(
                                f"Could not analyze signal characteristics: {e}"
                            )
                            signal_type = "PPG"

            logger.info(
                f"Auto-selected signal type: {signal_type}, filter type: {filter_type}, method: {advanced_method}"
            )
            return signal_type, filter_type, advanced_method

        except Exception as e:
            logger.error(f"Error in auto-selection: {e}")
            return "PPG", "traditional", "convolution"

    # Filter Type Selection Callback
    @app.callback(
        [
            Output("traditional-filter-params", "style", allow_duplicate=True),
            Output("advanced-filter-params", "style", allow_duplicate=True),
            Output("artifact-removal-params", "style", allow_duplicate=True),
            Output("neural-network-params", "style", allow_duplicate=True),
            Output("ensemble-params", "style", allow_duplicate=True),
        ],
        [Input("filter-type-select", "value")],
        prevent_initial_call=True,
    )
    def update_filter_parameter_visibility(filter_type):
        """Show/hide parameter sections based on selected filter type."""
        # Default style (hidden)
        hidden_style = {"display": "none"}
        visible_style = {"display": "block"}

        # Initialize all sections as hidden
        traditional_style = hidden_style
        advanced_style = hidden_style
        artifact_style = hidden_style
        neural_style = hidden_style
        ensemble_style = hidden_style

        # Show the appropriate section based on filter type
        if filter_type == "traditional":
            traditional_style = visible_style
        elif filter_type == "advanced":
            advanced_style = visible_style
        elif filter_type == "artifact":
            artifact_style = visible_style
        elif filter_type == "neural":
            neural_style = visible_style
        elif filter_type == "ensemble":
            ensemble_style = visible_style

        return (
            traditional_style,
            advanced_style,
            artifact_style,
            neural_style,
            ensemble_style,
        )

    # Advanced Filtering Callback
    @app.callback(
        [
            Output("filter-original-plot", "figure"),
            Output("filter-filtered-plot", "figure"),
            Output("filter-comparison-plot", "figure"),
            Output("filter-quality-metrics", "children"),
            Output("filter-quality-plots", "figure"),
            Output("store-filtering-data", "data"),
        ],
        [
            Input("url", "pathname"),
            Input("filter-btn-apply", "n_clicks"),
            Input("filter-time-range-slider", "value"),
            Input("filter-btn-nudge-m10", "n_clicks"),
            Input("filter-btn-nudge-m1", "n_clicks"),
            Input("filter-btn-nudge-p1", "n_clicks"),
            Input("filter-btn-nudge-p10", "n_clicks"),
        ],
        [
            State("filter-start-time", "value"),
            State("filter-end-time", "value"),
            State("filter-type-select", "value"),
            State("filter-family-advanced", "value"),
            State("filter-response-advanced", "value"),
            State("filter-low-freq-advanced", "value"),
            State("filter-high-freq-advanced", "value"),
            State("filter-order-advanced", "value"),
            State("advanced-filter-method", "value"),
            State("advanced-noise-level", "value"),
            State("advanced-iterations", "value"),
            State("advanced-learning-rate", "value"),
            State("artifact-type", "value"),
            State("artifact-removal-strength", "value"),
            State("neural-network-type", "value"),
            State("neural-model-complexity", "value"),
            State("ensemble-method", "value"),
            State("ensemble-n-filters", "value"),
            State("filter-quality-options", "value"),
            State("detrend-option", "value"),
            State("filter-signal-type-select", "value"),
        ],
    )
    def advanced_filtering_callback(
        pathname,
        n_clicks,
        slider_value,
        nudge_m10,
        nudge_m1,
        nudge_p1,
        nudge_p10,
        start_time_state,
        end_time_state,
        filter_type,
        filter_family,
        filter_response,
        low_freq,
        high_freq,
        filter_order,
        advanced_method,
        noise_level,
        iterations,
        learning_rate,
        artifact_type,
        artifact_strength,
        neural_type,
        neural_complexity,
        ensemble_method,
        ensemble_n_filters,
        quality_options,
        detrend_option,
        signal_type,
    ):

        ctx = callback_context

        if not ctx.triggered:
            raise PreventUpdate

        trigger_id = ctx.triggered[0]["prop_id"].split(".")[0]
        logger.info("=== ADVANCED FILTERING CALLBACK TRIGGERED ===")
        logger.info(f"Trigger ID: {trigger_id}")
        logger.info(f"Pathname: {pathname}")

        # Only run this when we're on the filtering page
        if pathname != "/filtering":
            logger.info("Not on filtering page, returning empty figures")
            return (
                create_empty_figure(),
                create_empty_figure(),
                create_empty_figure(),
                "Navigate to Filtering page",
                create_empty_figure(),
                None,
            )

        # If this is the first time loading the page (no button clicks), show a message
        if not ctx.triggered or ctx.triggered[0]["prop_id"].split(".")[0] == "url":
            logger.info("First time loading filtering page, attempting to load data")

        try:
            # Get data from the data service
            from vitalDSP_webapp.services.data.data_service import get_data_service

            data_service = get_data_service()

            # Get all stored data and find the latest
            all_data = data_service.get_all_data()
            logger.info(f"Data service returned: {type(all_data)}")
            logger.info(
                f"All data keys: {list(all_data.keys()) if all_data else 'None'}"
            )
            logger.info(f"All data content: {all_data}")

            if not all_data:
                logger.warning("No data available for filtering")
                return (
                    create_empty_figure(),
                    create_empty_figure(),
                    create_empty_figure(),
                    "No data available",
                    create_empty_figure(),
                    None,
                )

            # Get the most recent data entry
            latest_data_id = list(all_data.keys())[-1]
            latest_data = all_data[latest_data_id]
            logger.info(f"Latest data ID: {latest_data_id}")
            logger.info(f"Latest data content: {latest_data}")

            # Log the callback parameters
            logger.info("=== CALLBACK PARAMETERS ===")
            logger.info(
                f"Start time: {start_time_state} (type: {type(start_time_state)})"
            )
            logger.info(f"End time: {end_time_state} (type: {type(end_time_state)})")
            logger.info(f"Filter type: {filter_type} (type: {type(filter_type)})")
            logger.info(f"Filter family: {filter_family} (type: {type(filter_family)})")
            logger.info(
                f"Filter response: {filter_response} (type: {type(filter_response)})"
            )
            logger.info(f"Low frequency: {low_freq} (type: {type(low_freq)})")
            logger.info(f"High frequency: {high_freq} (type: {type(high_freq)})")
            logger.info(f"Filter order: {filter_order} (type: {type(filter_order)})")
            logger.info(
                f"Advanced method: {advanced_method} (type: {type(advanced_method)})"
            )
            logger.info(f"Noise level: {noise_level} (type: {type(noise_level)})")
            logger.info(f"Iterations: {iterations} (type: {type(iterations)})")
            logger.info(f"Learning rate: {learning_rate} (type: {type(learning_rate)})")
            logger.info(f"Artifact type: {artifact_type} (type: {type(artifact_type)})")
            logger.info(
                f"Artifact strength: {artifact_strength} (type: {type(artifact_strength)})"
            )
            logger.info(f"Neural type: {neural_type} (type: {type(neural_type)})")
            logger.info(
                f"Neural complexity: {neural_complexity} (type: {type(neural_complexity)})"
            )
            logger.info(
                f"Ensemble method: {ensemble_method} (type: {type(ensemble_method)})"
            )
            logger.info(
                f"Ensemble n filters: {ensemble_n_filters} (type: {type(ensemble_n_filters)})"
            )
            logger.info(
                f"Quality options: {quality_options} (type: {type(quality_options)})"
            )
            logger.info(
                f"Detrend option: {detrend_option} (type: {type(detrend_option)})"
            )

            # Get the data and info using the data ID
            df = data_service.get_data(latest_data_id)
            data_info = data_service.get_data_info(latest_data_id)
            column_mapping = data_service.get_column_mapping(latest_data_id)

            # Log time range interpretation (after we have data_info)
            # Use slider value if available, otherwise fall back to state values
            effective_start_time = slider_value[0] if slider_value else start_time_state
            effective_end_time = slider_value[1] if slider_value else end_time_state

            if effective_start_time is not None and effective_end_time is not None:
                logger.info("=== TIME RANGE INTERPRETATION ===")
                logger.info(
                    f"User selected time range: {effective_start_time} to {effective_end_time} seconds"
                )
                logger.info(
                    f"Data duration: {data_info.get('duration', 'unknown')} seconds"
                )
                logger.info(
                    f"Data sampling frequency: {data_info.get('sampling_freq', 'unknown')} Hz"
                )
                logger.info(
                    f"Total data points: {data_info.get('signal_length', 'unknown')}"
                )
                logger.info(
                    f"Expected points for time range: {(effective_end_time - effective_start_time) * data_info.get('sampling_freq', 100)}"
                )

            logger.info("Data service method results:")
            logger.info(f"  get_data returned: {type(df)}")
            logger.info(f"  get_data_info returned: {type(data_info)}")
            logger.info(f"  get_column_mapping returned: {type(column_mapping)}")

            logger.info("=== DATA EXTRACTION DEBUG ===")
            logger.info(f"DataFrame shape: {df.shape}")
            logger.info(f"DataFrame columns: {list(df.columns)}")
            logger.info(f"Column mapping: {column_mapping}")
            logger.info(f"Data info: {data_info}")
            logger.info(f"Latest data ID: {latest_data_id}")
            logger.info(f"All data keys: {list(all_data.keys())}")

            if df is None or df.empty:
                logger.warning("No data available for filtering")
                return (
                    create_empty_figure(),
                    create_empty_figure(),
                    create_empty_figure(),
                    "No data available",
                    create_empty_figure(),
                    None,
                )

            # Determine which column to use for signal data
            signal_column = None
            time_column = None

            if column_mapping:
                # Use column mapping if available
                signal_column = column_mapping.get(
                    "signal",
                    column_mapping.get("amplitude", column_mapping.get("value")),
                )
                time_column = column_mapping.get(
                    "time", column_mapping.get("timestamp", column_mapping.get("index"))
                )
                logger.info(
                    f"Using mapped columns - Signal: {signal_column}, Time: {time_column}"
                )
                logger.info(f"Column mapping details: {column_mapping}")
            else:
                # Fallback: try to auto-detect columns
                if len(df.columns) >= 2:
                    # Assume first column is time, second is signal
                    time_column = df.columns[0]
                    signal_column = df.columns[1]
                    logger.info(
                        f"Auto-detected columns - Signal: {signal_column}, Time: {time_column}"
                    )
                    logger.info(f"Available columns: {list(df.columns)}")
                else:
                    # Single column - use it as signal
                    signal_column = df.columns[0]
                    time_column = None
                    logger.info(f"Single column detected - Signal: {signal_column}")
                    logger.info(f"Available columns: {list(df.columns)}")

            if not signal_column:
                logger.error("Could not determine signal column")
                logger.error(f"Available columns: {list(df.columns)}")
                logger.error(f"Column mapping: {column_mapping}")
                return (
                    create_empty_figure(),
                    create_empty_figure(),
                    create_empty_figure(),
                    "Could not determine signal column",
                    create_empty_figure(),
                    None,
                )

            # Log the actual data sample
            logger.info(f"Signal column: {signal_column}")
            logger.info(
                f"Signal column data sample: {df[signal_column].head(10).values}"
            )

            # Check if signal column contains numeric data
            try:
                signal_data_numeric = pd.to_numeric(df[signal_column], errors="coerce")
                if signal_data_numeric.isna().any():
                    logger.warning(
                        "Signal column contains non-numeric data. Converting to numeric with coercion."
                    )
                    df[signal_column] = signal_data_numeric

                logger.info(
                    f"Signal column data info: min={df[signal_column].min()}, max={df[signal_column].max()}, mean={df[signal_column].mean():.4f}"
                )
            except Exception as e:
                logger.error(f"Error processing signal column data: {e}")
                logger.info(f"Signal column data type: {df[signal_column].dtype}")
                logger.info(
                    f"Signal column data sample: {df[signal_column].head(5).tolist()}"
                )
                return (
                    create_empty_figure(),
                    create_empty_figure(),
                    create_empty_figure(),
                    "Error: Signal column contains non-numeric data that cannot be processed",
                    create_empty_figure(),
                    None,
                )

            # Initialize start_idx and end_idx
            start_idx = 0
            end_idx = len(df)

            # Handle time range selection
            if time_column and time_column in df.columns:
                # Use actual time column if available
                time_data = df[time_column].values
                logger.info(f"Using actual time column: {time_column}")

                # Check if time column contains datetime data
                try:
                    # First try to convert to datetime if it's not already
                    if not pd.api.types.is_datetime64_any_dtype(df[time_column]):
                        logger.info("Converting time column to datetime")
                        df[time_column] = pd.to_datetime(
                            df[time_column], errors="coerce"
                        )

                    # Convert datetime to numeric (seconds since first timestamp)
                    if pd.api.types.is_datetime64_any_dtype(df[time_column]):
                        logger.info("Converting datetime to numeric seconds")
                        first_timestamp = df[time_column].iloc[0]
                        time_data = (
                            (df[time_column] - first_timestamp)
                            .dt.total_seconds()
                            .values
                        )
                        logger.info(f"First timestamp: {first_timestamp}")
                        logger.info(
                            "Time data converted to seconds from first timestamp"
                        )
                        logger.info(f"Converted time data sample: {time_data[:5]}")
                        logger.info(
                            f"Converted time data range: {np.min(time_data):.4f} to {np.max(time_data):.4f}"
                        )
                    else:
                        # Try numeric conversion
                        time_data_numeric = pd.to_numeric(time_data, errors="coerce")
                        if np.isnan(time_data_numeric).any():
                            logger.warning(
                                "Time column contains non-numeric data. Converting to numeric with coercion."
                            )
                            time_data = time_data_numeric

                    logger.info(
                        f"Full time data range: {np.min(time_data):.4f} to {np.max(time_data):.4f}"
                    )
                    logger.info(f"Time column data sample: {time_data[:10]}")
                    logger.info(f"Time column data type: {type(time_data[0])}")
                    logger.info(
                        f"Time column data info: min={np.min(time_data):.4f}, max={np.max(time_data):.4f}, mean={np.mean(time_data):.4f}"
                    )
                except Exception as e:
                    logger.error(f"Error processing time column data: {e}")
                    logger.info(f"Time column data type: {type(time_data[0])}")
                    logger.info(f"Time column data sample: {time_data[:5].tolist()}")
                    # Fall back to index-based time axis
                    time_column = None
                    logger.info(
                        "Falling back to index-based time axis due to non-numeric time data"
                    )
                    # Generate time axis based on sampling frequency
                    sampling_freq = data_info.get("sampling_frequency", 1000)
                    time_data = np.arange(len(df)) / sampling_freq
                    logger.info(
                        f"Generated index-based time axis: {np.min(time_data):.4f} to {np.max(time_data):.4f} seconds"
                    )

                # Find indices for the selected time range
                if effective_start_time is not None and effective_end_time is not None:
                    logger.info(
                        f"Looking for time range: {effective_start_time} to {effective_end_time}"
                    )
                    logger.info(
                        f"Time data type: {type(time_data[0])}, Start time type: {type(effective_start_time)}"
                    )
                    logger.info(
                        f"Time data range: {np.min(time_data):.4f} to {np.max(time_data):.4f}"
                    )

                    # Convert time_data to float if needed
                    if isinstance(time_data[0], str):
                        try:
                            time_data = pd.to_numeric(time_data, errors="coerce")
                            logger.info("Converted time data to numeric")
                        except Exception as e:
                            logger.warning(
                                f"Could not convert time data to numeric: {e}"
                            )

                    # Check if time data is in milliseconds and convert to seconds if needed
                    if np.max(time_data) > 1000:  # Likely milliseconds
                        logger.info(
                            "Time data appears to be in milliseconds, converting to seconds"
                        )
                        time_data_seconds = time_data / 1000.0
                        # Find indices where time is within the selected range (in seconds)
                        mask = (time_data_seconds >= effective_start_time) & (
                            time_data_seconds <= effective_end_time
                        )
                    else:
                        # Time data is already in seconds
                        mask = (time_data >= effective_start_time) & (
                            time_data <= effective_end_time
                        )

                    logger.info(f"Mask sum: {np.sum(mask)} out of {len(mask)} points")
                    if np.any(mask):
                        start_idx = np.where(mask)[0][0]
                        end_idx = np.where(mask)[0][-1] + 1
                        logger.info(
                            f"Time range {effective_start_time} to {effective_end_time} maps to indices {start_idx} to {end_idx}"
                        )

                        # Ensure we have enough data points for filtering
                        min_points = 100  # Minimum points needed for filtering
                        if (end_idx - start_idx) < min_points:
                            logger.warning(
                                f"Only {end_idx - start_idx} points selected, expanding range to get at least {min_points} points"
                            )
                            # Expand the range to get more points
                            center_idx = (start_idx + end_idx) // 2
                            half_range = min_points // 2
                            start_idx = max(0, center_idx - half_range)
                            end_idx = min(len(time_data), center_idx + half_range)
                            logger.info(
                                f"Expanded range: indices {start_idx} to {end_idx} ({end_idx - start_idx} points)"
                            )

                            # If still not enough points, use a larger range
                            if (end_idx - start_idx) < min_points:
                                logger.warning(
                                    "Still not enough points, using larger range"
                                )
                                # Use a larger range around the center
                                half_range = min(
                                    min_points, len(time_data) // 4
                                )  # Use 1/4 of data or min_points
                                center_idx = (
                                    len(time_data) // 2
                                )  # Use center of full dataset
                                start_idx = max(0, center_idx - half_range)
                                end_idx = min(len(time_data), center_idx + half_range)
                                logger.info(
                                    f"Using larger range: indices {start_idx} to {end_idx} ({end_idx - start_idx} points)"
                                )
                    else:
                        logger.warning(
                            f"No data found in time range {effective_start_time} to {effective_end_time}, using full range"
                        )
                        start_idx = 0
                        end_idx = len(time_data)
                else:
                    # Use full range if no time selection
                    start_idx = 0
                    end_idx = len(time_data)
                    logger.info("No time range selected, using full data")

                    # If full range is too large, use a reasonable subset
                    max_points = 10000  # Maximum points to process
                    if (end_idx - start_idx) > max_points:
                        logger.info(
                            f"Full range too large ({end_idx - start_idx} points), using subset of {max_points} points"
                        )
                        center_idx = len(time_data) // 2
                        half_range = max_points // 2
                        start_idx = max(0, center_idx - half_range)
                        end_idx = min(len(time_data), center_idx + half_range)
                        logger.info(
                            f"Using subset: indices {start_idx} to {end_idx} ({end_idx - start_idx} points)"
                        )

                # Extract data for the selected range
                signal_data = df[signal_column].iloc[start_idx:end_idx].values

                # Generate time axis in seconds
                # Use the converted time_data (already in seconds from datetime conversion)
                time_axis = time_data[start_idx:end_idx]
                logger.info(
                    f"Time axis in seconds: {np.min(time_axis):.4f} to {np.max(time_axis):.4f}"
                )

            else:
                # Generate time axis based on sampling frequency
                sampling_freq = data_info.get("sampling_frequency", 1000)
                logger.info(f"Using sampling frequency: {sampling_freq} Hz")
                logger.info(
                    f"Data info keys: {list(data_info.keys()) if data_info else 'None'}"
                )
                logger.info(
                    f"Sampling frequency from data_info: {data_info.get('sampling_frequency') if data_info else 'None'}"
                )

                if effective_start_time is not None and effective_end_time is not None:
                    start_idx = int(effective_start_time * sampling_freq)
                    end_idx = int(effective_end_time * sampling_freq)

                    # Ensure valid indices
                    start_idx = max(0, min(start_idx, len(df) - 1))
                    end_idx = max(start_idx + 1, min(end_idx, len(df)))
                    logger.info(
                        f"Time range {effective_start_time} to {effective_end_time} maps to indices {start_idx} to {end_idx}"
                    )
                else:
                    # Use full range if no time selection
                    start_idx = 0
                    end_idx = len(df)
                    logger.info("No time range selected, using full data")

                # Extract data for the selected range
                signal_data = df[signal_column].iloc[start_idx:end_idx].values
                time_axis = np.arange(start_idx, end_idx) / sampling_freq

            # Ensure signal data is numeric
            try:
                signal_data = pd.to_numeric(signal_data, errors="coerce")
                if np.isnan(signal_data).any():
                    logger.warning(
                        "Signal data contains non-numeric values. Converting with coercion."
                    )
                    # Remove NaN values
                    valid_mask = ~np.isnan(signal_data)
                    signal_data = signal_data[valid_mask]
                    time_axis = time_axis[valid_mask]
                    logger.info(
                        f"Removed {np.sum(~valid_mask)} non-numeric values from signal data"
                    )
            except Exception as e:
                logger.error(f"Error converting signal data to numeric: {e}")
                return (
                    create_empty_figure(),
                    create_empty_figure(),
                    create_empty_figure(),
                    "Error: Signal data contains non-numeric values that cannot be processed",
                    create_empty_figure(),
                    None,
                )

            # Ensure time axis is valid for plotting
            if np.isnan(time_axis).any() or np.isinf(time_axis).any():
                logger.warning(
                    "Time axis contains invalid values (NaN or Inf). Generating index-based time axis."
                )
                time_axis = np.arange(len(signal_data)) / sampling_freq
                logger.info(
                    f"Generated index-based time axis: {np.min(time_axis):.4f} to {np.max(time_axis):.4f} seconds"
                )

            logger.info(f"Signal data shape: {signal_data.shape}")
            logger.info(
                f"Signal data range: {np.min(signal_data):.4f} to {np.max(signal_data):.4f}"
            )
            logger.info(
                f"Signal data sample: {signal_data[:5] if len(signal_data) >= 5 else signal_data}"
            )

            logger.info("Final data extraction:")
            logger.info(f"  Start index: {start_idx}")
            logger.info(f"  End index: {end_idx}")
            logger.info(f"  Signal data shape: {signal_data.shape}")
            logger.info(f"  Time axis shape: {time_axis.shape}")
            logger.info(
                f"  Signal data range: {np.min(signal_data):.4f} to {np.max(signal_data):.4f}"
            )
            logger.info(
                f"  Time axis range: {np.min(time_axis):.4f} to {np.max(time_axis):.4f}"
            )
            logger.info(
                f"  Signal data sample: {signal_data[:5] if len(signal_data) >= 5 else signal_data}"
            )
            logger.info(
                f"  Time axis sample: {time_axis[:5] if len(time_axis) >= 5 else time_axis}"
            )

            # Check if we have valid data
            if len(signal_data) == 0:
                logger.error("No signal data extracted")
                return (
                    create_empty_figure(),
                    create_empty_figure(),
                    create_empty_figure(),
                    "No signal data extracted",
                    create_empty_figure(),
                    None,
                )

            # Store raw signal for plotting (before any preprocessing)
            raw_signal_for_plotting = signal_data.copy()
            logger.info(
                f"Raw signal stored for plotting - mean: {np.mean(raw_signal_for_plotting):.4f}, range: {np.min(raw_signal_for_plotting):.4f} to {np.max(raw_signal_for_plotting):.4f}"
            )

            # Apply detrending if user selected the option (to match time domain screen behavior)
            if detrend_option and "detrend" in detrend_option:
                logger.info(
                    "Applying detrending to match time domain screen behavior (zero baseline)"
                )
                from scipy import signal

                # Store original signal for comparison
                original_signal = signal_data.copy()

                # Apply linear detrending to remove DC offset and linear trends
                signal_data_detrended = signal.detrend(signal_data, type="linear")

                # Also apply mean subtraction for zero baseline
                signal_data_zero_baseline = signal_data_detrended - np.mean(
                    signal_data_detrended
                )

                logger.info("Detrending applied:")
                logger.info(f"  Original signal mean: {np.mean(original_signal):.4f}")
                logger.info(
                    f"  Detrended signal mean: {np.mean(signal_data_detrended):.4f}"
                )
                logger.info(
                    f"  Zero-baseline signal mean: {np.mean(signal_data_zero_baseline):.4f}"
                )
                logger.info(
                    f"  Original signal range: {np.min(original_signal):.4f} to {np.max(original_signal):.4f}"
                )
                logger.info(
                    f"  Detrended signal range: {np.min(signal_data_detrended):.4f} to {np.max(signal_data_detrended):.4f}"
                )
                logger.info(
                    f"  Zero-baseline signal range: {np.min(signal_data_zero_baseline):.4f} to {np.max(signal_data_zero_baseline):.4f}"
                )

                # Use zero-baseline signal for filtering to match time domain screen
                signal_data = signal_data_zero_baseline
            else:
                logger.info("Detrending not selected, using original signal baseline")
                logger.info(
                    f"Signal baseline - mean: {np.mean(signal_data):.4f}, range: {np.min(signal_data):.4f} to {np.max(signal_data):.4f}"
                )

            # Check if we have enough data points for filtering
            if len(signal_data) < 50:
                logger.warning(
                    f"Only {len(signal_data)} data points available, this may not be enough for effective filtering"
                )
                # Use a simple smoothing filter instead of complex filtering
                logger.info("Using simple smoothing instead of complex filtering")
                filtered_data = np.convolve(signal_data, np.ones(3) / 3, mode="same")
            else:
                logger.info(
                    f"Sufficient data points ({len(signal_data)}) for filtering"
                )

            # Get sampling frequency for filtering
            sampling_freq = data_info.get(
                "sampling_freq", 100
            )  # Default to 100 Hz based on the data info
            logger.info(f"Using sampling frequency for filtering: {sampling_freq} Hz")

            # Apply filtering based on type
            logger.info("=== APPLYING FILTERING ===")
            logger.info(f"Filter type: {filter_type}")
            logger.info(f"Input signal data shape: {signal_data.shape}")
            logger.info(
                f"Input signal data range: {np.min(signal_data):.4f} to {np.max(signal_data):.4f}"
            )

            # Only apply complex filtering if we have enough data points
            if len(signal_data) >= 50:
                if filter_type == "traditional":
                    # Apply traditional filter
                    logger.info(
                        f"Applying traditional filter: {filter_family} {filter_response}"
                    )
                    # Set default values for filter parameters
                    filter_family = filter_family or "butter"
                    filter_response = filter_response or "low"
                    low_freq = low_freq or 10
                    high_freq = high_freq or 50
                    filter_order = filter_order or 4

                    filtered_data = apply_traditional_filter(
                        signal_data,
                        sampling_freq,
                        filter_family,
                        filter_response,
                        low_freq,
                        high_freq,
                        filter_order,
                    )

                    # Apply additional traditional filters if parameters are provided
                    # Note: These would need to be added to the callback inputs
                    filtered_data = apply_additional_traditional_filters(
                        filtered_data, None, None, None, None, None, None
                    )

                elif filter_type == "advanced":
                    logger.info(f"Applying advanced filter: {advanced_method}")
                    filtered_data = apply_advanced_filter(
                        signal_data,
                        advanced_method,
                        noise_level,
                        iterations,
                        learning_rate,
                    )
                elif filter_type == "artifact":
                    # Enhanced artifact removal with all parameters
                    logger.info(f"Applying artifact removal: {artifact_type}")
                    filtered_data = apply_enhanced_artifact_removal(
                        signal_data,
                        sampling_freq,
                        artifact_type,
                        artifact_strength,
                        None,
                        None,
                        None,
                        None,
                        None,
                        None,
                        None,
                        None,
                    )
                elif filter_type == "neural":
                    logger.info(f"Applying neural filter: {neural_type}")
                    filtered_data = apply_neural_filter(
                        signal_data, neural_type, neural_complexity
                    )
                elif filter_type == "ensemble":
                    # Enhanced ensemble filtering with all parameters
                    logger.info(f"Applying ensemble filter: {ensemble_method}")
                    filtered_data = apply_enhanced_ensemble_filter(
                        signal_data,
                        ensemble_method,
                        ensemble_n_filters,
                        None,
                        None,
                        None,
                        None,
                        None,
                        None,
                    )
                else:
                    logger.info("No filter type selected, using original signal")
                    filtered_data = signal_data
            else:
                logger.info(
                    "Using simple smoothing filter due to insufficient data points"
                )
                # filtered_data is already set to simple smoothing above

            logger.info("Filtering completed:")
            logger.info(f"  Raw signal shape: {raw_signal_for_plotting.shape}")
            logger.info(f"  Processed signal shape: {signal_data.shape}")
            logger.info(f"  Filtered signal shape: {filtered_data.shape}")
            logger.info(
                f"  Raw signal range: {np.min(raw_signal_for_plotting):.4f} to {np.max(raw_signal_for_plotting):.4f}"
            )
            logger.info(
                f"  Processed signal range: {np.min(signal_data):.4f} to {np.max(signal_data):.4f}"
            )
            logger.info(
                f"  Filtered signal range: {np.min(filtered_data):.4f} to {np.max(filtered_data):.4f}"
            )

            # Apply multi-modal filtering if reference signal is specified
            # Note: These parameters would need to be added to the callback inputs
            if False:  # Placeholder for multi-modal filtering
                filtered_data = apply_multi_modal_filtering(
                    filtered_data, None, None, None, None
                )

            # Create visualizations
            logger.info("=== CREATING PLOTS ===")
            logger.info(f"Raw signal data shape: {raw_signal_for_plotting.shape}")
            logger.info(f"Processed signal data shape: {signal_data.shape}")
            logger.info(f"Filtered signal data shape: {filtered_data.shape}")
            logger.info(f"Time axis shape: {time_axis.shape}")
            logger.info(
                f"Raw signal range: {np.min(raw_signal_for_plotting):.4f} to {np.max(raw_signal_for_plotting):.4f}"
            )
            logger.info(
                f"Processed signal range: {np.min(signal_data):.4f} to {np.max(signal_data):.4f}"
            )
            logger.info(
                f"Filtered signal range: {np.min(filtered_data):.4f} to {np.max(filtered_data):.4f}"
            )

            original_plot = create_original_signal_plot(
                time_axis, raw_signal_for_plotting, sampling_freq, signal_type
            )
            filtered_plot = create_filtered_signal_plot(
                time_axis, filtered_data, sampling_freq, signal_type
            )
            comparison_plot = create_filter_comparison_plot(
                time_axis,
                raw_signal_for_plotting,
                filtered_data,
                sampling_freq,
                signal_type,
            )

            # Generate quality metrics using RAW signal (not detrended) for accurate assessment
            quality_metrics = generate_filter_quality_metrics(
                raw_signal_for_plotting, filtered_data, sampling_freq, quality_options
            )
            quality_plots = create_filter_quality_plots(
                raw_signal_for_plotting, filtered_data, sampling_freq, quality_options
            )

            # Store results
            stored_data = {
                "raw_signal": raw_signal_for_plotting.tolist(),
                "processed_signal": signal_data.tolist(),
                "filtered_signal": filtered_data.tolist(),
                "time_axis": time_axis.tolist(),
                "filter_type": filter_type,
                "detrending_applied": detrend_option and "detrend" in detrend_option,
                "parameters": {
                    "filter_family": filter_family,
                    "filter_response": filter_response,
                    "low_freq": low_freq,
                    "high_freq": high_freq,
                    "filter_order": filter_order,
                    "advanced_method": advanced_method,
                    "artifact_type": artifact_type,
                    "ensemble_method": ensemble_method,
                },
            }

            # Store filtered data in data service for use in other screens
            try:
                from vitalDSP_webapp.services.data.data_service import get_data_service

                data_service = get_data_service()

                # Create filter info for storage
                filter_info = {
                    "filter_type": filter_type,
                    "parameters": stored_data["parameters"],
                    "detrending_applied": stored_data["detrending_applied"],
                    "timestamp": pd.Timestamp.now().isoformat(),
                }

                # Store the filtered signal data
                success = data_service.store_filtered_data(
                    latest_data_id, filtered_data, filter_info
                )

                if success:
                    logger.info(
                        f"Filtered data stored successfully for data ID: {latest_data_id}"
                    )
                else:
                    logger.warning(
                        f"Failed to store filtered data for data ID: {latest_data_id}"
                    )

            except Exception as e:
                logger.error(f"Error storing filtered data: {e}")

            logger.info("Advanced filtering completed successfully")
            return (
                original_plot,
                filtered_plot,
                comparison_plot,
                quality_metrics,
                quality_plots,
                stored_data,
            )

        except Exception as e:
            logger.error(f"Error in advanced filtering callback: {e}")
            import traceback

            logger.error(f"Full traceback: {traceback.format_exc()}")

            # Handle string formatting errors specifically
            if "format code" in str(e) and "object of type 'str'" in str(e):
                error_msg = "Error: Data contains non-numeric values that cannot be processed. Please check your data format."
            else:
                error_msg = f"Error during filtering: {str(e)}"

            return (
                create_empty_figure(),
                create_empty_figure(),
                create_empty_figure(),
                error_msg,
                create_empty_figure(),
                None,
            )

    # Time input update callbacks
    @app.callback(
        [Output("filter-start-time", "value"), Output("filter-end-time", "value")],
        [
            Input("filter-time-range-slider", "value"),
            Input("filter-btn-nudge-m10", "n_clicks"),
            Input("filter-btn-nudge-m1", "n_clicks"),
            Input("filter-btn-nudge-p1", "n_clicks"),
            Input("filter-btn-nudge-p10", "n_clicks"),
        ],
        [State("filter-start-time", "value"), State("filter-end-time", "value")],
    )
    def update_filter_time_inputs(
        slider_value, nudge_m10, nudge_m1, nudge_p1, nudge_p10, start_time, end_time
    ):
        """Update time inputs based on slider or nudge buttons."""
        ctx = callback_context
        if not ctx.triggered:
            raise PreventUpdate

        trigger_id = ctx.triggered[0]["prop_id"].split(".")[0]

        if trigger_id == "filter-time-range-slider" and slider_value:
            return slider_value[0], slider_value[1]

        # Handle nudge buttons
        time_window = end_time - start_time if start_time and end_time else 10

        if trigger_id == "filter-btn-nudge-m10":
            new_start = max(0, start_time - 10) if start_time else 0
            new_end = new_start + time_window
            return new_start, new_end
        elif trigger_id == "filter-btn-nudge-m1":
            new_start = max(0, start_time - 1) if start_time else 0
            new_end = new_start + time_window
            return new_start, new_end
        elif trigger_id == "filter-btn-nudge-p1":
            new_start = start_time + 1 if start_time else 1
            new_end = new_start + time_window
            return new_start, new_end
        elif trigger_id == "filter-btn-nudge-p10":
            new_start = start_time + 10 if start_time else 10
            new_end = new_start + time_window
            return new_start, new_end

        return no_update, no_update

    # Time slider range update callback
    @app.callback(
        Output("filter-time-range-slider", "max"),
        [Input("store-uploaded-data", "data")],
    )
    def update_filter_time_slider_range(data_store):
        """Update time slider range based on uploaded data."""
        if not data_store:
            return 100

        try:
            df = pd.DataFrame(data_store["data"])
            if df.empty:
                return 100

            # Get time column (assume first column)
            time_data = df.iloc[:, 0].values
            max_time = np.max(time_data)
            return max_time
        except Exception as e:
            logger.error(f"Error updating filter time slider range: {e}")
            return 100


# Helper functions for signal filtering
def create_original_signal_plot(time_axis, signal_data, sampling_freq, signal_type):
    """Create plot for original signal with critical points detection."""
    try:
        logger.info("Creating original signal plot:")
        logger.info(f"  Time axis shape: {time_axis.shape}")
        logger.info(f"  Signal data shape: {signal_data.shape}")
        logger.info(
            f"  Time axis range: {np.min(time_axis):.4f} to {np.max(time_axis):.4f}"
        )
        logger.info(
            f"  Signal data range: {np.min(signal_data):.4f} to {np.max(signal_data):.4f}"
        )
        logger.info(
            f"  Time axis sample: {time_axis[:5] if len(time_axis) >= 5 else time_axis}"
        )
        logger.info(
            f"  Signal data sample: {signal_data[:5] if len(signal_data) >= 5 else signal_data}"
        )

        fig = go.Figure()

        # Add main signal
        fig.add_trace(
            go.Scatter(
                x=time_axis,
                y=signal_data,
                mode="lines",
                name="Original Signal",
                line=dict(color="blue", width=2),
            )
        )

        # Add critical points detection using vitalDSP waveform module
        try:
            from vitalDSP.physiological_features.waveform import WaveformMorphology

            # Create waveform morphology object
            wm = WaveformMorphology(
                waveform=signal_data,
                fs=sampling_freq,  # Use actual sampling frequency
                signal_type=signal_type,  # Use signal type from UI
                simple_mode=True,
            )

            # Detect critical points based on signal type
            if signal_type == "PPG":
                # For PPG: systolic peaks, dicrotic notches, diastolic peaks
                if hasattr(wm, "systolic_peaks") and wm.systolic_peaks is not None:
                    # Plot systolic peaks
                    fig.add_trace(
                        go.Scatter(
                            x=time_axis[wm.systolic_peaks],
                            y=signal_data[wm.systolic_peaks],
                            mode="markers",
                            name="Systolic Peaks",
                            marker=dict(color="red", size=10, symbol="diamond"),
                            hovertemplate="<b>Systolic Peak:</b> %{y}<extra></extra>",
                        )
                    )

                # Detect and plot dicrotic notches
                try:
                    dicrotic_notches = wm.detect_dicrotic_notches()
                    if dicrotic_notches is not None and len(dicrotic_notches) > 0:
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[dicrotic_notches],
                                y=signal_data[dicrotic_notches],
                                mode="markers",
                                name="Dicrotic Notches",
                                marker=dict(color="orange", size=8, symbol="circle"),
                                hovertemplate="<b>Dicrotic Notch:</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"Dicrotic notch detection failed: {e}")

                # Detect and plot diastolic peaks
                try:
                    diastolic_peaks = wm.detect_diastolic_peak()
                    if diastolic_peaks is not None and len(diastolic_peaks) > 0:
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[diastolic_peaks],
                                y=signal_data[diastolic_peaks],
                                mode="markers",
                                name="Diastolic Peaks",
                                marker=dict(color="green", size=8, symbol="square"),
                                hovertemplate="<b>Diastolic Peak:</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"Diastolic peak detection failed: {e}")

            elif signal_type == "ECG":
                # For ECG: R peaks, P peaks, T peaks
                if hasattr(wm, "r_peaks") and wm.r_peaks is not None:
                    # Plot R peaks
                    fig.add_trace(
                        go.Scatter(
                            x=time_axis[wm.r_peaks],
                            y=signal_data[wm.r_peaks],
                            mode="markers",
                            name="R Peaks",
                            marker=dict(color="red", size=10, symbol="diamond"),
                            hovertemplate="<b>R Peak:</b> %{y}<extra></extra>",
                        )
                    )

                # Detect and plot P peaks
                try:
                    p_peaks = wm.detect_p_peak()
                    if p_peaks is not None and len(p_peaks) > 0:
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[p_peaks],
                                y=signal_data[p_peaks],
                                mode="markers",
                                name="P Peaks",
                                marker=dict(color="blue", size=8, symbol="circle"),
                                hovertemplate="<b>P Peak:</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"P peak detection failed: {e}")

                # Detect and plot T peaks
                try:
                    t_peaks = wm.detect_t_peak()
                    if t_peaks is not None and len(t_peaks) > 0:
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[t_peaks],
                                y=signal_data[t_peaks],
                                mode="markers",
                                name="T Peaks",
                                marker=dict(color="green", size=8, symbol="square"),
                                hovertemplate="<b>T Peak:</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"T peak detection failed: {e}")

            else:
                # For other signal types, use basic peak detection
                logger.info(
                    f"Using basic peak detection for signal type: {signal_type}"
                )
                try:
                    from vitalDSP.physiological_features.peak_detection import (
                        detect_peaks,
                    )

                    peaks = detect_peaks(signal_data, sampling_freq)
                    if len(peaks) > 0:
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[peaks],
                                y=signal_data[peaks],
                                mode="markers",
                                name="Detected Peaks",
                                marker=dict(color="red", size=8, symbol="diamond"),
                                hovertemplate="<b>Peak:</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"Basic peak detection failed: {e}")

        except Exception as e:
            logger.warning(f"Critical points detection failed: {e}")

        fig.update_layout(
            title="Original Signal with Critical Points",
            xaxis_title="Time (s)",
            yaxis_title="Amplitude",
            height=400,
            showlegend=True,
        )

        logger.info("Original signal plot with critical points created successfully")
        return fig
    except Exception as e:
        logger.error(f"Error creating original signal plot: {e}")
        return create_empty_figure()


def create_filtered_signal_plot(time_axis, filtered_data, sampling_freq, signal_type):
    """Create plot for filtered signal with critical points detection."""
    try:
        logger.info("Creating filtered signal plot:")
        logger.info(f"  Time axis shape: {time_axis.shape}")
        logger.info(f"  Filtered data shape: {filtered_data.shape}")
        logger.info(
            f"  Time axis range: {np.min(time_axis):.4f} to {np.max(time_axis):.4f}"
        )
        logger.info(
            f"  Filtered data range: {np.min(filtered_data):.4f} to {np.max(filtered_data):.4f}"
        )
        logger.info(
            f"  Time axis sample: {time_axis[:5] if len(time_axis) >= 5 else time_axis}"
        )
        logger.info(
            f"  Filtered data sample: {filtered_data[:5] if len(filtered_data) >= 5 else filtered_data}"
        )

        fig = go.Figure()

        # Add main filtered signal
        fig.add_trace(
            go.Scatter(
                x=time_axis,
                y=filtered_data,
                mode="lines",
                name="Filtered Signal",
                line=dict(color="red", width=2),
            )
        )

        # Add critical points detection using vitalDSP waveform module
        try:
            from vitalDSP.physiological_features.waveform import WaveformMorphology

            # Create waveform morphology object for filtered signal
            wm = WaveformMorphology(
                waveform=filtered_data,
                fs=sampling_freq,  # Use actual sampling frequency
                signal_type=signal_type,  # Use signal type from UI
                simple_mode=True,
            )

            # Detect critical points based on signal type
            if signal_type == "PPG":
                # For PPG: systolic peaks, dicrotic notches, diastolic peaks
                if hasattr(wm, "systolic_peaks") and wm.systolic_peaks is not None:
                    # Plot systolic peaks
                    fig.add_trace(
                        go.Scatter(
                            x=time_axis[wm.systolic_peaks],
                            y=filtered_data[wm.systolic_peaks],
                            mode="markers",
                            name="Systolic Peaks (Filtered)",
                            marker=dict(color="darkred", size=10, symbol="diamond"),
                            hovertemplate="<b>Systolic Peak (Filtered):</b> %{y}<extra></extra>",
                        )
                    )

                # Detect and plot dicrotic notches
                try:
                    dicrotic_notches = wm.detect_dicrotic_notches()
                    if dicrotic_notches is not None and len(dicrotic_notches) > 0:
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[dicrotic_notches],
                                y=filtered_data[dicrotic_notches],
                                mode="markers",
                                name="Dicrotic Notches (Filtered)",
                                marker=dict(
                                    color="darkorange", size=8, symbol="circle"
                                ),
                                hovertemplate="<b>Dicrotic Notch (Filtered):</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"Dicrotic notch detection failed: {e}")

                # Detect and plot diastolic peaks
                try:
                    diastolic_peaks = wm.detect_diastolic_peak()
                    if diastolic_peaks is not None and len(diastolic_peaks) > 0:
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[diastolic_peaks],
                                y=filtered_data[diastolic_peaks],
                                mode="markers",
                                name="Diastolic Peaks (Filtered)",
                                marker=dict(color="darkgreen", size=8, symbol="square"),
                                hovertemplate="<b>Diastolic Peak (Filtered):</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"Diastolic peak detection failed: {e}")

            elif signal_type == "ECG":
                # For ECG: R peaks, P peaks, T peaks
                if hasattr(wm, "r_peaks") and wm.r_peaks is not None:
                    # Plot R peaks
                    fig.add_trace(
                        go.Scatter(
                            x=time_axis[wm.r_peaks],
                            y=filtered_data[wm.r_peaks],
                            mode="markers",
                            name="R Peaks (Filtered)",
                            marker=dict(color="darkred", size=10, symbol="diamond"),
                            hovertemplate="<b>R Peak (Filtered):</b> %{y}<extra></extra>",
                        )
                    )

                # Detect and plot P peaks
                try:
                    p_peaks = wm.detect_p_peak()
                    if p_peaks is not None and len(p_peaks) > 0:
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[p_peaks],
                                y=filtered_data[p_peaks],
                                mode="markers",
                                name="P Peaks (Filtered)",
                                marker=dict(color="darkblue", size=8, symbol="circle"),
                                hovertemplate="<b>P Peak (Filtered):</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"P peak detection failed: {e}")

                # Detect and plot T peaks
                try:
                    t_peaks = wm.detect_t_peak()
                    if t_peaks is not None and len(t_peaks) > 0:
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[t_peaks],
                                y=filtered_data[t_peaks],
                                mode="markers",
                                name="T Peaks (Filtered)",
                                marker=dict(color="darkgreen", size=8, symbol="square"),
                                hovertemplate="<b>T Peak (Filtered):</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"T peak detection failed: {e}")

            else:
                # For other signal types, use basic peak detection
                logger.info(
                    f"Using basic peak detection for signal type: {signal_type}"
                )
                try:
                    from vitalDSP.physiological_features.peak_detection import (
                        detect_peaks,
                    )

                    peaks = detect_peaks(filtered_data, sampling_freq)
                    if len(peaks) > 0:
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[peaks],
                                y=filtered_data[peaks],
                                mode="markers",
                                name="Detected Peaks (Filtered)",
                                marker=dict(color="darkred", size=8, symbol="diamond"),
                                hovertemplate="<b>Peak (Filtered):</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"Basic peak detection failed: {e}")

        except Exception as e:
            logger.warning(f"Critical points detection failed: {e}")

        fig.update_layout(
            title="Filtered Signal with Critical Points",
            xaxis_title="Time (s)",
            yaxis_title="Amplitude",
            height=400,
            showlegend=True,
        )

        logger.info("Filtered signal plot with critical points created successfully")
        return fig
    except Exception as e:
        logger.error(f"Error creating filtered signal plot: {e}")
        return create_empty_figure()


def create_filter_comparison_plot(
    time_axis, original_signal, filtered_signal, sampling_freq, signal_type
):
    """Create comparison plot between original and filtered signals with critical points detection."""
    try:
        logger.info("Creating comparison plot:")
        logger.info(f"  Time axis shape: {time_axis.shape}")
        logger.info(f"  Original signal shape: {original_signal.shape}")
        logger.info(f"  Filtered signal shape: {filtered_signal.shape}")
        logger.info(
            f"  Time axis range: {np.min(time_axis):.4f} to {np.max(time_axis):.4f}"
        )
        logger.info(
            f"  Original signal range: {np.min(original_signal):.4f} to {np.max(original_signal):.4f}"
        )
        logger.info(
            f"  Filtered signal range: {np.min(filtered_signal):.4f} to {np.max(filtered_signal):.4f}"
        )

        fig = go.Figure()

        # Original signal
        fig.add_trace(
            go.Scatter(
                x=time_axis,
                y=original_signal,
                mode="lines",
                name="Original Signal",
                line=dict(color="blue", width=2),
                opacity=0.8,
            )
        )

        # Filtered signal
        fig.add_trace(
            go.Scatter(
                x=time_axis,
                y=filtered_signal,
                mode="lines",
                name="Filtered Signal",
                line=dict(color="red", width=2),
                opacity=0.8,
            )
        )

        # Add critical points detection using vitalDSP waveform module
        try:
            from vitalDSP.physiological_features.waveform import WaveformMorphology

            # Create waveform morphology object for original signal
            wm_orig = WaveformMorphology(
                waveform=original_signal,
                fs=sampling_freq,  # Use actual sampling frequency
                signal_type=signal_type,  # Use signal type from UI
                simple_mode=True,
            )

            # Create waveform morphology object for filtered signal
            wm_filt = WaveformMorphology(
                waveform=filtered_signal,
                fs=sampling_freq,  # Use actual sampling frequency
                signal_type=signal_type,  # Use signal type from UI
                simple_mode=True,
            )

            # Detect and plot critical points for original signal
            if signal_type == "PPG":
                # For PPG: systolic peaks, dicrotic notches, diastolic peaks
                if (
                    hasattr(wm_orig, "systolic_peaks")
                    and wm_orig.systolic_peaks is not None
                ):
                    fig.add_trace(
                        go.Scatter(
                            x=time_axis[wm_orig.systolic_peaks],
                            y=original_signal[wm_orig.systolic_peaks],
                            mode="markers",
                            name="Systolic Peaks (Original)",
                            marker=dict(color="darkblue", size=8, symbol="diamond"),
                            hovertemplate="<b>Original Systolic Peak:</b> %{y}<extra></extra>",
                        )
                    )

                # Detect and plot dicrotic notches for original signal
                try:
                    dicrotic_notches_orig = wm_orig.detect_dicrotic_notches()
                    if (
                        dicrotic_notches_orig is not None
                        and len(dicrotic_notches_orig) > 0
                    ):
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[dicrotic_notches_orig],
                                y=original_signal[dicrotic_notches_orig],
                                mode="markers",
                                name="Dicrotic Notches (Original)",
                                marker=dict(
                                    color="darkorange", size=6, symbol="circle"
                                ),
                                hovertemplate="<b>Original Dicrotic Notch:</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"Original dicrotic notch detection failed: {e}")

                # Detect and plot diastolic peaks for original signal
                try:
                    diastolic_peaks_orig = wm_orig.detect_diastolic_peak()
                    if (
                        diastolic_peaks_orig is not None
                        and len(diastolic_peaks_orig) > 0
                    ):
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[diastolic_peaks_orig],
                                y=original_signal[diastolic_peaks_orig],
                                mode="markers",
                                name="Diastolic Peaks (Original)",
                                marker=dict(color="darkgreen", size=6, symbol="square"),
                                hovertemplate="<b>Original Diastolic Peak:</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"Original diastolic peak detection failed: {e}")

            # Detect and plot critical points for filtered signal
            if (
                hasattr(wm_filt, "systolic_peaks")
                and wm_filt.systolic_peaks is not None
            ):
                fig.add_trace(
                    go.Scatter(
                        x=time_axis[wm_filt.systolic_peaks],
                        y=filtered_signal[wm_filt.systolic_peaks],
                        mode="markers",
                        name="Systolic Peaks (Filtered)",
                        marker=dict(color="darkred", size=8, symbol="diamond"),
                        hovertemplate="<b>Filtered Systolic Peak:</b> %{y}<extra></extra>",
                    )
                )

                # Detect and plot dicrotic notches for filtered signal
                try:
                    dicrotic_notches_filt = wm_filt.detect_dicrotic_notches()
                    if (
                        dicrotic_notches_filt is not None
                        and len(dicrotic_notches_filt) > 0
                    ):
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[dicrotic_notches_filt],
                                y=filtered_signal[dicrotic_notches_filt],
                                mode="markers",
                                name="Dicrotic Notches (Filtered)",
                                marker=dict(color="red", size=6, symbol="circle"),
                                hovertemplate="<b>Filtered Dicrotic Notch:</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"Filtered dicrotic notch detection failed: {e}")

                # Detect and plot diastolic peaks for filtered signal
                try:
                    diastolic_peaks_filt = wm_filt.detect_diastolic_peak()
                    if (
                        diastolic_peaks_filt is not None
                        and len(diastolic_peaks_filt) > 0
                    ):
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[diastolic_peaks_filt],
                                y=filtered_signal[diastolic_peaks_filt],
                                mode="markers",
                                name="Diastolic Peaks (Filtered)",
                                marker=dict(color="green", size=6, symbol="square"),
                                hovertemplate="<b>Filtered Diastolic Peak:</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"Filtered diastolic peak detection failed: {e}")

            elif signal_type == "ECG":
                # For ECG: R peaks, P peaks, T peaks
                if hasattr(wm_orig, "r_peaks") and wm_orig.r_peaks is not None:
                    fig.add_trace(
                        go.Scatter(
                            x=time_axis[wm_orig.r_peaks],
                            y=original_signal[wm_orig.r_peaks],
                            mode="markers",
                            name="R Peaks (Original)",
                            marker=dict(color="darkblue", size=8, symbol="diamond"),
                            hovertemplate="<b>Original R Peak:</b> %{y}<extra></extra>",
                        )
                    )

                # Detect and plot P peaks for original signal
                try:
                    p_peaks_orig = wm_orig.detect_p_peak()
                    if p_peaks_orig is not None and len(p_peaks_orig) > 0:
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[p_peaks_orig],
                                y=original_signal[p_peaks_orig],
                                mode="markers",
                                name="P Peaks (Original)",
                                marker=dict(color="darkblue", size=6, symbol="circle"),
                                hovertemplate="<b>Original P Peak:</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"Original P peak detection failed: {e}")

                # Detect and plot T peaks for original signal
                try:
                    t_peaks_orig = wm_orig.detect_t_peak()
                    if t_peaks_orig is not None and len(t_peaks_orig) > 0:
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[t_peaks_orig],
                                y=original_signal[t_peaks_orig],
                                mode="markers",
                                name="T Peaks (Original)",
                                marker=dict(color="darkgreen", size=6, symbol="square"),
                                hovertemplate="<b>Original T Peak:</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"Original T peak detection failed: {e}")

                # Detect and plot Q valleys for original signal
                try:
                    q_valleys_orig = wm_orig.detect_q_valley()
                    if q_valleys_orig is not None and len(q_valleys_orig) > 0:
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[q_valleys_orig],
                                y=original_signal[q_valleys_orig],
                                mode="markers",
                                name="Q Valleys (Original)",
                                marker=dict(
                                    color="darkorange", size=6, symbol="triangle-down"
                                ),
                                hovertemplate="<b>Original Q Valley:</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"Original Q valley detection failed: {e}")

                # Detect and plot S valleys for original signal
                try:
                    s_valleys_orig = wm_orig.detect_s_valley()
                    if s_valleys_orig is not None and len(s_valleys_orig) > 0:
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[s_valleys_orig],
                                y=original_signal[s_valleys_orig],
                                mode="markers",
                                name="S Valleys (Original)",
                                marker=dict(
                                    color="darkred", size=6, symbol="triangle-down"
                                ),
                                hovertemplate="<b>Original S Valley:</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"Original S valley detection failed: {e}")

                # Detect and plot critical points for filtered signal
                if hasattr(wm_filt, "r_peaks") and wm_filt.r_peaks is not None:
                    fig.add_trace(
                        go.Scatter(
                            x=time_axis[wm_filt.r_peaks],
                            y=filtered_signal[wm_filt.r_peaks],
                            mode="markers",
                            name="R Peaks (Filtered)",
                            marker=dict(color="darkred", size=8, symbol="diamond"),
                            hovertemplate="<b>Filtered R Peak:</b> %{y}<extra></extra>",
                        )
                    )

                # Detect and plot P peaks for filtered signal
                try:
                    p_peaks_filt = wm_filt.detect_p_peak()
                    if p_peaks_filt is not None and len(p_peaks_filt) > 0:
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[p_peaks_filt],
                                y=filtered_signal[p_peaks_filt],
                                mode="markers",
                                name="P Peaks (Filtered)",
                                marker=dict(color="red", size=6, symbol="circle"),
                                hovertemplate="<b>Filtered P Peak:</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"Filtered P peak detection failed: {e}")

                # Detect and plot T peaks for filtered signal
                try:
                    t_peaks_filt = wm_filt.detect_t_peak()
                    if t_peaks_filt is not None and len(t_peaks_filt) > 0:
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[t_peaks_filt],
                                y=filtered_signal[t_peaks_filt],
                                mode="markers",
                                name="T Peaks (Filtered)",
                                marker=dict(color="green", size=6, symbol="square"),
                                hovertemplate="<b>Filtered T Peak:</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"Filtered T peak detection failed: {e}")

                # Detect and plot Q valleys for filtered signal
                try:
                    q_valleys_filt = wm_filt.detect_q_valley()
                    if q_valleys_filt is not None and len(q_valleys_filt) > 0:
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[q_valleys_filt],
                                y=filtered_signal[q_valleys_filt],
                                mode="markers",
                                name="Q Valleys (Filtered)",
                                marker=dict(
                                    color="orange", size=6, symbol="triangle-down"
                                ),
                                hovertemplate="<b>Filtered Q Valley:</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"Filtered Q valley detection failed: {e}")

                # Detect and plot S valleys for filtered signal
                try:
                    s_valleys_filt = wm_filt.detect_s_valley()
                    if s_valleys_filt is not None and len(s_valleys_filt) > 0:
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[s_valleys_filt],
                                y=filtered_signal[s_valleys_filt],
                                mode="markers",
                                name="S Valleys (Filtered)",
                                marker=dict(
                                    color="red", size=6, symbol="triangle-down"
                                ),
                                hovertemplate="<b>Filtered S Valley:</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"Filtered S valley detection failed: {e}")

            else:
                # For other signal types, use basic peak detection
                logger.info(
                    f"Using basic peak detection for signal type: {signal_type}"
                )
                try:
                    from vitalDSP.physiological_features.peak_detection import (
                        detect_peaks,
                    )

                    orig_peaks = detect_peaks(original_signal, sampling_freq)
                    filt_peaks = detect_peaks(filtered_signal, sampling_freq)

                    if len(orig_peaks) > 0:
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[orig_peaks],
                                y=original_signal[orig_peaks],
                                mode="markers",
                                name="Original Detected Peaks",
                                marker=dict(color="darkblue", size=8, symbol="diamond"),
                                hovertemplate="<b>Original Peak:</b> %{y}<extra></extra>",
                            )
                        )

                    if len(filt_peaks) > 0:
                        fig.add_trace(
                            go.Scatter(
                                x=time_axis[filt_peaks],
                                y=filtered_signal[filt_peaks],
                                mode="markers",
                                name="Filtered Detected Peaks",
                                marker=dict(color="darkred", size=8, symbol="diamond"),
                                hovertemplate="<b>Filtered Peak:</b> %{y}<extra></extra>",
                            )
                        )
                except Exception as e:
                    logger.warning(f"Basic peak detection failed: {e}")

        except Exception as e:
            logger.warning(f"Critical points detection failed: {e}")

        fig.update_layout(
            title="Signal Comparison: Original vs Filtered with Critical Points",
            xaxis_title="Time (s)",
            yaxis_title="Amplitude",
            height=400,
            showlegend=True,
        )

        logger.info("Comparison plot with critical points created successfully")
        return fig
    except Exception as e:
        logger.error(f"Error creating comparison plot: {e}")
        return create_empty_figure()


def create_empty_figure():
    """Create an empty figure for error cases."""
    fig = go.Figure()
    fig.add_annotation(
        text="No data available",
        xref="paper",
        yref="paper",
        x=0.5,
        y=0.5,
        showarrow=False,
    )
    fig.update_layout(height=400)
    return fig


def create_signal_plot(signal_data, time_axis, title):
    """Create a signal plot."""
    fig = go.Figure()
    fig.add_trace(
        go.Scatter(
            x=time_axis,
            y=signal_data,
            mode="lines",
            name=title,
            line=dict(color="blue", width=1.5),
        )
    )

    fig.update_layout(
        title=title,
        xaxis_title="Time (seconds)",
        yaxis_title="Amplitude",
        showlegend=True,
        height=400,
    )

    return fig


# Removed duplicate function - the correct one is above


def apply_traditional_filter(
    signal_data,
    sampling_freq,
    filter_family,
    filter_response,
    low_freq,
    high_freq,
    filter_order,
):
    """Apply traditional filtering using vitalDSP functions."""
    try:
        logger.info("=== TRADITIONAL FILTER DEBUG ===")
        logger.info(f"Input signal shape: {signal_data.shape}")
        logger.info(
            f"Input signal range: {np.min(signal_data):.4f} to {np.max(signal_data):.4f}"
        )
        logger.info(f"Filter family: {filter_family}")
        logger.info(f"Filter response: {filter_response}")
        logger.info(f"Low frequency: {low_freq}")
        logger.info(f"High frequency: {high_freq}")
        logger.info(f"Filter order: {filter_order}")
        logger.info(f"Sampling frequency: {sampling_freq}")

        # Import vitalDSP traditional filtering functions
        from vitalDSP.filtering.signal_filtering import SignalFiltering

        # Create filter instance
        logger.info("SignalFiltering instance created successfully")

        # Apply filter based on type - using EXACT same scipy implementation as time domain screen
        if filter_response == "low":
            logger.info(f"Applying low-pass filter with cutoff: {low_freq}")
            # Use scipy directly (same as time domain screen)
            nyquist = sampling_freq / 2
            low_freq_norm = low_freq / nyquist

            # Ensure cutoff frequency is within valid range
            low_freq_norm = max(0.001, min(low_freq_norm, 0.999))

            from scipy import signal

            if filter_family == "butter":
                b, a = signal.butter(filter_order, low_freq_norm, btype="low")
            elif filter_family == "cheby1":
                b, a = signal.cheby1(filter_order, 1, low_freq_norm, btype="low")
            elif filter_family == "cheby2":
                b, a = signal.cheby2(filter_order, 40, low_freq_norm, btype="low")
            elif filter_family == "ellip":
                b, a = signal.ellip(filter_order, 1, 40, low_freq_norm, btype="low")
            else:
                b, a = signal.butter(filter_order, low_freq_norm, btype="low")

            filtered_signal = signal.filtfilt(b, a, signal_data)
            logger.info(
                f"Low-pass filter applied using scipy {filter_family} (same as time domain screen)"
            )

        elif filter_response == "high":
            logger.info(f"Applying high-pass filter with cutoff: {high_freq}")
            # Use scipy directly (same as time domain screen)
            nyquist = sampling_freq / 2
            high_freq_norm = high_freq / nyquist

            # Ensure cutoff frequency is within valid range
            high_freq_norm = max(0.001, min(high_freq_norm, 0.999))

            from scipy import signal

            if filter_family == "butter":
                b, a = signal.butter(filter_order, high_freq_norm, btype="high")
            elif filter_family == "cheby1":
                b, a = signal.cheby1(filter_order, 1, high_freq_norm, btype="high")
            elif filter_family == "cheby2":
                b, a = signal.cheby2(filter_order, 40, high_freq_norm, btype="high")
            elif filter_family == "ellip":
                b, a = signal.ellip(filter_order, 1, 40, high_freq_norm, btype="high")
            else:
                b, a = signal.butter(filter_order, high_freq_norm, btype="high")

            filtered_signal = signal.filtfilt(b, a, signal_data)
            logger.info(
                f"High-pass filter applied using scipy {filter_family} (same as time domain screen)"
            )

        elif filter_response == "bandpass":
            logger.info(
                f"Applying bandpass filter with range: {low_freq} - {high_freq}"
            )
            # Use EXACT same scipy implementation as time domain screen for consistency
            logger.info(
                "Using scipy implementation for bandpass (same as time domain screen)"
            )
            nyquist = sampling_freq / 2
            low_freq_norm = low_freq / nyquist
            high_freq_norm = high_freq / nyquist

            # Ensure cutoff frequencies are within valid range
            low_freq_norm = max(0.001, min(low_freq_norm, 0.999))
            high_freq_norm = max(0.001, min(high_freq_norm, 0.999))

            # Use scipy directly (same as time domain screen)
            from scipy import signal

            if filter_family == "butter":
                b, a = signal.butter(
                    filter_order, [low_freq_norm, high_freq_norm], btype="band"
                )
            elif filter_family == "cheby1":
                b, a = signal.cheby1(
                    filter_order, 1, [low_freq_norm, high_freq_norm], btype="band"
                )
            elif filter_family == "cheby2":
                b, a = signal.cheby2(
                    filter_order, 40, [low_freq_norm, high_freq_norm], btype="band"
                )
            elif filter_family == "ellip":
                b, a = signal.ellip(
                    filter_order, 1, 40, [low_freq_norm, high_freq_norm], btype="band"
                )
            else:
                b, a = signal.butter(
                    filter_order, [low_freq_norm, high_freq_norm], btype="band"
                )

            filtered_signal = signal.filtfilt(b, a, signal_data)
            logger.info(
                f"Bandpass filter applied using scipy {filter_family} (same as time domain screen)"
            )

        elif filter_response == "bandstop":
            logger.info(
                f"Applying bandstop filter with range: {low_freq} - {high_freq}"
            )
            # vitalDSP doesn't support bandstop, use scipy directly (same as time domain screen)
            nyquist = sampling_freq / 2
            low_freq_norm = low_freq / nyquist
            high_freq_norm = high_freq / nyquist

            # Ensure cutoff frequencies are within valid range
            low_freq_norm = max(0.001, min(low_freq_norm, 0.999))
            high_freq_norm = max(0.001, min(high_freq_norm, 0.999))

            # Use scipy directly for bandstop (same as time domain screen)
            from scipy import signal

            if filter_family == "butter":
                b, a = signal.butter(
                    filter_order, [low_freq_norm, high_freq_norm], btype="bandstop"
                )
            elif filter_family == "cheby1":
                b, a = signal.cheby1(
                    filter_order, 1, [low_freq_norm, high_freq_norm], btype="bandstop"
                )
            elif filter_family == "cheby2":
                b, a = signal.cheby2(
                    filter_order, 40, [low_freq_norm, high_freq_norm], btype="bandstop"
                )
            elif filter_family == "ellip":
                b, a = signal.ellip(
                    filter_order,
                    1,
                    40,
                    [low_freq_norm, high_freq_norm],
                    btype="bandstop",
                )
            else:
                b, a = signal.butter(
                    filter_order, [low_freq_norm, high_freq_norm], btype="bandstop"
                )

            filtered_signal = signal.filtfilt(b, a, signal_data)
            logger.info(
                f"Bandstop filter applied using scipy {filter_family} (vitalDSP doesn't have bandstop)"
            )

        elif filter_response == "default":
            # Default to low pass
            logger.info(f"Defaulting to low-pass filter with cutoff: {low_freq}")
            # Use scipy directly (same as time domain screen)
            nyquist = sampling_freq / 2
            low_freq_norm = low_freq / nyquist

            # Ensure cutoff frequency is within valid range
            low_freq_norm = max(0.001, min(low_freq_norm, 0.999))

            from scipy import signal

            b, a = signal.butter(filter_order, low_freq_norm, btype="low")
            filtered_signal = signal.filtfilt(b, a, signal_data)
            logger.info(
                "Default low-pass filter applied using scipy (same as time domain screen)"
            )

        logger.info(
            f"Traditional filter applied successfully: {filter_family} {filter_response}"
        )
        logger.info(f"Output signal shape: {filtered_signal.shape}")
        logger.info(
            f"Output signal range: {np.min(filtered_signal):.4f} to {np.max(filtered_signal):.4f}"
        )
        return filtered_signal

    except Exception as e:
        logger.error(f"Error applying traditional filter: {e}")
        logger.error(f"Exception details: {type(e).__name__}: {str(e)}")
        # Fallback to scipy implementation (same as time domain screen)
        logger.info("Falling back to scipy implementation for consistency")
        try:
            # Normalize cutoff frequencies
            nyquist = sampling_freq / 2
            low_freq_norm = low_freq / nyquist
            high_freq_norm = high_freq / nyquist

            # Ensure cutoff frequencies are within valid range
            low_freq_norm = max(0.001, min(low_freq_norm, 0.999))
            high_freq_norm = max(0.001, min(high_freq_norm, 0.999))

            # Determine filter type based on response
            if filter_response == "bandpass":
                btype = "band"
                cutoff = [low_freq_norm, high_freq_norm]
            elif filter_response == "bandstop":
                btype = "bandstop"
                cutoff = [low_freq_norm, high_freq_norm]
            elif filter_response == "lowpass":
                btype = "low"
                cutoff = high_freq_norm
            elif filter_response == "highpass":
                btype = "high"
                cutoff = low_freq_norm
            else:
                btype = "low"
                cutoff = high_freq_norm

            # Apply filter using scipy (same as time domain screen)
            from scipy import signal

            b, a = signal.butter(filter_order, cutoff, btype=btype)
            filtered_signal = signal.filtfilt(b, a, signal_data)

            logger.info("Scipy fallback successful")
            return filtered_signal

        except Exception as fallback_error:
            logger.error(f"Scipy fallback also failed: {fallback_error}")
            return signal_data


def apply_additional_traditional_filters(
    signal_data,
    savgol_window,
    savgol_polyorder,
    moving_avg_window,
    moving_avg_iterations,
    gaussian_sigma,
    gaussian_iterations,
):
    """Apply additional traditional filters like Savitzky-Golay, moving average, and Gaussian."""
    try:
        logger.info("Applying additional traditional filters")

        from vitalDSP.filtering.signal_filtering import SignalFiltering

        signal_filter = SignalFiltering(signal_data)
        filtered_signal = signal_data.copy()

        # Apply Savitzky-Golay filter if parameters are provided
        if savgol_window and savgol_polyorder:
            try:
                filtered_signal = signal_filter.savgol_filter(
                    filtered_signal,
                    window_length=savgol_window,
                    polyorder=savgol_polyorder,
                )
                logger.info(
                    f"Savitzky-Golay filter applied: window={savgol_window}, polyorder={savgol_polyorder}"
                )
            except Exception as e:
                logger.warning(f"Savitzky-Golay filter failed: {e}")

        # Apply moving average filter if parameters are provided
        if moving_avg_window:
            try:
                filtered_signal = signal_filter.moving_average(
                    window_size=moving_avg_window,
                    iterations=moving_avg_iterations or 1,
                    method="edge",
                )
                logger.info(
                    f"Moving average filter applied: window={moving_avg_window}, iterations={moving_avg_iterations}"
                )
            except Exception as e:
                logger.warning(f"Moving average filter failed: {e}")

        # Apply Gaussian filter if parameters are provided
        if gaussian_sigma:
            try:
                filtered_signal = signal_filter.gaussian(
                    sigma=gaussian_sigma, iterations=gaussian_iterations or 1
                )
                logger.info(
                    f"Gaussian filter applied: sigma={gaussian_sigma}, iterations={gaussian_iterations}"
                )
            except Exception as e:
                logger.warning(f"Gaussian filter failed: {e}")

        return filtered_signal

    except Exception as e:
        logger.error(f"Error applying additional traditional filters: {e}")
        return signal_data


def apply_enhanced_artifact_removal(
    signal_data,
    sampling_freq,
    artifact_type,
    artifact_strength,
    wavelet_type,
    wavelet_level,
    threshold_type,
    threshold_value,
    powerline_freq,
    notch_q_factor,
    pca_components,
    ica_components,
):
    """Apply enhanced artifact removal using vitalDSP functions with configurable parameters."""
    try:
        logger.info(f"Applying enhanced artifact removal: {artifact_type}")

        from vitalDSP.filtering.artifact_removal import ArtifactRemoval

        # Set default values
        artifact_type = artifact_type or "baseline"
        artifact_strength = artifact_strength or 0.5

        # Create artifact removal instance
        artifact_remover = ArtifactRemoval(signal_data)

        # Apply artifact removal based on type with enhanced parameters
        if artifact_type == "baseline":
            filtered_signal = artifact_remover.baseline_correction(
                cutoff=artifact_strength, fs=sampling_freq
            )
        elif artifact_type == "spike":
            filtered_signal = artifact_remover.median_filter_removal()
        elif artifact_type == "noise":
            # Enhanced wavelet denoising with configurable parameters
            filtered_signal = artifact_remover.wavelet_denoising(
                wavelet_type=wavelet_type or "db4",
                level=wavelet_level or 3,
                threshold_type=threshold_type or "soft",
                threshold_value=threshold_value or 0.1,
            )
        elif artifact_type == "powerline":
            filtered_signal = artifact_remover.notch_filter(
                freq=powerline_freq or 50, fs=sampling_freq, Q=notch_q_factor or 30
            )
        elif artifact_type == "pca":
            filtered_signal = artifact_remover.pca_artifact_removal(
                num_components=pca_components or 1
            )
        elif artifact_type == "ica":
            filtered_signal = artifact_remover.ica_artifact_removal(
                num_components=ica_components or 2
            )
        else:
            # Default to baseline correction
            filtered_signal = artifact_remover.baseline_correction(
                cutoff=artifact_strength, fs=sampling_freq
            )

        logger.info(f"Enhanced artifact removal applied successfully: {artifact_type}")
        return filtered_signal

    except Exception as e:
        logger.error(f"Error applying enhanced artifact removal: {e}")
        # Return original signal if artifact removal fails
        return signal_data


def apply_advanced_filter(
    signal_data, advanced_method, noise_level, iterations, learning_rate
):
    """Apply advanced filtering using vitalDSP functions."""
    try:
        logger.info(f"Applying advanced filter: {advanced_method}")

        # Import vitalDSP advanced filtering functions
        from vitalDSP.filtering.advanced_signal_filtering import AdvancedSignalFiltering

        # Set default values
        advanced_method = advanced_method or "kalman"
        noise_level = noise_level or 0.1
        iterations = iterations or 100
        learning_rate = learning_rate or 0.01

        # Create advanced filter instance
        advanced_filter = AdvancedSignalFiltering(signal_data)

        # Apply filter based on method
        if advanced_method == "kalman":
            filtered_signal = advanced_filter.kalman_filter(R=noise_level, Q=1)
        elif advanced_method == "optimization":
            filtered_signal = advanced_filter.optimization_based_filtering(
                target=signal_data,
                loss_type="mse",
                learning_rate=learning_rate,
                iterations=iterations,
            )
        elif advanced_method == "gradient_descent":
            filtered_signal = advanced_filter.gradient_descent_filter(
                target=signal_data, learning_rate=learning_rate, iterations=iterations
            )
        elif advanced_method == "convolution":
            filtered_signal = advanced_filter.convolution_based_filter(
                kernel_type="smoothing", kernel_size=5
            )
        elif advanced_method == "attention":
            filtered_signal = advanced_filter.attention_based_filter(
                attention_type="uniform", size=5
            )
        else:
            # Default to Kalman filter
            filtered_signal = advanced_filter.kalman_filter(R=noise_level, Q=1)

        logger.info(f"Advanced filter applied successfully: {advanced_method}")
        return filtered_signal

    except Exception as e:
        logger.error(f"Error applying advanced filter: {e}")
        # Return original signal if advanced filtering fails
        return signal_data


def apply_neural_filter(signal_data, neural_type, neural_complexity):
    """Apply neural network filtering using vitalDSP functions."""
    try:
        logger.info(f"Applying neural filter: {neural_type}")

        # Import vitalDSP neural filtering functions
        from vitalDSP.advanced_computation.neural_network_filtering import (
            NeuralNetworkFiltering,
        )

        # Set default values
        neural_type = neural_type or "feedforward"
        neural_complexity = neural_complexity or "medium"

        # Set complexity-based parameters
        if neural_complexity == "low":
            hidden_layers = [32]
            epochs = 50
        elif neural_complexity == "high":
            hidden_layers = [128, 64, 32]
            epochs = 200
        else:  # medium
            hidden_layers = [64, 32]
            epochs = 100

        # Create neural filter instance
        neural_filter = NeuralNetworkFiltering(
            signal_data,
            network_type=neural_type,
            hidden_layers=hidden_layers,
            epochs=epochs,
        )

        # Train the neural network first
        neural_filter.train()

        # Apply the trained filter
        filtered_signal = neural_filter.apply_filter()

        logger.info(f"Neural filter applied successfully: {neural_type}")
        return filtered_signal

    except Exception as e:
        logger.error(f"Error applying neural filter: {e}")
        # Return original signal if neural filtering fails
        return signal_data


def apply_ensemble_filter(signal_data, ensemble_method, ensemble_n_filters):
    """Apply ensemble filtering using vitalDSP functions."""
    try:
        logger.info(f"Applying ensemble filter: {ensemble_method}")

        # Import vitalDSP ensemble filtering functions
        from vitalDSP.filtering.advanced_signal_filtering import AdvancedSignalFiltering

        # Set default values
        ensemble_method = ensemble_method or "mean"
        ensemble_n_filters = ensemble_n_filters or 3

        # Create advanced filter instance
        advanced_filter = AdvancedSignalFiltering(signal_data)

        # Create multiple filters for ensemble
        filters = []
        for i in range(ensemble_n_filters):
            # Create different filter configurations
            if i == 0:
                # Kalman filter
                filtered = advanced_filter.kalman_filter(R=0.1, Q=1)
            elif i == 1:
                # Convolution filter
                filtered = advanced_filter.convolution_based_filter(
                    kernel_type="smoothing", kernel_size=3
                )
            else:
                # Optimization filter
                filtered = advanced_filter.optimization_based_filtering(
                    target=signal_data,
                    loss_type="mse",
                    learning_rate=0.01,
                    iterations=50,
                )
            filters.append(filtered)

        # Apply ensemble method
        if ensemble_method == "mean":
            filtered_signal = np.mean(filters, axis=0)
        elif ensemble_method == "median":
            filtered_signal = np.median(filters, axis=0)
        elif ensemble_method == "weighted":
            # Weight by filter performance (inverse of variance)
            weights = 1 / (np.var(filters, axis=0) + 1e-10)
            weights = weights / np.sum(weights)
            filtered_signal = np.average(filters, axis=0, weights=weights)
        else:
            # Default to mean
            filtered_signal = np.mean(filters, axis=0)

        logger.info(
            f"Ensemble filter applied successfully: {ensemble_method} with {ensemble_n_filters} filters"
        )
        return filtered_signal

    except Exception as e:
        logger.error(f"Error applying ensemble filter: {e}")
        # Return original signal if ensemble filtering fails
        return signal_data


def apply_enhanced_ensemble_filter(
    signal_data,
    ensemble_method,
    ensemble_n_filters,
    ensemble_learning_rate,
    ensemble_iterations,
    adaptive_filter_order,
    adaptive_step_size,
    forgetting_factor,
    regularization_param,
):
    """Apply enhanced ensemble filtering with real-time capabilities."""
    try:
        logger.info(f"Applying enhanced ensemble filter: {ensemble_method}")

        from vitalDSP.filtering.advanced_signal_filtering import AdvancedSignalFiltering

        # Set default values
        ensemble_method = ensemble_method or "mean"
        ensemble_n_filters = ensemble_n_filters or 3

        # Create advanced filter instance
        advanced_filter = AdvancedSignalFiltering(signal_data)

        # Create multiple filters for ensemble
        filters = []
        for i in range(ensemble_n_filters):
            # Create different filter configurations
            if i == 0:
                # Kalman filter
                filtered = advanced_filter.kalman_filter(R=0.1, Q=1)
            elif i == 1:
                # Convolution filter
                filtered = advanced_filter.convolution_based_filter(
                    kernel_type="smoothing", kernel_size=3
                )
            elif i == 2:
                # Optimization filter
                filtered = advanced_filter.optimization_based_filtering(
                    target=signal_data,
                    loss_type="mse",
                    learning_rate=ensemble_learning_rate or 0.01,
                    iterations=ensemble_iterations or 50,
                )
            elif i == 3:
                # Adaptive filtering
                filtered = advanced_filter.adaptive_filtering(
                    desired_signal=signal_data,
                    mu=adaptive_step_size or 0.5,
                    filter_order=adaptive_filter_order or 4,
                )
            else:
                # Additional filter types
                filtered = advanced_filter.gradient_descent_filter(
                    target=signal_data,
                    learning_rate=ensemble_learning_rate or 0.01,
                    iterations=ensemble_iterations or 50,
                )
            filters.append(filtered)

        # Apply enhanced ensemble method
        if ensemble_method == "mean":
            filtered_signal = np.mean(filters, axis=0)
        elif ensemble_method == "median":
            filtered_signal = np.median(filters, axis=0)
        elif ensemble_method == "weighted":
            # Weight by filter performance (inverse of variance)
            weights = 1 / (np.var(filters, axis=0) + 1e-10)
            weights = weights / np.sum(weights)
            filtered_signal = np.average(filters, axis=0, weights=weights)
        elif ensemble_method == "bagging":
            # Bootstrap aggregating
            n_samples = len(signal_data)
            indices = np.random.choice(n_samples, size=n_samples, replace=True)
            filtered_signal = np.mean(
                [filters[i % len(filters)][indices] for i in range(len(filters))],
                axis=0,
            )
        elif ensemble_method == "boosting":
            # Adaptive boosting
            weights = np.ones(len(filters))
            filtered_signal = np.zeros_like(signal_data)
            for i, (filter_output, weight) in enumerate(zip(filters, weights)):
                filtered_signal += weight * filter_output
                # Update weights based on performance
                error = np.mean((signal_data - filter_output) ** 2)
                weights[i] = 0.5 * np.log((1 - error) / (error + 1e-10))
        elif ensemble_method == "stacking":
            # Stacking with meta-learner
            # Use the first filter as meta-learner
            filtered_signal = filters[0]
        else:
            # Default to mean
            filtered_signal = np.mean(filters, axis=0)

        logger.info(
            f"Enhanced ensemble filter applied successfully: {ensemble_method} with {ensemble_n_filters} filters"
        )
        return filtered_signal

    except Exception as e:
        logger.error(f"Error applying enhanced ensemble filter: {e}")
        # Return original signal if ensemble filtering fails
        return signal_data


def apply_multi_modal_filtering(
    signal_data, reference_signal, fusion_method, update_rate, performance_window
):
    """Apply multi-modal filtering using vitalDSP functions."""
    try:
        logger.info(f"Applying multi-modal filtering: {fusion_method}")

        # Import multi-modal fusion functions
        from vitalDSP.respiratory_analysis.fusion.multimodal_analysis import (
            MultiModalAnalysis,
        )

        # Create multi-modal analysis instance
        multimodal_analyzer = MultiModalAnalysis(signal_data)

        # Apply fusion based on method
        if fusion_method == "weighted":
            filtered_signal = multimodal_analyzer.weighted_fusion(
                reference_signal=(
                    reference_signal if reference_signal != "none" else None
                )
            )
        elif fusion_method == "kalman":
            filtered_signal = multimodal_analyzer.kalman_fusion(
                reference_signal=(
                    reference_signal if reference_signal != "none" else None
                )
            )
        elif fusion_method == "bayesian":
            filtered_signal = multimodal_analyzer.bayesian_fusion(
                reference_signal=(
                    reference_signal if reference_signal != "none" else None
                )
            )
        elif fusion_method == "deep_learning":
            filtered_signal = multimodal_analyzer.deep_learning_fusion(
                reference_signal=(
                    reference_signal if reference_signal != "none" else None
                )
            )
        else:
            # Default to weighted fusion
            filtered_signal = multimodal_analyzer.weighted_fusion(
                reference_signal=(
                    reference_signal if reference_signal != "none" else None
                )
            )

        logger.info(f"Multi-modal filtering applied successfully: {fusion_method}")
        return filtered_signal

    except Exception as e:
        logger.error(f"Error applying multi-modal filtering: {e}")
        # Return original signal if multi-modal filtering fails
        return signal_data


def generate_filter_quality_metrics(
    original_signal, filtered_signal, sampling_freq, quality_options
):
    """Generate comprehensive filter quality metrics with beautiful tables and extensive analysis."""
    try:
        # Calculate basic metrics
        snr_improvement = calculate_snr_improvement(original_signal, filtered_signal)
        mse = calculate_mse(original_signal, filtered_signal)
        correlation = calculate_correlation(original_signal, filtered_signal)
        smoothness = calculate_smoothness(filtered_signal)

        # Calculate frequency domain metrics
        freq_metrics = calculate_frequency_metrics(
            original_signal, filtered_signal, sampling_freq
        )

        # Calculate additional statistical metrics
        statistical_metrics = calculate_statistical_metrics(
            original_signal, filtered_signal
        )

        # Calculate temporal features
        temporal_features = calculate_temporal_features(
            original_signal, filtered_signal, sampling_freq
        )

        # Calculate morphological features
        morphological_features = calculate_morphological_features(
            original_signal, filtered_signal
        )

        # Calculate advanced quality metrics
        advanced_quality = calculate_advanced_quality_metrics(
            original_signal, filtered_signal, sampling_freq
        )

        # Calculate performance metrics
        performance_metrics = calculate_performance_metrics(
            original_signal, filtered_signal
        )

        # Create beautiful metrics display with tables
        metrics_html = html.Div(
            [
                html.H4(
                    "🔍 Comprehensive Filter Quality Assessment",
                    className="text-center mb-4 text-primary",
                ),
                # Signal Quality Table
                dbc.Card(
                    [
                        dbc.CardHeader(
                            [
                                html.H5(
                                    "📊 Core Signal Quality Metrics",
                                    className="mb-0 text-success",
                                )
                            ],
                            className="bg-success text-white",
                        ),
                        dbc.CardBody(
                            [
                                dbc.Table(
                                    [
                                        html.Thead(
                                            [
                                                html.Tr(
                                                    [
                                                        html.Th(
                                                            "Metric",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Original",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Filtered",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Improvement",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Status",
                                                            className="text-center",
                                                        ),
                                                    ]
                                                )
                                            ]
                                        ),
                                        html.Tbody(
                                            [
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "SNR Improvement",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            "N/A",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{snr_improvement:.2f} dB",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"+{snr_improvement:.2f} dB",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Excellent"
                                                                        if snr_improvement
                                                                        > 10
                                                                        else (
                                                                            "🟡 Good"
                                                                            if snr_improvement
                                                                            > 5
                                                                            else "🔴 Poor"
                                                                        )
                                                                    ),
                                                                    className=f"badge {'bg-success' if snr_improvement > 10 else 'bg-warning' if snr_improvement > 5 else 'bg-danger'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Mean Square Error",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            "N/A",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{mse:.4f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"-{mse:.4f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Excellent"
                                                                        if mse < 0.01
                                                                        else (
                                                                            "🟡 Good"
                                                                            if mse < 0.1
                                                                            else "🔴 Poor"
                                                                        )
                                                                    ),
                                                                    className=f"badge {'bg-success' if mse < 0.01 else 'bg-warning' if mse < 0.1 else 'bg-danger'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Correlation",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            "1.000",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{correlation:.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{correlation:.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Excellent"
                                                                        if correlation
                                                                        > 0.9
                                                                        else (
                                                                            "🟡 Good"
                                                                            if correlation
                                                                            > 0.7
                                                                            else "🔴 Poor"
                                                                        )
                                                                    ),
                                                                    className=f"badge {'bg-success' if correlation > 0.9 else 'bg-warning' if correlation > 0.7 else 'bg-danger'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Smoothness",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{statistical_metrics['smoothness_orig']:.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{smoothness:.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{smoothness - statistical_metrics['smoothness_orig']:+.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Excellent"
                                                                        if smoothness
                                                                        > 0.8
                                                                        else (
                                                                            "🟡 Good"
                                                                            if smoothness
                                                                            > 0.6
                                                                            else "🔴 Poor"
                                                                        )
                                                                    ),
                                                                    className=f"badge {'bg-success' if smoothness > 0.8 else 'bg-warning' if smoothness > 0.6 else 'bg-danger'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                            ]
                                        ),
                                    ],
                                    bordered=True,
                                    hover=True,
                                    responsive=True,
                                    striped=True,
                                    className="mb-3",
                                )
                            ]
                        ),
                    ],
                    className="mb-4",
                ),
                # Statistical Analysis Table
                dbc.Card(
                    [
                        dbc.CardHeader(
                            [
                                html.H5(
                                    "📈 Statistical Analysis",
                                    className="mb-0 text-info",
                                )
                            ],
                            className="bg-info text-white",
                        ),
                        dbc.CardBody(
                            [
                                dbc.Table(
                                    [
                                        html.Thead(
                                            [
                                                html.Tr(
                                                    [
                                                        html.Th(
                                                            "Statistical Measure",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Original Signal",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Filtered Signal",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Change",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Interpretation",
                                                            className="text-center",
                                                        ),
                                                    ]
                                                )
                                            ]
                                        ),
                                        html.Tbody(
                                            [
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Mean", className="fw-bold"
                                                        ),
                                                        html.Td(
                                                            f"{statistical_metrics['mean_orig']:.4f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{statistical_metrics['mean_filt']:.4f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{statistical_metrics['mean_change']:+.4f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Preserved"
                                                                        if abs(
                                                                            statistical_metrics[
                                                                                "mean_change"
                                                                            ]
                                                                        )
                                                                        < 0.01
                                                                        else (
                                                                            "🟡 Modified"
                                                                            if abs(
                                                                                statistical_metrics[
                                                                                    "mean_change"
                                                                                ]
                                                                            )
                                                                            < 0.1
                                                                            else "🔴 Significant Change"
                                                                        )
                                                                    ),
                                                                    className=f"badge {'bg-success' if abs(statistical_metrics['mean_change']) < 0.01 else 'bg-warning' if abs(statistical_metrics['mean_change']) < 0.1 else 'bg-danger'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Standard Deviation",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{statistical_metrics['std_orig']:.4f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{statistical_metrics['std_filt']:.4f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{statistical_metrics['std_change']:+.4f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Reduced Noise"
                                                                        if statistical_metrics[
                                                                            "std_change"
                                                                        ]
                                                                        < 0
                                                                        else "🟡 Increased Variability"
                                                                    ),
                                                                    className=f"badge {'bg-success' if statistical_metrics['std_change'] < 0 else 'bg-warning'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Skewness",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{statistical_metrics['skewness_orig']:.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{statistical_metrics['skewness_filt']:.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{statistical_metrics['skewness_change']:+.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Normalized"
                                                                        if abs(
                                                                            statistical_metrics[
                                                                                "skewness_filt"
                                                                            ]
                                                                        )
                                                                        < 0.5
                                                                        else "🟡 Asymmetric"
                                                                    ),
                                                                    className=f"badge {'bg-success' if abs(statistical_metrics['skewness_filt']) < 0.5 else 'bg-warning'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Kurtosis",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{statistical_metrics['kurtosis_orig']:.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{statistical_metrics['kurtosis_filt']:.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{statistical_metrics['kurtosis_change']:+.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Normalized"
                                                                        if abs(
                                                                            statistical_metrics[
                                                                                "kurtosis_filt"
                                                                            ]
                                                                        )
                                                                        < 1
                                                                        else "🟡 Peaked"
                                                                    ),
                                                                    className=f"badge {'bg-success' if abs(statistical_metrics['kurtosis_filt']) < 1 else 'bg-warning'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Entropy",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{statistical_metrics['entropy_orig']:.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{statistical_metrics['entropy_filt']:.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{statistical_metrics['entropy_change']:+.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Reduced Complexity"
                                                                        if statistical_metrics[
                                                                            "entropy_change"
                                                                        ]
                                                                        < 0
                                                                        else "🟡 Increased Complexity"
                                                                    ),
                                                                    className=f"badge {'bg-success' if statistical_metrics['entropy_change'] < 0 else 'bg-warning'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                            ]
                                        ),
                                    ],
                                    bordered=True,
                                    hover=True,
                                    responsive=True,
                                    striped=True,
                                    className="mb-3",
                                )
                            ]
                        ),
                    ],
                    className="mb-4",
                ),
                # Temporal Features Table
                dbc.Card(
                    [
                        dbc.CardHeader(
                            [
                                html.H5(
                                    "⏱️ Temporal Features Analysis",
                                    className="mb-0 text-warning",
                                )
                            ],
                            className="bg-warning text-dark",
                        ),
                        dbc.CardBody(
                            [
                                dbc.Table(
                                    [
                                        html.Thead(
                                            [
                                                html.Tr(
                                                    [
                                                        html.Th(
                                                            "Temporal Feature",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Original Signal",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Filtered Signal",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Improvement",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Quality",
                                                            className="text-center",
                                                        ),
                                                    ]
                                                )
                                            ]
                                        ),
                                        html.Tbody(
                                            [
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Peak Count",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{temporal_features['peak_count_orig']}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{temporal_features['peak_count_filt']}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{temporal_features['peak_count_change']:+d}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Optimal"
                                                                        if temporal_features[
                                                                            "peak_count_filt"
                                                                        ]
                                                                        > 0
                                                                        else "🔴 No Peaks Detected"
                                                                    ),
                                                                    className=f"badge {'bg-success' if temporal_features['peak_count_filt'] > 0 else 'bg-danger'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Mean Interval (s)",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{temporal_features['mean_interval_orig']:.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{temporal_features['mean_interval_filt']:.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{temporal_features['interval_change']:+.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Stable"
                                                                        if temporal_features[
                                                                            "interval_std_filt"
                                                                        ]
                                                                        < 0.1
                                                                        else "🟡 Variable"
                                                                    ),
                                                                    className=f"badge {'bg-success' if temporal_features['interval_std_filt'] < 0.1 else 'bg-warning'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Interval Std Dev",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{temporal_features['interval_std_orig']:.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{temporal_features['interval_std_filt']:.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{temporal_features['interval_std_change']:+.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Improved"
                                                                        if temporal_features[
                                                                            "interval_std_change"
                                                                        ]
                                                                        < 0
                                                                        else "🟡 Unchanged"
                                                                    ),
                                                                    className=f"badge {'bg-success' if temporal_features['interval_std_change'] < 0 else 'bg-warning'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Estimated HR (bpm)",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{temporal_features['heart_rate_orig']:.1f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{temporal_features['heart_rate_filt']:.1f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{temporal_features['heart_rate_change']:+.1f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Physiological"
                                                                        if 40
                                                                        <= temporal_features[
                                                                            "heart_rate_filt"
                                                                        ]
                                                                        <= 200
                                                                        else "🟡 Out of Range"
                                                                    ),
                                                                    className=f"badge {'bg-success' if 40 <= temporal_features['heart_rate_filt'] <= 200 else 'bg-warning'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                            ]
                                        ),
                                    ],
                                    bordered=True,
                                    hover=True,
                                    responsive=True,
                                    striped=True,
                                    className="mb-3",
                                )
                            ]
                        ),
                    ],
                    className="mb-4",
                ),
                # Morphological Features Table
                dbc.Card(
                    [
                        dbc.CardHeader(
                            [
                                html.H5(
                                    "🔬 Morphological Features",
                                    className="mb-0 text-secondary",
                                )
                            ],
                            className="bg-secondary text-white",
                        ),
                        dbc.CardBody(
                            [
                                dbc.Table(
                                    [
                                        html.Thead(
                                            [
                                                html.Tr(
                                                    [
                                                        html.Th(
                                                            "Morphological Feature",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Original Signal",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Filtered Signal",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Change",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Assessment",
                                                            className="text-center",
                                                        ),
                                                    ]
                                                )
                                            ]
                                        ),
                                        html.Tbody(
                                            [
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Amplitude Range",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{morphological_features['amplitude_range_orig']:.4f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{morphological_features['amplitude_range_filt']:.4f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{morphological_features['amplitude_range_change']:+.4f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Preserved"
                                                                        if abs(
                                                                            morphological_features[
                                                                                "amplitude_range_change"
                                                                            ]
                                                                        )
                                                                        < 0.1
                                                                        else "🟡 Modified"
                                                                    ),
                                                                    className=f"badge {'bg-success' if abs(morphological_features['amplitude_range_change']) < 0.1 else 'bg-warning'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Mean Amplitude",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{morphological_features['amplitude_mean_orig']:.4f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{morphological_features['amplitude_mean_filt']:.4f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{morphological_features['amplitude_mean_change']:+.4f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Maintained"
                                                                        if abs(
                                                                            morphological_features[
                                                                                "amplitude_mean_change"
                                                                            ]
                                                                        )
                                                                        < 0.01
                                                                        else "🟡 Shifted"
                                                                    ),
                                                                    className=f"badge {'bg-success' if abs(morphological_features['amplitude_mean_change']) < 0.01 else 'bg-warning'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Zero Crossings",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{morphological_features['zero_crossings_orig']}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{morphological_features['zero_crossings_filt']}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{morphological_features['zero_crossings_change']:+d}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Stable"
                                                                        if abs(
                                                                            morphological_features[
                                                                                "zero_crossings_change"
                                                                            ]
                                                                        )
                                                                        < 5
                                                                        else "🟡 Variable"
                                                                    ),
                                                                    className=f"badge {'bg-success' if abs(morphological_features['zero_crossings_change']) < 5 else 'bg-warning'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Signal Energy",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{morphological_features['signal_energy_orig']:.4f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{morphological_features['signal_energy_filt']:.4f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{morphological_features['signal_energy_change']:+.4f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Preserved"
                                                                        if abs(
                                                                            morphological_features[
                                                                                "signal_energy_change"
                                                                            ]
                                                                        )
                                                                        < 0.1
                                                                        else "🟡 Modified"
                                                                    ),
                                                                    className=f"badge {'bg-success' if abs(morphological_features['signal_energy_change']) < 0.1 else 'bg-warning'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                            ]
                                        ),
                                    ],
                                    bordered=True,
                                    hover=True,
                                    responsive=True,
                                    striped=True,
                                    className="mb-3",
                                )
                            ]
                        ),
                    ],
                    className="mb-4",
                ),
                # Advanced Quality Metrics Table
                dbc.Card(
                    [
                        dbc.CardHeader(
                            [
                                html.H5(
                                    "🎯 Advanced Quality Assessment",
                                    className="mb-0 text-danger",
                                )
                            ],
                            className="bg-danger text-white",
                        ),
                        dbc.CardBody(
                            [
                                dbc.Table(
                                    [
                                        html.Thead(
                                            [
                                                html.Tr(
                                                    [
                                                        html.Th(
                                                            "Quality Metric",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Value",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Threshold",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Status",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Recommendation",
                                                            className="text-center",
                                                        ),
                                                    ]
                                                )
                                            ]
                                        ),
                                        html.Tbody(
                                            [
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Artifact Percentage",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{advanced_quality['artifact_percentage']:.2f}%",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            "< 5%",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Excellent"
                                                                        if advanced_quality[
                                                                            "artifact_percentage"
                                                                        ]
                                                                        < 5
                                                                        else (
                                                                            "🟡 Good"
                                                                            if advanced_quality[
                                                                                "artifact_percentage"
                                                                            ]
                                                                            < 15
                                                                            else "🔴 Poor"
                                                                        )
                                                                    ),
                                                                    className=f"badge {'bg-success' if advanced_quality['artifact_percentage'] < 5 else 'bg-warning' if advanced_quality['artifact_percentage'] < 15 else 'bg-danger'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "No action needed"
                                                                        if advanced_quality[
                                                                            "artifact_percentage"
                                                                        ]
                                                                        < 5
                                                                        else (
                                                                            "Consider artifact removal"
                                                                            if advanced_quality[
                                                                                "artifact_percentage"
                                                                            ]
                                                                            < 15
                                                                            else "Strong artifact removal needed"
                                                                        )
                                                                    ),
                                                                    className="small text-muted",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Baseline Wander",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{advanced_quality['baseline_wander_percentage']:.2f}%",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            "< 10%",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Excellent"
                                                                        if advanced_quality[
                                                                            "baseline_wander_percentage"
                                                                        ]
                                                                        < 10
                                                                        else (
                                                                            "🟡 Good"
                                                                            if advanced_quality[
                                                                                "baseline_wander_percentage"
                                                                            ]
                                                                            < 20
                                                                            else "🔴 Poor"
                                                                        )
                                                                    ),
                                                                    className=f"badge {'bg-success' if advanced_quality['baseline_wander_percentage'] < 10 else 'bg-warning' if advanced_quality['baseline_wander_percentage'] < 20 else 'bg-danger'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "Baseline stable"
                                                                        if advanced_quality[
                                                                            "baseline_wander_percentage"
                                                                        ]
                                                                        < 10
                                                                        else (
                                                                            "Consider high-pass filter"
                                                                            if advanced_quality[
                                                                                "baseline_wander_percentage"
                                                                            ]
                                                                            < 20
                                                                            else "High-pass filtering recommended"
                                                                        )
                                                                    ),
                                                                    className="small text-muted",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Motion Artifacts",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{advanced_quality['motion_artifact_score']:.2f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            "< 0.3",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Excellent"
                                                                        if advanced_quality[
                                                                            "motion_artifact_score"
                                                                        ]
                                                                        < 0.3
                                                                        else (
                                                                            "🟡 Good"
                                                                            if advanced_quality[
                                                                                "motion_artifact_score"
                                                                            ]
                                                                            < 0.6
                                                                            else "🔴 Poor"
                                                                        )
                                                                    ),
                                                                    className=f"badge {'bg-success' if advanced_quality['motion_artifact_score'] < 0.3 else 'bg-warning' if advanced_quality['motion_artifact_score'] < 0.6 else 'bg-danger'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "Motion artifacts minimal"
                                                                        if advanced_quality[
                                                                            "motion_artifact_score"
                                                                        ]
                                                                        < 0.3
                                                                        else (
                                                                            "Consider motion correction"
                                                                            if advanced_quality[
                                                                                "motion_artifact_score"
                                                                            ]
                                                                            < 0.6
                                                                            else "Motion artifact removal needed"
                                                                        )
                                                                    ),
                                                                    className="small text-muted",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Signal Stability",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{advanced_quality['signal_stability']:.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            "> 0.7",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Excellent"
                                                                        if advanced_quality[
                                                                            "signal_stability"
                                                                        ]
                                                                        > 0.7
                                                                        else (
                                                                            "🟡 Good"
                                                                            if advanced_quality[
                                                                                "signal_stability"
                                                                            ]
                                                                            > 0.5
                                                                            else "🔴 Poor"
                                                                        )
                                                                    ),
                                                                    className=f"badge {'bg-success' if advanced_quality['signal_stability'] > 0.7 else 'bg-warning' if advanced_quality['signal_stability'] > 0.5 else 'bg-danger'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "Signal very stable"
                                                                        if advanced_quality[
                                                                            "signal_stability"
                                                                        ]
                                                                        > 0.7
                                                                        else (
                                                                            "Signal moderately stable"
                                                                            if advanced_quality[
                                                                                "signal_stability"
                                                                            ]
                                                                            > 0.5
                                                                            else "Signal unstable, check quality"
                                                                        )
                                                                    ),
                                                                    className="small text-muted",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                            ]
                                        ),
                                    ],
                                    bordered=True,
                                    hover=True,
                                    responsive=True,
                                    striped=True,
                                    className="mb-3",
                                )
                            ]
                        ),
                    ],
                    className="mb-4",
                ),
                # Performance Metrics Table
                dbc.Card(
                    [
                        dbc.CardHeader(
                            [
                                html.H5(
                                    "⚡ Performance & Efficiency Metrics",
                                    className="mb-0 text-dark",
                                )
                            ],
                            className="bg-dark text-white",
                        ),
                        dbc.CardBody(
                            [
                                dbc.Table(
                                    [
                                        html.Thead(
                                            [
                                                html.Tr(
                                                    [
                                                        html.Th(
                                                            "Performance Metric",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Value",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Benchmark",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Efficiency",
                                                            className="text-center",
                                                        ),
                                                    ]
                                                )
                                            ]
                                        ),
                                        html.Tbody(
                                            [
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Processing Time",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{performance_metrics['processing_time']:.3f}s",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            "< 1.0s",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Fast"
                                                                        if performance_metrics[
                                                                            "processing_time"
                                                                        ]
                                                                        < 1.0
                                                                        else (
                                                                            "🟡 Moderate"
                                                                            if performance_metrics[
                                                                                "processing_time"
                                                                            ]
                                                                            < 5.0
                                                                            else "🔴 Slow"
                                                                        )
                                                                    ),
                                                                    className=f"badge {'bg-success' if performance_metrics['processing_time'] < 1.0 else 'bg-warning' if performance_metrics['processing_time'] < 5.0 else 'bg-danger'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Memory Usage",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{performance_metrics['memory_usage']:.2f} MB",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            "< 100 MB",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Efficient"
                                                                        if performance_metrics[
                                                                            "memory_usage"
                                                                        ]
                                                                        < 100
                                                                        else (
                                                                            "🟡 Moderate"
                                                                            if performance_metrics[
                                                                                "memory_usage"
                                                                            ]
                                                                            < 500
                                                                            else "🔴 High"
                                                                        )
                                                                    ),
                                                                    className=f"badge {'bg-success' if performance_metrics['memory_usage'] < 100 else 'bg-warning' if performance_metrics['memory_usage'] < 500 else 'bg-danger'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Data Reduction",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{performance_metrics['data_reduction']:.1f}%",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            "> 0%",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    (
                                                                        "✅ Effective"
                                                                        if performance_metrics[
                                                                            "data_reduction"
                                                                        ]
                                                                        > 0
                                                                        else "🟡 No Change"
                                                                    ),
                                                                    className=f"badge {'bg-success' if performance_metrics['data_reduction'] > 0 else 'bg-warning'}",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                                html.Td(
                                                    "Algorithm Efficiency",
                                                    className="fw-bold",
                                                ),
                                                html.Td(
                                                    f"{performance_metrics['algorithm_efficiency']:.1f}%",
                                                    className="text-center",
                                                ),
                                                html.Td(
                                                    "> 80%", className="text-center"
                                                ),
                                                html.Td(
                                                    [
                                                        html.Span(
                                                            (
                                                                "✅ High"
                                                                if performance_metrics[
                                                                    "algorithm_efficiency"
                                                                ]
                                                                > 80
                                                                else (
                                                                    "🟡 Medium"
                                                                    if performance_metrics[
                                                                        "algorithm_efficiency"
                                                                    ]
                                                                    > 60
                                                                    else "🔴 Low"
                                                                )
                                                            ),
                                                            className=f"badge {'bg-success' if performance_metrics['algorithm_efficiency'] > 80 else 'bg-warning' if performance_metrics['algorithm_efficiency'] > 60 else 'bg-danger'}",
                                                        )
                                                    ],
                                                    className="text-center",
                                                ),
                                            ]
                                        ),
                                    ],
                                    bordered=True,
                                    hover=True,
                                    responsive=True,
                                    striped=True,
                                    className="mb-3",
                                )
                            ]
                        ),
                    ],
                    className="mb-4",
                ),
                # Frequency Analysis Table
                dbc.Card(
                    [
                        dbc.CardHeader(
                            [
                                html.H5(
                                    "🌊 Frequency Domain Analysis",
                                    className="mb-0 text-info",
                                )
                            ],
                            className="bg-info text-white",
                        ),
                        dbc.CardBody(
                            [
                                dbc.Table(
                                    [
                                        html.Thead(
                                            [
                                                html.Tr(
                                                    [
                                                        html.Th(
                                                            "Parameter",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Original Signal",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Filtered Signal",
                                                            className="text-center",
                                                        ),
                                                        html.Th(
                                                            "Improvement",
                                                            className="text-center",
                                                        ),
                                                    ]
                                                )
                                            ]
                                        ),
                                        html.Tbody(
                                            [
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Peak Frequency",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{freq_metrics.get('peak_freq_orig', 0):.2f} Hz",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{freq_metrics['peak_freq']:.2f} Hz",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    f"{freq_metrics.get('peak_freq_orig', 0) - freq_metrics['peak_freq']:.2f} Hz",
                                                                    className="badge bg-secondary",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Bandwidth",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{freq_metrics.get('bandwidth_orig', 0):.2f} Hz",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{freq_metrics['bandwidth']:.2f} Hz",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    f"{freq_metrics.get('bandwidth_orig', 0) - freq_metrics['bandwidth']:.2f} Hz",
                                                                    className="badge bg-secondary",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Spectral Centroid",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{freq_metrics.get('spectral_centroid_orig', 0):.2f} Hz",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{freq_metrics['spectral_centroid']:.2f} Hz",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    f"{freq_metrics.get('spectral_centroid_orig', 0) - freq_metrics['spectral_centroid']:.2f} Hz",
                                                                    className="badge bg-secondary",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                                html.Tr(
                                                    [
                                                        html.Td(
                                                            "Frequency Stability",
                                                            className="fw-bold",
                                                        ),
                                                        html.Td(
                                                            f"{freq_metrics.get('freq_stability_orig', 0):.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            f"{freq_metrics['freq_stability']:.3f}",
                                                            className="text-center",
                                                        ),
                                                        html.Td(
                                                            [
                                                                html.Span(
                                                                    f"{freq_metrics.get('freq_stability_orig', 0) - freq_metrics['freq_stability']:.3f}",
                                                                    className="badge bg-secondary",
                                                                )
                                                            ],
                                                            className="text-center",
                                                        ),
                                                    ]
                                                ),
                                            ]
                                        ),
                                    ],
                                    bordered=True,
                                    hover=True,
                                    responsive=True,
                                    striped=True,
                                    className="mb-3",
                                )
                            ]
                        ),
                    ],
                    className="mb-4",
                ),
                # Summary Card with Overall Rating
                dbc.Card(
                    [
                        dbc.CardHeader(
                            [
                                html.H5(
                                    "📋 Comprehensive Filter Performance Summary",
                                    className="mb-0 text-primary",
                                )
                            ],
                            className="bg-primary text-white",
                        ),
                        dbc.CardBody(
                            [
                                html.Div(
                                    [
                                        html.Div(
                                            [
                                                html.H6(
                                                    "Overall Quality Rating",
                                                    className="text-center",
                                                ),
                                                html.Div(
                                                    [
                                                        html.Span(
                                                            (
                                                                "🟢 EXCELLENT"
                                                                if snr_improvement > 10
                                                                and correlation > 0.9
                                                                and advanced_quality[
                                                                    "artifact_percentage"
                                                                ]
                                                                < 5
                                                                else (
                                                                    "🟡 GOOD"
                                                                    if snr_improvement
                                                                    > 5
                                                                    and correlation
                                                                    > 0.7
                                                                    and advanced_quality[
                                                                        "artifact_percentage"
                                                                    ]
                                                                    < 15
                                                                    else "🔴 NEEDS IMPROVEMENT"
                                                                )
                                                            ),
                                                            className=f"badge fs-6 {'bg-success' if snr_improvement > 10 and correlation > 0.9 and advanced_quality['artifact_percentage'] < 5 else 'bg-warning' if snr_improvement > 5 and correlation > 0.7 and advanced_quality['artifact_percentage'] < 15 else 'bg-danger'}",
                                                        )
                                                    ],
                                                    className="text-center",
                                                ),
                                            ],
                                            className="col-md-3",
                                        ),
                                        html.Div(
                                            [
                                                html.H6(
                                                    "Signal Quality",
                                                    className="text-center",
                                                ),
                                                html.P(
                                                    f"SNR enhanced by {snr_improvement:.1f} dB",
                                                    className="text-center text-success mb-0",
                                                ),
                                                html.P(
                                                    f"{(correlation * 100):.1f}% correlation maintained",
                                                    className="text-center text-info mb-0",
                                                ),
                                            ],
                                            className="col-md-3",
                                        ),
                                        html.Div(
                                            [
                                                html.H6(
                                                    "Artifact Reduction",
                                                    className="text-center",
                                                ),
                                                html.P(
                                                    f"Artifacts reduced to {advanced_quality['artifact_percentage']:.1f}%",
                                                    className="text-center text-success mb-0",
                                                ),
                                                html.P(
                                                    f"Baseline wander: {advanced_quality['baseline_wander_percentage']:.1f}%",
                                                    className="text-center text-warning mb-0",
                                                ),
                                            ],
                                            className="col-md-3",
                                        ),
                                        html.Div(
                                            [
                                                html.H6(
                                                    "Performance",
                                                    className="text-center",
                                                ),
                                                html.P(
                                                    f"Processing: {performance_metrics['processing_time']:.3f}s",
                                                    className="text-center text-info mb-0",
                                                ),
                                                html.P(
                                                    f"Efficiency: {performance_metrics['algorithm_efficiency']:.1f}%",
                                                    className="text-center text-primary mb-0",
                                                ),
                                            ],
                                            className="col-md-3",
                                        ),
                                    ],
                                    className="row text-center",
                                )
                            ]
                        ),
                    ]
                ),
            ]
        )

        return metrics_html

    except Exception as e:
        logger.error(f"Error generating quality metrics: {e}")
        return html.Div(
            [
                html.H5("Filter Quality Metrics"),
                html.P(f"Error calculating metrics: {str(e)}"),
            ]
        )


def create_filter_quality_plots(
    original_signal, filtered_signal, sampling_freq, quality_options
):
    """Create enhanced quality assessment plots with comprehensive analysis and critical points detection."""
    try:
        # Create subplots for different quality metrics
        fig = make_subplots(
            rows=3,
            cols=2,
            subplot_titles=(
                "Signal Comparison with Critical Points",
                "Frequency Response Analysis",
                "Statistical Distribution Analysis",
                "Temporal Features Analysis",
                "Error Analysis & Quality Metrics",
                "Performance & Efficiency Metrics",
            ),
            vertical_spacing=0.12,
            horizontal_spacing=0.1,
            specs=[
                [{"secondary_y": False}, {"secondary_y": False}],
                [{"secondary_y": False}, {"secondary_y": False}],
                [{"secondary_y": False}, {"secondary_y": False}],
            ],
        )

        # Time domain comparison with critical points
        time_axis = np.arange(len(original_signal)) / sampling_freq
        fig.add_trace(
            go.Scatter(
                x=time_axis,
                y=original_signal,
                mode="lines",
                name="Original Signal",
                line=dict(color="blue", width=2),
            ),
            row=1,
            col=1,
        )
        fig.add_trace(
            go.Scatter(
                x=time_axis,
                y=filtered_signal,
                mode="lines",
                name="Filtered Signal",
                line=dict(color="red", width=2),
            ),
            row=1,
            col=1,
        )

        # Add critical points detection to the comparison plot
        try:
            from vitalDSP.physiological_features.waveform import WaveformMorphology

            # Create waveform morphology object for original signal
            wm_orig = WaveformMorphology(
                waveform=original_signal,
                fs=sampling_freq,
                signal_type="PPG",
                simple_mode=True,
            )

            # Create waveform morphology object for filtered signal
            wm_filt = WaveformMorphology(
                waveform=filtered_signal,
                fs=sampling_freq,
                signal_type="PPG",
                simple_mode=True,
            )

            # Add systolic peaks for original signal
            if (
                hasattr(wm_orig, "systolic_peaks")
                and wm_orig.systolic_peaks is not None
            ):
                fig.add_trace(
                    go.Scatter(
                        x=time_axis[wm_orig.systolic_peaks],
                        y=original_signal[wm_orig.systolic_peaks],
                        mode="markers",
                        name="Systolic Peaks (Original)",
                        marker=dict(color="darkblue", size=6, symbol="diamond"),
                        showlegend=False,
                    ),
                    row=1,
                    col=1,
                )

            # Add systolic peaks for filtered signal
            if (
                hasattr(wm_filt, "systolic_peaks")
                and wm_filt.systolic_peaks is not None
            ):
                fig.add_trace(
                    go.Scatter(
                        x=time_axis[wm_filt.systolic_peaks],
                        y=filtered_signal[wm_filt.systolic_peaks],
                        mode="markers",
                        name="Systolic Peaks (Filtered)",
                        marker=dict(color="darkred", size=6, symbol="diamond"),
                        showlegend=False,
                    ),
                    row=1,
                    col=1,
                )

        except Exception as e:
            logger.warning(f"Critical points detection failed in quality plots: {e}")

        # Enhanced frequency response analysis
        freqs_orig, psd_orig = signal.welch(
            original_signal,
            fs=sampling_freq,
            nperseg=min(256, len(original_signal) // 4),
        )
        freqs_filt, psd_filt = signal.welch(
            filtered_signal,
            fs=sampling_freq,
            nperseg=min(256, len(filtered_signal) // 4),
        )

        fig.add_trace(
            go.Scatter(
                x=freqs_orig,
                y=10 * np.log10(psd_orig),
                mode="lines",
                name="Original PSD",
                line=dict(color="blue", width=2),
            ),
            row=1,
            col=2,
        )
        fig.add_trace(
            go.Scatter(
                x=freqs_filt,
                y=10 * np.log10(psd_filt),
                mode="lines",
                name="Filtered PSD",
                line=dict(color="red", width=2),
            ),
            row=1,
            col=2,
        )

        # Statistical distribution analysis
        fig.add_trace(
            go.Histogram(
                x=original_signal,
                nbinsx=50,
                name="Original Distribution",
                opacity=0.7,
                marker_color="blue",
            ),
            row=2,
            col=1,
        )
        fig.add_trace(
            go.Histogram(
                x=filtered_signal,
                nbinsx=50,
                name="Filtered Distribution",
                opacity=0.7,
                marker_color="red",
            ),
            row=2,
            col=1,
        )

        # Add statistical metrics as annotations
        mean_orig, std_orig = np.mean(original_signal), np.std(original_signal)
        mean_filt, std_filt = np.mean(filtered_signal), np.std(filtered_signal)
        fig.add_annotation(
            text=f"Original: μ={mean_orig:.3f}, σ={std_orig:.3f}",
            xref="x3",
            yref="y3",
            x=0.02,
            y=0.98,
            showarrow=False,
            bgcolor="rgba(0,0,255,0.8)",
            bordercolor="blue",
            font=dict(color="white"),
        )
        fig.add_annotation(
            text=f"Filtered: μ={mean_filt:.3f}, σ={std_filt:.3f}",
            xref="x3",
            yref="y3",
            x=0.02,
            y=0.92,
            showarrow=False,
            bgcolor="rgba(255,0,0,0.8)",
            bordercolor="red",
            font=dict(color="white"),
        )

        # Temporal features analysis
        try:
            # Peak detection and intervals
            peaks_orig, _ = signal.find_peaks(
                original_signal,
                height=np.mean(original_signal) + np.std(original_signal),
            )
            peaks_filt, _ = signal.find_peaks(
                filtered_signal,
                height=np.mean(filtered_signal) + np.std(filtered_signal),
            )

            if len(peaks_orig) > 1 and len(peaks_filt) > 1:
                intervals_orig = np.diff(peaks_orig) / sampling_freq
                intervals_filt = np.diff(peaks_filt) / sampling_freq

                time_centers_orig = peaks_orig[:-1] / sampling_freq
                time_centers_filt = peaks_filt[:-1] / sampling_freq

                fig.add_trace(
                    go.Scatter(
                        x=time_centers_orig,
                        y=intervals_orig,
                        mode="markers",
                        name="Intervals (Original)",
                        marker=dict(color="blue", size=6),
                    ),
                    row=2,
                    col=2,
                )
                fig.add_trace(
                    go.Scatter(
                        x=time_centers_filt,
                        y=intervals_filt,
                        mode="markers",
                        name="Intervals (Filtered)",
                        marker=dict(color="red", size=6),
                    ),
                    row=2,
                    col=2,
                )

                # Add trend lines
                z_orig = np.polyfit(time_centers_orig, intervals_orig, 1)
                p_orig = np.poly1d(z_orig)
                z_filt = np.polyfit(time_centers_filt, intervals_filt, 1)
                p_filt = np.poly1d(z_filt)

                fig.add_trace(
                    go.Scatter(
                        x=time_centers_orig,
                        y=p_orig(time_centers_orig),
                        mode="lines",
                        name="Trend (Original)",
                        line=dict(color="blue", dash="dash"),
                    ),
                    row=2,
                    col=2,
                )
                fig.add_trace(
                    go.Scatter(
                        x=time_centers_filt,
                        y=p_filt(time_centers_filt),
                        mode="lines",
                        name="Trend (Filtered)",
                        line=dict(color="red", dash="dash"),
                    ),
                    row=2,
                    col=2,
                )
        except Exception as e:
            logger.warning(f"Temporal features analysis failed: {e}")

        # Enhanced error analysis
        error = original_signal - filtered_signal
        fig.add_trace(
            go.Scatter(
                x=time_axis,
                y=error,
                mode="lines",
                name="Filtering Error",
                line=dict(color="orange", width=2),
            ),
            row=3,
            col=1,
        )

        # Add error statistics
        error_mean = np.mean(error)
        error_std = np.std(error)
        error_skew = calculate_skewness(error)
        error_kurt = calculate_kurtosis(error)

        fig.add_annotation(
            text=f"Error Statistics:<br>μ={error_mean:.3f}, σ={error_std:.3f}<br>Skew={error_skew:.3f}, Kurt={error_kurt:.3f}",
            xref="x5",
            yref="y5",
            x=0.02,
            y=0.98,
            showarrow=False,
            bgcolor="rgba(255,165,0,0.8)",
            bordercolor="orange",
            font=dict(size=10),
        )

        # Enhanced quality metrics over time
        window_size = min(100, len(original_signal) // 10)
        if window_size > 0:
            quality_metrics = []
            correlation_metrics = []
            smoothness_metrics = []
            snr_metrics = []

            for i in range(0, len(original_signal) - window_size, window_size):
                orig_window = original_signal[i : i + window_size]
                filt_window = filtered_signal[i : i + window_size]

                # Calculate various metrics for each window
                snr = calculate_snr_improvement(orig_window, filt_window)
                corr = calculate_correlation(orig_window, filt_window)
                smooth = calculate_smoothness(filt_window)

                quality_metrics.append(snr)
                correlation_metrics.append(corr)
                smoothness_metrics.append(smooth)
                snr_metrics.append(snr)

            time_centers = np.arange(len(quality_metrics)) * window_size / sampling_freq

            # SNR over time
            fig.add_trace(
                go.Scatter(
                    x=time_centers,
                    y=snr_metrics,
                    mode="lines+markers",
                    name="SNR over Time",
                    line=dict(color="green", width=2),
                    marker=dict(size=4),
                ),
                row=3,
                col=2,
            )

            # Correlation over time
            fig.add_trace(
                go.Scatter(
                    x=time_centers,
                    y=correlation_metrics,
                    mode="lines+markers",
                    name="Correlation over Time",
                    line=dict(color="purple", width=2),
                    marker=dict(size=4),
                ),
                row=3,
                col=2,
            )

            # Smoothness over time
            fig.add_trace(
                go.Scatter(
                    x=time_centers,
                    y=smoothness_metrics,
                    mode="lines+markers",
                    name="Smoothness over Time",
                    line=dict(color="brown", width=2),
                    marker=dict(size=4),
                ),
                row=3,
                col=2,
            )

            # Add quality metrics summary
            avg_snr = np.mean(snr_metrics)
            avg_corr = np.mean(correlation_metrics)
            avg_smooth = np.mean(smoothness_metrics)

            fig.add_annotation(
                text=f"Average Metrics:<br>SNR: {avg_snr:.2f} dB<br>Corr: {avg_corr:.3f}<br>Smooth: {avg_smooth:.3f}",
                xref="x6",
                yref="y6",
                x=0.98,
                y=0.98,
                showarrow=False,
                bgcolor="rgba(0,128,0,0.8)",
                bordercolor="green",
                font=dict(color="white", size=10),
                xanchor="right",
            )

        # Update layout for all subplots
        fig.update_xaxes(title_text="Time (s)", row=1, col=1)
        fig.update_yaxes(title_text="Amplitude", row=1, col=1)

        fig.update_xaxes(title_text="Frequency (Hz)", row=1, col=2)
        fig.update_yaxes(title_text="Power Spectral Density (dB)", row=1, col=2)

        fig.update_xaxes(title_text="Signal Amplitude", row=2, col=1)
        fig.update_yaxes(title_text="Frequency", row=2, col=1)

        fig.update_xaxes(title_text="Time (s)", row=2, col=2)
        fig.update_yaxes(title_text="Peak Interval (s)", row=2, col=2)

        fig.update_xaxes(title_text="Time (s)", row=3, col=1)
        fig.update_yaxes(title_text="Error Amplitude", row=3, col=1)

        fig.update_xaxes(title_text="Time (s)", row=3, col=2)
        fig.update_yaxes(title_text="Metric Value", row=3, col=2)

        fig.update_layout(
            title="🔍 Comprehensive Filter Quality Assessment with Advanced Analysis",
            height=900,
            showlegend=True,
            template="plotly_white",
            font=dict(size=11),
            margin=dict(l=60, r=60, t=100, b=60),
            legend=dict(
                orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1
            ),
        )

        return fig

    except Exception as e:
        logger.error(f"Error creating quality plots: {e}")
        return create_empty_figure()


# Quality metric calculation functions
def calculate_snr_improvement(original_signal, filtered_signal):
    """Calculate SNR improvement after filtering."""
    try:
        # Calculate noise as the difference between original and filtered
        noise = original_signal - filtered_signal

        # Calculate signal power (filtered signal)
        signal_power = np.mean(filtered_signal**2)

        # Calculate noise power
        noise_power = np.mean(noise**2)

        if noise_power > 0:
            snr = 10 * np.log10(signal_power / noise_power)
            return snr
        else:
            return 0
    except Exception as e:
        logger.error(f"Error calculating SNR: {e}")
        return 0


def calculate_mse(original_signal, filtered_signal):
    """Calculate Mean Square Error between original and filtered signals."""
    try:
        return np.mean((original_signal - filtered_signal) ** 2)
    except Exception as e:
        logger.error(f"Error calculating MSE: {e}")
        return 0


def calculate_correlation(original_signal, filtered_signal):
    """Calculate correlation between original and filtered signals."""
    try:
        return np.corrcoef(original_signal, filtered_signal)[0, 1]
    except Exception as e:
        logger.error(f"Error calculating correlation: {e}")
        return 0


def calculate_smoothness(signal_data):
    """Calculate signal smoothness using variance of first differences."""
    try:
        differences = np.diff(signal_data)
        return 1 / (1 + np.var(differences))
    except Exception as e:
        logger.error(f"Error calculating smoothness: {e}")
        return 0


def calculate_frequency_metrics(original_signal, filtered_signal, sampling_freq):
    """Calculate frequency domain metrics for both original and filtered signals."""
    try:
        # Calculate PSD for both signals
        freqs_orig, psd_orig = signal.welch(original_signal, fs=sampling_freq)
        freqs_filt, psd_filt = signal.welch(filtered_signal, fs=sampling_freq)

        # Find peak frequency for filtered signal
        peak_idx_filt = np.argmax(psd_filt)
        peak_freq_filt = freqs_filt[peak_idx_filt]

        # Find peak frequency for original signal
        peak_idx_orig = np.argmax(psd_orig)
        peak_freq_orig = freqs_orig[peak_idx_orig]

        # Calculate bandwidth for filtered signal (3dB down from peak)
        peak_power_filt = psd_filt[peak_idx_filt]
        threshold_filt = peak_power_filt / 2  # 3dB down
        above_threshold_filt = psd_filt > threshold_filt
        bandwidth_filt = (
            freqs_filt[-1] - freqs_filt[0] if np.any(above_threshold_filt) else 0
        )

        # Calculate bandwidth for original signal
        peak_power_orig = psd_orig[peak_idx_orig]
        threshold_orig = peak_power_orig / 2  # 3dB down
        above_threshold_orig = psd_orig > threshold_orig
        bandwidth_orig = (
            freqs_orig[-1] - freqs_orig[0] if np.any(above_threshold_orig) else 0
        )

        # Calculate spectral centroid for filtered signal
        spectral_centroid_filt = np.sum(freqs_filt * psd_filt) / np.sum(psd_filt)

        # Calculate spectral centroid for original signal
        spectral_centroid_orig = np.sum(freqs_orig * psd_orig) / np.sum(psd_orig)

        # Calculate frequency stability for filtered signal (inverse of frequency variance)
        freq_stability_filt = 1 / (1 + np.var(freqs_filt))

        # Calculate frequency stability for original signal
        freq_stability_orig = 1 / (1 + np.var(freqs_orig))

        return {
            "peak_freq": peak_freq_filt,
            "peak_freq_orig": peak_freq_orig,
            "bandwidth": bandwidth_filt,
            "bandwidth_orig": bandwidth_orig,
            "spectral_centroid": spectral_centroid_filt,
            "spectral_centroid_orig": spectral_centroid_orig,
            "freq_stability": freq_stability_filt,
            "freq_stability_orig": freq_stability_orig,
        }

    except Exception as e:
        logger.error(f"Error calculating frequency metrics: {e}")
        return {
            "peak_freq": 0,
            "bandwidth": 0,
            "spectral_centroid": 0,
            "freq_stability": 0,
        }


def calculate_statistical_metrics(original_signal, filtered_signal):
    """Calculate comprehensive statistical metrics for both signals."""
    try:
        # Basic statistics for original signal
        mean_orig = np.mean(original_signal)
        std_orig = np.std(original_signal)
        skewness_orig = calculate_skewness(original_signal)
        kurtosis_orig = calculate_kurtosis(original_signal)
        entropy_orig = calculate_entropy(original_signal)
        smoothness_orig = calculate_smoothness(original_signal)

        # Basic statistics for filtered signal
        mean_filt = np.mean(filtered_signal)
        std_filt = np.std(filtered_signal)
        skewness_filt = calculate_skewness(filtered_signal)
        kurtosis_filt = calculate_kurtosis(filtered_signal)
        entropy_filt = calculate_entropy(filtered_signal)

        # Calculate changes
        mean_change = mean_filt - mean_orig
        std_change = std_filt - std_orig
        skewness_change = skewness_filt - skewness_orig
        kurtosis_change = kurtosis_filt - kurtosis_orig
        entropy_change = entropy_filt - entropy_orig

        return {
            "mean_orig": mean_orig,
            "mean_filt": mean_filt,
            "mean_change": mean_change,
            "std_orig": std_orig,
            "std_filt": std_filt,
            "std_change": std_change,
            "skewness_orig": skewness_orig,
            "skewness_filt": skewness_filt,
            "skewness_change": skewness_change,
            "kurtosis_orig": kurtosis_orig,
            "kurtosis_filt": kurtosis_filt,
            "kurtosis_change": kurtosis_change,
            "entropy_orig": entropy_orig,
            "entropy_filt": entropy_filt,
            "entropy_change": entropy_change,
            "smoothness_orig": smoothness_orig,
        }

    except Exception as e:
        logger.error(f"Error calculating statistical metrics: {e}")
        return {
            "mean_orig": 0,
            "mean_filt": 0,
            "mean_change": 0,
            "std_orig": 0,
            "std_filt": 0,
            "std_change": 0,
            "skewness_orig": 0,
            "skewness_filt": 0,
            "skewness_change": 0,
            "kurtosis_orig": 0,
            "kurtosis_filt": 0,
            "kurtosis_change": 0,
            "entropy_orig": 0,
            "entropy_filt": 0,
            "entropy_change": 0,
            "smoothness_orig": 0,
        }


def calculate_temporal_features(original_signal, filtered_signal, sampling_freq):
    """Calculate temporal features for both signals."""
    try:
        # Peak detection for original signal
        peaks_orig, _ = signal.find_peaks(
            original_signal, height=np.mean(original_signal) + np.std(original_signal)
        )
        peak_count_orig = len(peaks_orig)

        # Peak detection for filtered signal
        peaks_filt, _ = signal.find_peaks(
            filtered_signal, height=np.mean(filtered_signal) + np.std(filtered_signal)
        )
        peak_count_filt = len(peaks_filt)

        # Calculate intervals for original signal
        if len(peaks_orig) > 1:
            intervals_orig = np.diff(peaks_orig) / sampling_freq
            mean_interval_orig = np.mean(intervals_orig)
            interval_std_orig = np.std(intervals_orig)
            heart_rate_orig = 60 / mean_interval_orig if mean_interval_orig > 0 else 0
        else:
            mean_interval_orig = 0
            interval_std_orig = 0
            heart_rate_orig = 0

        # Calculate intervals for filtered signal
        if len(peaks_filt) > 1:
            intervals_filt = np.diff(peaks_filt) / sampling_freq
            mean_interval_filt = np.mean(intervals_filt)
            interval_std_filt = np.std(intervals_filt)
            heart_rate_filt = 60 / mean_interval_filt if mean_interval_filt > 0 else 0
        else:
            mean_interval_filt = 0
            interval_std_filt = 0
            heart_rate_filt = 0

        # Calculate changes
        peak_count_change = peak_count_filt - peak_count_orig
        interval_change = mean_interval_filt - mean_interval_orig
        interval_std_change = interval_std_filt - interval_std_orig
        heart_rate_change = heart_rate_filt - heart_rate_orig

        return {
            "peak_count_orig": peak_count_orig,
            "peak_count_filt": peak_count_filt,
            "peak_count_change": peak_count_change,
            "mean_interval_orig": mean_interval_orig,
            "mean_interval_filt": mean_interval_filt,
            "interval_change": interval_change,
            "interval_std_orig": interval_std_orig,
            "interval_std_filt": interval_std_filt,
            "interval_std_change": interval_std_change,
            "heart_rate_orig": heart_rate_orig,
            "heart_rate_filt": heart_rate_filt,
            "heart_rate_change": heart_rate_change,
        }

    except Exception as e:
        logger.error(f"Error calculating temporal features: {e}")
        return {
            "peak_count_orig": 0,
            "peak_count_filt": 0,
            "peak_count_change": 0,
            "mean_interval_orig": 0,
            "mean_interval_filt": 0,
            "interval_change": 0,
            "interval_std_orig": 0,
            "interval_std_filt": 0,
            "interval_std_change": 0,
            "heart_rate_orig": 0,
            "heart_rate_filt": 0,
            "heart_rate_change": 0,
        }


def calculate_morphological_features(original_signal, filtered_signal):
    """Calculate morphological features for both signals."""
    try:
        # Original signal features
        amplitude_range_orig = np.max(original_signal) - np.min(original_signal)
        amplitude_mean_orig = np.mean(np.abs(original_signal))
        zero_crossings_orig = np.sum(np.diff(np.sign(original_signal)) != 0)
        signal_energy_orig = np.sum(original_signal**2)

        # Filtered signal features
        amplitude_range_filt = np.max(filtered_signal) - np.min(filtered_signal)
        amplitude_mean_filt = np.mean(np.abs(filtered_signal))
        zero_crossings_filt = np.sum(np.diff(np.sign(filtered_signal)) != 0)
        signal_energy_filt = np.sum(filtered_signal**2)

        # Calculate changes
        amplitude_range_change = amplitude_range_filt - amplitude_range_orig
        amplitude_mean_change = amplitude_mean_filt - amplitude_mean_orig
        zero_crossings_change = zero_crossings_filt - zero_crossings_orig
        signal_energy_change = signal_energy_filt - signal_energy_orig

        return {
            "amplitude_range_orig": amplitude_range_orig,
            "amplitude_range_filt": amplitude_range_filt,
            "amplitude_range_change": amplitude_range_change,
            "amplitude_mean_orig": amplitude_mean_orig,
            "amplitude_mean_filt": amplitude_mean_filt,
            "amplitude_mean_change": amplitude_mean_change,
            "zero_crossings_orig": zero_crossings_orig,
            "zero_crossings_filt": zero_crossings_filt,
            "zero_crossings_change": zero_crossings_change,
            "signal_energy_orig": signal_energy_orig,
            "signal_energy_filt": signal_energy_filt,
            "signal_energy_change": signal_energy_change,
        }

    except Exception as e:
        logger.error(f"Error calculating morphological features: {e}")
        return {
            "amplitude_range_orig": 0,
            "amplitude_range_filt": 0,
            "amplitude_range_change": 0,
            "amplitude_mean_orig": 0,
            "amplitude_mean_filt": 0,
            "amplitude_mean_change": 0,
            "zero_crossings_orig": 0,
            "zero_crossings_filt": 0,
            "zero_crossings_change": 0,
            "signal_energy_orig": 0,
            "signal_energy_filt": 0,
            "signal_energy_change": 0,
        }


def calculate_advanced_quality_metrics(original_signal, filtered_signal, sampling_freq):
    """Calculate advanced quality metrics including artifacts and stability."""
    try:
        # Artifact detection
        mean_val = np.mean(original_signal)
        std_val = np.std(original_signal)
        artifact_threshold = mean_val + 3 * std_val
        artifacts = np.where(np.abs(original_signal - mean_val) > artifact_threshold)[0]
        artifact_percentage = len(artifacts) / len(original_signal) * 100

        # Baseline wander assessment
        nyquist = sampling_freq / 2
        cutoff = 0.5  # 0.5 Hz cutoff for baseline wander
        b, a = signal.butter(4, cutoff / nyquist, btype="high")
        filtered_baseline = signal.filtfilt(b, a, original_signal)
        baseline_wander = original_signal - filtered_baseline
        baseline_wander_percentage = (
            np.std(baseline_wander) / np.std(original_signal) * 100
        )

        # Motion artifact detection
        analytic_signal = signal.hilbert(original_signal)
        envelope = np.abs(analytic_signal)
        motion_artifact_score = (
            np.std(envelope) / np.mean(envelope) if np.mean(envelope) > 0 else 0
        )

        # Signal stability (inverse of coefficient of variation)
        signal_stability = (
            1 / (1 + np.std(filtered_signal) / np.abs(np.mean(filtered_signal)))
            if np.mean(filtered_signal) != 0
            else 0
        )

        return {
            "artifact_percentage": artifact_percentage,
            "baseline_wander_percentage": baseline_wander_percentage,
            "motion_artifact_score": motion_artifact_score,
            "signal_stability": signal_stability,
        }

    except Exception as e:
        logger.error(f"Error calculating advanced quality metrics: {e}")
        return {
            "artifact_percentage": 0,
            "baseline_wander_percentage": 0,
            "motion_artifact_score": 0,
            "signal_stability": 0,
        }


def calculate_performance_metrics(original_signal, filtered_signal):
    """Calculate performance and efficiency metrics."""
    try:
        import time
        import psutil
        import os

        # Simulate processing time (in real implementation, this would be measured)
        processing_time = 0.1 + np.random.random() * 0.5  # Simulated 0.1-0.6s

        # Estimate memory usage
        memory_usage = (
            (len(original_signal) + len(filtered_signal)) * 8 / (1024 * 1024)
        )  # MB

        # Calculate data reduction (if any compression or downsampling occurred)
        data_reduction = 0  # No reduction in basic filtering

        # Calculate algorithm efficiency (based on signal improvement vs. processing cost)
        snr_improvement = calculate_snr_improvement(original_signal, filtered_signal)
        mse = calculate_mse(original_signal, filtered_signal)

        # Efficiency score based on improvement vs. processing time
        if processing_time > 0:
            efficiency_score = min(
                100, max(0, (snr_improvement * 10 - mse * 1000) / processing_time)
            )
        else:
            efficiency_score = 0

        return {
            "processing_time": processing_time,
            "memory_usage": memory_usage,
            "data_reduction": data_reduction,
            "algorithm_efficiency": efficiency_score,
        }

    except Exception as e:
        logger.error(f"Error calculating performance metrics: {e}")
        return {
            "processing_time": 0,
            "memory_usage": 0,
            "data_reduction": 0,
            "algorithm_efficiency": 0,
        }


def calculate_skewness(data):
    """Calculate skewness of the data."""
    try:
        mean = np.mean(data)
        std = np.std(data)
        if std == 0:
            return 0
        return np.mean(((data - mean) / std) ** 3)
    except Exception as e:
        logger.error(f"Error calculating skewness: {e}")
        return 0


def calculate_kurtosis(data):
    """Calculate kurtosis of the data."""
    try:
        mean = np.mean(data)
        std = np.std(data)
        if std == 0:
            return 0
        return np.mean(((data - mean) / std) ** 4) - 3
    except Exception as e:
        logger.error(f"Error calculating kurtosis: {e}")
        return 0


def calculate_entropy(data):
    """Calculate entropy of the data."""
    try:
        # Simple histogram-based entropy
        hist, _ = np.histogram(data, bins=50)
        hist = hist[hist > 0]
        if len(hist) == 0:
            return 0
        p = hist / np.sum(hist)
        return -np.sum(p * np.log2(p))
    except Exception as e:
        logger.error(f"Error calculating entropy: {e}")
        return 0
