# wcs/ai/DialogMyTV.py
import xbmc
import xbmcgui
import xbmcaddon
from urllib.parse import quote_plus
from wcs.ai.DialogAIChatRecommendation import AIChatRecommendationDialog
from wcs.ai.MyTVChannelManager import MyTVChannelManager
from wcs import user_data

class MyTVDialog(AIChatRecommendationDialog):
    def __init__(self, xml_filename, addon_path, *args, **kwargs):
        super(MyTVDialog, self).__init__(xml_filename, addon_path, *args, **kwargs)
        self._nav_section_id = 'my_tv'
        self.channel_manager = MyTVChannelManager(self.addon)
        self.current_channel_index = 0

    def onInit(self):
        self._reset_state()
        self.setProperty('WCS.AIChat.Title', 'Moje televizní vysílání')
        self.setProperty('WCS.AIChat.Status', 'Připraven')
        
        # Always start with the first channel
        self.current_channel_index = 0
        
        # Load View
        self.refresh_channels_view()
        
        # Ensure sidebar is hidden initially, handled by base class logic or show_nav_sidebar arg
        if self._show_nav_on_init:
            self._show_nav_sidebar(animate=False)
        else:
            self.clearProperty('WCS.AIChat.Visible')
            self._delayed_focus(2000, 0.5)

    def refresh_channels_view(self):
        """Populate the bottom list with channels."""
        channels = self.channel_manager.get_all_channels()
        list_control = self.getControl(2000)
        list_control.reset()
        
        for ch in channels:
            item = xbmcgui.ListItem(label=ch.name)
            # Use channel icon or fallback
            icon = ch.icon if ch.icon else 'special://home/addons/plugin.video.milionar/resources/media/placeholder_tv_card.png'
            item.setArt({'poster': icon})
            item.setProperty('channel_id', ch.id)
            list_control.addItem(item)
            
        # Add "Create New Channel" item
        create_item = xbmcgui.ListItem(label="Vytvořit nový kanál")
        create_item.setArt({'poster': 'special://home/addons/plugin.video.milionar/resources/media/plus_card.png'}) # Fallback to placeholder if not exists
        create_item.setProperty('is_create_button', 'true')
        list_control.addItem(create_item)
            
        # Select first if available (and reset index if out of bounds)
        if self.current_channel_index >= list_control.size():
            self.current_channel_index = 0
            
        if list_control.size() > 0:
            list_control.selectItem(self.current_channel_index)
            self.update_editor_view()
            self.refresh_program_view()

    def update_editor_view(self):
        """Update grid 3000 based on selected channel."""
        list_control = self.getControl(2000)
        idx = list_control.getSelectedPosition()
        if idx < 0:
            return
            
        item = list_control.getListItem(idx)
        
        # If "Create New" is selected, clear editor or show "Press Enter to Create"
        if item.getProperty('is_create_button') == 'true':
            self.getControl(3000).reset()
            self.getControl(4000).reset()
            return
            
        channel_id = item.getProperty('channel_id')
        channel = self.channel_manager.get_channel_by_id(channel_id)
        
        grid_control = self.getControl(3000)
        grid_control.reset()
        
        if channel:
            for series in channel.series_list:
                s_item = xbmcgui.ListItem(label=series.get('name'))
                poster = series.get('poster_path') or series.get('poster')
                if poster and not poster.startswith('http'):
                     poster = f"https://image.tmdb.org/t/p/w500{poster}"
                elif not poster:
                     poster = 'special://home/addons/plugin.video.milionar/resources/media/placeholder_tv_card.png'
                
                s_item.setArt({'poster': poster})
                s_item.setProperty('series_id', str(series.get('id')))
                s_item.setProperty('channel_id', channel_id)
                grid_control.addItem(s_item)

    def refresh_program_view(self):
        """Generate and display upcoming program."""
        list_control = self.getControl(2000)
        idx = list_control.getSelectedPosition()
        if idx < 0: return

        item = list_control.getListItem(idx)
        channel_id = item.getProperty('channel_id')
        channel = self.channel_manager.get_channel_by_id(channel_id)
        
        program_list = self.getControl(4000)
        program_list.reset()
        
        if not channel or not channel.series_list:
             item = xbmcgui.ListItem(label="Žádný program. Přidejte seriály.")
             program_list.addItem(item)
             return

        # Generate schedule (simulate)
        # To avoid duplicated logic, we might need a method in ChannelManager to "simulate_schedule(count)"
        # For now, let's implement simple randomized view since we don't have persistence simulation easily available
        # But we can try to be smart.
        
        from wcs.library import LibraryManager
        import random
        
        schedule = []
        series_candidates = list(channel.series_list)
        
        # We try to generate 10 items
        # Taking "Next Up" for each series is static unless we simulate watching.
        # Simulation:
        # 1. Get current "Next Up" for all series in channel.
        # 2. Store them in a local dict {series_id: {season, episode}}
        # 3. Randomly pick series, use local dict to get episode, then increment local dict.
        
        simulated_progress = {} # series_id -> (season, episode)
        
        # Pre-fetch initial progress (optimization: fetch only when picked?)
        # Fetching all might be slow if channel is huge.
        # Let's fetch on demand.
        
        for i in range(12): # Generate 12 items
            if not series_candidates: break
            
            # Weighted random? Or just random.
            series = random.choice(series_candidates)
            series_id = str(series.get('id'))
            series_name = series.get('name')
            
            # Check if we have progress for this series
            if series_id not in simulated_progress:
                # Find real "Next Up" from Library
                # We need user_data to know what was watched?
                # ChannelManager logic uses `user_data.load_recently_played` to find last watched.
                # Use manager helper if possible, but manager returns ONE episode.
                # Let's duplicate the lookup logic here but optimized for simulation?
                # Actually, reuse Manager's logic would be best but it renders ONE random.
                
                # Let's implement robust "Next Up" lookup here.
                # 1. Look in recently played settings (cache this outside loop)
                pass # Already loaded? logic is inside get_random_episode...
                
                # We'll rely on ChannelManager helper but we need to inject "last watched" overrides?
                # No, ChannelManager doesn't support overrides.
                # Let's just call LibraryManager.get_next_episode... with our simulated values.
                
                # Initial state: Get from REAL recently played
                last_season = 1
                last_episode = 0
                
                # Load real recently played once
                if not hasattr(self, '_recently_played_cache'):
                     self._recently_played_cache = user_data.load_recently_played(self.addon)
                
                for rp in self._recently_played_cache:
                    if str(rp.get('tmdb_id', '')) == series_id or rp.get('title') == series_name:
                         if 'season' in rp and 'episode' in rp:
                             last_season = int(rp['season'])
                             last_episode = int(rp['episode'])
                         break
                
                simulated_progress[series_id] = (last_season, last_episode)

            # Use simulated progress
            curr_s, curr_e = simulated_progress[series_id]
            
            # Ask Library for Next after Cur S, Cur E
            next_meta = LibraryManager.get_next_episode_metadata_from_library(series_name, curr_s, curr_e)
            
            if next_meta:
                 # Found episode. Add to schedule.
                 title = f"{series_name} - S{next_meta['season_number']:02d}E{next_meta['episode_number']:02d}"
                 ep_name = next_meta.get('episode_title', '')
                 if ep_name:
                     title += f" {ep_name}"
                 
                 item = xbmcgui.ListItem(label=title)
                 item.setLabel2(next_meta.get('episode_runtime', ''))
                 item.setProperty('tmdb_id', series_id)
                 item.setProperty('series_name', series_name)
                 item.setProperty('season', str(next_meta['season_number']))
                 item.setProperty('episode', str(next_meta['episode_number']))
                 
                 # Extra properties for playback history
                 item.setProperty('episode_title', next_meta.get('episode_title', ''))
                 item.setProperty('plot', next_meta.get('episode_plot', ''))
                 item.setProperty('rating', str(next_meta.get('episode_rating', '')))
                 item.setProperty('poster', next_meta.get('series_poster', ''))
                 item.setProperty('fanart', next_meta.get('series_fanart', ''))
                 item.setProperty('genre', next_meta.get('series_genre', ''))
                 item.setProperty('year', str(next_meta.get('episode_year', '')))
                 
                 program_list.addItem(item)
                 
                 # Advance simulation
                 simulated_progress[series_id] = (next_meta['season_number'], next_meta['episode_number'])
            else:
                 # Series ended or not found? Remove from candidates for this generation to avoid retrying empty
                 series_candidates.remove(series)

    def onAction(self, action):
        # Detect movement in bottom list to refresh grid
        # ACTION_MOVE_LEFT = 1, ACTION_MOVE_RIGHT = 2
        if self.getFocusId() == 2000:
            if action.getId() in [1, 2]:
                # Allow UI to update selection then refresh
                xbmc.sleep(50) # Tiny delay to let list update selection
                self.update_editor_view()
                self.refresh_program_view()
        
        super(MyTVDialog, self).onAction(action)

    def onClick(self, controlId):
        if controlId == 2000:
            # Check if "Create New"
            list_control = self.getControl(2000)
            if list_control.getSelectedItem().getProperty('is_create_button') == 'true':
                self._create_new_channel()
            else:
                # Play Channel
                self._play_current_channel()
        elif controlId == 3000:
            # Context Menu for Grid Item (Remove)
            self._handle_grid_click()
        elif controlId == 3001:
            # Add from My Series
            self._add_from_my_series()
        elif controlId == 3002:
            # Add New (Search)
            self._add_new_search()
        elif controlId == 3003:
            # Delete Channel
            self._delete_current_channel()
        elif controlId == 3004:
            # Play Broadcast (First item in upcoming)
            self._play_broadcast()
        elif controlId == 3005:
            # Refresh/Shuffle
            self.refresh_program_view()
            xbmcgui.Dialog().notification("Moje TV", "Program aktualizován", xbmcgui.NOTIFICATION_INFO)
        elif controlId == 4000:
            # Play Program Item
            self._play_program_item()
        
        super(MyTVDialog, self).onClick(controlId)

    def _create_new_channel(self):
        name = xbmcgui.Dialog().input("Název kanálu", type=xbmcgui.INPUT_ALPHANUM)
        if not name: return
        
        self.channel_manager.create_channel(name)
        # Select the new one (last one before the create button)
        self.current_channel_index = len(self.channel_manager.get_all_channels()) - 1
        self.refresh_channels_view()
        xbmcgui.Dialog().notification("Moje TV", f"Kanál '{name}' vytvořen.", xbmcgui.NOTIFICATION_INFO)
        
        # Auto-trigger "Add from My Series"
        self._add_from_my_series()

    def _delete_current_channel(self):
        list_control = self.getControl(2000)
        item = list_control.getSelectedItem()
        if not item or item.getProperty('is_create_button') == 'true': return
        
        channel_id = item.getProperty('channel_id')
        channel_name = item.getLabel()
        
        if xbmcgui.Dialog().yesno("Smazat kanál", f"Opravdu chccete smazat kanál '{channel_name}'?"):
            # We need method in manager to delete
            # self.channel_manager.delete_channel(channel_id) # Missing method
            # Let's implement ad-hoc or add to manager. Best to add to manager.
            # For quick fix, I will do it here via accessing list directly, but cleaner is to update manager file.
            # I will update manager file first? No, I can access internal list if I have to, but let's assume I can update manager.
            # Actually I already implemented the manager file in previous turns. I should check if I have delete method.
            # I don't think I added delete method.
            
            # Accessing internal list for now to save tool calls, or re-write manager.
            # Let's rewrite manager slightly or just filter list.
            
            self.channel_manager.channels = [ch for ch in self.channel_manager.channels if ch.id != channel_id]
            self.channel_manager._save_channels()
            
            self.current_channel_index = 0
            self.refresh_channels_view()
            self.current_channel_index = 0
            self.refresh_channels_view()
            self.refresh_channels_view()
            xbmcgui.Dialog().notification("Moje TV", "Kanál smazán.", xbmcgui.NOTIFICATION_INFO)

    def _play_broadcast(self):
        """Plays all items in the upcoming program list continuously."""
        list_control = self.getControl(4000)
        size = list_control.size()
        if size == 0:
            xbmcgui.Dialog().notification("Moje TV", "Žádný program k vysílání.", xbmcgui.NOTIFICATION_INFO)
            return
            
        self.close()
        
        # Get Playlist
        playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
        playlist.clear()
        
        # Add all items to playlist
        for i in range(size):
            item = list_control.getListItem(i)
            
            series_name = item.getProperty('series_name')
            season = item.getProperty('season')
            episode = item.getProperty('episode')
            tmdb_id = item.getProperty('tmdb_id')
            
            if not series_name or not season or not episode:
                continue

            # Metadata params
            episode_title = item.getProperty('episode_title')
            plot = item.getProperty('plot')
            rating = item.getProperty('rating')
            poster = item.getProperty('poster')
            fanart = item.getProperty('fanart')
            genre = item.getProperty('genre')
            year = item.getProperty('year')
            
            # Construct plugin URL for PLAYLIST action
            url = (f"plugin://{self.addon.getAddonInfo('id')}?action=play_episode_from_addon_playlist"
                   f"&series_name={quote_plus(series_name)}"
                   f"&season_number={season}"
                   f"&episode_number={episode}"
                   f"&tmdb_id={tmdb_id}"
                   f"&episode_title={quote_plus(episode_title)}"
                   f"&plot={quote_plus(plot)}"
                   f"&rating={quote_plus(rating)}"
                   f"&poster={quote_plus(poster)}"
                   f"&fanart={quote_plus(fanart)}"
                   f"&genre={quote_plus(genre)}"
                   f"&year={quote_plus(year)}")
            
            # Create list item for playlist
            li = xbmcgui.ListItem(label=item.getLabel())
            li.setInfo('video', {
                'title': item.getLabel(),
                'plot': plot, 
                'year': int(year) if year.isdigit() else 0,
                'premiered': year,
                'mediatype': 'episode',
                'season': int(season),
                'episode': int(episode),
                'tvshowtitle': series_name
            })
            li.setArt({
                'poster': poster,
                'fanart': fanart,
                'thumb': poster
            })
            
            playlist.add(url, li)
            
        # Start playback
        xbmc.Player().play(playlist)

    def _play_program_item(self):
        list_control = self.getControl(4000)
        item = list_control.getSelectedItem()
        if not item: return
        
        series_name = item.getProperty('series_name')
        season = item.getProperty('season')
        episode = item.getProperty('episode')
        tmdb_id = item.getProperty('tmdb_id')
        
        # Metadata pro utils.play_episode_from_addon
        episode_title = item.getProperty('episode_title')
        plot = item.getProperty('plot')
        rating = item.getProperty('rating')
        poster = item.getProperty('poster')
        fanart = item.getProperty('fanart')
        genre = item.getProperty('genre')
        year = item.getProperty('year')
        
        if not series_name or not season or not episode:
             return

        self.close()
        
        # Trigger play action via plugin URL - using standard utils function
        url = (f"plugin://{self.addon.getAddonInfo('id')}?action=play_episode_from_addon"
               f"&series_name={quote_plus(series_name)}"
               f"&season_number={season}"
               f"&episode_number={episode}"
               f"&tmdb_id={tmdb_id}"
               f"&episode_title={quote_plus(episode_title)}"
               f"&plot={quote_plus(plot)}"
               f"&rating={quote_plus(rating)}"
               f"&poster={quote_plus(poster)}"
               f"&fanart={quote_plus(fanart)}"
               f"&genre={quote_plus(genre)}"
               f"&year={quote_plus(year)}")
        
        xbmc.executebuiltin(f"PlayMedia({url})")

    def _play_current_channel(self):
        """Spustí přehrávání aktuálního kanálu (náhodná epizoda Next Up)."""
        list_control = self.getControl(2000)
        item = list_control.getSelectedItem()
        if not item: return
        
        channel_id = item.getProperty('channel_id')
        
        # Najít další epizodu pro přehrání
        next_episode = self.channel_manager.get_random_episode_for_channel(channel_id)
        
        if not next_episode:
            xbmcgui.Dialog().notification(
                self.addon.getAddonInfo('name'),
                "Kanál nemá žádné dostupné epizody",
                xbmcgui.NOTIFICATION_INFO
            )
            return
            
        self.close()
        
        # Přehrát epizodu pomocí standardní akce
        series_name = next_episode.get('series_name') or next_episode.get('series_title')
        season = next_episode.get('season_number')
        episode = next_episode.get('episode_number')
        
        url = (f"plugin://{self.addon.getAddonInfo('id')}?action=play_episode_from_addon"
               f"&series_name={quote_plus(series_name)}"
               f"&season_number={season}"
               f"&episode_number={episode}"
               f"&tmdb_id={next_episode.get('tmdb_id', '')}"
               f"&episode_title={quote_plus(next_episode.get('episode_title', ''))}"
               f"&plot={quote_plus(next_episode.get('episode_plot', ''))}"
               f"&rating={quote_plus(str(next_episode.get('episode_rating', '')))}"
               f"&poster={quote_plus(next_episode.get('series_poster', ''))}"
               f"&fanart={quote_plus(next_episode.get('series_fanart', ''))}"
               f"&year={quote_plus(str(next_episode.get('episode_year', '')))}")
        
        xbmc.executebuiltin(f"PlayMedia({url})")


    def _handle_grid_click(self):
        grid = self.getControl(3000)
        item = grid.getSelectedItem()
        if not item: return
        
        series_label = item.getLabel()
        channel_id = item.getProperty('channel_id')
        series_id = item.getProperty('series_id')
        
        # Context menu
        menu = xbmcgui.Dialog().contextmenu([f"Smazat '{series_label}' z kanálu"])
        if menu == 0:
            # Remove
            self.channel_manager.toggle_series_in_channel(channel_id, {'id': series_id})
            # Full refresh to update icon
            self.refresh_channels_view()
            xbmcgui.Dialog().notification("Moje TV", f"'{series_label}' odebráno.", xbmcgui.NOTIFICATION_INFO)

    def _add_from_my_series(self):
        # Get My Series
        my_series = user_data.load_tmdb_series(self.addon)
        if not my_series:
             xbmcgui.Dialog().notification("Moje TV", "Nenalezeny žádné uložené seriály.", xbmcgui.NOTIFICATION_INFO)
             return
             
        # Filter out already added ones?
        list_control = self.getControl(2000)
        channel_id = list_control.getSelectedItem().getProperty('channel_id')
        channel = self.channel_manager.get_channel_by_id(channel_id)
        current_ids = [str(s.get('id')) for s in channel.series_list]
        
        candidates = [s for s in my_series if str(s.get('id')) not in current_ids]
        
        if not candidates:
             xbmcgui.Dialog().notification("Moje TV", "Všechny vaše seriály už jsou v kanálu.", xbmcgui.NOTIFICATION_INFO)
             return
             
        # Multi select
        labels = [f"{s.get('name')} ({s.get('year', '')})" for s in candidates]
        selected = xbmcgui.Dialog().multiselect("Přidat do kanálu", labels)
        
        if selected:
            for idx in selected:
                self.channel_manager.toggle_series_in_channel(channel_id, candidates[idx])
            # Full refresh to update icon
            self.refresh_channels_view()
            xbmcgui.Dialog().notification("Moje TV", "Seriály přidány.", xbmcgui.NOTIFICATION_INFO)

    def _add_new_search(self):
        # Copied logic from DialogMySeries, adapted
        import requests
        from wcs.metadata.TMDbClient import get_tmdb_api_key
        
        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)
            results = response.json().get('results', [])
        except Exception:
            return
            
        if not results:
             xbmcgui.Dialog().notification("Moje TV", "Nic nenalezeno.", xbmcgui.NOTIFICATION_INFO)
             return
             
        choices = [f"{item['name']} ({item.get('first_air_date', '')[:4]})" for item in results]
        selected_idx = xbmcgui.Dialog().select("Vyberte seriál", choices)
        
        if selected_idx >= 0:
            selected_item = results[selected_idx]
            list_control = self.getControl(2000)
            channel_id = list_control.getSelectedItem().getProperty('channel_id')
            
            self.channel_manager.toggle_series_in_channel(channel_id, selected_item)
            # Full refresh
            self.refresh_channels_view()
            xbmcgui.Dialog().notification("Moje TV", f"'{selected_item['name']}' přidáno.", xbmcgui.NOTIFICATION_INFO)


def show_my_tv_dialog(addon, show_nav_sidebar=False, nav_position=0):
    dialog = MyTVDialog(
        "ai/DialogMyTV.xml",
        addon.getAddonInfo('path'),
        "Default",
        "1080i",
        show_nav_sidebar=show_nav_sidebar,
        nav_position=nav_position
    )
    dialog.doModal()
    del dialog
