"""
Debug dialog "AI Command Center" pro zobrazení a ladění AI requestů/odpovědí.
"""

import xbmcgui
import xbmcaddon
import json
import xbmc
import time
from wcs.ai.UsageTracker import PRICING_TABLES, calculate_cost, format_cost

def is_debug_mode_enabled():
    """Kontroluje, zda je zapnutý debug mód."""
    addon = xbmcaddon.Addon()
    return addon.getSetting("ai_debug_mode") == "true"

def parse_chat_messages(messages):
    """
    Naformátuje seznam zpráv (list of dicts) do čitelného textu pro Visualizer.
    Splits content by newlines to ensure readability in Kodi text box.
    """
    output = ""
    if isinstance(messages, list):
        for msg in messages:
            role = msg.get('role', 'unknown').upper()
            content = msg.get('content', '')
            output += f"[B][COLOR FFFFFF00]{role}:[/COLOR][/B][CR]{content}[CR][CR]"
    elif isinstance(messages, str):
        output = messages
    return output

class AIDebugRequestDialog(xbmcgui.WindowXMLDialog):
    def __init__(self, *args, **kwargs):
        super().__init__(*args)
        self.data_raw = kwargs.get('data_raw', {})
        self.data_text = kwargs.get('data_text', "") # Extrahovaný text nebo zprávy
        self.metadata = kwargs.get('metadata', {})   # {provider, model, latency, ...}
        self.mode = kwargs.get('mode', 'request')    # 'request' or 'response'
        self.on_action_callback = kwargs.get('on_action', None) # (action_id) -> void
        
        # Nová data pro Context View
        self.context_titles = kwargs.get('context_titles', [])
        self.context_limit = kwargs.get('context_limit', None)
        
        self.closed = False
        self.current_view = "visualizer" # visualizer, raw, stats, context

    def onInit(self):
        # Nastavení základních informací do GUI
        self.setProperty('Mode', self.mode.upper())
        provider = self.metadata.get('provider', 'Unknown')
        model = self.metadata.get('model', 'Unknown')
        self.setProperty('Provider', provider)
        self.setProperty('Model', model)
        
        # Zpracování RAW dat do stringu
        try:
            raw_json = json.dumps(self.data_raw, indent=2, ensure_ascii=False)
        except:
            raw_json = str(self.data_raw)
        self.setProperty('Data.Raw', raw_json)
        
        # Zpracování Visualizeru a Labelu Menu
        formatted_text = ""
        sidebar_label = "CHAT VISUALIZER"
        action_label = "ODESLAT"
        
        if self.mode == 'request':
            sidebar_label = "REQUEST DATA"
            action_label = "ODESLAT"
            
            # === STANDARDNÍ FORMÁT OD VŠECH KLIENTŮ ===
            # Klienti posílají messages kde první zpráva s role: system je system prompt
            messages = self.data_raw.get('messages', [])
            
            # Extrahovat system prompt z messages (první message s role: system)
            system_msg = ""
            for msg in messages:
                if msg.get('role') == 'system':
                    system_msg = msg.get('content', '')
                    break
            
            formatted_text = parse_chat_messages(messages)
            xbmc.log(f"[plugin.video.milionar] Request formatted_text length: {len(formatted_text)}, messages count: {len(messages)}", xbmc.LOGINFO)
            
            # System prompt
            if not system_msg:
                system_msg = "Nenalezen žádný System Prompt."
            self.setProperty('Data.Context', system_msg)
            
            # Formatování Context Titles List
            if self.context_titles:
                ctx_list_str = "\n".join(self.context_titles)
            else:
                ctx_list_str = "Žádná kontextová data (seznam titulů) nebyla předána."
            self.setProperty('Data.ContextList', ctx_list_str)
            
            # ContextLimit - předaný nebo fallback z nastavení
            if self.context_limit:
                limit_display = str(self.context_limit)
            else:
                try:
                    limit_display = xbmcaddon.Addon().getSetting('ai_context_history_limit') or "20"
                except:
                    limit_display = "20"
            self.setProperty('ContextLimit', limit_display)
            
        else:
            sidebar_label = "RESPONSE DATA"
            action_label = "OK"
            # U response zobrazujeme hlavně text odpovědi
            formatted_text = self.data_text
            # Pokud není předaný text, zkusíme ho vytáhnout z raw dat
            if not formatted_text and isinstance(self.data_raw, dict):
                try:
                    # OpenAI Chat Completions API (standardní formát)
                    formatted_text = self.data_raw['choices'][0]['message']['content']
                except (KeyError, IndexError, TypeError):
                    try:
                        # OpenAI Responses API formát (nový formát)
                        output = self.data_raw.get('output', [])
                        if output and isinstance(output, list):
                            for evt in output:
                                if evt.get('type') == 'message':
                                    content = evt.get('content', [])
                                    if content and isinstance(content, list):
                                        formatted_text = content[0].get('text', '')
                                        break
                    except (KeyError, IndexError, TypeError):
                        pass
                    
                    if not formatted_text:
                        try:
                            # Google API formát
                            formatted_text = self.data_raw['candidates'][0]['content']['parts'][0]['text']
                        except (KeyError, IndexError, TypeError):
                            formatted_text = "Nelze extrahovat obsah odpovědi z JSON dat."
            
            self.setProperty('Data.Context', "System Context není dostupný v odpovědi.")

        self.setProperty('Data.Visualizer', formatted_text)
        self.setProperty('Sidebar.Label.Visualizer', sidebar_label)
        self.setProperty('ActionLabel', action_label)
        
        # Statistiky - Detailní výpočet
        usage = self.data_raw.get('usage', {})
        
        # Google API Fallback (usageMetadata -> usage)
        if not usage and 'usageMetadata' in self.data_raw:
            meta = self.data_raw['usageMetadata']
            usage = {
                'prompt_tokens': meta.get('promptTokenCount', 0),
                'completion_tokens': meta.get('candidatesTokenCount', 0),
                'total_tokens': meta.get('totalTokenCount', 0)
            }
        
        cost_info = calculate_cost(self._normalize_provider(provider), model, usage)

        in_tokens = cost_info.get('input_tokens', 0)
        cached_tokens = cost_info.get('cached_tokens', 0)
        out_tokens = cost_info.get('output_tokens', 0)
        
        # Fallback: Pokud calculate_cost vrátí 0, zkusíme raw data
        if in_tokens == 0:
            raw_input = usage.get('prompt_tokens') or usage.get('input_tokens') or 0
            if raw_input > 0:
                in_tokens = raw_input
                cached_tokens = 0
                out_tokens = usage.get('completion_tokens') or usage.get('output_tokens') or 0
                xbmc.log(f"[plugin.video.milionar] Metrics Fallback triggered: Input={in_tokens}, Output={out_tokens}", xbmc.LOGINFO)

        total_tokens = in_tokens + cached_tokens + out_tokens
        
        self.setProperty('Stats.InputTokens', str(in_tokens))
        self.setProperty('Stats.CachedTokens', str(cached_tokens))
        self.setProperty('Stats.OutputTokens', str(out_tokens))
        self.setProperty('Stats.TotalTokens', str(total_tokens))
        
        # Reasoning Tokens (pokud jsou k dispozici v details)
        reasoning_tokens = 0
        if 'completion_tokens_details' in usage:
             reasoning_tokens = usage['completion_tokens_details'].get('reasoning_tokens', 0)
        self.setProperty('Stats.ReasoningTokens', str(reasoning_tokens))

        # Latence a Rychlost
        latency = self.metadata.get('latency', 0)
        self.setProperty('Stats.Latency', f"{latency:.2f}s")
        
        speed = 0
        if latency > 0 and out_tokens > 0:
            speed = out_tokens / latency
        self.setProperty('Stats.Speed', f"{speed:.1f} T/s")
        
        # Náklady - používáme format_cost pro respektování nastavení měny
        addon = xbmcaddon.Addon()
        input_cost = cost_info.get('input_cost', 0)
        cached_cost = cost_info.get('cached_input_cost', 0)
        output_cost = cost_info.get('output_cost', 0)
        total_cost = cost_info.get('total_cost', 0)

        self.setProperty('Stats.InputCost', format_cost(input_cost, addon))
        self.setProperty('Stats.CachedCost', format_cost(cached_cost, addon))
        self.setProperty('Stats.OutputCost', format_cost(output_cost, addon))
        self.setProperty('Stats.TotalCost', format_cost(total_cost, addon))
        
        # Calculate SAVINGS from Caching
        # Logic: (Cached Tokens * Input Price) - (Cached Tokens * Cached Price)
        # However, we can just assume Input Price is higher.
        # Simple way: Check pricing table or just differentiate cost.
        # Savings = (Cost if these tokens were normal input) - (Actual cost as cached)
        # We don't have the raw price per token here easily without re-querying UsageTracker.
        # Let's use a simpler heuristic or update UsageTracker usage.
        # BETTER: UsageTracker calculate_cost returns a dict. Let's see if we can deduce it.
        # Actually, simpler: Savings = (cached_tokens * (input_price_per_token - cached_price_per_token))
        # Since I cannot see the price table here easily, I will estimate based on the ratio if available, 
        # OR simply display the Cached Cost and let user see it's low.
        # WAIT, user asked for "kolik cached ušetří".
        # Let's import PRICING_TABLES from UsageTracker to start of file if not there (it is).
        
        savings = 0.0
        savings_percent = 0.0
        
        if cached_tokens > 0:
             # Find provider/model pricing
             p_key = self._normalize_provider(provider)
             pricing = PRICING_TABLES.get(p_key, {}).get(model)
             if not pricing: 
                 # Fallback to wildcard or default
                 pricing = PRICING_TABLES.get(p_key, {}).get('*', {})
             
             if pricing:
                 input_price = pricing.get('input', 0)
                 cached_price = pricing.get('cached_input', 0) # Often 0 or lower
                 
                 # Cost if not cached
                 potential_cost = (cached_tokens / 1_000_000) * input_price
                 
                 # Actual cost
                 actual_cached_cost = (cached_tokens / 1_000_000) * cached_price
                 
                 savings = potential_cost - actual_cached_cost
                 if potential_cost > 0:
                     savings_percent = (savings / potential_cost) * 100

        self.setProperty('Stats.SavingsCost', format_cost(savings, addon))
        self.setProperty('Stats.SavingsPercent', f"{savings_percent:.1f}%")

        # Finish Reason
        finish_reason = "unknown"
        if isinstance(self.data_raw, dict) and 'choices' in self.data_raw:
             try:
                 finish_reason = self.data_raw['choices'][0]['finish_reason']
             except: pass
        self.setProperty('Stats.FinishReason', str(finish_reason).upper())
        # Nastavení defaultního pohledu a fokusu
        self.setFocusId(8001)
        self.update_view('visualizer')
        
        # === UI TWEAKS BASED ON MODE ===
        if self.mode == 'response':
            # 1. Upravit tlačítka akcí (Send/Cancel -> Single OK)
            self.getControl(8001).setLabel('  OK')       # Přejmenovat ODESLAT na OK
            self.getControl(8002).setVisible(False)     # Skrýt ZRUŠIT
            
            # 2. Skrýt SYSTEM CONTEXT a CONTEXT TITLES (jsou jen pro request)
            self.getControl(9003).setVisible(False)
            self.getControl(9005).setVisible(False)
            
        xbmc.log(f"[plugin.video.milionar] Dialog initialized, CurrentView: visualizer, Mode: {self.mode}", xbmc.LOGINFO)

    def _normalize_provider(self, provider_name):
        """Převede název providera na klíč používaný v UsageTracker."""
        p = provider_name.lower()
        if 'openai' in p: return 'openai'
        if 'anthropic' in p or 'claude' in p: return 'anthropic'
        if 'google' in p or 'gemini' in p: return 'google'
        if 'mistral' in p: return 'mistral'
        if 'groq' in p: return 'groq'
        return p 

    def update_view(self, view_name):
        self.current_view = view_name
        self.setProperty('CurrentView', view_name)
        # XML bude reagovat na String.IsEqual(Window.Property(CurrentView), 'visualizer') atd.

    def onFocus(self, controlId):
        # Sidebar navigace - okamžitý náhled
        if controlId == 9001:
            self.update_view('visualizer')
        elif controlId == 9002:
            self.update_view('raw')
        elif controlId == 9003:
            self.update_view('context')
        elif controlId == 9004:
            self.update_view('stats')
        elif controlId == 9005: # Nové tlačítko pro Context Titles (9004 je obsazeno systémovým kontextem)
            self.update_view('context_titles')
        # Tlačítka dole (Odeslat/Zrušit) zobrazí Visualizer (první položka)
        # Tlačítka dole (Odeslat/Zrušit) zobrazí Visualizer (první položka)
        elif controlId == 8001 or controlId == 8002:
             self.update_view('visualizer')

    def onClick(self, controlId):
        try:
            # Akce tlačítka pro odeslání/zavření
            if controlId == 8001: # Odeslat / OK
                if self.on_action_callback:
                    # Callback VŽDY před close(), abychom měli jistotu, že se provede
                    action = 'send' if self.mode == 'request' else 'continue'
                    self.on_action_callback(action)
                
                self.closed = True
                self.close()
                
            elif controlId == 8002: # Zrušit / Cancel
                if self.on_action_callback:
                    self.on_action_callback('cancel')
                
                self.closed = True
                self.close()
                
        except Exception as e:
            xbmc.log(f"[plugin.video.milionar] Error in AIDebugRequestDialog.onClick: {e}", xbmc.LOGERROR)
            self.close() # Vždy zavřít při chybě
        
        # Sidebar click logic removed to support pure arrow navigation
        # Navigation is handled by XML <onright> tags


    def onAction(self, action):
        # HARD FORCE CLOSE on Back/Escape/PreviousMenu
        # 10 = ACTION_PREVIOUS_MENU (ESC)
        # 92 = ACTION_NAV_BACK (Back on remote)
        # 9  = ACTION_PARENT_DIR
        if action.getId() in (9, 10, 92): 
            self.closed = True
            self.close()
            if self.on_action_callback:
                self.on_action_callback('cancel')

# Helper funkce pro volání dialogu
def show_api_request_debug(provider, model, request_data, context_titles=None, context_limit=None, force=False):
    if not force and not is_debug_mode_enabled(): return True
    
    result = {'action': 'cancel'}
    def callback(action):
        result['action'] = action
        
    metadata = {'provider': provider, 'model': model, 'latency': 0}
    
    _show_dialog(request_data, None, metadata, 'request', callback, context_titles=context_titles, context_limit=context_limit)
    
    return result['action'] == 'send'

def show_api_response_debug(provider, model, response_data, response_text=None, latency=0, force=False):
    if not force and not is_debug_mode_enabled(): return True
    
    result = {'action': 'cancel'}
    def callback(action):
        result['action'] = action
        
    metadata = {'provider': provider, 'model': model, 'latency': latency}
    
    _show_dialog(response_data, response_text, metadata, 'response', callback)
    
    return result['action'] == 'continue'

def show_api_error_debug(provider, model, error_message, error_data=None, force=False):
    if not force and not is_debug_mode_enabled(): return
    
    # Pro error použijeme zjednodušený "response" mód
    metadata = {'provider': provider, 'model': model, 'latency': 0}
    data = {'error': error_message, 'details': error_data}
    
    def callback(action): pass
    _show_dialog(data, error_message, metadata, 'response', callback)

def _show_dialog(data_raw, data_text, metadata, mode, callback, **kwargs):
    addon = xbmcaddon.Addon()
    xml_path = 'ai/DialogAIDebugRequest.xml' # Cesta relativní k resources/skins/Default/1080i/
    
    # Dialog se musí vytvořit s kwargs
    try:
        dialog = AIDebugRequestDialog(
            xml_path, 
            addon.getAddonInfo('path'), 
            'Default', 
            '1080i',
            data_raw=data_raw,
            data_text=data_text,
            metadata=metadata,
            mode=mode,
            on_action=callback,
            **kwargs
        )
        dialog.doModal()
        del dialog
    except Exception as e:
        xbmc.log(f"[plugin.video.milionar] Chyba při otevírání {xml_path}: {e}", xbmc.LOGERROR)
        xbmcgui.Dialog().ok("Chyba Debuggeru", str(e))