"""
DialogAddSeries - Standalone dialog for adding series to a MyTV channel.

This dialog provides four ways to add series:
1. From user's saved library (Moje serialy)
2. Search on TMDb
3. TMDb recommendations based on existing channel content
4. AI recommendations based on existing channel content
"""

import xbmc
import xbmcgui
import xbmcaddon
import threading
import requests
from urllib.parse import quote_plus

from wcs import user_data
from wcs.caching import get_cache_manager
from wcs.metadata.TMDbClient import get_tmdb_api_key
from wcs.ai.AIProvider import AIProvider
from wcs.ai.DialogAIChatRecommendation import AIRecommendationPromptBuilder


class AddSeriesDialog:
    """
    Controller for the inline Add Series dialog in DialogMyTV.xml.
    
    Provides 4 action cards:
    - Z mojí knihovny (9201)
    - Vyhledat na TMDb (9202)
    - Doporučit z TMDb (9203)
    - Doporučit od AI (9204)
    
    And a series listing view (9211) with metadata panel.
    
    NOTE: This is NOT a WindowXMLDialog - it controls an inline section
    within MyTVDialog using window properties.
    """
    
    # TMDb genre ID to Czech name mapping
    GENRE_MAP = {
        10759: 'Akce a dobrodružství', 16: 'Animovaný', 35: 'Komedie',
        80: 'Krimi', 99: 'Dokument', 18: 'Drama', 10751: 'Rodinný',
        10762: 'Dětský', 9648: 'Záhadný', 10763: 'Zprávy',
        10764: 'Reality', 10765: 'Sci-Fi a fantasy', 10766: 'Telenovela',
        10767: 'Talk Show', 10768: 'Válečný a politický', 37: 'Western'
    }
    
    def __init__(self, parent_window, addon, channel_manager, channel_id, on_close_callback=None):
        """
        Initialize the Add Series dialog controller.
        
        Args:
            parent_window: MyTVDialog instance (the host window)
            addon: xbmcaddon.Addon instance
            channel_manager: MyTVChannelManager instance
            channel_id: ID of the channel to add series to
            on_close_callback: Optional callback function called when dialog closes.
                               Receives (channel_id, series_added) as arguments.
        """
        self.parent = parent_window
        self.addon = addon
        self.channel_manager = channel_manager
        self.channel_id = channel_id
        self._on_close_callback = on_close_callback
        
        # Get channel reference
        self.channel = None
        if self.channel_manager and self.channel_id:
            self.channel = self.channel_manager.get_channel_by_id(self.channel_id)
        
        # Internal state
        self._items = []  # Current listing items
        self._cache = get_cache_manager()
        self._series_added = False  # Track if any series was added
        self._is_active = False
    
    def show(self):
        """Show the inline Add Series dialog."""
        self._is_active = True
        self._series_added = False
        
        # Set initial state via window properties
        self.parent.setProperty('WCS.MyTV.AddDialog.Active', 'true')
        self.parent.setProperty('WCS.MyTV.AddDialog.Description', 
                        'Vyberte seriály z vaší uložené knihovny a přidejte je do kanálu.')
        self.parent.clearProperty('WCS.MyTV.AddDialog.ListingMode')
        self.parent.clearProperty('WCS.MyTV.AddDialog.ListingTitle')
        
        # Repeated focus attempts - Kodi sometimes needs multiple tries
        for attempt in range(5):
            xbmc.sleep(100)
            self.parent.setFocusId(9201)
            xbmc.sleep(50)
            if self.parent.getFocusId() == 9201:
                break
    
    def hide(self):
        """Hide the inline Add Series dialog."""
        self._is_active = False
        self.parent.clearProperty('WCS.MyTV.AddDialog.Active')
        self.parent.clearProperty('WCS.MyTV.AddDialog.ListingMode')
        self.parent.clearProperty('WCS.MyTV.AddDialog.ListingTitle')
        self.parent.clearProperty('WCS.MyTV.AddDialog.Description')
        
        # Call on_close callback if provided
        if self._on_close_callback:
            try:
                self._on_close_callback(self.channel_id, self._series_added)
            except Exception as e:
                xbmc.log(f"[AddSeriesDialog] Error in on_close callback: {e}", xbmc.LOGERROR)
        
        # Return focus to the grid
        self.parent.setFocusId(9100)
    
    def is_active(self):
        """Return True if the dialog is currently active."""
        return self._is_active
    
    def onAction(self, action):
        """Handle user input actions. Returns True if handled."""
        if not self._is_active:
            return False
        
        action_id = action.getId()
        
        # ESC / Back
        if action_id in [10, 92]:  # ACTION_PREVIOUS_MENU, ACTION_NAV_BACK
            # If action buttons are visible, hide them first
            if self.parent.getProperty('WCS.MyTV.AddDialog.ActionsVisible'):
                self._hide_action_buttons()
                return True
            elif self.parent.getProperty('WCS.MyTV.AddDialog.ListingMode'):
                # In listing mode - go back to action selection
                self.parent.clearProperty('WCS.MyTV.AddDialog.ListingMode')
                self.parent.clearProperty('WCS.MyTV.AddDialog.ListingTitle')
                self.parent.setFocusId(9201)
            else:
                # In action selection - close dialog
                self.hide()
            return True
        
        return False  # Let parent handle other actions
    
    def onClick(self, controlId):
        """Handle click events. Returns True if handled."""
        if not self._is_active:
            return False
        
        # Close button
        if controlId == 9200:
            self.hide()
            return True
        
        # Action cards
        elif controlId == 9201:
            self._show_series_listing('my_series')
            return True
        elif controlId == 9202:
            self._show_series_listing('search')
            return True
        elif controlId == 9203:
            self._show_series_listing('tmdb_recommendations')
            return True
        elif controlId == 9204:
            self._show_series_listing('ai_recommendations')
            return True
        
        # Series listing - show action buttons
        elif controlId == 9211:
            self._show_action_buttons()
            return True
        
        # Action buttons list
        elif controlId == 9220:
            self._execute_selected_action()
            return True
        
        return False
    
    def onFocus(self, controlId):
        """Handle focus changes to update descriptions."""
        if not self._is_active:
            return
        
        descriptions = {
            9201: 'Vyberte seriály z vaší uložené knihovny a přidejte je do kanálu.',
            9202: 'Vyhledejte seriál podle názvu na TMDb.',
            9203: 'Získejte doporučení na základě seriálů v kanálu.',
            9204: 'Nechte AI navrhnout seriály podle vašich preferencí.',
        }
        if controlId in descriptions:
            self.parent.setProperty('WCS.MyTV.AddDialog.Description', descriptions[controlId])
    
    def was_series_added(self):
        """Return True if any series was added during this dialog session."""
        return self._series_added
    
    # ==================================================================================
    # LISTING METHODS
    # ==================================================================================
    
    def _show_series_listing(self, source):
        """Show series listing for the given source."""
        items = []
        title = ""
        
        if source == 'my_series':
            title = "Z mojí knihovny"
            my_series = user_data.load_tmdb_series(self.addon)
            if not my_series:
                self.parent._show_toast("Žádné uložené seriály", "warning")
                return
            
            # Show dialog immediately, enrich asynchronously
            self.parent.setProperty('WCS.MyTV.AddDialog.ListingMode', source)
            self.parent.setProperty('WCS.MyTV.AddDialog.ListingTitle', title)
            self._items = my_series
            
            # Start async enrichment
            threading.Thread(target=self._enrich_my_series, args=(my_series,), daemon=True).start()
            return
        
        elif source == 'search':
            title = "Vyhledávání na TMDb"
            search_query = xbmcgui.Dialog().input("Hledat seriál", type=xbmcgui.INPUT_ALPHANUM)
            if not search_query:
                return
            try:
                url = f'https://api.themoviedb.org/3/search/tv?api_key={get_tmdb_api_key()}&language=cs-CZ&query={quote_plus(search_query)}'
                response = requests.get(url, timeout=10)
                items = response.json().get('results', [])
            except Exception as e:
                xbmc.log(f"[AddSeriesDialog] Search error: {e}", xbmc.LOGERROR)
                return
            if not items:
                self.parent._show_toast("Nic nenalezeno", "warning")
                return
        
        elif source == 'tmdb_recommendations':
            title = "Doporučení z TMDb"
            if not self.channel or not self.channel.series_list:
                self.parent._show_toast("Kanál nemá žádné seriály", "warning")
                return
            
            all_recs = []
            seen_ids = set()
            current_ids = {str(s.get('id')) for s in self.channel.series_list}
            
            # Get recommendations for each series (max 3)
            for series in self.channel.series_list[:3]:
                series_id = series.get('id')
                try:
                    url = f'https://api.themoviedb.org/3/tv/{series_id}/recommendations?api_key={get_tmdb_api_key()}&language=cs-CZ'
                    response = requests.get(url, timeout=10)
                    recs = response.json().get('results', [])
                    for rec in recs:
                        rec_id = str(rec.get('id'))
                        if rec_id not in seen_ids and rec_id not in current_ids:
                            seen_ids.add(rec_id)
                            all_recs.append(rec)
                except Exception as e:
                    xbmc.log(f"[AddSeriesDialog] TMDb recommendations error: {e}", xbmc.LOGERROR)
            
            if not all_recs:
                self.parent._show_toast("Žádná doporučení", "info")
                return
            items = all_recs[:20]
        
        elif source == 'ai_recommendations':
            title = "Doporučení od AI"
            if not self.channel or not self.channel.series_list:
                self.parent._show_toast("Kanál nemá žádné seriály pro kontext", "warning")
                return
            
            # Show loading state
            self.parent.setProperty('WCS.MyTV.AddDialog.ListingMode', source)
            self.parent.setProperty('WCS.MyTV.AddDialog.ListingTitle', "Načítám AI doporučení...")
            
            # Start AI in background
            threading.Thread(target=self._fetch_ai_recommendations, daemon=True).start()
            return
        
        if not items:
            return
        
        # Store and display items
        self._items = items
        self.parent.setProperty('WCS.MyTV.AddDialog.ListingMode', source)
        self.parent.setProperty('WCS.MyTV.AddDialog.ListingTitle', title)
        self._populate_list(items)
        self.parent.setFocusId(9211)
    
    def _enrich_my_series(self, my_series):
        """Enrich my_series with TMDb metadata (async worker)."""
        list_control = self.parent.getControl(9211)
        list_control.reset()
        
        current_ids = self._get_current_channel_ids()
        enriched = []
        
        for series in my_series:
            tmdb_id = series.get('id')
            if not tmdb_id:
                enriched.append(series)
                self._add_item_to_list(list_control, series, current_ids)
                continue
            
            cache_key = f"tv_detail_{tmdb_id}"
            cached = self._cache.get(cache_key)
            
            if cached:
                enriched.append(cached)
                self._add_item_to_list(list_control, cached, current_ids)
            else:
                try:
                    url = f'https://api.themoviedb.org/3/tv/{tmdb_id}?api_key={get_tmdb_api_key()}&language=cs-CZ'
                    response = requests.get(url, timeout=5)
                    if response.status_code == 200:
                        full_data = response.json()
                        self._cache.set(cache_key, full_data, ttl_seconds=7*24*3600)
                        enriched.append(full_data)
                        self._add_item_to_list(list_control, full_data, current_ids)
                    else:
                        enriched.append(series)
                        self._add_item_to_list(list_control, series, current_ids)
                except Exception as e:
                    xbmc.log(f"[AddSeriesDialog] TMDb fetch error: {e}", xbmc.LOGWARNING)
                    enriched.append(series)
                    self._add_item_to_list(list_control, series, current_ids)
        
        self._items = enriched
        self._cache.flush()
        
        if list_control.size() > 0:
            self.parent.setFocusId(9211)
    
    def _fetch_ai_recommendations(self):
        """Fetch AI recommendations (async worker)."""
        try:
            import json
            
            series_items = list(self.channel.series_list)
            
            # Build prompt using AIRecommendationPromptBuilder
            context = {'type': 'my_series', 'data': series_items}
            prompt_builder = AIRecommendationPromptBuilder('series', context)
            system_prompt = prompt_builder.build_system_prompt()
            
            # Build user message with series context
            series_names = [s.get('name', '') for s in series_items if s.get('name')]
            user_msg = f"Na základě těchto seriálů doporuč další: {', '.join(series_names[:10])}"
            
            # Call AI
            ai_provider = AIProvider()
            response, usage = ai_provider.send_prompt(f"{system_prompt}\n\nUser: {user_msg}")
            
            if not response:
                self.parent._show_toast("AI nevrátila odpověď", "warning")
                return
            
            # Parse JSON response
            try:
                data = json.loads(response)
                recommendations = data.get('recommendations', [])
            except json.JSONDecodeError:
                self.parent._show_toast("AI odpověď není validní JSON", "error")
                return
            
            if not recommendations:
                self.parent._show_toast("AI nedoporučila žádné seriály", "warning")
                return
            
            # Lookup on TMDb
            current_ids = self._get_current_channel_ids()
            tmdb_items = []
            
            for rec in recommendations:
                rec_title = rec.get('title') or rec.get('original_title')
                rec_year = rec.get('year')
                
                tmdb_data = self._search_tmdb(rec_title, rec_year)
                if tmdb_data:
                    item_id = str(tmdb_data.get('id'))
                    if item_id not in current_ids:
                        tmdb_items.append(tmdb_data)
            
            if not tmdb_items:
                self.parent._show_toast("Nenalezeny seriály na TMDb", "warning")
                return
            
            # Update dialog
            self._items = tmdb_items
            self.parent.setProperty('WCS.MyTV.AddDialog.ListingTitle', "Doporučení od AI")
            self._populate_list(tmdb_items)
            self.parent.setFocusId(9211)
            
        except Exception as e:
            xbmc.log(f"[AddSeriesDialog] AI recommendations error: {e}", xbmc.LOGERROR)
            self.parent._show_toast("Chyba AI doporučení", "error")
    
    def _search_tmdb(self, title, year=None):
        """Search TMDb for a series by title and optional year."""
        if not title:
            return None
        try:
            url = f'https://api.themoviedb.org/3/search/tv?api_key={get_tmdb_api_key()}&language=cs-CZ&query={quote_plus(title)}'
            if year:
                url += f'&first_air_date_year={year}'
            response = requests.get(url, timeout=5)
            results = response.json().get('results', [])
            return results[0] if results else None
        except Exception as e:
            xbmc.log(f"[AddSeriesDialog] TMDb search error: {e}", xbmc.LOGWARNING)
            return None
    
    # ==================================================================================
    # LIST POPULATION METHODS
    # ==================================================================================
    
    def _populate_list(self, items):
        """Populate the series listing control."""
        try:
            list_control = self.parent.getControl(9211)
            list_control.reset()
            
            current_ids = self._get_current_channel_ids()
            
            for item_data in items:
                self._add_item_to_list(list_control, item_data, current_ids)
                
        except Exception as e:
            xbmc.log(f"[AddSeriesDialog] Error populating list: {e}", xbmc.LOGERROR)
    
    def _add_item_to_list(self, list_control, item_data, current_ids):
        """Add a single item to the list control."""
        try:
            item = xbmcgui.ListItem(label=item_data.get('name', ''))
            
            # Poster
            poster = item_data.get('poster_path') or item_data.get('poster', '')
            if poster and not poster.startswith('http'):
                poster = f"https://image.tmdb.org/t/p/w500{poster}"
            
            # Fanart
            fanart = item_data.get('backdrop_path') or item_data.get('fanart', '')
            if fanart and not fanart.startswith('http'):
                fanart = f"https://image.tmdb.org/t/p/w1280{fanart}"
            
            item.setArt({
                'poster': poster or 'special://home/addons/plugin.video.milionar/resources/media/placeholder_tv_card.png',
                'fanart': fanart or 'special://home/addons/plugin.video.milionar/resources/media/fanart_fallback.jpg'
            })
            
            # Properties
            item.setProperty('tmdb_id', str(item_data.get('id', '')))
            
            # Year
            year_val = item_data.get('first_air_date', '') or item_data.get('year', '')
            item.setProperty('year', str(year_val)[:4] if year_val else '')
            
            # Rating
            rating_val = item_data.get('vote_average') or item_data.get('rating') or 0
            item.setProperty('rating', str(round(float(rating_val), 1)) if rating_val else '0')
            
            # Plot
            plot_val = item_data.get('overview', '') or item_data.get('plot', '')
            item.setProperty('plot', plot_val)
            
            # Genre
            genres = item_data.get('genre_ids', [])
            if genres:
                genre_names = self._map_genre_ids(genres)
            else:
                genre_names = item_data.get('genre', '') or item_data.get('genres', '')
                if isinstance(genre_names, list):
                    genre_names = ', '.join([g.get('name', '') for g in genre_names if isinstance(g, dict)])
            item.setProperty('genre', genre_names if genre_names else '')
            
            # Check if already in channel
            if str(item_data.get('id')) in current_ids:
                item.setProperty('is_added', 'true')
            
            list_control.addItem(item)
        except Exception as e:
            xbmc.log(f"[AddSeriesDialog] Error adding item: {e}", xbmc.LOGERROR)
    
    def _map_genre_ids(self, genre_ids):
        """Map TMDb genre IDs to names."""
        names = [self.GENRE_MAP.get(gid, '') for gid in genre_ids[:2] if gid in self.GENRE_MAP]
        return ', '.join(names) if names else ''
    
    def _get_current_channel_ids(self):
        """Get set of series IDs currently in the channel."""
        if self.channel and self.channel.series_list:
            return {str(s.get('id')) for s in self.channel.series_list}
        return set()
    
    # ==================================================================================
    # ADD SERIES METHODS
    # ==================================================================================
    
    def _add_series_from_listing(self):
        """Add the currently selected series to the channel."""
        try:
            list_control = self.parent.getControl(9211)
            selected_pos = list_control.getSelectedPosition()
            
            if selected_pos < 0 or not self._items:
                return
            
            selected_item = self._items[selected_pos]
            series_id = str(selected_item.get('id'))
            
            # Check if already added
            current_ids = self._get_current_channel_ids()
            if series_id in current_ids:
                self.parent._show_toast("Seriál už je v kanálu", "info")
                return
            
            # Add to channel
            self.channel_manager.toggle_series_in_channel(self.channel_id, selected_item)
            
            # Update the item to show checkmark
            list_item = list_control.getListItem(selected_pos)
            list_item.setProperty('is_added', 'true')
            
            # Update channel reference
            self.channel = self.channel_manager.get_channel_by_id(self.channel_id)
            
            # Track that we added something
            self._series_added = True
            
            self.parent._show_toast(f"'{selected_item.get('name')}' přidáno", "success")
            
        except Exception as e:
            xbmc.log(f"[AddSeriesDialog] Error adding series: {e}", xbmc.LOGERROR)
    
    # ==================================================================================
    # ACTION BUTTONS METHODS
    # ==================================================================================
    
    def _show_action_buttons(self):
        """Show action buttons for the currently selected series."""
        try:
            list_control = self.parent.getControl(9211)
            selected_pos = list_control.getSelectedPosition()
            
            if selected_pos < 0 or not self._items:
                return
            
            # Store selected item for later use
            self._selected_item = self._items[selected_pos]
            self._selected_pos = selected_pos
            
            # Populate action buttons list
            action_list = self.parent.getControl(9220)
            action_list.reset()
            
            # Define actions
            actions = [
                ("Přidat do kanálu", "add_to_channel"),
                ("Moje seriály", "add_to_my_series"),
                ("Podobné", "find_similar"),
                ("Hrát hru", "play_game"),
            ]
            
            for label, action_id in actions:
                item = xbmcgui.ListItem(label=label)
                item.setProperty('action_id', action_id)
                action_list.addItem(item)
            
            # Show actions
            self.parent.setProperty('WCS.MyTV.AddDialog.ActionsVisible', 'true')
            self.parent.setFocusId(9220)
            
        except Exception as e:
            xbmc.log(f"[AddSeriesDialog] Error showing action buttons: {e}", xbmc.LOGERROR)
    
    def _hide_action_buttons(self):
        """Hide action buttons and return focus to series list."""
        self.parent.clearProperty('WCS.MyTV.AddDialog.ActionsVisible')
        self.parent.setFocusId(9211)
    
    def _execute_selected_action(self):
        """Execute the selected action from the action buttons list."""
        try:
            action_list = self.parent.getControl(9220)
            selected_pos = action_list.getSelectedPosition()
            
            if selected_pos < 0:
                return
            
            selected_item = action_list.getListItem(selected_pos)
            action_id = selected_item.getProperty('action_id')
            
            # Hide buttons first
            self._hide_action_buttons()
            
            # Execute action
            if action_id == 'add_to_channel':
                self._action_add_to_channel()
            elif action_id == 'add_to_my_series':
                self._action_add_to_my_series()
            elif action_id == 'find_similar':
                self._action_find_similar()
            elif action_id == 'play_game':
                self._action_play_game()
                
        except Exception as e:
            xbmc.log(f"[AddSeriesDialog] Error executing action: {e}", xbmc.LOGERROR)
    
    def _action_add_to_channel(self):
        """Add the selected series to the channel."""
        if not hasattr(self, '_selected_item') or not self._selected_item:
            return
        
        selected_item = self._selected_item
        series_id = str(selected_item.get('id'))
        
        # Check if already added
        current_ids = self._get_current_channel_ids()
        if series_id in current_ids:
            self.parent._show_toast("Seriál už je v kanálu", "info")
            return
        
        # Add to channel
        self.channel_manager.toggle_series_in_channel(self.channel_id, selected_item)
        
        # Update the item to show checkmark
        try:
            list_control = self.parent.getControl(9211)
            list_item = list_control.getListItem(self._selected_pos)
            list_item.setProperty('is_added', 'true')
        except:
            pass
        
        # Update channel reference
        self.channel = self.channel_manager.get_channel_by_id(self.channel_id)
        
        # Track that we added something
        self._series_added = True
        
        self.parent._show_toast(f"'{selected_item.get('name')}' přidáno", "success")
    
    def _action_add_to_my_series(self):
        """Add the selected series to user's My Series library."""
        if not hasattr(self, '_selected_item') or not self._selected_item:
            return
        
        selected_item = self._selected_item
        
        # Prepare series data for user_data
        series_data = {
            'id': selected_item.get('id'),
            'name': selected_item.get('name'),
            'poster_path': selected_item.get('poster_path'),
            'backdrop_path': selected_item.get('backdrop_path'),
            'first_air_date': selected_item.get('first_air_date', ''),
            'overview': selected_item.get('overview', ''),
            'vote_average': selected_item.get('vote_average', 0),
        }
        
        # Load existing series
        existing = user_data.load_tmdb_series(self.addon) or []
        
        # Check if already exists
        if any(str(s.get('id')) == str(series_data['id']) for s in existing):
            self.parent._show_toast("Seriál už je v knihovně", "info")
            return
        
        # Add to list
        existing.append(series_data)
        user_data.store_tmdb_series(self.addon, existing)
        
        self.parent._show_toast(f"'{series_data['name']}' uloženo do knihovny", "success")
    
    def _action_find_similar(self):
        """Find similar series on TMDb."""
        if not hasattr(self, '_selected_item') or not self._selected_item:
            return
        
        selected_item = self._selected_item
        series_id = selected_item.get('id')
        series_name = selected_item.get('name', 'Seriál')
        
        try:
            # Fetch recommendations
            url = f'https://api.themoviedb.org/3/tv/{series_id}/recommendations?api_key={get_tmdb_api_key()}&language=cs-CZ'
            response = requests.get(url, timeout=10)
            results = response.json().get('results', [])
            
            if not results:
                self.parent._show_toast("Žádné podobné seriály", "info")
                return
            
            # Filter out already in channel
            current_ids = self._get_current_channel_ids()
            filtered = [r for r in results if str(r.get('id')) not in current_ids]
            
            if not filtered:
                self.parent._show_toast("Všechny podobné už jsou v kanálu", "info")
                return
            
            # Update listing with similar series
            self._items = filtered[:20]
            self.parent.setProperty('WCS.MyTV.AddDialog.ListingTitle', f"Podobné: {series_name}")
            self._populate_list(filtered[:20])
            self.parent.setFocusId(9211)
            
        except Exception as e:
            xbmc.log(f"[AddSeriesDialog] Error finding similar: {e}", xbmc.LOGERROR)
            self.parent._show_toast("Chyba při hledání", "error")
    
    def _action_play_game(self):
        """Launch Millionaire game for the selected series."""
        if not hasattr(self, '_selected_item') or not self._selected_item:
            return
        
        selected_item = self._selected_item
        series_id = selected_item.get('id')
        series_name = selected_item.get('name', '')
        
        # Close the Add Series dialog first
        self.hide()
        
        # Launch the game via Kodi plugin URL
        import xbmc
        game_url = f"plugin://plugin.video.milionar/?action=play_text_game&media_type=series&tmdb_id={series_id}&title={quote_plus(series_name)}"
        xbmc.executebuiltin(f"RunPlugin({game_url})")


def create_add_series_controller(parent_window, addon, channel_manager, channel_id, on_close_callback=None):
    """
    Create an AddSeriesDialog controller for the inline dialog.
    
    Args:
        parent_window: MyTVDialog instance (the host window)
        addon: xbmcaddon.Addon instance
        channel_manager: MyTVChannelManager instance
        channel_id: ID of the channel to add series to
        on_close_callback: Optional callback function called when dialog closes.
    
    Returns:
        AddSeriesDialog: Controller instance
    """
    return AddSeriesDialog(parent_window, addon, channel_manager, channel_id, on_close_callback)

