"""
ChannelNameGenerator - Automatické generování názvů kanálů podle žánrů.

Podporuje dvě varianty:
1. Náhodný výběr z předdefinovaných kreativních názvů podle dominantního žánru
2. AI generování pomocí LLM API
"""

import random
import xbmc
import xbmcaddon

from wcs.ai.AIProvider import AIProvider


class ChannelNameGenerator:
    """
    Generator kreativnich nazvu kanalu/kin podle zanru.
    
    Podporuje dva typy:
    - 'tv': MyTV kanaly se serialy
    - 'cinema': MyCinema kina s filmy
    """
    
    # TMDb TV genre ID -> list of creative Czech channel names
    GENRE_NAMES = {
        10759: [  # Action & Adventure
            "Adrenalín", "Akční jízda", "Plný plyn", "Na ostří nože", "Nebezpečná zóna",
            "Hrdinsky", "V akci", "Napětí na maximum", "Bez limitu", "Výzva přijata"
        ],
        16: [  # Animation
            "Animáček", "Kreslené světy", "Barevné příběhy", "Animovaná magie", "Pohádkový svět",
            "Kresba a fantazie", "Živé kresby", "Animované dobrodružství", "Svět animace", "Kouzelná tužka"
        ],
        35: [  # Comedy
            "Smíchov", "Dobrá nálada", "Úsměv na rtech", "Veselé večery", "Lehké srdce",
            "Humor bez hranic", "Salvy smíchu", "Komediální mix", "Úlet dne", "Pro zasmání"
        ],
        80: [  # Crime
            "Stopy zločinu", "Noční hlídka", "Detektivní klub", "Temná strana", "Vyšetřování",
            "Za mřížemi", "Policejní stanice", "Zákon a spravedlnost", "Kriminální příběhy", "Stín podezření"
        ],
        99: [  # Documentary
            "Okno do světa", "Pohled zblízka", "Skutečné příběhy", "Za kulisami", "Dokument dne",
            "Poznání", "Svět kolem nás", "Fakta a objevy", "Realita", "Pod lupou"
        ],
        18: [  # Drama
            "Lidské osudy", "Hlubiny emocí", "Životní příběhy", "Drama večer", "Silné momenty",
            "Srdce na dlani", "Citová bouře", "Osudy lidí", "Mezi řádky", "Pravdivé drama"
        ],
        10751: [  # Family
            "Rodinné večery", "Pro celou rodinu", "Společné chvíle", "Rodinná pohoda", "Domácí kino",
            "U krbu", "Generace spolu", "Rodinný čas", "Pro malé i velké", "Všichni spolu"
        ],
        10762: [  # Kids
            "Dětský svět", "Pro nejmenší", "Pohádkový koutek", "Dětská radost", "Malí diváci",
            "Svět dětí", "Veselé dobrodružství", "Pro kluky a holky", "Dětský ráj", "Školáček"
        ],
        9648: [  # Mystery
            "Záhadné příběhy", "Tajemno", "Neznámé teritorium", "Mystérium", "Skryté pravdy",
            "Za závojem", "Nevysvětlitelné", "Temné tajemství", "Enigma", "Hádanka dne"
        ],
        10763: [  # News
            "Zpravodaj", "Aktuálně", "Ze světa", "Denní přehled", "Info kanál",
            "Události dne", "Novinky", "Zprávy 24", "Report", "Aktuální dění"
        ],
        10764: [  # Reality
            "Skutečný život", "Reality TV", "Bez scénáře", "Pravda a nic než pravda", "Za kamerou",
            "Autentické příběhy", "Realita show", "Bez přípravy", "Živě", "Nepředvídatelné"
        ],
        10765: [  # Sci-Fi & Fantasy
            "Za horizontem", "Budoucnost volá", "Jiné světy", "Fantazie a věda", "Vesmírná odysea",
            "Portál do neznáma", "Dimenze X", "Magie a technologie", "Nadpřirozeno", "Sci-Fi klub"
        ],
        10766: [  # Soap
            "Srdcové záležitosti", "Denní drama", "Láska a intriky", "Seriálové odpoledne", "Osudy hrdinů",
            "Emoce non-stop", "Rodinné vztahy", "Příběhy bez konce", "Srdce v plamenech", "Touhy a sny"
        ],
        10767: [  # Talk
            "Rozhovory", "Na slovíčko", "Talk show večer", "Hosté večera", "Debatní klub",
            "Na kávě s...", "Interview", "Povídání", "Otevřeně", "Face to face"
        ],
        10768: [  # War & Politics
            "Válečné příběhy", "Politická aréna", "Zákopy historie", "Moc a válka", "Bojové pole",
            "Historické konflikty", "Za frontou", "Politické drama", "Svět ve válce", "Boj o moc"
        ],
        37: [  # Western
            "Divoký západ", "Kovbojské příběhy", "Prairie", "Westernový klub", "Pod žhnoucím sluncem",
            "Revolveroví hrdinové", "Pouštní stopy", "Západ slunce", "Šerifova hvězda", "Cesta na západ"
        ]
    }
    
    # Fallback names for mixed genres or unknown genres
    FALLBACK_NAMES = [
        "Večerní program", "Můj mix", "Televize pro mě", "Oblíbené", "Moje volba",
        "Seriálový večer", "Bez názvu", "Nový kanál", "Kanál dle výběru", "Mix dne"
    ]
    
    # Genre ID to short Czech name (for combination display)
    GENRE_SHORT_NAMES = {
        10759: "Akce",
        16: "Animovaný",
        35: "Komedie",
        80: "Krimi",
        99: "Dokument",
        18: "Drama",
        10751: "Rodinný",
        10762: "Dětský",
        9648: "Záhady",
        110: "Zprávy",
        10764: "Reality",
        10765: "Sci-Fi",
        10766: "Telenovela",
        10767: "Talk Show",
        10768: "Válečný",
        37: "Western"
    }
    
    # ========== CINEMA (Movie) GENRE NAMES ==========
    # TMDb Movie genre IDs are different from TV genre IDs
    CINEMA_GENRE_NAMES = {
        28: [  # Action
            "Akce bez kompromisů", "Adrenalinovka", "Bojové scény", "Hrdinové v akci", "Exploze a honičky",
            "Místo činu", "Na ostří nože", "Akční maraton", "Bez milosti", "Plný plyn"
        ],
        12: [  # Adventure
            "Dobrodružné výpravy", "Za horizontem", "Neznámá země", "Objevitelé", "Velká cesta",
            "Expedice", "Za pokladem", "Dobrodružná jízda", "Nový svět", "Výpravy za sluncem"
        ],
        16: [  # Animation
            "Animovaná magie", "Kreslenky", "Barevné světy", "Živé kresby", "Animovaný sen",
            "Pohádkový film", "Pixelová zábava", "Animace pro všechny", "Kouzelný svět", "Tužka a fantazie"
        ],
        35: [  # Comedy
            "Smíchov", "Dobrá nálada", "Úsměv na rtech", "Veselé večery", "Komediální maraton",
            "Pro zasmání", "Salvy smíchu", "Úlet filmu", "Humor bez hranic", "Lehký film"
        ],
        80: [  # Crime
            "Stopy zločinu", "Zločin a trest", "Temná strana", "Mafie", "Organizovaný zločin",
            "Svět podsvětí", "Gangsterky", "Noční místo", "Zločinecké osudy", "Bez zákona"
        ],
        99: [  # Documentary
            "Okno do světa", "Pohled zblízka", "Skutečné příběhy", "Za kulisami", "Dokument dne",
            "Realita", "Pod lupou", "Fakta a objevy", "Svět kolem nás", "Poznávací film"
        ],
        18: [  # Drama
            "Lidské osudy", "Hlubiny emocí", "Životní příběhy", "Silné momenty", "Drama večera",
            "Srdce na dlani", "Citová bouře", "Mezi řádky", "Pravdivé drama", "Emoční film"
        ],
        10751: [  # Family
            "Pro celou rodinu", "Rodinné večery", "Společné chvíle", "Rodinná pohoda", "Domácí kino",
            "U krbu", "Generace spolu", "Pro malé i velké", "Všichni spolu", "Rodinný film"
        ],
        14: [  # Fantasy
            "Kouzelné světy", "Fantasy maraton", "Magie a meč", "Jiné světy", "Portál do neznáma",
            "Nadpřirozeno", "Mytické příběhy", "Svět fantazie", "Zakleté kino", "Legendy ožívají"
        ],
        36: [  # History
            "Historické ódy", "Z minulosti", "Velké dějiny", "Epochy", "Kronika dějin",
            "Starověké příběhy", "Historický maraton", "Minulost ožívá", "Dějinné momenty", "Čas králů"
        ],
        27: [  # Horror
            "Hrůzostrašné kino", "Noční můry", "Temné stíny", "Strach v očích", "Krev a děsy",
            "Hororová noc", "Nesestříhané filmy", "Paranormální", "Zlo číhající", "Peklo v kine"
        ],
        10402: [  # Music
            "Hudební filmy", "Melodie kina", "Hudební scény", "Koncertní sál", "Rytmus v obraze",
            "Zpívání pod hvězdami", "Muzikálové večery", "Tance a písně", "Hudební magie", "Zvuk filmu"
        ],
        9648: [  # Mystery
            "Záhadné příběhy", "Tajemno", "Neznámé teritorium", "Mystérium", "Skryté pravdy",
            "Za závojem", "Nevysvětlitelné", "Temné tajemství", "Enigma", "Hádanka večera"
        ],
        10749: [  # Romance
            "Romantické večery", "Láska na plátně", "Srdcové záležitosti", "Romantická komedie", "Lásky příběh",
            "Pro zamilované", "Valentýnské kino", "Svět lásky", "Romantický maraton", "Polibky na plátně"
        ],
        878: [  # Science Fiction
            "Za horizontem", "Budoucnost volá", "Jiné světy", "Vesmírná odysea", "Sci-Fi maraton",
            "Galaktické kino", "Techno sny", "Kosmická stanice", "Futuristické vize", "Dimenze X"
        ],
        10770: [  # TV Movie
            "Televizní film", "Domácí kino", "Večerní film", "Televize pro mě", "Filmový vecer",
            "Prima film", "Domácí projekce", "TV premiéra", "Večerní pohoda", "Domácí filmy"
        ],
        53: [  # Thriller
            "Napětí do poslední chvíle", "Thrillerová noc", "Na ostří nože", "Srážející dech", "Napínavý večer",
            "Adrenalin v žilách", "Nebezpečná zóna", "Temné tajemství", "Bez úniku"
        ],
        10752: [  # War
            "Válečné příběhy", "Zákopy historie", "Bojové pole", "Za frontou", "Svět ve válce",
            "Hrdinové války", "Válečný epos", "Boj o moc", "Historické konflikty", "Den D"
        ],
        37: [  # Western
            "Divoký západ", "Kovbojské příběhy", "Prérie", "Westernový maraton", "Pod žhnoucím sluncem",
            "Revolveroví hrdinové", "Pouštní stopy", "Západ slunce", "Šerifova hvězda", "Cesta na západ"
        ]
    }
    
    # Fallback names for MyCinema (movies)
    CINEMA_FALLBACK_NAMES = [
        "Moje kino", "Filmový večer", "Filmový maraton", "Oblíbené filmy", "Moje volba",
        "Večerní projekce", "Nové kino", "Filmový mix", "Projekce dne", "Kino pro mě"
    ]
    
    # Cinema genre short names (same IDs as CINEMA_GENRE_NAMES)
    CINEMA_GENRE_SHORT_NAMES = {
        28: "Akce",
        12: "Dobrodružný",
        16: "Animovaný",
        35: "Komedie",
        80: "Krimi",
        99: "Dokument",
        18: "Drama",
        10751: "Rodinný",
        14: "Fantasy",
        36: "Historický",
        27: "Horor",
        10402: "Hudební",
        9648: "Záhady",
        10749: "Romantický",
        878: "Sci-Fi",
        10770: "TV Film",
        53: "Thriller",
        10752: "Válečný",
        37: "Western"
    }
    
    def __init__(self, addon=None):
        """
        Initialize the generator.
        
        Args:
            addon: xbmcaddon.Addon instance (optional, needed for AI mode)
        """
        self.addon = addon or xbmcaddon.Addon()
    
    def generate_from_genres(self, media_list, media_type='tv'):
        """
        Generate channel/cinema name based on dominant genres from media list.
        
        Uses random selection from predefined creative names.
        
        Args:
            media_list: List of media dicts with 'genre_ids' or 'genres' field
            media_type: 'tv' for MyTV channels, 'cinema' for MyCinema
            
        Returns:
            str: Generated name
        """
        log_prefix = '[MyCinema]' if media_type == 'cinema' else '[MyTV]'
        fallback_names = self.CINEMA_FALLBACK_NAMES if media_type == 'cinema' else self.FALLBACK_NAMES
        genre_names_map = self.CINEMA_GENRE_NAMES if media_type == 'cinema' else self.GENRE_NAMES
        genre_short_names = self.CINEMA_GENRE_SHORT_NAMES if media_type == 'cinema' else self.GENRE_SHORT_NAMES
        
        xbmc.log(f"{log_prefix} generate_from_genres called with {len(media_list) if media_list else 0} items", xbmc.LOGINFO)
        
        if not media_list:
            fallback = random.choice(fallback_names)
            xbmc.log(f"{log_prefix} No items, using fallback: {fallback}", xbmc.LOGINFO)
            return fallback
        
        # Collect all genre IDs from all media items
        genre_counts = {}
        for item in media_list:
            item_name = item.get('name') or item.get('title', 'Unknown')
            genre_ids = self._extract_genre_ids(item)
            for gid in genre_ids:
                genre_counts[gid] = genre_counts.get(gid, 0) + 1
        
        if not genre_counts:
            fallback = random.choice(fallback_names)
            xbmc.log(f"{log_prefix} No genres found, using fallback: {fallback}", xbmc.LOGINFO)
            return fallback
        
        # Sort by frequency (descending)
        sorted_genres = sorted(genre_counts.items(), key=lambda x: x[1], reverse=True)
        
        # Get top 1-2 genres
        top_genre_id = sorted_genres[0][0]
        top_genre_name = genre_short_names.get(top_genre_id, f'ID:{top_genre_id}')
        
        # Check if there's a second significant genre (at least 50% of top genre count)
        if len(sorted_genres) > 1:
            second_genre_id = sorted_genres[1][0]
            second_count = sorted_genres[1][1]
            top_count = sorted_genres[0][1]
            
            # If second genre is significant and different, use combination
            if second_count >= top_count * 0.5 and second_genre_id != top_genre_id:
                combined_name = self._generate_combined_name(top_genre_id, second_genre_id, media_type)
                xbmc.log(f"{log_prefix} Using combined name: {combined_name}", xbmc.LOGINFO)
                return combined_name
        
        # Single dominant genre - random selection
        single_name = self._generate_single_genre_name(top_genre_id, media_type)
        xbmc.log(f"{log_prefix} Using single genre name: {single_name}", xbmc.LOGINFO)
        return single_name
    
    def generate_from_ai(self, media_list, media_type='tv', current_name=None):
        """
        Generate channel/cinema name using AI/LLM.
        
        Sends media names and genres to AI and asks for creative name.
        
        Args:
            media_list: List of media dicts
            media_type: 'tv' for MyTV channels, 'cinema' for MyCinema
            current_name: Optional current channel name (for regeneration,
                         AI will generate a different name)
            
        Returns:
            str: AI-generated name, or fallback if AI fails
        """
        fallback_names = self.CINEMA_FALLBACK_NAMES if media_type == 'cinema' else self.FALLBACK_NAMES
        genre_short_names = self.CINEMA_GENRE_SHORT_NAMES if media_type == 'cinema' else self.GENRE_SHORT_NAMES
        
        if not media_list:
            return random.choice(fallback_names)
        
        try:
            # Build context - media names and genres
            media_info = []
            for item in media_list:
                name = item.get('name') or item.get('title', '')
                genres = self._extract_genre_names(item, media_type)
                if name:
                    if genres:
                        media_info.append(f"- {name} ({genres})")
                    else:
                        media_info.append(f"- {name}")
            
            if not media_info:
                return random.choice(fallback_names)
            
            # Build prompt based on media type
            if media_type == 'cinema':
                prompt = f"""Jsi kreativni copywriter specializujici se na filmovy branding.

Tvym ukolem je vymyslet originalni a zapamatovatelny nazev pro nove soukrome kino. Toto kino bude promitat nasledujici filmy:

{chr(10).join(media_info)}

Zamysli se nad tim, co maji tyto filmy spolecneho:
- Jaka je jejich prevladajici atmosfera? (napinava, temna, odlehcena, dramaticka, futuristicka...)
- Jake emoce vyvolavaji? (strach, smich, napeti, dojeti, vzruseni...)
- Jaky typ divaka by si je vybral?
- Jake jsou jejich hlavni zanrove prvky?

Na zaklade teto analyzy vytvor nazev kina, ktery:
- Je v cestine
- Ma maximalne 3 slova
- Vystihuje podstatu a atmosferu nabizeneho obsahu
- Zni profesionalne jako skutecne kino
- Je snadno zapamatovatelny a originalni
- Muze obsahovat slovo "kino" ale nemusi

Odpovez POUZE nazvem kina, nic dalsiho nepridavej.

Nazev:"""
            else:
                # Build current name instruction
                current_name_instruction = ""
                if current_name:
                    current_name_instruction = f"""
Aktualni nazev kanalu je "{current_name}". Vygeneruj JINY nazev, neopakuj ho."""

                prompt = f"""Vygeneruj kratky cesky nazev televizniho kanalu podle jeho obsahu.

Kanal vysila tyto serialy:
{chr(10).join(media_info)}
{current_name_instruction}
Pravidla:
- Cesky, max 3 slova
- Nazev MUSI vychazet z obsahu kanalu (zanry, atmosfera, typ serialu)
- Zni jako skutecny televizni kanal

Priklady nazvu pro inspiraci (NEKOPIRUJ je, vytvor vlastni podle obsahu):
"Komedie - Smichov", "Komedie - Dobra nalada", "Komedie - Usměv na rtech",
"Drama - Lidske osudy", "Drama - Hlubiny emoci", "Drama - Silne momenty",
"Krimi - Stopy zlocinu", "Krimi - Nocni hlidka", "Krimi - Temna strana",
"Sci-Fi - Za horizontem", "Sci-Fi - Jine svety", "Adrenalin", "Vecer plny napeti",
"Rodinne vecery", "Zahadne pribehy", "Akcni jizda", "Animacek"

Odpovez POUZE nazvem kanalu.

Nazev:"""
            
            # Call AI
            ai_provider = AIProvider()
            response, usage = ai_provider.send_prompt(
                prompt, usage_type="cinema_name" if media_type == 'cinema' else "channel_name")
            
            if response:
                # Clean up response - remove quotes, extra whitespace, newlines
                name = response.strip().strip('"\'').strip()
                # Limit length
                if len(name) <= 30 and name:
                    log_prefix = '[MyCinema]' if media_type == 'cinema' else '[MyTV]'
                    xbmc.log(f"{log_prefix} AI generated name: {name}", xbmc.LOGINFO)
                    return name
            
            # Fallback to genre-based if AI failed or returned garbage
            return self.generate_from_genres(media_list, media_type)
            
        except Exception as e:
            xbmc.log(f"[ChannelNameGenerator] AI generation failed: {e}", xbmc.LOGERROR)
            return self.generate_from_genres(media_list, media_type)
    
    def _extract_genre_ids(self, series):
        """Extract genre IDs from a series dict."""
        # Try genre_ids first (TMDb API format)
        if 'genre_ids' in series and series['genre_ids']:
            return series['genre_ids']
        
        # Try genres (detailed format with objects)
        if 'genres' in series:
            genres = series['genres']
            if isinstance(genres, list):
                return [g.get('id') for g in genres if isinstance(g, dict) and g.get('id')]
        
        return []
    
    def _extract_genre_names(self, media, media_type='tv'):
        """Extract genre names as comma-separated string."""
        genre_short_names = self.CINEMA_GENRE_SHORT_NAMES if media_type == 'cinema' else self.GENRE_SHORT_NAMES
        
        genre_ids = self._extract_genre_ids(media)
        if genre_ids:
            names = [genre_short_names.get(gid, '') for gid in genre_ids[:2]]
            return ', '.join([n for n in names if n])
        
        # Try genre string directly
        if 'genre' in media and media['genre']:
            return media['genre']
        
        return ''
    
    def _generate_single_genre_name(self, genre_id, media_type='tv'):
        """Generate name for a single dominant genre.
        
        Format: "(genre name) - (creative name)"
        Example: "Drama - Lidske osudy"
        """
        genre_names_map = self.CINEMA_GENRE_NAMES if media_type == 'cinema' else self.GENRE_NAMES
        genre_short_names = self.CINEMA_GENRE_SHORT_NAMES if media_type == 'cinema' else self.GENRE_SHORT_NAMES
        fallback_names = self.CINEMA_FALLBACK_NAMES if media_type == 'cinema' else self.FALLBACK_NAMES
        
        genre_name = genre_short_names.get(genre_id, '')
        
        if genre_id in genre_names_map:
            creative_name = random.choice(genre_names_map[genre_id])
            if genre_name:
                full_name = f"{genre_name} - {creative_name}"
            else:
                full_name = creative_name
            return full_name
        
        # Fallback - no creative names for this genre
        fallback = random.choice(fallback_names)
        if genre_name:
            full_name = f"{genre_name} - {fallback}"
        else:
            full_name = fallback
        return full_name
    
    def _generate_combined_name(self, genre_id_1, genre_id_2, media_type='tv'):
        """Generate combined name for two dominant genres.
        
        Format: "(genre1) / (genre2) - (creative name from genre1)"
        Example: "Sci-Fi / Drama - Jine svety"
        """
        genre_names_map = self.CINEMA_GENRE_NAMES if media_type == 'cinema' else self.GENRE_NAMES
        genre_short_names = self.CINEMA_GENRE_SHORT_NAMES if media_type == 'cinema' else self.GENRE_SHORT_NAMES
        fallback_names = self.CINEMA_FALLBACK_NAMES if media_type == 'cinema' else self.FALLBACK_NAMES
        
        name1 = genre_short_names.get(genre_id_1, '')
        name2 = genre_short_names.get(genre_id_2, '')
        
        if name1 and name2:
            # Get creative name from the first (top) genre
            if genre_id_1 in genre_names_map:
                creative_name = random.choice(genre_names_map[genre_id_1])
            elif genre_id_2 in genre_names_map:
                creative_name = random.choice(genre_names_map[genre_id_2])
            else:
                creative_name = random.choice(fallback_names)
            
            full_name = f"{name1} / {name2} - {creative_name}"
            return full_name
        elif name1:
            return self._generate_single_genre_name(genre_id_1, media_type)
        elif name2:
            return self._generate_single_genre_name(genre_id_2, media_type)
        else:
            return random.choice(fallback_names)
