"""
Tabbed Flow View Widget - Shows Overview + Frame Type specific tabs
"""

from textual.widgets import TabbedContent, TabPane, DataTable, Static
from textual.containers import Vertical, Horizontal
from textual.reactive import reactive
from typing import TYPE_CHECKING, Dict, List, Optional, Set
from rich.text import Text
from rich.table import Table
from rich.panel import Panel
from .flow_table_v2 import EnhancedFlowTable

if TYPE_CHECKING:
    from ....analysis.core import EthernetAnalyzer
    from ....models import FlowStats


class FrameTypeFlowTable(DataTable):
    """Flow table filtered for a specific frame type"""
    
    def __init__(self, frame_type: str, **kwargs):
        super().__init__(**kwargs)
        self.frame_type = frame_type
        self.cursor_type = "row"
        self.zebra_stripes = True
        self.show_header = True
        self.show_row_labels = False
        
    def setup_columns(self):
        """Setup columns for frame-type specific view"""
        self.add_column("Flow", width=4, key="flow_id")
        self.add_column("Source IP", width=16, key="src_ip")
        self.add_column("Src Port", width=8, key="src_port")
        self.add_column("Dest IP", width=16, key="dst_ip")
        self.add_column("Dst Port", width=8, key="dst_port")
        self.add_column("Protocol", width=8, key="protocol")
        self.add_column("Packets", width=8, key="packets")
        self.add_column("Avg ΔT", width=10, key="avg_delta")
        self.add_column("Std ΔT", width=10, key="std_delta")
        self.add_column("Outliers", width=8, key="outliers")
        self.add_column("Quality", width=8, key="quality")


class FrameTypeStatsPanel(Static):
    """Statistics panel for a specific frame type"""
    
    def __init__(self, frame_type: str, **kwargs):
        super().__init__(**kwargs)
        self.frame_type = frame_type
        self._stats_content = f"Statistics for {self.frame_type}\n\nNo data available yet."
        
    def render(self):
        """Render frame type statistics"""
        return Panel(
            self._stats_content,
            title=f"📊 {self.frame_type} Statistics",
            border_style="blue"
        )
    
    def update_content(self, content: str):
        """Update the statistics content"""
        self._stats_content = content
        self.refresh()


class FrameTypeTabContent(Vertical):
    """Content for a specific frame type tab"""
    
    def __init__(self, frame_type: str, analyzer: 'EthernetAnalyzer', **kwargs):
        super().__init__(**kwargs)
        self.frame_type = frame_type
        self.analyzer = analyzer
        
    def compose(self):
        """Compose the frame type tab content"""
        with Horizontal():
            # Left side - Flow table for this frame type (sanitize ID)
            table_id = f"table-{self.frame_type.replace('-', '_').replace(':', '_')}"
            yield FrameTypeFlowTable(self.frame_type, id=table_id)
            
            # Right side - Frame type statistics (sanitize ID)
            stats_id = f"stats-{self.frame_type.replace('-', '_').replace(':', '_')}"
            yield FrameTypeStatsPanel(self.frame_type, id=stats_id)
    
    def on_mount(self):
        """Initialize the frame type tab"""
        table_id = f"#table-{self.frame_type.replace('-', '_').replace(':', '_')}"
        table = self.query_one(table_id, FrameTypeFlowTable)
        table.setup_columns()
        self.refresh_data()
    
    def refresh_data(self):
        """Refresh data for this frame type"""
        try:
            table_id = f"#table-{self.frame_type.replace('-', '_').replace(':', '_')}"
            table = self.query_one(table_id, FrameTypeFlowTable)
            
            # Clear existing data
            table.clear()
            
            # Get flows that have this frame type
            flows_with_frametype = []
            flow_list = list(self.analyzer.flows.values())
            
            for i, flow in enumerate(flow_list):
                if self.frame_type in flow.frame_types:
                    ft_stats = flow.frame_types[self.frame_type]
                    flows_with_frametype.append((i, flow, ft_stats))
            
            # Add rows for flows with this frame type
            for flow_idx, flow, ft_stats in flows_with_frametype:
                # Calculate quality score
                quality_score = self._calculate_quality_score(ft_stats)
                quality_text = self._format_quality(quality_score)
                
                # Format timing statistics
                avg_delta = f"{ft_stats.avg_inter_arrival * 1000:.1f}ms" if ft_stats.avg_inter_arrival > 0 else "N/A"
                std_delta = f"{ft_stats.std_inter_arrival * 1000:.1f}ms" if ft_stats.std_inter_arrival > 0 else "N/A"
                
                row_data = [
                    str(flow_idx + 1),  # Flow ID
                    flow.src_ip,
                    str(flow.src_port),
                    flow.dst_ip,
                    str(flow.dst_port),
                    flow.transport_protocol,
                    str(ft_stats.count),
                    avg_delta,
                    std_delta,
                    str(len(ft_stats.outlier_frames)),
                    quality_text
                ]
                
                table.add_row(*row_data, key=f"flow-{flow_idx}")
            
            # Update statistics panel
            self._update_stats_panel(flows_with_frametype)
            
        except Exception as e:
            # Handle case where widgets aren't ready yet
            pass
    
    def _calculate_quality_score(self, ft_stats) -> float:
        """Calculate quality score for frame type stats"""
        if ft_stats.count == 0:
            return 0.0
        
        # Base score on outlier rate and timing consistency
        outlier_rate = len(ft_stats.outlier_frames) / ft_stats.count
        consistency = 1.0 - min(outlier_rate * 2, 1.0)  # Lower outlier rate = higher consistency
        
        return consistency * 100
    
    def _format_quality(self, quality_score: float) -> Text:
        """Format quality score with color coding"""
        if quality_score >= 90:
            return Text(f"{quality_score:.0f}%", style="green")
        elif quality_score >= 70:
            return Text(f"{quality_score:.0f}%", style="yellow")
        else:
            return Text(f"{quality_score:.0f}%", style="red")
    
    def _update_stats_panel(self, flows_with_frametype):
        """Update the statistics panel with current data"""
        try:
            stats_id = f"#stats-{self.frame_type.replace('-', '_').replace(':', '_')}"
            stats_panel = self.query_one(stats_id, FrameTypeStatsPanel)
            
            if not flows_with_frametype:
                stats_content = f"No flows found with {self.frame_type} frames"
            else:
                # Calculate aggregate statistics
                total_flows = len(flows_with_frametype)
                total_packets = sum(ft_stats.count for _, _, ft_stats in flows_with_frametype)
                total_outliers = sum(len(ft_stats.outlier_frames) for _, _, ft_stats in flows_with_frametype)
                
                # Calculate average timing
                avg_timings = [ft_stats.avg_inter_arrival for _, _, ft_stats in flows_with_frametype if ft_stats.avg_inter_arrival > 0]
                overall_avg = sum(avg_timings) / len(avg_timings) if avg_timings else 0
                
                # Format statistics
                stats_content = f"""Flows: {total_flows}
Total Packets: {total_packets:,}
Total Outliers: {total_outliers}
Outlier Rate: {(total_outliers/total_packets*100):.1f}% 
Avg Inter-arrival: {overall_avg*1000:.1f}ms"""
            
            # Update the panel content using the new method
            stats_panel.update_content(stats_content)
            
        except Exception as e:
            pass


class TabbedFlowView(TabbedContent):
    """Tabbed view showing Overview + Frame Type specific tabs"""
    
    active_frame_types = reactive(set())
    
    def __init__(self, analyzer: 'EthernetAnalyzer', **kwargs):
        super().__init__(**kwargs)
        self.analyzer = analyzer
        self.overview_table = None
        self.frame_type_tabs = {}
        
    def compose(self):
        """Create the tabbed interface"""
        # Overview tab (always present)
        with TabPane("Overview", id="tab-overview"):
            self.overview_table = EnhancedFlowTable(self.analyzer, id="overview-flow-table")
            yield self.overview_table
        
        # Create tabs for common frame types (based on detection analysis)
        common_frame_types = ["CH10-Data", "CH10-ACTTS", "TMATS", "PTP-Sync", "PTP-Signaling", "UDP", "IGMP"]
        
        for frame_type in common_frame_types:
            tab_id = f"tab-{frame_type.lower().replace('-', '_').replace(':', '_')}"
            content_id = f"content-{frame_type.replace('-', '_').replace(':', '_')}"
            with TabPane(frame_type, id=tab_id):
                tab_content = FrameTypeTabContent(frame_type, self.analyzer, id=content_id)
                self.frame_type_tabs[frame_type] = tab_content
                yield tab_content
    
    def _create_frame_type_tabs(self):
        """Create tabs for detected frame types"""
        frame_types = self._get_detected_frame_types()
        
        for frame_type in sorted(frame_types):
            tab_id = f"tab-{frame_type.lower().replace('-', '_').replace(':', '_')}"
            with TabPane(frame_type, id=tab_id):
                tab_content = FrameTypeTabContent(frame_type, self.analyzer, id=f"content-{frame_type}")
                self.frame_type_tabs[frame_type] = tab_content
                yield tab_content
    
    def _get_detected_frame_types(self) -> Set[str]:
        """Get all detected frame types from current flows"""
        frame_types = set()
        
        for flow in self.analyzer.flows.values():
            frame_types.update(flow.frame_types.keys())
        
        return frame_types
    
    def on_mount(self):
        """Initialize tabs"""
        self.refresh_all_tabs()
    
    def refresh_all_tabs(self):
        """Refresh data in all tabs"""
        # Refresh overview tab
        if self.overview_table:
            self.overview_table.refresh_data()
        
        # Get detected frame types
        detected_frame_types = self._get_detected_frame_types()
        
        # Refresh frame type tabs that have data
        for frame_type, tab_content in self.frame_type_tabs.items():
            if frame_type in detected_frame_types:
                tab_content.refresh_data()
                # Tab has data, it will show content when selected
                pass
            else:
                # Tab has no data, it will show empty when selected
                pass
    
    def update_tabs(self):
        """Update tabs based on newly detected frame types"""
        current_frame_types = self._get_detected_frame_types()
        
        # Check if we need to add new tabs
        new_frame_types = current_frame_types - self.active_frame_types
        if new_frame_types:
            # This would require rebuilding the widget
            # For now, just refresh existing tabs
            self.refresh_all_tabs()
        
        self.active_frame_types = current_frame_types