from urllib.parse import urlencode, parse_qsl
from spider_config import spiders
from playback_record import get_playback_records, add_playback_record, delete_playback_record, PlaybackRecord
from favorite_record import get_favorite_records, add_favorite_record, delete_favorite_record, FavoriteRecord
from spider_aliyundrive import SpiderAliyunDrive
from spider import SpiderItem, SpiderItemType, SpiderPlayURL
from utils import get_image_path
from danmaku import set_danmaku_url_cache, del_danmaku_url_cache
from cache import get_cache, set_cache, del_cache
from proxy import get_qrcode_url, get_web_url
import sys
import traceback
import xbmc
import xbmcgui
import xbmcplugin
import xbmcaddon
import json
import requests
import urllib3
import time

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

_URL = sys.argv[0]
_HANDLE = int(sys.argv[1])
_ADDON = xbmcaddon.Addon()


def get_url(**kwargs):
    return '{}?{}'.format(_URL, urlencode(kwargs))


def action_homepage():
    xbmcplugin.setPluginCategory(_HANDLE, '数据源')

    list_item = xbmcgui.ListItem(label='插件设置')
    list_item.setArt({'icon': get_image_path('setting.png')})
    xbmcplugin.addDirectoryItem(
        _HANDLE,
        get_url(action='setting'),
        list_item,
        True,
    )

    list_item = xbmcgui.ListItem(label='聚合搜索（全文匹配）')
    list_item.setArt({'icon': get_image_path('search.png')})
    xbmcplugin.addDirectoryItem(
        _HANDLE,
        get_url(action='search'),
        list_item,
        True,
    )

    list_item = xbmcgui.ListItem(label='聚合搜索（拼音首字母）')
    list_item.setArt({'icon': get_image_path('search.png')})
    xbmcplugin.addDirectoryItem(
        _HANDLE,
        get_url(action='fuzzy_search'),
        list_item,
        True,
    )

    list_item = xbmcgui.ListItem(label='播放记录')
    list_item.setArt({'icon': get_image_path('playback_records.png')})
    xbmcplugin.addDirectoryItem(
        _HANDLE,
        get_url(action='playback_records'),
        list_item,
        True,
    )

    list_item = xbmcgui.ListItem(label='收藏夹')
    list_item.setArt({'icon': get_image_path('favorite_records.png')})
    xbmcplugin.addDirectoryItem(
        _HANDLE,
        get_url(action='favorite_records'),
        list_item,
        True,
    )

    list_item = xbmcgui.ListItem(label='播放阿里云盘分享链接')
    list_item.setInfo(
        'video', {
            'plot':
            '使用说明:\n1. 扫描二维码或用浏览器访问:\n{}\n2. 提交阿里云盘分享链接\n3. 点击kodi中的播放阿里云分享链接按钮'
            .format(get_web_url()),
        })
    list_item.setArt({'icon': get_qrcode_url()})
    xbmcplugin.addDirectoryItem(
        _HANDLE,
        get_url(action='aliyundrive_share_url'),
        list_item,
        True,
    )

    for spider_class in spiders:
        spider = spiders[spider_class]
        if spider.hide():
            continue
        list_item = xbmcgui.ListItem(label=spider.name())
        list_item = xbmcgui.ListItem(label='数据源:{}'.format(spider.name()))
        list_item.setArt({
            'icon': spider.logo(),
        })
        url = get_url(
            action='list_items',
            spider_class=spider_class,
        )
        is_folder = True
        xbmcplugin.addDirectoryItem(_HANDLE, url, list_item, is_folder)

    xbmcplugin.endOfDirectory(_HANDLE)


def action_list_items(spider_class, parent_item=None, page=1):
    spider = spiders[spider_class]

    if parent_item is None:
        xbmcplugin.setPluginCategory(_HANDLE, spider.name())

        if spider.is_searchable():
            list_item = xbmcgui.ListItem(label='聚合搜索（全文匹配）')
            list_item.setArt({'icon': get_image_path('search.png')})
            xbmcplugin.addDirectoryItem(
                _HANDLE,
                get_url(action='search', spider_class=spider_class),
                list_item,
                True,
            )

            list_item = xbmcgui.ListItem(label='聚合搜索（拼音首字母）')
            list_item.setArt({'icon': get_image_path('search.png')})
            xbmcplugin.addDirectoryItem(
                _HANDLE,
                get_url(action='fuzzy_search', spider_class=spider_class),
                list_item,
                True,
            )
    else:
        xbmcplugin.setPluginCategory(_HANDLE, parent_item['name'])

        list_item = xbmcgui.ListItem(label='添加到收藏夹')
        list_item.setArt({'icon': get_image_path('add_favorite_record.png')})
        xbmcplugin.addDirectoryItem(
            _HANDLE,
            get_url(
                action='add_favorite_record',
                spider_class=spider_class,
                item=json.dumps(parent_item),
            ),
            list_item,
            False,
        )

    items, has_next_page = spider.list_items(parent_item, page)

    for item in items:
        list_item = xbmcgui.ListItem(label=item['name'])
        list_item.setInfo(
            'video', {
                'title': item['name'],
                'plot': item['description'],
                'cast': item['cast'],
                'director': item['director'],
                'country': item['area'],
                'year': item['year'],
                'mediatype': 'video'
            })
        if item['type'] == SpiderItemType.File:
            list_item.setProperty('IsPlayable', 'true')
            list_item.setArt({
                'icon':
                item['cover']
                if len(item['cover']) > 0 else get_image_path('picture.png'),
            })
            url = get_url(
                action='resolve_play_url',
                spider_class=spider_class,
                parent_item=json.dumps(parent_item),
                item=json.dumps(item),
            )
            is_folder = False
        else:
            list_item.setArt({
                'icon':
                item['cover']
                if len(item['cover']) > 0 else get_image_path('folder.png'),
            })
            url = get_url(
                action='list_items',
                spider_class=spider_class,
                parent_item=json.dumps(item),
            )
            is_folder = True
        xbmcplugin.addDirectoryItem(_HANDLE, url, list_item, is_folder)

    if has_next_page and len(items) > 0:
        list_item = xbmcgui.ListItem(label='下一页')
        list_item.setArt({'icon': get_image_path('folder.png')})
        xbmcplugin.addDirectoryItem(
            _HANDLE,
            get_url(
                action='list_items',
                spider_class=spider_class,
                parent_item=json.dumps(parent_item),
                page=page + 1,
            ),
            list_item,
            True,
        )

    xbmcplugin.endOfDirectory(_HANDLE)


def action_resolve_play_url(spider_class, parent_item, item):
    spider = spiders[spider_class]

    if len(item['sources']) > 1 and _ADDON.getSettingBool(
            'source_dialog_switch'):
        names = []
        for source in item['sources']:
            names.append(source['name'])
        ret = xbmcgui.Dialog().select('请选择播放源', names, preselect=0)
        if ret >= 0:
            source = item['sources'][ret]
        else:
            source = item['sources'][0]
    else:
        source = item['sources'][0]

    danmakus = item['danmakus']
    subtitles = item['subtitles']
    play_url = spider.resolve_play_url(source['params'])
    if len(play_url['danmakus']) > 0:
        danmakus = play_url['danmakus']
    if len(play_url['subtitles']) > 0:
        danmakus = play_url['subtitles']

    play_item = xbmcgui.ListItem(path=play_url['url'])
    if len(danmakus) > 0 and _ADDON.getSettingBool('danmaku_switch'):
        danmaku = None
        if len(danmakus) > 1 and _ADDON.getSettingBool(
                'danmaku_dialog_switch'):
            names = []
            for danmaku in danmakus:
                names.append(danmaku['name'])
            ret = xbmcgui.Dialog().select('请选择弹幕或取消', names, preselect=0)
            if ret >= 0:
                danmaku = danmakus[ret]
        else:
            danmaku = danmakus[0]
        if danmaku:
            # play_item.setSubtitles([danmaku['url']])
            set_danmaku_url_cache(danmaku['url'])
        else:
            del_danmaku_url_cache()
    elif len(subtitles) > 0:
        subtitle = None
        if len(subtitles) > 1:
            names = []
            for subtitle in subtitles:
                names.append(subtitle['name'])
            ret = xbmcgui.Dialog().select('请选择字幕或取消', names)
            if ret >= 0:
                subtitle = subtitles[ret]
        else:
            subtitle = subtitles[0]
        if subtitle:
            play_item.setSubtitles([subtitle['url']])
    if parent_item is not None:
        add_playback_record(PlaybackRecord(spider_class, parent_item, item))
    xbmcplugin.setResolvedUrl(_HANDLE, True, listitem=play_item)


def action_search(spider_class='', keyword=''):
    xbmcplugin.setPluginCategory(_HANDLE, '搜索结果')

    if len(keyword) == 0:
        kb = xbmc.Keyboard('', '请输入影片名称')
        kb.doModal()
        if not kb.isConfirmed():
            return
        keyword = kb.getText()

    for cls in spiders:
        if len(spider_class) > 0 and cls != spider_class:
            continue
        spider = spiders[cls]

        if spider.hide():
            continue

        try:
            for item in spider.search(keyword):
                if spider_class:
                    name = item['name']
                else:
                    name = '{}:{}'.format(spider.name(), item['name'])
                list_item = xbmcgui.ListItem(label=name)
                list_item.setInfo(
                    'video', {
                        'title': name,
                        'plot': item['description'],
                        'cast': item['cast'],
                        'director': item['director'],
                        'country': item['area'],
                        'year': item['year'],
                        'mediatype': 'video'
                    })
                if item['type'] == SpiderItemType.File:
                    list_item.setProperty('IsPlayable', 'true')
                    list_item.setArt({
                        'icon':
                        item['cover'] if len(item['cover']) > 0 else
                        get_image_path('picture.png'),
                    })
                    url = get_url(
                        action='resolve_play_url',
                        spider_class=cls,
                        item=json.dumps(item),
                    )
                    is_folder = False
                else:
                    list_item.setArt({
                        'icon':
                        item['cover'] if len(item['cover']) > 0 else
                        get_image_path('folder.png'),
                    })
                    url = get_url(
                        action='list_items',
                        spider_class=cls,
                        parent_item=json.dumps(item),
                    )
                    is_folder = True
                xbmcplugin.addDirectoryItem(_HANDLE, url, list_item, is_folder)
        except Exception:
            print(traceback.format_exc())

    xbmcplugin.endOfDirectory(_HANDLE)


def action_fuzzy_search(spider_class=''):
    xbmcplugin.setPluginCategory(_HANDLE, '热门搜索')

    kb = xbmc.Keyboard('', '请输入影片名称的拼音首字母')
    kb.doModal()
    if not kb.isConfirmed():
        return
    keyword = kb.getText()

    r = requests.get('http://s.video.qq.com/smartbox',
                     params={
                         'plat': 2,
                         'ver': 0,
                         'num': 10,
                         'otype': 'json',
                         'query': keyword,
                     })
    data = json.loads(r.text[13:len(r.text) - 1])

    for item in data['item']:
        list_item = xbmcgui.ListItem(label=item['word'])
        url = get_url(
            action='search',
            spider_class=spider_class,
            keyword=item['word'],
        )
        is_folder = True
        xbmcplugin.addDirectoryItem(_HANDLE, url, list_item, is_folder)

    xbmcplugin.endOfDirectory(_HANDLE)


def action_playback_records():
    xbmcplugin.setPluginCategory(_HANDLE, '播放记录')

    records = get_playback_records()
    for record in records:
        spider = spiders[record['spider_class']]
        parent_item = record['parent_item']
        item = record['item']
        list_item = xbmcgui.ListItem(label='{}:{}:{}'.format(
            spider.name(), parent_item['name'], item['name']))
        list_item.setInfo(
            'video', {
                'title': parent_item['name'],
                'plot': parent_item['description'],
                'cast': parent_item['cast'],
                'director': parent_item['director'],
                'country': parent_item['area'],
                'year': parent_item['year'],
                'mediatype': 'video'
            })
        list_item.setArt({
            'icon':
            parent_item['cover'] if len(parent_item['cover']) > 0 else
            get_image_path('picture.png'),
        })
        url = get_url(
            action='playback_record',
            record=json.dumps(record),
            ts=str(int(time.time())),
        )
        is_folder = True
        xbmcplugin.addDirectoryItem(_HANDLE, url, list_item, is_folder)

    xbmcplugin.endOfDirectory(_HANDLE)


def action_playback_record(record, ts=0):
    key = 'last_opened_playback_record'
    just_opended = False
    data = get_cache(key)
    if data:
        data = json.loads(data)
        last_record = data['record']
        last_ts = data['ts']
        just_opended = last_record['spider_class'] == record[
            'spider_class'] and last_record['parent_item']['id'] == record[
                'parent_item']['id'] and last_ts == ts

    if not just_opended:
        options = ['打开', '删除']
        ret = xbmcgui.Dialog().select('请选择要执行的操作', options, preselect=0)
        if ret >= 0:
            option = options[ret]
            if option == '删除':
                delete_playback_record(record)
                return

    action_list_items(record['spider_class'], record['parent_item'])
    set_cache(key, json.dumps({'record': record, 'ts': ts}))


def action_setting():
    _ADDON.openSettings()


def action_aliyundrive_share_url():
    aliyundrive_share_url = get_cache('aliyundrive_share_url').strip()
    if aliyundrive_share_url:
        del_cache('aliyundrive_share_url')
    else:
        kb = xbmc.Keyboard('', '请输入阿里云盘分享链接')
        kb.doModal()
        if not kb.isConfirmed():
            return
        aliyundrive_share_url = kb.getText().strip()

    spider_class = SpiderAliyunDrive.__name__
    action_list_items(
        spider_class,
        parent_item=SpiderItem(
            type=SpiderItemType.Directory,
            id=aliyundrive_share_url,
            name=aliyundrive_share_url,
        ),
    )


def action_add_favorite_record(spider_class, item):
    ret = xbmcgui.Dialog().yesno('提示', '是否要添加到收藏夹?')
    if ret:
        add_favorite_record(FavoriteRecord(spider_class, item))


def action_favorite_records():
    xbmcplugin.setPluginCategory(_HANDLE, '收藏夹')

    records = get_favorite_records()
    for record in records:
        spider = spiders[record['spider_class']]
        item = record['item']
        list_item = xbmcgui.ListItem(
            label='{}:{}'.format(spider.name(), item['name']))
        list_item.setInfo(
            'video', {
                'title': item['name'],
                'plot': item['description'],
                'cast': item['cast'],
                'director': item['director'],
                'country': item['area'],
                'year': item['year'],
                'mediatype': 'video'
            })
        list_item.setArt({
            'icon':
            item['cover']
            if len(item['cover']) > 0 else get_image_path('picture.png'),
        })
        url = get_url(action='favorite_record',
                      record=json.dumps(record),
                      ts=str(int(time.time())))
        is_folder = True
        xbmcplugin.addDirectoryItem(_HANDLE, url, list_item, is_folder)

    xbmcplugin.endOfDirectory(_HANDLE)


def action_favorite_record(record, ts=0):
    key = 'last_opened_favorite_record'
    just_opended = False
    data = get_cache(key)
    if data:
        data = json.loads(data)
        last_record = data['record']
        last_ts = data['ts']
        just_opended = last_record['spider_class'] == record[
            'spider_class'] and last_record['item']['id'] == record['item'][
                'id'] and last_ts == ts

    if not just_opended:
        options = ['打开', '删除']
        ret = xbmcgui.Dialog().select('请选择要执行的操作', options, preselect=0)
        if ret >= 0:
            option = options[ret]
            if option == '删除':
                delete_favorite_record(record)
                return

    action_list_items(record['spider_class'], record['item'])
    set_cache(key, json.dumps({'record': record, 'ts': ts}))


def router(paramstring):
    params = dict(parse_qsl(paramstring))
    if params:
        if params['action'] == 'list_items':
            action_list_items(
                params['spider_class'],
                json.loads(params['parent_item'])
                if 'parent_item' in params else None,
                int(params['page']) if 'page' in params else 1,
            )
        elif params['action'] == 'resolve_play_url':
            action_resolve_play_url(
                params['spider_class'],
                json.loads(params['parent_item'])
                if 'parent_item' in params else None,
                json.loads(params['item']),
            )
        elif params['action'] == 'search':
            action_search(
                params['spider_class'] if 'spider_class' in params else '',
                params['keyword'] if 'keyword' in params else '',
            )
        elif params['action'] == 'fuzzy_search':
            action_fuzzy_search(params['spider_class'] if 'spider_class' in
                                params else '')
        elif params['action'] == 'playback_records':
            action_playback_records()
        elif params['action'] == 'playback_record':
            action_playback_record(
                json.loads(params['record']),
                int(params['ts'] if 'ts' in params else 0),
            )
        elif params['action'] == 'setting':
            action_setting()
        elif params['action'] == 'aliyundrive_share_url':
            action_aliyundrive_share_url()
        elif params['action'] == 'add_favorite_record':
            action_add_favorite_record(
                params['spider_class'],
                json.loads(params['item']),
            )
        elif params['action'] == 'favorite_records':
            action_favorite_records()
        elif params['action'] == 'favorite_record':
            action_favorite_record(
                json.loads(params['record']),
                int(params['ts'] if 'ts' in params else 0),
            )
        else:
            raise ValueError('Invalid paramstring: {}!'.format(paramstring))
    else:
        action_homepage()


if __name__ == '__main__':
    router(sys.argv[2][1:])
