# enhanced_results_display_manager.py """ Enhanced Results Display Manager for UI Classification Improvements. This module provides enhanced display formatting for chat results with clear visual separation between AI analysis, patient messages, and provider summaries. Requirements: 1.1, 1.2, 7.1, 7.2 """ import html from typing import Dict, List, Optional, Any from dataclasses import dataclass from enum import Enum from src.core.provider_summary_generator import ProviderSummary from src.core.spiritual_state import SpiritualAssessment, SpiritualState from src.config.enhanced_display_config import ( EnhancedDisplayConfig, get_enhanced_display_config, EnhancedDisplayConfigManager ) class SectionType(Enum): """Types of content sections for display.""" AI_ANALYSIS = "ai_analysis" PATIENT_MESSAGE = "patient_message" PROVIDER_SUMMARY = "provider_summary" @dataclass class ContentSection: """Represents a content section with styling information.""" section_type: SectionType content: str styling: Dict[str, str] icon: Optional[str] = None priority: int = 0 @dataclass class ContentSection: """Represents a content section with styling information.""" section_type: SectionType content: str styling: Dict[str, str] icon: Optional[str] = None priority: int = 0 class EnhancedResultsDisplayManager: """ Enhanced Results Display Manager for improved UI formatting. Provides methods to format different types of content with clear visual separation and consistent styling according to requirements 1.1, 1.2, 7.1, 7.2. """ def __init__(self, config: Optional[EnhancedDisplayConfig] = None, config_manager: Optional[EnhancedDisplayConfigManager] = None): """ Initialize the display manager. Args: config: Optional configuration for display formatting config_manager: Optional configuration manager for dynamic updates """ self.config_manager = config_manager if config is not None: self.config = config elif self.config_manager is not None: self.config = self.config_manager.get_config() else: self.config = get_enhanced_display_config() # Initialize error handler for validation and recovery (lazy loaded) self._error_handler = None @property def error_handler(self): """Lazy load error handler to avoid circular imports.""" if self._error_handler is None: from src.core.ui_error_handler import UIErrorHandler self._error_handler = UIErrorHandler() return self._error_handler def format_ai_analysis_section( self, classification: str, indicators: List[str], reasoning: str, confidence: Optional[float] = None ) -> str: """ Format AI analysis section with clear labeling and visual styling. Args: classification: The classification result (RED/YELLOW/GREEN) indicators: List of distress indicators reasoning: AI reasoning for the classification confidence: Optional confidence score Returns: Formatted HTML string for AI analysis section Requirements: 1.1, 7.1 """ try: # Validate inputs if not classification: classification = "UNKNOWN" if not indicators: indicators = ["No indicators available"] if not reasoning: reasoning = "No reasoning provided" # Check if enhancements are enabled if not self.config.enabled: return self._format_basic_ai_analysis(classification, indicators, reasoning, confidence) # Get classification color color = self.config.get_classification_color(classification) section_config = self.config.get_section_config("ai_analysis") # Build confidence display confidence_text = "" if confidence is not None: confidence_percent = int(confidence * 100) confidence_text = f"
Confidence: {confidence_percent}%
" # Build indicators list indicators_html = "" if indicators: indicators_list = "".join([f"
  • {html.escape(indicator)}
  • " for indicator in indicators]) indicators_html = f"""
    Indicators:
    """ # Build reasoning section reasoning_html = f"""
    Reasoning:
    {html.escape(reasoning)}
    """ # Build icon display icon_html = "" if self.config.use_icons: icon_html = f"{section_config.icon}" # Combine all elements with enhanced styling content = f"""
    {icon_html} AI Analysis - {classification} FLAG
    {confidence_text} {indicators_html} {reasoning_html}
    """ return content except Exception as e: # Handle formatting errors with degraded display error_context = f"AI analysis formatting failed: {str(e)}" fallback_content = self._format_basic_ai_analysis(classification, indicators, reasoning, confidence) return self.error_handler.create_degraded_display(error_context, fallback_content) def format_patient_message_section(self, message: str) -> str: """ Format patient message section with appropriate styling. Args: message: The patient's message content Returns: Formatted HTML string for patient message section Requirements: 1.2, 7.2 """ try: # Validate input if not message: message = "No message content available" # Check if enhancements are enabled if not self.config.enabled: return self._format_basic_patient_message(message) section_config = self.config.get_section_config("patient_message") # Build icon display icon_html = "" if self.config.use_icons: icon_html = f"{section_config.icon}" content = f"""
    {icon_html} Patient Message
    {html.escape(message)}
    """ return content except Exception as e: # Handle formatting errors with degraded display error_context = f"Patient message formatting failed: {str(e)}" fallback_content = self._format_basic_patient_message(message) return self.error_handler.create_degraded_display(error_context, fallback_content) def format_provider_summary_section(self, summary_data: ProviderSummary) -> str: """ Format provider summary section with enhanced styling. Args: summary_data: Provider summary data to format Returns: Formatted HTML string for provider summary section Requirements: 1.1, 1.2, 7.1, 7.2 """ try: # Validate and fix summary data if needed validation_result = self.error_handler.validate_provider_summary_structure(summary_data) if validation_result.has_critical_errors(): # Apply fallback template for critical errors summary_data = self.error_handler.apply_fallback_template(summary_data, "general") # Check if enhancements are enabled if not self.config.enabled: return self._format_basic_provider_summary(summary_data) section_config = self.config.get_section_config("provider_summary") # Get urgency color urgency_colors = { 'IMMEDIATE': self.config.classification_colors.red, 'URGENT': self.config.classification_colors.yellow, 'STANDARD': self.config.classification_colors.green } urgency_color = urgency_colors.get(summary_data.urgency_level, self.config.classification_colors.red) # Build patient info section patient_info = f"""
    Patient Information:
    Name: {html.escape(summary_data.patient_name)}
    Phone: {html.escape(summary_data.patient_phone)}
    """ # Build indicators section indicators_html = "" if summary_data.indicators: indicators_list = "".join([f"
  • {html.escape(indicator)}
  • " for indicator in summary_data.indicators]) indicators_html = f"""
    Distress Indicators:
    """ # Build situation description situation_html = f"""
    Situation Overview:
    {html.escape(summary_data.situation_description)}
    """ # Build urgency information urgency_html = f"""
    Urgency Level: {summary_data.urgency_level}
    Follow-up Timeline: {summary_data.follow_up_timeline}
    """ # Build icon display icon_html = "" if self.config.use_icons: icon_html = f"{section_config.icon}" # Add validation warnings if any warnings_html = "" if validation_result.warnings: warnings_list = "".join([f"
  • {warning.message}
  • " for warning in validation_result.warnings]) warnings_html = f"""
    ⚠️ Validation Warnings:
    """ # Combine all elements with enhanced styling content = f"""
    {icon_html} Provider Summary For Spiritual Care Team
    {patient_info} {urgency_html} {situation_html} {indicators_html} {warnings_html}
    """ return content except Exception as e: # Handle formatting errors with degraded display error_context = f"Provider summary formatting failed: {str(e)}" fallback_content = self._format_basic_provider_summary(summary_data) return self.error_handler.create_degraded_display(error_context, fallback_content) def create_visual_separators(self) -> Dict[str, str]: """ Create visual separators for different content types. Returns: Dictionary mapping section types to separator HTML Requirements: 7.1, 7.2 """ # Check if separators are enabled if not self.config.use_visual_separators: return { "section_break": "
    ", "content_divider": "
    ", "major_break": "
    " } separators = { "section_break": f"""

    {self.config.separators.section_separator}
    """, "content_divider": f"""
    """, "major_break": f"""
    {self.config.separators.major_break_symbol}
    """ } return separators def apply_section_styling(self, content: str, section_type: SectionType) -> str: """ Apply consistent styling to a content section. Args: content: The content to style section_type: The type of section for appropriate styling Returns: Styled HTML content Requirements: 7.1, 7.2 """ # Base styling for all sections base_style = "margin: 15px 0; padding: 10px; border-radius: 6px;" # Section-specific styling section_styles = { SectionType.AI_ANALYSIS: base_style + "background-color: #f8f9fa; border-left: 4px solid #6c757d;", SectionType.PATIENT_MESSAGE: base_style + "background-color: #f0f7ff; border-left: 4px solid #4a90e2;", SectionType.PROVIDER_SUMMARY: base_style + "background-color: #fff8f0; border-left: 4px solid #dc3545;" } style = section_styles.get(section_type, base_style) return f"""
    {content}
    """ def format_combined_results( self, ai_analysis: Optional[Dict[str, Any]] = None, patient_message: Optional[str] = None, provider_summary: Optional[ProviderSummary] = None ) -> str: """ Format combined results with all sections and proper separation. Args: ai_analysis: Optional AI analysis data patient_message: Optional patient message provider_summary: Optional provider summary data Returns: Complete formatted HTML with all sections Requirements: 1.1, 1.2, 7.1, 7.2 """ sections = [] separators = self.create_visual_separators() # Add AI analysis section if provided if ai_analysis: ai_section = self.format_ai_analysis_section( classification=ai_analysis.get('classification', 'UNKNOWN'), indicators=ai_analysis.get('indicators', []), reasoning=ai_analysis.get('reasoning', ''), confidence=ai_analysis.get('confidence') ) sections.append(ai_section) # Add patient message section if provided if patient_message: patient_section = self.format_patient_message_section(patient_message) sections.append(patient_section) # Add provider summary section if provided if provider_summary: summary_section = self.format_provider_summary_section(provider_summary) sections.append(summary_section) # Join sections with separators if len(sections) > 1: content = separators["section_break"].join(sections) elif sections: content = sections[0] else: content = "
    No content to display
    " return content def _format_basic_ai_analysis(self, classification: str, indicators: List[str], reasoning: str, confidence: Optional[float] = None) -> str: """Fallback basic formatting for AI analysis when enhancements are disabled.""" confidence_text = f" (Confidence: {int(confidence * 100)}%)" if confidence else "" indicators_text = f"Indicators: {', '.join(indicators)}" if indicators else "No indicators" return f"""
    AI Analysis - {classification} FLAG{confidence_text}
    {indicators_text}
    Reasoning: {reasoning}
    """ def _format_basic_patient_message(self, message: str) -> str: """Fallback basic formatting for patient message when enhancements are disabled.""" return f"""
    Patient Message
    {html.escape(message)}
    """ def _format_basic_provider_summary(self, summary_data: ProviderSummary) -> str: """Fallback basic formatting for provider summary when enhancements are disabled.""" return f"""
    Provider Summary
    Patient: {summary_data.patient_name}
    Phone: {summary_data.patient_phone}
    Urgency: {summary_data.urgency_level}
    Situation: {summary_data.situation_description}
    """ def update_config(self, new_config: EnhancedDisplayConfig) -> None: """ Update the configuration for this display manager. Args: new_config: New configuration to use """ self.config = new_config def reload_config(self) -> None: """Reload configuration from the config manager if available.""" if self.config_manager is not None: self.config = self.config_manager.get_config() else: self.config = get_enhanced_display_config() def is_enhanced_mode_enabled(self) -> bool: """Check if enhanced display mode is enabled.""" return self.config.enabled def get_css_styles(self) -> str: """ Get CSS styles for enhanced display. Returns: CSS string for enhanced display styling """ return self.config.generate_base_css()