# -*- coding: utf-8 -*-
"""Actions for Kodi library items (docs/plan/skin-milionar/080): sources, game, similar, add to a channel.

Entry points: skin.milionar's info dialog menu (window 1121) and the context menu
(context.py, every skin). Both pass dbtype + dbid; everything else is resolved here.
"""
import json
from urllib.parse import quote_plus

import xbmc
import xbmcgui

ADDON_ID = 'plugin.video.milionar'
BASE = 'plugin://{}/'.format(ADDON_ID)

S_NO_TMDB = 32240          # "TMDb ID of this title was not found"
S_ADD_TO = 32241           # "Add to MyTV" / heading
S_ADD_TO_CINEMA = 32242
S_NEW_CHANNEL = 32243
S_NEW_CHANNEL_NAME = 32244
S_ADDED = 32245
S_REMOVED = 32246

DETAILS = {
    'movie': ('VideoLibrary.GetMovieDetails', 'movieid', 'moviedetails',
              ['title', 'originaltitle', 'year', 'plot', 'art', 'uniqueid', 'genre', 'runtime', 'rating']),
    'tvshow': ('VideoLibrary.GetTVShowDetails', 'tvshowid', 'tvshowdetails',
               ['title', 'originaltitle', 'year', 'plot', 'art', 'uniqueid', 'genre']),
    'episode': ('VideoLibrary.GetEpisodeDetails', 'episodeid', 'episodedetails',
                ['title', 'showtitle', 'season', 'episode', 'plot', 'art', 'tvshowid', 'uniqueid']),
}


def _rpc(method, params):
    return json.loads(xbmc.executeJSONRPC(json.dumps(
        {'jsonrpc': '2.0', 'id': 1, 'method': method, 'params': params}))).get('result', {})


def _details(dbtype, dbid):
    method, key, result_key, props = DETAILS[dbtype]
    return _rpc(method, {key: int(dbid), 'properties': props}).get(result_key, {})


def _tmdb_id(media_type, row):
    """tmdb id from the library's uniqueid; else a TMDb search by title and year."""
    found = (row.get('uniqueid') or {}).get('tmdb')
    if found:
        return found
    from wcs.metadata import TMDbLogo
    return TMDbLogo._search_tmdb_id(media_type, row.get('title', ''), row.get('year', ''))


def resolve(dbtype, dbid):
    """Everything the actions need about one library item. For an episode the show is resolved too."""
    row = _details(dbtype, dbid)
    if not row:
        return None
    art = row.get('art') or {}
    info = {'dbtype': dbtype, 'title': row.get('title', ''), 'year': row.get('year', ''),
            'plot': row.get('plot', ''), 'poster': art.get('poster') or art.get('tvshow.poster', ''),
            'fanart': art.get('fanart') or art.get('tvshow.fanart', ''), 'rating': row.get('rating', '')}
    if dbtype == 'episode':
        show = _details('tvshow', row.get('tvshowid'))
        info.update(series_name=row.get('showtitle') or show.get('title', ''), season=row.get('season'),
                    episode=row.get('episode'), episode_title=row.get('title', ''),
                    year=show.get('year', ''), poster=info['poster'] or (show.get('art') or {}).get('poster', ''))
        info['tmdb_id'] = _tmdb_id('tv', show)
        info['original_title'] = show.get('originaltitle') or info['series_name']
    else:
        info['original_title'] = row.get('originaltitle') or info['title']
        info['tmdb_id'] = _tmdb_id('tv' if dbtype == 'tvshow' else 'movie', row)
    return info


def _run(query):
    xbmc.executebuiltin('RunPlugin({}?{})'.format(BASE.rstrip('/'), query))


def sources(addon, info):
    """Search Webshare/Kraska sources for the movie or the episode (the addon's own search dialog + playback)."""
    if info['dbtype'] == 'episode':
        _run('action=play_episode_from_addon&series_name={}&season_number={}&episode_number={}'
             '&episode_title={}&year={}&poster={}&tmdb_id={}'.format(
                 quote_plus(info['series_name']), info['season'], info['episode'],
                 quote_plus(info['episode_title']), quote_plus(str(info['year'])),
                 quote_plus(info['poster']), info.get('tmdb_id') or ''))
    else:
        _run('action=play_movie_from_addon&title={}&year={}&plot={}&poster={}&fanart={}&tmdb_id={}'.format(
            quote_plus(info['title']), quote_plus(str(info['year'])), quote_plus(info['plot']),
            quote_plus(info['poster']), quote_plus(info['fanart']), info.get('tmdb_id') or ''))


def game(addon, info):
    from wcs.games import millionaire
    media = 'movie' if info['dbtype'] == 'movie' else 'tv'
    title = info.get('series_name') or info['title']
    episode = info['dbtype'] == 'episode'
    _run(millionaire.query(millionaire.Subject(
        title=title, tmdb_id=str(info.get('tmdb_id') or ''), media_type=media, plot=info['plot'],
        year=info.get('year') or '', poster=info['poster'], backdrop=info['fanart'],
        episode_title=info.get('episode_title', '') if episode else '',
        season_number=info.get('season') if episode else None, episode_number=info.get('episode') if episode else None)))


def similar(addon, info):
    if not info.get('tmdb_id'):
        xbmcgui.Dialog().notification('Milionář', addon.getLocalizedString(S_NO_TMDB), xbmcgui.NOTIFICATION_INFO)
        return
    action = 'display_similar_movies_dialog' if info['dbtype'] == 'movie' else 'display_similar_series_dialog'
    _run('action={}&tmdb_id={}&original_title={}'.format(action, info['tmdb_id'], quote_plus(info['original_title'])))


def add_channel(addon, info):
    """Pick a MyCinema cinema (movie) or MyTV channel (show / episode's show) and add the title to it."""
    from wcs.ai.MediaChannelManager import MediaChannelManager
    from wcs.metadata import TMDbClient
    if not info.get('tmdb_id'):
        xbmcgui.Dialog().notification('Milionář', addon.getLocalizedString(S_NO_TMDB), xbmcgui.NOTIFICATION_INFO)
        return
    movie = info['dbtype'] == 'movie'
    manager = MediaChannelManager(addon, 'cinema' if movie else 'tv')
    channels = manager.get_all_channels()
    labels = [c.name for c in channels] + ['[B]{}[/B]'.format(addon.getLocalizedString(S_NEW_CHANNEL))]
    picked = xbmcgui.Dialog().select(addon.getLocalizedString(S_ADD_TO_CINEMA if movie else S_ADD_TO), labels)
    if picked < 0:
        return
    if picked == len(channels):
        name = xbmcgui.Dialog().input(addon.getLocalizedString(S_NEW_CHANNEL_NAME), type=xbmcgui.INPUT_ALPHANUM)
        if not name.strip():
            return
        channel = manager.create_channel(name.strip())
    else:
        channel = channels[picked]
    data = TMDbClient.fetch_tmdb_item_detail('movie' if movie else 'tv', info['tmdb_id'], {}, addon) or {}
    data.setdefault('id', info['tmdb_id'])
    present = any(str(m.get('id')) == str(info['tmdb_id']) for m in channel.media_list)
    if not present:
        manager.toggle_media_in_channel(channel.id, data)
    xbmcgui.Dialog().notification(channel.name, addon.getLocalizedString(S_REMOVED if present else S_ADDED),
                                  xbmcgui.NOTIFICATION_INFO, 3000)


ACTIONS = {'lib_sources': sources, 'lib_game': game, 'lib_similar': similar, 'lib_add_channel': add_channel}


def run(addon, action, params):
    dbtype, dbid = params.get('dbtype'), params.get('dbid')
    if dbtype not in DETAILS or not str(dbid).isdigit():
        return
    info = resolve(dbtype, dbid)
    if info:
        ACTIONS[action](addon, info)
