import xbmc
import xbmcgui
import xbmcaddon
import xbmcplugin
import json
import threading
import requests
import os
from datetime import datetime
from wcs.ai import AIHandler as ai_handler
from wcs.metadata.TMDbClient import get_tmdb_api_key
from wcs import utils
from wcs.ui import UI
from wcs.webshare import WebshareClient as webshare_api


class AIRecommendationPromptBuilder:
    """
    Helper třída pro skládání system a user promptů pro AI chat doporučování.
    System prompt je session-stable (nastaví se na začátku a nemění se).
    User message se mění s každou inferencí.
    """
    
    def __init__(self, media_type="movie", context=None):
        self.addon = xbmcaddon.Addon()
        self.media_type = media_type
        self.context = context
        self._system_prompt = None  # Cache pro session-stable system prompt
        
    def _load_template(self, filename):
        """Načte šablonu promptu ze souboru."""
        try:
            addon_dir = self.addon.getAddonInfo('path')
            prompt_file = os.path.join(addon_dir, 'resources', 'prompts', 'ai_recommendations', filename)
            if os.path.exists(prompt_file):
                with open(prompt_file, 'r', encoding='utf-8') as f:
                    return f.read()
            xbmc.log(f"[plugin.video.milionar] Prompt file not found: {prompt_file}", level=xbmc.LOGWARNING)
        except Exception as e:
            xbmc.log(f"[plugin.video.milionar] Error loading prompt file: {e}", level=xbmc.LOGERROR)
        return None
        
    def _get_media_label(self):
        """Vrací český label pro typ média."""
        if self.context:
            c_type = self.context.get('type')
            if c_type in ['my_mixed_collection', 'recently_played', 'favorite_actors', 'favorite_directors', 'favorite_writers']:
                return "filmů a seriálů"
            elif c_type in ['my_collections', 'collection']:
                return "filmových kolekcí"
        return "filmů" if self.media_type == "movie" else "seriálů"
    
    def _is_mixed_content(self):
        """Zjistí, jestli jde o mix filmů a seriálů."""
        if self.context:
            c_type = self.context.get('type')
            return c_type in ['my_mixed_collection', 'recently_played', 'favorite_actors', 'favorite_directors', 'favorite_writers']
        return False
    
    def _get_media_type_instruction(self):
        """Vrací instrukce pro typ média."""
        if self.context and self.context.get('type') in ['my_collections', 'collection']:
            return (
                "REŽIM KOLEKCE:\n"
                "Doporučuješ FILMOVÉ KOLEKCE a SÁGY (trilogie, franšízy), ne jednotlivé filmy.\n"
                "Zaměř se na ucelené série jako 'Pán prstenů kolekce', 'Marvel kolekce', atd."
            )
        elif self._is_mixed_content():
            return (
                "REŽIM MIX:\n"
                "Doporučuješ FILMY i SERIÁLY současně. Nabízej rozmanitý mix podle vkusu uživatele."
            )
        elif self.media_type == "series":
            return (
                "REŽIM SERIÁLY:\n"
                "Doporučuješ výhradně SERIÁLY."
            )
        else:
            return (
                "REŽIM FILMY:\n"
                "Doporučuješ výhradně FILMY."
            )
    
    def _get_json_format(self):
        """Vrací JSON formát podle typu média."""
        if self._is_mixed_content():
            return '''{
  "message": "Tvá otázka nebo komentář (max 2-3 věty)",
  "buttons": [
    {"label": "Text tlačítka", "value": "Odpověď která se odešle"}
  ],
  "recommendations": [
    {"title": "Český název", "year": "YYYY", "type": "movie nebo tv", "original_title": "Originální název"}
  ]
}'''
        else:
            return '''{
  "message": "Tvá otázka nebo komentář (max 2-3 věty)",
  "buttons": [
    {"label": "Text tlačítka", "value": "Odpověď která se odešle"}
  ],
  "recommendations": [
    {"title": "Český název", "year": "YYYY", "original_title": "Originální název"}
  ]
}'''
    
    def _get_json_type_rule(self):
        """Vrací pravidlo pro type pole (jen pro mix)."""
        if self._is_mixed_content():
            return "- Pole 'type' MUSÍ být buď 'movie' (pro filmy) nebo 'tv' (pro seriály). SPRÁVNĚ URČI TYP.\n"
        return ""
    
    def build_system_prompt(self, force_rebuild=False):
        """
        Sestaví session-stable system prompt.
        Obsahuje: role definition, časový kontext, temporální inteligenci, pravidla dialogu.
        """
        if self._system_prompt and not force_rebuild:
            return self._system_prompt
            
        template = self._load_template('system_prompt.txt')
        if not template:
            # Fallback
            self._system_prompt = f"Jsi asistent pro {self._get_media_label()}. Odpověz v JSON formátu."
            return self._system_prompt
        
        recomm_count = int(self.addon.getSetting('ai_recommendation_count') or 11)
        media_label = self._get_media_label()
        media_type_instruction = self._get_media_type_instruction()
        json_format = self._get_json_format()
        json_type_rule = self._get_json_type_rule()
        
        # Časový kontext pro temporální inteligenci
        now = datetime.now()
        current_time_str = now.strftime("%d.%m.%Y %H:%M (%A)")
        
        # Region a jazyk
        try:
            user_lang = xbmc.getLanguage(xbmc.ISO_639_1)
        except:
            user_lang = 'cs'
        try:
            if hasattr(xbmc, 'ISO_3166_1'):
                user_region = xbmc.getRegion(xbmc.ISO_3166_1)
            else:
                user_region = user_lang.upper()
        except:
            user_region = 'CZ'
        
        # Nahradit {json_format} markerem (obsahuje {})
        prompt = template.replace('{json_format}', '<<<JSON_FORMAT>>>')
        prompt = prompt.format(
            current_time_str=current_time_str,
            user_region=user_region,
            user_lang=user_lang,
            media_label=media_label,
            media_type_instruction=media_type_instruction,
            recomm_count=recomm_count,
            json_type_rule=json_type_rule
        )
        prompt = prompt.replace('<<<JSON_FORMAT>>>', json_format)
        
        self._system_prompt = prompt
        return self._system_prompt
    
    def build_messages(self, chat_history, context_instruction=""):
        """
        Sestaví pole messages pro multi-turn API.
        Vrací nativní formát zpráv pro LLM API.
        
        Args:
            chat_history: Historie konverzace [{"role": "user/assistant", "content": "..."}]
            context_instruction: Volitelná kontextová instrukce
            
        Returns:
            list: Pole messages [{"role": "user/assistant", "content": "..."}]
        """
        messages = []
        
        # Error handling pro prázdnou historii
        if not chat_history:
            return messages
        
        # Přidat celou historii konverzace
        for i, msg in enumerate(chat_history):
            # Normalizovat role name pro API (assistant místo AI)
            role = "assistant" if msg['role'] == "assistant" else "user"
            content = msg['content']
            
            # Pokud je context instruction a toto je PRVNÍ user zpráva,
            # NAHRADÍME obsah context instruction (ne přidáváme k němu)
            if i == 0 and role == "user" and context_instruction:
                content = context_instruction
            
            messages.append({
                "role": role,
                "content": content
            })
        
        return messages

class AIChatRecommendationDialog(xbmcgui.WindowXMLDialog):
    def __init__(self, xml_filename, addon_path, *args, **kwargs):
        super(AIChatRecommendationDialog, self).__init__(xml_filename, addon_path)
        self.addon = xbmcaddon.Addon()
        self.history = [] # List of {"role": "...", "content": "..."}
        self.media_type = None # "movie" or "series"
        self.tmdb_results = []
        self._thinking_stop = threading.Event()
        self._thinking_thread = None
        self._dot_count = 0
        self.context = kwargs.get('context', None)
        # Cache pro preview detaily (klíč = tmdb_id)
        self._preview_cache = {}
        self._last_preview_id = None
        # Prompt builder pro sestavení system a user promptů
        self._prompt_builder = None  # Inicializuje se v onInit po nastavení media_type
        
    def onInit(self):
        # Pokud máme kontext, přeskočíme úvodní výběr
        if self.context:
            self.media_type = self.context.get('media_type', 'movie')
            
            # Zobrazit uživatelskou "tichou" zprávu nebo uvítání
            welcome_msg = "Analyzuji váš výběr..."
            self.append_chat_message("AI", welcome_msg)
            
            # Simulovat první zprávu uživatele (která se odešle AI)
            initial_user_msg = self.context.get('initial_message')
            
            if not initial_user_msg:
                c_type = self.context.get('type')
                c_val = self.context.get('value')
                if self.media_type == "movie":
                    media_label = "filmy"
                elif self.media_type == "collection":
                    media_label = "filmové kolekce"
                else:
                    media_label = "seriály"
                
                if c_type == 'genre':
                    initial_user_msg = f"Doporuč mi nejlepší {media_label} v žánru {c_val}."
                elif c_type == 'person':
                    p_type = self.context.get('person_type', 'osoba') # actor/director...
                    role_map = {'actor': 'kde hraje', 'director': 'od režiséra', 'writer': 'od scenáristy'}
                    role_str = role_map.get(p_type, 'od')
                    initial_user_msg = f"Doporuč mi {media_label} {role_str} {c_val}."
                elif c_type in ['favorite_actors', 'favorite_directors', 'favorite_writers']:
                    what_map = {'favorite_actors': 'oblíbených herců', 'favorite_directors': 'oblíbených režisérů', 'favorite_writers': 'oblíbených scenáristů'}
                    what = what_map.get(c_type, 'oblíbených osobností')
                    initial_user_msg = f"Doporuč mi {media_label} na základě mých {what}."
                elif c_type == 'country':
                    initial_user_msg = f"Doporuč mi {media_label} ze země {c_val}."
                elif c_type == 'year':
                    initial_user_msg = f"Doporuč mi {media_label} z roku {c_val}."
                elif c_type == 'my_mixed_collection':
                    initial_user_msg = "Doporuč mi filmy nebo seriály podle mé celé sbírky."
                elif c_type == 'my_collections':
                    initial_user_msg = "Doporuč mi filmové kolekce a ságy, které by se mi mohly líbit podle mých uložených kolekcí."
                elif c_type == 'collection':
                    initial_user_msg = f"Doporuč mi {media_label} z kolekce {c_val}."
                elif c_type == 'category':
                    initial_user_msg = f"Doporuč mi {media_label} z kategorie {c_val}."
                elif c_type == 'section_root':
                    # Uživatel klikl na "Poradit se s AI" přímo v sekci Filmy nebo Seriály
                    # Volá stejnou funkci jako set_mode button v AI chat rootu
                    self._start_simple_media_conversation()
                    return
                else:
                    initial_user_msg = f"Doporuč mi {media_label} na základě aktuálního výběru."

            self.history.append({"role": "user", "content": initial_user_msg})
            
            # Inicializovat prompt builder pro tento kontext
            self._prompt_builder = AIRecommendationPromptBuilder(self.media_type, self.context)
            
            # IHNED start AI conversation
            self._start_ai_conversation(is_initial_context=True)
            return

        # Standardní flow bez kontextu
        # Initial Welcome Message
        welcome_msg = "Co chcete doporučit?"
        self.append_chat_message("AI", welcome_msg)
        
        # Initial Buttons - CHOOSE TYPE FIRST
        self.update_buttons([
            {"label": "Filmy", "value": "set_mode:movie"},
            {"label": "Seriály", "value": "set_mode:series"}
        ])
        
        # Clear recommendations
        self.getControl(2000).reset()
        
        # Ensure Input is hidden initially
        self.clearProperty('WCS.AIChat.ShowInput')
        
        # Set focus on buttons list, NOT input field
        self.setFocusId(4000)

    def append_chat_message(self, sender, text):
        """Append message to chat history textbox."""
        history_control = self.getControl(1000)
        current_text = history_control.getText()
        
        # Format: Sender: Message
        # Using colors
        if sender == "AI":
            line = f"[COLOR blue]AI:[/COLOR] {text}\n"
        else:
            line = f"[COLOR orange]Ty:[/COLOR] {text}\n"
            
        new_text = current_text + line
        history_control.setText(new_text)
        
        # Auto-scroll not easily possible on TextBox without tricky calculations or ensuring 'pagecontrol' works.
        # But we set pagecontrol to scrollbar in XML, so user can scroll.\n        
    def update_buttons(self, buttons):
        """Update dynamic buttons list."""
        # buttons: list of dicts {"label": str, "value": str}
        list_control = self.getControl(4000)
        list_control.reset()
        
        for btn in buttons:
            item = xbmcgui.ListItem(label=btn['label'])
            item.setProperty('value', btn['value'])
            list_control.addItem(item)
            
    def onClick(self, controlId):
        # Action Buttons (Dynamic)
        if controlId == 4000:
            list_control = self.getControl(4000)
            item = list_control.getSelectedItem()
            if not item: return
            
            val = item.getProperty('value')
            label = item.getLabel()
            
            # Handle Local Mode Switching
            if val.startswith("set_mode:"):
                self.media_type = val.split(":")[1]
                self._start_simple_media_conversation()
            else:
                # Send button value (if exists) or label as user text
                # Value obsahuje specifickou instrukci pro LLM, label je jen pro uživatele
                text_for_llm = val if val else label
                # V UI zobrazit label, do LLM poslat value
                self.handle_user_input(text_for_llm, display_text=label)
                
        # Send Text Button
        elif controlId == 3001:
            input_control = self.getControl(3000)
            text = input_control.getText()
            if text:
                input_control.setText("") # Clear input
                self.handle_user_input(text)
                
        # Recommendations Panel
        elif controlId == 2000:
            self.handle_recommendation_click()
            
        # Preview Action Buttons
        elif controlId == 6100:
            self._handle_preview_action_click()
    
    def onAction(self, action):
        """Handle navigation actions for preview updates."""
        action_id = action.getId()
        
        # Navigace v seznamu doporučení - aktualizovat preview
        if action_id in (xbmcgui.ACTION_MOVE_LEFT, xbmcgui.ACTION_MOVE_RIGHT):
            focused_id = self.getFocusId()
            if focused_id == 2000:
                # Po malém zpoždění aktualizovat preview (dát čas na změnu výběru)
                import time
                time.sleep(0.05)
                self._update_preview_for_current_item()
        
        # Zavření dialogu
        elif action_id in (xbmcgui.ACTION_PREVIOUS_MENU, xbmcgui.ACTION_NAV_BACK):
            # Pokud jsme na tlačítkách preview, vrátit fokus na seznam (ne zavřít)
            if self.getFocusId() == 6100:
                self.setFocusId(2000)
                return
            
            self._clear_preview_properties()
            self.close()
    
    def onFocus(self, controlId):
        """Handle focus changes - populate preview on recommendation hover."""
        if controlId == 2000:
            # Focus na panel doporučení - aktualizovat preview
            self._update_preview_for_current_item()
        elif controlId != 6100 and controlId != 6200:
            # Opuštění panelu doporučení - skrýt preview
            self._clear_preview_properties()
    
    def _update_preview_for_current_item(self):
        """Načte a zobrazí preview pro aktuálně focusovaný titul."""
        try:
            list_control = self.getControl(2000)
            item = list_control.getSelectedItem()
            if not item:
                self._clear_preview_properties()
                return
            
            tmdb_id = item.getProperty('tmdb_id')
            if not tmdb_id:
                self._clear_preview_properties()
                return
                
            # Pokud je to stejný titul, nic nedělej
            if tmdb_id == self._last_preview_id:
                return
            
            # Při změně titulu: nejdřív skrýt overlay (slide dolů), pak zobrazit nová data (slide nahoru)
            is_title_change = self._last_preview_id is not None
            
            # Uložit data pro použití po animaci
            media_type = item.getProperty('media_type') or self.media_type or 'movie'
            title = item.getProperty('title') or item.getLabel()
            year = item.getProperty('year') or ''
            poster = item.getArt('poster') or ''
            
            if is_title_change:
                # Skrýt overlay (animace dolů)
                self.clearProperty('WCS.AIPreview.State')
                
                def delayed_update():
                    import time
                    time.sleep(0.25)
                    self._clear_preview_properties()
                    self._apply_new_preview(tmdb_id, media_type, title, year, poster)
                
                threading.Thread(target=delayed_update, daemon=True).start()
                
            else:
                # První zobrazení - rovnou nastavit
                self._apply_new_preview(tmdb_id, media_type, title, year, poster)
                
        except Exception as e:
            xbmc.log(f"[plugin.video.milionar] Preview update error: {e}", xbmc.LOGERROR)
    
    def _apply_new_preview(self, tmdb_id, media_type, title, year, poster):
        """Nastaví nová preview data a spustí načtení z TMDb."""
        self._last_preview_id = tmdb_id
        
        # Nastavit základní properties (spustí Visible slide animaci)
        self.setProperty('WCS.AIPreview.Title', title)
        self.setProperty('WCS.AIPreview.Year', year)
        self.setProperty('WCS.AIPreview.Poster', poster)
        self.setProperty('WCS.AIPreview.MediaTypeLabel', 'Film' if media_type == 'movie' else 'Seriál')
        
        # Naplnit akční tlačítka
        self._populate_preview_actions(media_type, tmdb_id, title, year)
        
        # Načíst rozšířená data z cache nebo API
        if tmdb_id in self._preview_cache:
            self._apply_cached_preview_data(self._preview_cache[tmdb_id])
        else:
            # Vymazat staré rozšířené properties
            self.clearProperty('WCS.AIPreview.State') # Skrýt overlay
            self.clearProperty('WCS.AIPreview.Fanart')
            self.clearProperty('WCS.AIPreview.InfoBlock')
            self.clearProperty('WCS.AIPreview.IsCompact')
            self.clearProperty('WCS.AIPreview.Plot')
            # Načíst data v pozadí
            threading.Thread(target=self._fetch_preview_details, args=(tmdb_id, media_type)).start()
    
    def _clear_preview_properties(self):
        """Vymaže všechny preview properties."""
        props = ['Title', 'Year', 'Poster', 'Fanart', 'InfoBlock', 'Plot', 'IsCompact', 'State']
        for prop in props:
            self.clearProperty(f'WCS.AIPreview.{prop}')
        self._last_preview_id = None
    
    def _fetch_preview_details(self, tmdb_id, media_type):
        """Načte rozšířené detaily z TMDb API."""
        try:
            api_key = get_tmdb_api_key()
            endpoint = 'movie' if media_type == 'movie' else 'tv'
            url = f'https://api.themoviedb.org/3/{endpoint}/{tmdb_id}'
            params = {'api_key': api_key, 'language': 'cs-CZ', 'append_to_response': 'credits'}
            
            resp = requests.get(url, params=params, timeout=5)
            if resp.status_code == 200:
                data = resp.json()
                
                # Připravit cache data
                cache_data = {
                    'rating': f"{data.get('vote_average', 0):.1f}/10" if data.get('vote_average') else '',
                    'runtime': f"{data.get('runtime', 0)} min" if media_type == 'movie' and data.get('runtime') else '',
                    'genre': ', '.join([g['name'] for g in data.get('genres', [])[:3]]),
                    'plot': data.get('overview', ''),
                    'poster': f"https://image.tmdb.org/t/p/w500{data.get('poster_path')}" if data.get('poster_path') else '',
                    'fanart': f"https://image.tmdb.org/t/p/w1280{data.get('backdrop_path')}" if data.get('backdrop_path') else '',
                    'tagline': data.get('tagline', ''),
                }
                
                # Pro seriály: počet sezón a STATUS
                if media_type != 'movie':
                    num_seasons = data.get('number_of_seasons', 0)
                    runtime_parts = []
                    if num_seasons:
                        runtime_parts.append(f"{num_seasons} sezón")
                    
                    # Status seriálu
                    status = data.get('status', '')
                    if status == 'Returning Series':
                        runtime_parts.append("[COLOR green]Pokračuje[/COLOR]")
                    elif status in ['Ended', 'Canceled']:
                        runtime_parts.append("[COLOR red]Ukončen[/COLOR]")
                        
                    cache_data['runtime'] = "  |  ".join(runtime_parts)
                
                # Režie/Tvůrci
                credits = data.get('credits', {})
                if media_type == 'movie':
                    directors = [c['name'] for c in credits.get('crew', []) if c.get('job') == 'Director'][:2]
                    cache_data['director'] = f"Režie: {', '.join(directors)}" if directors else ''
                else:
                    creators = [c['name'] for c in data.get('created_by', [])][:2]
                    cache_data['director'] = f"Tvůrci: {', '.join(creators)}" if creators else ''
                
                # Sestavit formátovaný řádek metadat (Rating | Runtime | Genre)
                meta_parts = []
                if cache_data['rating']:
                    meta_parts.append(f"[COLOR FF0099FF]{cache_data['rating']}[/COLOR]")
                if cache_data['runtime']:
                    meta_parts.append(cache_data['runtime'])
                if cache_data['genre']:
                    meta_parts.append(cache_data['genre'])
                
                cache_data['metadata_line'] = "  [COLOR grey]|[/COLOR]  ".join(meta_parts)
                
                # Sestavit kompletní InfoBlock (Tagline + Metadata + Režie)
                info_lines = []
                # 1. Tagline (kurzíva, světle šedá)
                if cache_data['tagline']:
                    info_lines.append(f"[COLOR FFDDDDDD][I]{cache_data['tagline']}[/I][/COLOR]")
                
                # 2. Metadata (Rating | Runtime | Genre)
                if cache_data['metadata_line']:
                    info_lines.append(cache_data['metadata_line'])
                
                # 3. Režie (šedá)
                if cache_data['director']:
                    # director string už obsahuje "Režie: ...", jen obarvíme
                     info_lines.append(f"[COLOR grey]{cache_data['director']}[/COLOR]")

                cache_data['info_block'] = "[CR]".join(info_lines)

                # Uložit do cache
                self._preview_cache[tmdb_id] = cache_data
                
                # Flag pro kompaktní layout (pokud chybí tagline, posuneme tlačítka nahoru)
                # Tagline je prázdný string, pokud není
                cache_data['is_compact'] = "true" if not cache_data.get('tagline') else ""
                
                # Aplikovat pokud je stále správný titul
                if self._last_preview_id == tmdb_id:
                    self._apply_cached_preview_data(cache_data)
                    
        except Exception as e:
            xbmc.log(f"[plugin.video.milionar] Preview fetch error: {e}", xbmc.LOGERROR)
    
    def _apply_cached_preview_data(self, data):
        """Aplikuje cache data na preview properties."""
        self.setProperty('WCS.AIPreview.Rating', data.get('rating', ''))
        self.setProperty('WCS.AIPreview.Runtime', data.get('runtime', ''))
        self.setProperty('WCS.AIPreview.Genre', data.get('genre', ''))
        self.setProperty('WCS.AIPreview.Director', data.get('director', ''))
        self.setProperty('WCS.AIPreview.Plot', data.get('plot', ''))
        if data.get('poster'):
            self.setProperty('WCS.AIPreview.Poster', data['poster'])
        if data.get('fanart'):
            self.setProperty('WCS.AIPreview.Fanart', data['fanart'])
        self.setProperty('WCS.AIPreview.InfoBlock', data.get('info_block', ''))
        
        # Nastavit compact mode property (pro XML animaci)
        if data.get('is_compact') == "true":
            self.setProperty('WCS.AIPreview.IsCompact', "true")
        else:
            self.clearProperty('WCS.AIPreview.IsCompact')
            
        # Zobrazit overlay (spustí Slide Up animaci)
        self.setProperty('WCS.AIPreview.State', 'Show')
    
    def _populate_preview_actions(self, media_type, tmdb_id, title, year):
        """Naplní akční tlačítka podle typu média."""
        try:
            list_control = self.getControl(6100)
            list_control.reset()
            
            if media_type == 'movie':
                actions = [
                    {'label': 'Přehrát', 'action': 'play'},
                    {'label': 'Detaily', 'action': 'details'},
                    {'label': 'Moje filmy', 'action': 'add_list'},
                    {'label': 'Knihovna', 'action': 'add_library'},
                    {'label': 'Podobné', 'action': 'similar'},
                ]
            elif media_type in ['series', 'tv']:
                actions = [
                    {'label': 'Detaily', 'action': 'details'},
                    {'label': 'Sezóny', 'action': 'seasons'},
                    {'label': 'Moje seriály', 'action': 'add_list'},
                    {'label': 'Knihovna', 'action': 'add_library'},
                    {'label': 'Podobné', 'action': 'similar'},
                ]
            else:  # collection
                actions = [
                    {'label': 'Filmy', 'action': 'collection_movies'},
                    {'label': 'Moje filmy', 'action': 'add_list'},
                    {'label': 'Knihovna', 'action': 'add_library'},
                ]
            
            for act in actions:
                item = xbmcgui.ListItem(label=act['label'])
                item.setProperty('action', act['action'])
                item.setProperty('tmdb_id', str(tmdb_id))
                item.setProperty('title', title)
                item.setProperty('year', year)
                item.setProperty('media_type', media_type)
                list_control.addItem(item)
                
        except Exception as e:
            xbmc.log(f"[plugin.video.milionar] Preview actions error: {e}", xbmc.LOGERROR)
    
    def _handle_preview_action_click(self):
        """Zpracuje kliknutí na akční tlačítko v preview."""
        try:
            list_control = self.getControl(6100)
            item = list_control.getSelectedItem()
            if not item:
                return
            
            action = item.getProperty('action')
            tmdb_id = item.getProperty('tmdb_id')
            title = item.getProperty('title')
            year = item.getProperty('year')
            media_type = item.getProperty('media_type')
            
            if action == 'play':
                # Přehrát film
                cache_data = self._preview_cache.get(tmdb_id, {})
                plot = cache_data.get('plot', '')
                poster = self.getProperty('WCS.AIPreview.Poster')
                from wcs.utils import search_and_play_movie
                search_and_play_movie(title, year, plot, poster, '', '', '', '', '', self.addon)
                
            elif action == 'details':
                # Zobrazit WCS detaily
                m_type = 'tv' if media_type in ['series', 'tv'] else 'movie'
                url = f"plugin://{self.addon.getAddonInfo('id')}?action=show_wcs_details&media_type={m_type}&tmdb_id={tmdb_id}"
                xbmc.executebuiltin(f"RunPlugin({url})")
                
            elif action == 'seasons':
                # Zobrazit sezóny seriálu
                from urllib.parse import quote_plus
                url = f"plugin://{self.addon.getAddonInfo('id')}?action=display_series_seasons&series_id={tmdb_id}&name={quote_plus(title)}"
                self.close()
                xbmc.executebuiltin(f'AlarmClock(OpenSeasons,Container.Update({url}),00:01,silent)')
                
            elif action == 'add_list':
                # Přidat do seznamu
                if media_type == 'movie':
                    from wcs.ui.UI import add_movie_item_to_list
                    add_movie_item_to_list(self.addon, tmdb_id, title)
                else:
                    from wcs.ui.UI import add_series_item_to_list
                    add_series_item_to_list(self.addon, tmdb_id, title)
                    
            elif action == 'add_library':
                # Přidat do knihovny Kodi
                from wcs.library import LibraryManager as library
                lib_media_type = 'movie' if media_type == 'movie' else 'series'
                id_key = 'movie_id' if media_type == 'movie' else 'series_id'
                library.check_settings_and_add_item({'media_type': lib_media_type, id_key: tmdb_id}, self.addon)
                
            elif action == 'similar':
                # Inspirovat se podobnými
                inspiration_text = f"Najdi podobné {'filmy' if media_type == 'movie' else 'seriály'} jako: {title} ({year})"
                # Skrýt overlay a fokus na chat, aby byla vidět odpověď
                self._clear_preview_properties()
                self.setFocusId(4000)
                self.handle_user_input(inspiration_text)
                
            elif action == 'collection_movies':
                # Zobrazit filmy v kolekci
                from urllib.parse import quote_plus
                url = f"plugin://{self.addon.getAddonInfo('id')}?action=list_collection_movies&collection_id={tmdb_id}&collection_name={quote_plus(title)}"
                xbmc.executebuiltin(f"Container.Update({url})")
                
        except Exception as e:
            xbmc.log(f"[plugin.video.milionar] Preview action error: {e}", xbmc.LOGERROR)
    
    def _start_simple_media_conversation(self):
        """
        Spustí jednoduchou konverzaci pro doporučení filmů/seriálů bez kontextu.
        Volá se z:
          - set_mode button (uživatel vybral Filmy/Seriály v AI chat rootu)
          - section_root kontext (uživatel dal "Poradit se s AI" v sekci Filmy/Seriály)
        """
        user_msg = "Chci doporučit filmy." if self.media_type == "movie" else "Chci doporučit seriály."
        
        self.append_chat_message("Ty", user_msg)
        self.history.append({"role": "user", "content": user_msg})
        
        # Inicializovat prompt builder
        self._prompt_builder = AIRecommendationPromptBuilder(self.media_type, self.context)
        
        # Start AI conversation
        self._start_ai_conversation()
    
    def _start_ai_conversation(self, is_initial_context=False):
        """Start AI conversation immediately after media type selection or on init with context."""
        # Start animated thinking indicator
        self._start_thinking_animation()
        
        # Call AI in thread
        # Pokud jde o initial context, posíláme prázdný user_text, protože zpráva je už v historii v onInit
        user_text = "" 
        t = threading.Thread(target=self._ai_worker, args=(user_text,))
        t.start()
    
    def _start_thinking_animation(self):
        """Start the animated dots animation."""
        self._thinking_stop.clear()
        self._dot_count = 0
        self._thinking_thread = threading.Thread(target=self._animate_dots)
        self._thinking_thread.start()
    
    def _stop_thinking_animation(self):
        """Stop the animated dots animation."""
        self._thinking_stop.set()
        if self._thinking_thread:
            self._thinking_thread.join(timeout=1)
            self._thinking_thread = None
    
    def _animate_dots(self):
        """Animate the dots in thinking status."""
        import time
        while not self._thinking_stop.is_set():
            dots = "." * (self._dot_count % 4)
            self.setProperty('WCS.AIChat.Status', f'AI přemýšlí{dots}')
            self._dot_count += 1
            time.sleep(0.4)
            
    def handle_user_input(self, user_text, display_text=None):
        """Process user input, update UI, and call AI.
        
        Args:
            user_text: Text který se pošle do LLM
            display_text: Volitelný text pro zobrazení v UI (pokud None, použije se user_text)
        """
        if not self.media_type:
            # Should not happen if UI is correct, but fallback
            self.media_type = "movie"
            
        # 1. Update Chat UI - zobrazit display_text nebo user_text
        ui_text = display_text if display_text else user_text
        self.append_chat_message("Ty", ui_text)
        
        # 2. Add to history - uložit plný text pro LLM kontext
        self.history.append({"role": "user", "content": user_text})
        
        # 3. Start animated thinking indicator
        self._start_thinking_animation()
        
        # 4. Call AI in thread
        t = threading.Thread(target=self._ai_worker, args=(user_text,))
        t.start()
    
    def _get_context_instruction(self):
        """
        Získá kontextovou instrukci pro AI na základě aktivního kontextu.
        Generuje specifické instrukce pro různé typy kontextu (my_movies, genre, person, atd.).
        """
        if not self.context:
            return ""
        
        ctx_type = self.context.get('type')
        ctx_val = self.context.get('value')
        ctx_data = self.context.get('data', [])
        
        # Načtení limitu pro kontext (počet titulů k analýze z knihovny)
        try:
            limit_setting = self.addon.getSetting('ai_context_history_limit')
            limit = int(limit_setting) if limit_setting else 20
        except:
            limit = 20
        
        media_label = "filmů" if self.media_type == "movie" else "seriálů"
        
        # === MY MOVIES / MY SERIES ===
        if ctx_type in ['my_movies', 'my_series'] and ctx_data:
            titles = [f"{item.get('title', item.get('name'))} ({item.get('year')})" for item in ctx_data[:limit]]
            titles_str = ", ".join(titles)
            return f"Mám v knihovně tyto {media_label}: {titles_str} - najdi mi podobné tituly podle mého vkusu."
        
        # === MY MIXED COLLECTION ===
        elif ctx_type == 'my_mixed_collection' and ctx_data:
            movies = ctx_data.get('movies', [])
            series = ctx_data.get('series', [])
            
            m_count, s_count = len(movies), len(series)
            target_m, target_s = limit // 2, limit - limit // 2
            
            if m_count < target_m:
                target_s += (target_m - m_count)
                target_m = m_count
            elif s_count < target_s:
                target_m += (target_s - s_count)
                target_s = s_count
            
            m_titles = [f"{m.get('title')} ({m.get('year')})" for m in movies[:target_m]]
            s_titles = [f"{s.get('name')} ({s.get('year')})" for s in series[:target_s]]
            all_str = ", ".join(m_titles + s_titles)
            
            return f"Mám v knihovně: {all_str} - najdi mi podobné tituly podle mého vkusu."
        
        # === RECENTLY PLAYED ===
        elif ctx_type == 'recently_played' and ctx_data:
            titles = []
            for item in ctx_data[:limit]:
                title = item.get('title', '')
                year = item.get('year', '')
                
                if item.get('media_type') == 'series':
                    ep_title = item.get('episode_title', '')
                    season, episode = item.get('season'), item.get('episode')
                    if season is not None and episode is not None:
                        ep_str = f"S{int(season):02d}E{int(episode):02d}"
                        title += f" ({ep_str} {ep_title or ''})"
                        
                if year:
                    title += f" ({year})"
                titles.append(title)
            
            titles_str = ", ".join(titles)
            return f"Naposledy jsem sledoval: {titles_str} - najdi mi podobné tituly."
        
        # === MY COLLECTIONS ===
        elif ctx_type == 'my_collections' and ctx_data:
            c_names = [c.get('name', 'Neznámá kolekce') for c in ctx_data[:50]]
            colls_str = ", ".join(c_names)
            return f"Sbírám tyto kolekce: {colls_str} - najdi mi další podobné filmové ságy."
        
        # === FAVORITE ACTORS/DIRECTORS/WRITERS ===
        elif ctx_type in ['favorite_actors', 'favorite_directors', 'favorite_writers'] and ctx_data:
            names = [item.get('name') for item in ctx_data]
            names_str = ", ".join(names)
            what_map = {'favorite_actors': 'herce', 'favorite_directors': 'režiséry', 'favorite_writers': 'scenáristy'}
            what = what_map.get(ctx_type, 'osobnosti')
            return f"Mám rád tyto {what}: {names_str} - najdi mi díla s nimi nebo podobného stylu."
        
        # === GENRE ===
        elif ctx_type == 'genre':
            return f"Zajímá mě žánr {ctx_val} - najdi mi nejlepší tituly."
        
        # === PERSON ===
        elif ctx_type == 'person':
            p_type = self.context.get('person_type', 'osoba')
            return f"Zajímá mě {p_type} {ctx_val} - najdi mi díla s touto osobností."
        
        # === COUNTRY ===
        elif ctx_type == 'country':
            return f"Zajímá mě tvorba ze země {ctx_val} - najdi mi nejlepší tituly."
        
        # === YEAR ===
        elif ctx_type == 'year':
            return f"Zajímá mě rok {ctx_val} - najdi mi nejlepší tituly z tohoto období."
        
        # === COLLECTION ===
        elif ctx_type == 'collection':
            return f"Zajímá mě kolekce {ctx_val} - najdi mi podobné filmové ságy."
        
        # === CATEGORY ===
        elif ctx_type == 'category':
            return f"Prohlížím sekci {ctx_val} - zohledni to při doporučování."
        
        return ""
        
    def _ai_worker(self, user_text):
        # Zajistit, že máme prompt builder
        if not self._prompt_builder:
            self._prompt_builder = AIRecommendationPromptBuilder(self.media_type, self.context)
        
        # Sestavit system prompt
        system_prompt = self._prompt_builder.build_system_prompt()
        
        # Získat context_instruction z kontextu (pokud existuje)
        context_instruction = self._get_context_instruction()
        
        # Sestavit messages pole pro multi-turn API
        messages = self._prompt_builder.build_messages(
            self.history, 
            context_instruction=context_instruction
        )
        
        # Volat funkci v AIHandler s nativním messages polem
        data, usage = ai_handler.send_chat_recommendation(system_prompt, messages)
        
        # Stop the thinking animation
        self._stop_thinking_animation()
        
        if not data:
            self.setProperty('WCS.AIChat.Status', 'Chyba komunikace')
            return

        # Update History with COMPLETE AI response (celý JSON včetně recommendations)
        # Model tak bude vědět jaké tituly už doporučil
        import json
        full_response_json = json.dumps(data, ensure_ascii=False)
        self.history.append({"role": "assistant", "content": full_response_json})
        
        # Pro UI zobrazit jen message
        ai_msg = data.get('message', '')
        
        # Schedule UI Update on main thread logic (using xbmc operations is mostly safe, but let's be careful)
        # We can call methods directly as they mostly use Kodi GUI calls which are thread-safe enough for property/control setting usually
        self.append_chat_message("AI", ai_msg)
        self.setProperty('WCS.AIChat.Status', 'Připraven')
        
        # SHOW INPUT FIELD after first AI response
        self.setProperty('WCS.AIChat.ShowInput', 'true')
        
        # Načíst buttons a recommendations jednou
        buttons = data.get('buttons', [])
        recs = data.get('recommendations', [])
        
        # Pokud máme doporučení, přidej tlačítko pro další várku
        if recs:
            recomm_count = int(self.addon.getSetting('ai_recommendation_count') or 11)
            more_button = {
                "label": f"Dej mi dalších {recomm_count} návrhů",
                "value": f"Doporuč mi PŘESNĚ {recomm_count} NOVÝCH a UNIKÁTNÍCH titulů. Nesmíš opakovat žádný titul z předchozích doporučení v historii. Hledej v širší žánrové paletě, méně známé filmy, zahraniční tvorbu, starší klasiky. TMDb má miliony titulů - vždy existuje dalších {recomm_count} skvělých titulů!"
            }
            buttons.insert(0, more_button)
        
        self.update_buttons(buttons)
        
        # Handle Recommendations (používáme již načtené recs)
        if recs:
            self.fetch_and_display_recommendations(recs)
            
    def fetch_and_display_recommendations(self, recommendations):
        """Fetch TMDB data and populate list."""
        # Use a worker to fetch TMDB to avoid freezing
        t = threading.Thread(target=self._tmdb_worker, args=(recommendations,))
        t.start()
        
    def _tmdb_worker(self, recommendations):
        list_control = self.getControl(2000)
        list_control.reset()
        
        for rec in recommendations:
            title = rec.get('title')
            year = rec.get('year')
            # Determine media type for this specific item (mixed content support)
            # Default to self.media_type if not specified by AI
            item_media_type = rec.get('type')
            if item_media_type not in ['movie', 'tv']:
                 item_media_type = self.media_type
                 
            # Fetch TMDB
            tmdb_data = self._search_tmdb(title, year, item_media_type)
            
            if tmdb_data:
                # Create ListItem - pro seriály TMDb vrací 'name' místo 'title'
                display_title = tmdb_data.get('title') or tmdb_data.get('name') or title
                item = xbmcgui.ListItem(label=display_title)
                poster = tmdb_data.get('poster_path')
                if poster:
                    item.setArt({'poster': f'https://image.tmdb.org/t/p/w500{poster}'})
                    
                # Store metadata for actions
                item.setProperty('tmdb_id', str(tmdb_data.get('id')))
                item.setProperty('media_type', item_media_type)
                item.setProperty('title', tmdb_data.get('title') or tmdb_data.get('name') or '')
                item.setProperty('year', tmdb_data.get('release_date', '')[:4] if item_media_type=='movie' else tmdb_data.get('first_air_date', '')[:4])
                item.setProperty('original_title', tmdb_data.get('original_title', tmdb_data.get('original_name','')))
                
                list_control.addItem(item)
                
    def _search_tmdb(self, title, year, media_type):
        """Identify movie/series/collection in TMDB."""
        try:
            api_key = get_tmdb_api_key()
            if media_type == "movie":
                endpoint = "search/movie"
            elif media_type == "collection":
                endpoint = "search/collection"
            else:
                endpoint = "search/tv"

            params = {'api_key': api_key, 'language': 'cs-CZ', 'query': title}
            if year and media_type != "collection": # Collections dont handle year filter well in search
                if media_type == "movie":
                     params['year'] = year
                else:
                     params['first_air_date_year'] = year
                    
            resp = requests.get(f'https://api.themoviedb.org/3/{endpoint}', params=params, timeout=5)
            if resp.status_code == 200:
                results = resp.json().get('results', [])
                if results:
                    return results[0]
        except Exception as e:
            xbmc.log(f"TMDB Error: {e}", xbmc.LOGERROR)
        return None

    def handle_recommendation_click(self):
        """Handle click on recommendation card."""
        list_control = self.getControl(2000)
        item = list_control.getSelectedItem()
        if not item: return
        
        tmdb_id = item.getProperty('tmdb_id')
        title = item.getProperty('title')
        year = item.getProperty('year')
        media_type = item.getProperty('media_type')
        
        # Načíst preferovanou akci z nastavení
        # Values: "Vyhledat na Webshare", "Vyhledat a přehrát", "Zobrazit WCS detaily", "Zobrazit menu akcí"
        click_action = self.addon.getSetting('ai_click_action')
        
        # Pro kolekce vždy zobrazíme menu, nebo pokud uživatel explicitně chce menu
        if media_type == "collection" or click_action == "Zobrazit menu akcí":
            self._show_action_menu(tmdb_id, title, year, media_type, item)
            return

        # Rychlé akce pro Film a Seriál
        if click_action == "Vyhledat na Webshare":
            # Varianta 1: Rovnou vyhledá na webshare (textové hledání)
            if media_type == "movie":
                # Pro filmy se chová stejně jako akce "Přehrát" - tj. vyhledá soubory a nabídne výběr (process play)
                plot = item.getProperty('plot') or ''
                poster = item.getArt('poster') or ''
                from wcs.utils import search_and_play_movie
                search_and_play_movie(title, year, plot, poster, '', '', '', '', '', self.addon)
                # NEZAVÍRAT self.close() - zavře se samo pokud začne přehrávání (Dialog.Close(all)), jinak zůstane otevřeno
            else:
                # Pro seriály/kolekce použijeme fallback na menu
                self._show_action_menu(tmdb_id, title, year, media_type, item)

        elif click_action == "Vyhledat a přehrát":
            # Varianta 2: Rovnou vyhledá na webshare a automaticky přehraje (pokud to jde, jinak search & play)
            if media_type == "movie":
                plot = item.getProperty('plot') or ''
                poster = item.getArt('poster') or ''
                from wcs.utils import search_and_play_movie
                # search_and_play_movie zahájí proces výběru a přehrání s vynuceným autoplay
                search_and_play_movie(title, year, plot, poster, '', '', '', '', '', self.addon, autoplay=True)
                # NEZAVÍRAT self.close()
            else:
                # Pro seriály/kolekce použijeme fallback na menu
                self._show_action_menu(tmdb_id, title, year, media_type, item)
                
        elif click_action == "Zobrazit WCS detaily":
            # Varianta 3: Místo otevření dialogu přesuneme fokus na preview tlačítka (uživatel si detaily/přehrání vybere tam)
            self.setFocusId(6100)

    def _show_action_menu(self, tmdb_id, title, year, media_type, item):
        """Standardní modální dialog s akcemi (původní chování)."""
        dialog = xbmcgui.Dialog()
        
        if media_type == "collection":
            # KOLEKCE
            opts = [
                "Zobrazit filmy v kolekci",
                f"Inspiruj se: {title}",
                "Přidat do Moje filmy",
                "Přidat do knihovny Kodi"
            ]
            sel = dialog.select(f"Akce: {title}", opts)
            
            if sel == 0:
                # Zobrazit kolekci 
                from urllib.parse import quote_plus
                url = f"plugin://{self.addon.getAddonInfo('id')}?action=list_collection_movies&collection_id={tmdb_id}&collection_name={quote_plus(title)}"
                xbmc.executebuiltin(f"Container.Update({url})")
            elif sel == 1:
                inspiration_text = f"Najdi podobné filmové kolekce jako: {title}"
                self.handle_user_input(inspiration_text)
            elif sel == 2:
                # Přidat do Moje filmy
                url = f"plugin://{self.addon.getAddonInfo('id')}?action=add_collection_to_my_movies&collection_id={tmdb_id}"
                xbmc.executebuiltin(f"RunPlugin({url})")
            elif sel == 3:
                # Přidat do knihovny Kodi
                url = f"plugin://{self.addon.getAddonInfo('id')}?action=add_collection_to_library&collection_id={tmdb_id}"
                xbmc.executebuiltin(f"RunPlugin({url})")
                
        elif media_type == "series" or media_type == "tv":
            # SERIÁL
            opts = [
                "Zobrazit detaily",
                "Zobrazit sezóny",
                f"Inspiruj se: {title}",
                "Přidat do Moje seriály",
                "Přidat do knihovny Kodi"
            ]
            sel = dialog.select(f"Akce: {title} ({year})", opts)
            
            if sel == 0:
                detail_url = f"plugin://{self.addon.getAddonInfo('id')}?action=show_wcs_details&media_type=tv&tmdb_id={tmdb_id}"
                xbmc.executebuiltin(f"RunPlugin({detail_url})")
            elif sel == 1:
                from urllib.parse import quote_plus
                seasons_url = f"plugin://{self.addon.getAddonInfo('id')}?action=display_series_seasons&series_id={tmdb_id}&name={quote_plus(title)}"
                self.close()
                xbmc.executebuiltin(f'AlarmClock(OpenSeasons,Container.Update({seasons_url}),00:01,silent)')
            elif sel == 2:
                inspiration_text = f"Najdi podobné seriály jako: {title} ({year})"
                self.handle_user_input(inspiration_text)
            elif sel == 3:
                from wcs.ui.UI import add_series_item_to_list
                add_series_item_to_list(self.addon, tmdb_id, title)
            elif sel == 4:
                from wcs.library import LibraryManager as library
                library.check_settings_and_add_item({'media_type': 'series', 'series_id': tmdb_id}, self.addon)
        else:
            # FILM
            opts = [
                "Zobrazit detaily",
                "Přehrát",
                f"Inspiruj se: {title}",
                "Přidat do Moje filmy",
                "Přidat do knihovny Kodi"
            ]
            sel = dialog.select(f"Akce: {title} ({year})", opts)
            
            if sel == 0:
                detail_url = f"plugin://{self.addon.getAddonInfo('id')}?action=show_wcs_details&media_type=movie&tmdb_id={tmdb_id}"
                xbmc.executebuiltin(f"RunPlugin({detail_url})")
            elif sel == 1:
                plot = item.getProperty('plot') or ''
                poster = item.getArt('poster') or ''
                from wcs.utils import search_and_play_movie
                search_and_play_movie(title, year, plot, poster, '', '', '', '', '', self.addon)
                self.close()
            elif sel == 2:
                inspiration_text = f"Najdi podobné filmy jako: {title} ({year})"
                self.handle_user_input(inspiration_text)
            elif sel == 3:
                from wcs.ui.UI import add_movie_item_to_list
                add_movie_item_to_list(self.addon, tmdb_id, title)
            elif sel == 4:
                from wcs.library import LibraryManager as library
                library.check_settings_and_add_item({'media_type': 'movie', 'movie_id': tmdb_id}, self.addon)
