"""
Modern TUI Interface for StreamLens
Focused on Flow Analysis, Packet Decoding, and Statistical Analysis
"""

import curses
from typing import TYPE_CHECKING, List, Optional
from enum import Enum

from .navigation import NavigationHandler
from .modern_views import FlowAnalysisView, PacketDecoderView, StatisticalAnalysisView
from ..utils.signal_visualizer import signal_visualizer

if TYPE_CHECKING:
    from ..analysis.core import EthernetAnalyzer


class ViewMode(Enum):
    FLOW_ANALYSIS = "flow"
    PACKET_DECODER = "decode" 
    STATISTICAL_ANALYSIS = "stats"


class ModernTUIInterface:
    """
    Modern StreamLens TUI Interface
    
    Three primary views accessed via 1/2/3:
    - 1: Flow Analysis - Visual flow overview with enhanced protocol detection
    - 2: Packet Decoder - Deep protocol inspection and field extraction  
    - 3: Statistical Analysis - Timing analysis, outliers, and quality metrics
    """
    
    def __init__(self, analyzer: 'EthernetAnalyzer'):
        self.analyzer = analyzer
        self.navigation = NavigationHandler()
        
        # Current view mode
        self.current_view = ViewMode.FLOW_ANALYSIS
        
        # Initialize view controllers
        self.flow_view = FlowAnalysisView(analyzer)
        self.decoder_view = PacketDecoderView(analyzer)
        self.stats_view = StatisticalAnalysisView(analyzer)
        
        # Global state
        self.selected_flow_key = None
        self.show_help = False
    
    def run(self, stdscr):
        """Main TUI loop for modern interface"""
        curses.curs_set(0)  # Hide cursor
        stdscr.keypad(True)
        
        # Set timeout based on live mode
        if self.analyzer.is_live:
            stdscr.timeout(500)  # 0.5 second for live updates
        else:
            stdscr.timeout(1000)  # 1 second for static analysis
        
        while True:
            try:
                stdscr.clear()
                
                # Draw header with view indicators
                self._draw_header(stdscr)
                
                # Draw main content based on current view
                if self.current_view == ViewMode.FLOW_ANALYSIS:
                    self.flow_view.draw(stdscr, self.selected_flow_key)
                elif self.current_view == ViewMode.PACKET_DECODER:
                    self.decoder_view.draw(stdscr, self.selected_flow_key)
                elif self.current_view == ViewMode.STATISTICAL_ANALYSIS:
                    self.stats_view.draw(stdscr, self.selected_flow_key)
                
                # Draw status bar
                self._draw_status_bar(stdscr)
                
                # Overlay help if requested
                if self.show_help:
                    self._draw_help_overlay(stdscr)
                
                stdscr.refresh()
                
                # Handle input
                key = stdscr.getch()
                
                # Handle timeout (no key pressed) - refresh for live capture
                if key == -1 and self.analyzer.is_live:
                    continue
                
                action = self._handle_input(key)
                
                if action == 'quit':
                    if self.analyzer.is_live:
                        self.analyzer.stop_capture = True
                    break
                    
            except curses.error:
                # Handle terminal resize or other curses errors
                pass
    
    def _draw_header(self, stdscr):
        """Draw the header with application title and view tabs"""
        height, width = stdscr.getmaxyx()
        
        # Title
        title = "StreamLens - Ethernet Traffic Analyzer"
        stdscr.addstr(0, 2, title, curses.A_BOLD)
        
        # Live indicator
        if self.analyzer.is_live:
            live_text = "[LIVE]"
            stdscr.addstr(0, width - len(live_text) - 2, live_text, 
                         curses.A_BOLD | curses.A_BLINK)
        
        # View tabs
        tab_line = 1
        tab_x = 2
        
        # 1: Flow Analysis
        if self.current_view == ViewMode.FLOW_ANALYSIS:
            stdscr.addstr(tab_line, tab_x, "[1: Flow Analysis]", curses.A_REVERSE)
        else:
            stdscr.addstr(tab_line, tab_x, " 1: Flow Analysis ", curses.A_DIM)
        tab_x += 19
        
        # 2: Packet Decoder  
        if self.current_view == ViewMode.PACKET_DECODER:
            stdscr.addstr(tab_line, tab_x, "[2: Packet Decoder]", curses.A_REVERSE)
        else:
            stdscr.addstr(tab_line, tab_x, " 2: Packet Decoder ", curses.A_DIM)
        tab_x += 20
        
        # 3: Statistical Analysis
        if self.current_view == ViewMode.STATISTICAL_ANALYSIS:
            stdscr.addstr(tab_line, tab_x, "[3: Statistical Analysis]", curses.A_REVERSE)
        else:
            stdscr.addstr(tab_line, tab_x, " 3: Statistical Analysis ", curses.A_DIM)
        
        # Draw separator line
        stdscr.addstr(2, 0, "─" * width)
    
    def _draw_status_bar(self, stdscr):
        """Draw status bar with context-sensitive help"""
        height, width = stdscr.getmaxyx()
        status_y = height - 1
        
        # Base controls
        status_text = "[1-3]Views [↑↓]Navigate [Enter]Select [H]Help [Q]Quit"
        
        # Add view-specific controls
        if self.current_view == ViewMode.FLOW_ANALYSIS:
            status_text += " [V]Visualize [D]Decode"
        elif self.current_view == ViewMode.PACKET_DECODER:
            status_text += " [E]Export [C]Copy"
        elif self.current_view == ViewMode.STATISTICAL_ANALYSIS:
            status_text += " [R]Refresh [O]Outliers"
        
        # Add live capture controls
        if self.analyzer.is_live:
            status_text += " [P]Pause"
        
        stdscr.addstr(status_y, 0, status_text[:width-1], curses.A_REVERSE)
    
    def _draw_help_overlay(self, stdscr):
        """Draw help overlay with comprehensive controls"""
        height, width = stdscr.getmaxyx()
        
        # Calculate overlay size
        overlay_height = min(20, height - 4)
        overlay_width = min(80, width - 4)
        start_y = (height - overlay_height) // 2
        start_x = (width - overlay_width) // 2
        
        # Create help window
        help_lines = [
            "StreamLens - Help",
            "",
            "VIEWS:",
            "  1   - Flow Analysis: Visual flow overview and protocol detection",
            "  2   - Packet Decoder: Deep packet inspection and field extraction",
            "  3   - Statistical Analysis: Timing analysis and quality metrics",
            "",
            "NAVIGATION:",
            "  ↑/↓   - Navigate items",
            "  Enter - Select flow/packet",
            "  Tab   - Switch panels (when available)",
            "  PgUp/PgDn - Scroll large lists",
            "",
            "ANALYSIS:",
            "  V - Visualize signals (Flow Analysis)",
            "  D - Deep decode selected flow",
            "  E - Export decoded data",
            "  R - Refresh statistics",
            "  O - Show outlier details",
            "",
            "GENERAL:",
            "  H - Toggle this help",
            "  Q - Quit application",
            "",
            "Press any key to close help..."
        ]
        
        # Draw background
        for y in range(overlay_height):
            stdscr.addstr(start_y + y, start_x, " " * overlay_width, curses.A_REVERSE)
        
        # Draw help content
        for i, line in enumerate(help_lines[:overlay_height-1]):
            if start_y + i < height - 1:
                display_line = line[:overlay_width-2]
                attr = curses.A_REVERSE | curses.A_BOLD if i == 0 else curses.A_REVERSE
                stdscr.addstr(start_y + i, start_x + 1, display_line, attr)
    
    def _handle_input(self, key: int) -> str:
        """Handle keyboard input with view-specific actions"""
        
        # Global controls
        if key == ord('q') or key == ord('Q'):
            return 'quit'
        elif key == ord('h') or key == ord('H'):
            self.show_help = not self.show_help
            return 'help_toggle'
        elif self.show_help:
            # Any key closes help
            self.show_help = False
            return 'help_close'
        
        # View switching
        elif key == ord('1'):
            self.current_view = ViewMode.FLOW_ANALYSIS
            return 'view_change'
        elif key == ord('2'):
            self.current_view = ViewMode.PACKET_DECODER
            return 'view_change'
        elif key == ord('3'):
            self.current_view = ViewMode.STATISTICAL_ANALYSIS
            return 'view_change'
        
        # Delegate to current view
        elif self.current_view == ViewMode.FLOW_ANALYSIS:
            return self.flow_view.handle_input(key, self._get_flows_list())
        elif self.current_view == ViewMode.PACKET_DECODER:
            return self.decoder_view.handle_input(key, self._get_flows_list())
        elif self.current_view == ViewMode.STATISTICAL_ANALYSIS:
            return self.stats_view.handle_input(key, self._get_flows_list())
        
        return 'none'
    
    def _get_flows_list(self):
        """Get prioritized list of flows for analysis"""
        flows_list = list(self.analyzer.flows.values())
        
        # Sort by relevance: enhanced flows first, then by packet count
        flows_list.sort(key=lambda x: (
            x.enhanced_analysis.decoder_type != "Standard",  # Enhanced first
            self.analyzer.statistics_engine.get_max_sigma_deviation(x),  # High outliers
            x.frame_count  # Packet count
        ), reverse=True)
        
        return flows_list
    
    def get_selected_flow(self):
        """Get currently selected flow for cross-view communication"""
        if self.selected_flow_key:
            return self.analyzer.flows.get(self.selected_flow_key)
        return None
    
    def set_selected_flow(self, flow_key):
        """Set selected flow for cross-view communication"""
        self.selected_flow_key = flow_key