# -*- coding: utf-8 -*-
# vStream https://github.com/Kodi-vStream/venom-xbmc-addons
# Venom.
import re
import string
import unicodedata

from resources.lib.comaddon import addon, xbmc
from resources.lib.db import cDb
from resources.lib.util import QuoteSafe
import random

# rouge E26543
# jaune F7D571
# bleu clair 87CEEC  ou skyblue / hoster
# vert 37BCB5
# bleu foncer 08435A / non utiliser


class cGuiElement:

    DEFAULT_FOLDER_ICON = 'icon.png'
    # COUNT = 0
    DB = cDb()

    def __init__(self):

        addons = addon()
        
        # self.__sRootArt = cConfig().getRootArt()
        self.__sFunctionName = ''
        self.__sRootArt = 'special://home/addons/plugin.video.mando/resources/art/'
        self.__sType = 'Video'
        self.__sMeta = 0
        self.__sPlaycount = 0
        self.__sTrailer = ''
        self.__sMetaAddon = addons.getSetting('meta-view')
        self.__sImdb = ''
        self.__sTmdb = ''
        self.__sMediaUrl = ''
        self.__sSiteUrl = ''
        # contient le titre qui sera coloré
        self.__sTitle = ''
        # contient le titre propre
        self.__sCleanTitle = ''
        # titre considéré Vu
        self.__sTitleWatched = ''
        # contient le titre modifié pour BDD
        self.__sFileName = ''
        self.__sDescription = ''
        self.__sGenre = ''
        self.__sThumbnail = ''
        self.__sPoster = ''
        self.__Season = ''
        self.__Episode = ''
        self.__sIcon = self.DEFAULT_FOLDER_ICON
        self.__sFanart = 'special://home/addons/plugin.video.mando/fanart.jpg'
        self.__sDecoColor = addons.getSetting('deco_color')

        # For meta search
        # TmdbId the movie database https://developers.themoviedb.org/
        self.__TmdbId = ''
        # ImdbId pas d'api http://www.imdb.com/
        self.__ImdbId = ''
        self.__Year = ''

        self.__aItemValues = {}
        self.__aProperties = {}
        self.__aContextElements = []
        self.__sSiteName = ''
        
        # categorie utilisé pour marque-page et recherche.
        # 1 - movies/saga , 2 - tvshow/episode/anime, 5 - misc/Next
        self.__sCat = ''

    # def __len__(self): return self.__sCount

    # def getCount(self):
    #     return cGuiElement.COUNT

    def setType(self, sType):
        self.__sType = sType

    def getType(self):
        return self.__sType

    def setCat(self, sCat):
        self.__sCat = sCat

    def getCat(self):
        return self.__sCat

    def setMetaAddon(self, sMetaAddon):
        self.__sMetaAddon = sMetaAddon

    def getMetaAddon(self):
        return self.__sMetaAddon

    def setTrailer(self, sTrailer):
        self.__sTrailer = sTrailer

    def getTrailer(self):
        return self.__sTrailer

    def setTmdbId(self, data):
        self.__TmdbId = data

    def getTmdbId(self):
        return self.__TmdbId

    def setImdbId(self, data):
        self.__ImdbId = data

    def getImdbId(self):
        return self.__ImdbId

    def setYear(self, data):
        self.__Year = data

    def getYear(self):
        return self.__Year

    def setGenre(self, genre):
        self.__sGenre = genre

    def getGenre(self):
        return self.__sGenre

    def setMeta(self, sMeta):
        self.__sMeta = sMeta

    def getMeta(self):
        return self.__sMeta

    def setMediaUrl(self, sMediaUrl):
        self.__sMediaUrl = sMediaUrl

    def getMediaUrl(self):
        return self.__sMediaUrl

    def setSiteUrl(self, sSiteUrl):
        self.__sSiteUrl = sSiteUrl

    def getSiteUrl(self):
        return self.__sSiteUrl

    def setSiteName(self, sSiteName):
        self.__sSiteName = sSiteName

    def getSiteName(self):
        return self.__sSiteName

    def setFileName(self, sFileName):
        self.__sFileName = self.str_conv(sFileName)

    def getFileName(self):
        return self.__sFileName

    def setFunction(self, sFunctionName):
        self.__sFunctionName = sFunctionName

    def getFunction(self):
        return self.__sFunctionName

    def TraiteTitre(self, sTitle):

        # Format Obligatoire a traiter via le fichier source
        # -------------------------------------------------
        # Episode 7 a 9 > Episode 7-9
        # Saison 1 à ? > Saison 1-?
        # Format de date > 11/22/3333 ou 11-22-3333

        # convertion unicode ne fonctionne pas avec les accents

        try:
            # traitement du titre pour les caracteres spéciaux déplacé dans parser plus global
            # traitement du titre pour retirer le - quand c'est une Saison. Tiret, tiret moyen et cadratin
            sTitle = sTitle.replace(' - Saison', ' Saison').replace(' – Saison', ' Saison').replace(' — Saison', ' Saison')

            sTitle = sTitle.decode('utf-8')
        except:
            pass

        # recherche l'année, uniquement si entre caractere special a cause de 2001 odysse de l'espace ou k2000
        string = re.search('([^\w ][0-9]{4}[^\w ])', sTitle)
        if string:
            sTitle = sTitle.replace(string.group(0), '')
            self.__Year = str(string.group(0)[1:5])
            self.addItemValues('year', self.__Year)

        # recherche une date
        string = re.search('([\d]{2}[\/|-]\d{2}[\/|-]\d{4})', sTitle)
        if string:
            sTitle = sTitle.replace(string.group(0), '')
            self.__Date = str(string.group(0))
            sTitle = '%s (%s) ' % (sTitle, self.__Date)

        #~ #recherche Lang
        #~ index = {' vostfr': ' [VOSTFR]', ' vf': ' [VF]', ' truefrench': ' [TrueFrench]'}
        #~ for cle in index:
            #~ sTitle = sTitle.replace(cle.upper(), index[cle]).replace(cle, index[cle]).replace('(%s)' % (cle), index[cle])

        #~ #recherche Qualité
        #~ index = {'1080i': '(1080)', '1080p': '(1080)', '1080I': '(1080)', '1080P': '(1080)', '720i': '(720)', '720p': '(720)', '720I': '(720)', '720P': '(720)'}
        #~ for cle in index:
            #~ sTitle = sTitle.replace(cle, index[cle]).replace('[%s]' % (cle), index[cle])

        # Recherche saison et episode a faire pr serie uniquement
        if True:
            m = re.search('(?i)(?:^|[^a-z])((?:E|(?:\wpisode\s?))([0-9]+(?:[\-\.][0-9\?]+)*))', sTitle, re.UNICODE)
            if m:
                # ok y a des episodes
                sTitle = sTitle.replace(m.group(1), '')
                ep = m.group(2)
                if len(ep) == 1:
                    ep = '0' + ep
                self.__Episode = ep
                self.addItemValues('Episode', self.__Episode)

                # pour les saisons
                m = re.search('(?i)( s(?:aison +)*([0-9]+(?:\-[0-9\?]+)*))', sTitle, re.UNICODE)
                if m:
                    sTitle = sTitle.replace(m.group(1), '')
                    sa = m.group(2)
                    if len(sa) == 1:
                        sa = '0' + sa
                    self.__Season = sa
                    self.addItemValues('Season', self.__Season)

            else:
                # pas d'episode mais y a t il des saisons ?
                m = re.search('(?i)( s(?:aison +)*([0-9]+(?:\-[0-9\?]+)*))', sTitle, re.UNICODE)
                if m:
                    sTitle = sTitle.replace(m.group(1), '')
                    sa = m.group(2)
                    if len(sa) == 1:
                        sa = '0' + sa
                    self.__Season = sa
                    self.addItemValues('Season', self.__Season)

        # vire doubles espaces
        sTitle = re.sub(' +', ' ', sTitle)
        # enleve les crochets et les parentheses si elle sont vides
        sTitle = sTitle.replace('()', '').replace('[]', '').replace('- -', '-')

        # vire espace a la fin et les - (attention, il y a 2 tirets differents meme si invisible a l'oeil nu et un est en unicode)
        sTitle = re.sub('[- –]+$', '', sTitle)
        # et au debut
        if sTitle.startswith(' '):
            sTitle = sTitle[1:]

        # recherche les Tags restant : () ou [] sauf tag couleur
        sTitle = re.sub('([\(|\[](?!\/*COLOR)[^\)\(\]\[]+?[\]|\)])', '[COLOR ' + self.__sDecoColor + ']\\1[/COLOR]', sTitle)

        # on reformate SXXEXX Titre [tag] (Annee)
        sTitle2 = ''
        if self.__Season:
            sTitle2 = sTitle2 + 'S' + self.__Season
        if self.__Episode:
            sTitle2 = sTitle2 + 'E' + self.__Episode

        # Titre unique pour pour marquer VU (avec numéro de l'épisode pour les séries)
        self.__sTitleWatched = self.str_conv(sTitle).replace(' ', '')
        if sTitle2:
            self.__sTitleWatched += '_' + sTitle2

        if sTitle2:
            sTitle2 = '[COLOR %s]%s[/COLOR] ' % (self.__sDecoColor, sTitle2)

        sTitle2 = sTitle2 + sTitle

        if self.__Year:
            sTitle2 = '%s [COLOR %s](%s)[/COLOR]' % (sTitle2, self.__sDecoColor, self.__Year)

        #Py3
        try:
            if "Ã©" in sTitle2:
                sTitle2 = sTitle2.encode("iso-8859-1", 'ignore')
                sTitle2 = str(sTitle2, encoding="utf8", errors='ignore')
        except:
            pass

        # on repasse en utf-8
        try:
            return sTitle2.encode('utf-8')
        except AttributeError:
            return sTitle2

    def getEpisodeTitre(self, sTitle):

        string = re.search('(?i)(e(?:[a-z]+sode\s?)*([0-9]+))', str(sTitle))
        if string:
            sTitle = sTitle.replace(string.group(1), '')
            self.__Episode = ('%02d' % int(string.group(2)))
            sTitle = '%s [COLOR %s]E%s[/COLOR]' % (sTitle, self.__sDecoColor, self.__Episode)
            self.addItemValues('Episode', self.__Episode)
            return sTitle, True

        return sTitle, False

    def setTitle(self, sTitle):
        #Convertie les bytes en strs pour le replace.
        if xbmc.getInfoLabel('system.buildversion')[0:2] >= '19':
            if isinstance(sTitle, bytes):
                sTitle = sTitle.decode('utf-8')
        
        self.__sCleanTitle = sTitle.replace('[]', '').replace('()', '').strip()
        try:
            sTitle = sTitle.strip().decode('utf-8')
        except:
            pass

        if not sTitle.startswith('[COLOR'):
            self.__sTitle = self.TraiteTitre(sTitle)
        else:
            self.__sTitle = sTitle

    def getTitle(self):
        return self.__sTitle

    def getCleanTitle(self):
        return self.__sCleanTitle

#    def setTitleWatched(self, sTitleWatched):
#        self.__sTitleWatched = sTitleWatched

    def getTitleWatched(self):
        return self.__sTitleWatched

    def setDescription(self, sDescription):
        #Py3
        try:
            self.__sDescription = sDescription.encode('latin-1')
        except:
            self.__sDescription = sDescription

    def getDescription(self):
        return self.__sDescription

    def setThumbnail(self, sThumbnail):
        self.__sThumbnail = sThumbnail

    def getThumbnail(self):
        return self.__sThumbnail

    def setPoster(self, sPoster):
        self.__sPoster = sPoster

    def getPoster(self):
        return self.__sPoster

    def setFanart(self, sFanart):
        if (sFanart != ''):
            self.__sFanart = sFanart

    def setMovieFanart(self):
        self.__sFanart = self.__sFanart

    def setTvFanart(self):
        self.__sFanart = self.__sFanart

    def setDirectTvFanart(self):
        self.__sFanart = self.__sFanart

    def setDirFanart(self, sIcon):
        self.__sFanart = self.__sFanart

    def getFanart(self):
        return self.__sFanart

    def setIcon(self, sIcon):
        try:
            self.__sIcon = unicode(sIcon, 'utf-8')
        except:
            self.__sIcon = sIcon
        self.__sIcon = self.__sIcon.encode('utf-8')
        self.__sIcon = QuoteSafe(self.__sIcon)

    def getIcon(self):
        # if 'http' in self.__sIcon:
        #    return UnquotePlus(self.__sIcon)
        folder = 'special://home/addons/plugin.video.mando/resources/art'
        path = '/'.join([folder, self.__sIcon])
        # return os.path.join(unicode(self.__sRootArt, 'utf-8'), self.__sIcon)
        return path

    def addItemValues(self, sItemKey, mItemValue):
        self.__aItemValues[sItemKey] = mItemValue

    def getItemValue(self, sItemKey):
        if sItemKey not in self.__aItemValues:
            return
        return self.__aItemValues[sItemKey]

    def getWatched(self):

        # Fonctionne pour marquer lus un dossier
        if not self.getTitleWatched():
            return 0

        meta = {}
        meta['title'] = self.getTitleWatched()
        meta['site'] = self.getSiteUrl()

        data = self.DB.get_watched(meta)
        return data

    def str_conv(self, data):
        # Pas d'autre solution pour le moment que de faire comme ca.
        if isinstance(data, str):
            # Must be encoded in UTF-8
            try:
                data = data.decode('utf8')
            except AttributeError:
                pass

        try:
            data = data.decode('utf8')
        except (AttributeError, UnicodeEncodeError):
            pass

        data = unicodedata.normalize('NFKD', data).encode('ascii', 'ignore')
        # cherche la saison et episode puis les balises [color]titre[/color]
        # data, saison = self.getSaisonTitre(data)
        # data, episode = self.getEpisodeTitre(data)
        # supprimer les balises
        data = re.sub(r'\[.*\]|\(.*\)', r'', str(data))
        data = data.replace('VF', '').replace('VOSTFR', '').replace('FR', '')
        # data = re.sub(r'[0-9]+?', r'', str(data))
        data = data.replace('-', ' ')  # on garde un espace pour que Orient-express ne devienne pas Orientexpress pour la recherche tmdb
        data = data.replace('Saison', '').replace('saison', '').replace('Season', '').replace('Episode', '').replace('episode', '')
        data = re.sub('[^%s]' % (string.ascii_lowercase + string.digits), ' ', data.lower())
        # data = QuotePlus(data)

        # data = data.decode('string-escape')
        return data

    def getInfoLabel(self):
        meta = {
            'title': xbmc.getInfoLabel('ListItem.title'),
            # 'label': xbmc.getInfoLabel('ListItem.title'),
            'originaltitle': xbmc.getInfoLabel('ListItem.originaltitle'),
            'year': xbmc.getInfoLabel('ListItem.year'),
            'genre': xbmc.getInfoLabel('ListItem.genre'),
            'director': xbmc.getInfoLabel('ListItem.director'),
            'country': xbmc.getInfoLabel('ListItem.country'),
            'rating': xbmc.getInfoLabel('ListItem.rating'),
            'votes': xbmc.getInfoLabel('ListItem.votes'),
            'mpaa': xbmc.getInfoLabel('ListItem.mpaa'),
            'duration': xbmc.getInfoLabel('ListItem.duration'),
            'trailer': xbmc.getInfoLabel('ListItem.trailer'),
            'writer': xbmc.getInfoLabel('ListItem.writer'),
            'studio': xbmc.getInfoLabel('ListItem.studio'),
            'tagline': xbmc.getInfoLabel('ListItem.tagline'),
            'plotoutline': xbmc.getInfoLabel('ListItem.plotoutline'),
            'plot': xbmc.getInfoLabel('ListItem.plot'),
            'cover_url': xbmc.getInfoLabel('ListItem.Art(thumb)'),
            'backdrop_url': xbmc.getInfoLabel('ListItem.Art(fanart)'),
            'imdb_id': xbmc.getInfoLabel('ListItem.IMDBNumber'),
            'season': xbmc.getInfoLabel('ListItem.season'),
            'episode': xbmc.getInfoLabel('ListItem.episode')
            }

        if 'title' in meta and meta['title']:
            meta['title'] = self.getTitle()

        for key, value in meta.items():
            self.addItemValues(key, value)

        if 'backdrop_url' in meta and meta['backdrop_url']:
            self.addItemProperties('fanart_image', meta['backdrop_url'])
            self.__sFanart = meta['backdrop_url']
        if 'trailer' in meta and meta['trailer']:
            self.__sTrailer = meta['trailer']
        if 'cover_url' in meta and meta['cover_url']:
            self.__sThumbnail = meta['cover_url']
            self.__sPoster = meta['cover_url']

        return

    def getMetadonne(self):
        metaType = self.getMeta()
        if metaType == 0:  # non media -> on sort, et on enleve le fanart
            self.addItemProperties('fanart_image', '')
            return

        from resources.lib.tmdb import cTMDb
        TMDb = cTMDb()

        sTitle = self.__sFileName

        # sTitle = self.__sTitle.decode('latin-1').encode('utf-8')
        # sTitle = re.sub(r'\[.*\]|\(.*\)', r'', str(self.__sFileName))
        # sTitle = sTitle.replace('VF', '').replace('VOSTFR', '').replace('FR', '')

        # On nettoie le titre pour la recherche
        sTitle = sTitle.replace('version longue', '')

        # Integrale de films, on nettoie le titre pour la recherche
        if metaType == 3:
            sTitle = sTitle.replace('integrales', '')
            sTitle = sTitle.replace('integrale', '')
            sTitle = sTitle.replace('2 films', '')
            sTitle = sTitle.replace('6 films', '')
            sTitle = sTitle.replace('7 films', '')
            sTitle = sTitle.replace('trilogie', '')
            sTitle = sTitle.replace('trilogy', '')
            sTitle = sTitle.replace('quadrilogie', '')
            sTitle = sTitle.replace('pentalogie', '')
            sTitle = sTitle.replace('octalogie', '')
            sTitle = sTitle.replace('hexalogie', '')
            sTitle = sTitle.replace('tetralogie', '')
            sTitle = sTitle.strip()
            if sTitle.endswith(' les'):
                sTitle = sTitle[:-4]
            if sTitle.endswith(' la') or sTitle.endswith(' l') :
                sTitle = sTitle[:-3]
            sTitle = sTitle.strip()

        sType = str(metaType).replace('1', 'movie').replace('2', 'tvshow').replace('3', 'collection').replace('4', 'anime').replace('7', 'person').replace('8', 'network')

        meta = {}
        if sType:
            args = (sType, sTitle)
            kwargs = {}
            if (self.__ImdbId):
                kwargs['imdb_id'] = self.__ImdbId
            if (self.__TmdbId):
                kwargs['tmdb_id'] = self.__TmdbId
            if (self.__Year):
                kwargs['year'] = self.__Year
            if (self.__Season):
                kwargs['season'] = self.__Season
            if (self.__Episode):
                kwargs['episode'] = self.__Episode

            try:
                meta = TMDb.get_meta(*args, **kwargs)
            except:
                pass

        else:
            return

        meta['title'] = self.getTitle()

        if 'media_type' in meta:
            meta.pop('media_type')

        if 'imdb_id' in meta:
            imdb_id = meta.pop('imdb_id')
            if imdb_id:
                self.__ImdbId = imdb_id

        if 'tmdb_id' in meta:
            tmdb_id = meta.pop('tmdb_id')
            if tmdb_id:
                self.__TmdbId = tmdb_id

        if 'tvdb_id' in meta:
#            if meta['tvdb_id']:
#             self.__TvdbId = meta['tvdb_id']
            meta.pop('tvdb_id')

        # Si fanart trouvé dans les meta alors on l'utilise, sinon on n'en met pas
        if 'backdrop_url' in meta:
            url = meta.pop('backdrop_url')
            if url:
                self.addItemProperties('fanart_image', url)
                self.__sFanart = url
            else:
                self.addItemProperties('fanart_image', '')

        if 'backdrop_path' in meta:
            meta.pop('backdrop_path')

        if 'poster_path' in meta:
            meta.pop('poster_path')

        if 'cover_url' in meta:
            cover = meta.pop('cover_url')
            if cover:
                self.__sThumbnail = cover
                self.__sPoster = cover

        if 'trailer' in meta and meta['trailer']:
            self.__sTrailer = meta['trailer']

        for key, value in meta.items():
            self.addItemValues(key, value)

        return

    def getItemValues(self):
        self.addItemValues('Title', self.getTitle())

        # https://kodi.wiki/view/InfoLabels
        # https://codedocs.xyz/xbmc/xbmc/group__python__xbmcgui__listitem.html#ga0b71166869bda87ad744942888fb5f14

        # - Video Values:
        # - genre : string (Comedy)
        # - year : integer (2009)
        # - episode : integer (4)
        # - season : integer (1)
        # - top250 : integer (192)
        # - tracknumber : integer (3)
        # - rating : float (6.4) - range is 0..10
        # - watched : depreciated - use playcount instead
        # - playcount : integer (2) - number of times this item has been played
        # - overlay : integer (2) - range is 0..8. See GUIListItem.h for values
        # - cast : list (Michal C. Hall)
        # - castandrole : list (Michael C. Hall|Dexter)
        # - director : string (Dagur Kari)
        # - mpaa : string (PG-13)
        # - plot : string (Long Description)
        # - plotoutline : string (Short Description)
        # - title : string (Big Fan)
        # - originaltitle : string (Big Fan)
        # - sorttitle : string (Big Fan)
        # - duration : string (3:18)
        # - studio : string (Warner Bros.)
        # - tagline : string (An awesome movie) - short description of movie
        # - writer : string (Robert D. Siegel)
        # - tvshowtitle : string (Heroes)
        # - premiered : string (2005-03-04)
        # - status : string (Continuing) - status of a TVshow
        # - code : string (tt0110293) - IMDb code
        # - aired : string (2008-12-07)
        # - credits : string (Andy Kaufman) - writing credits
        # - lastplayed : string (Y-m-d h:m:s = 2009-04-05 23:16:04)
        # - album : string (The Joshua Tree)
        # - artist : list (['U2'])
        # - votes : string (12345 votes)
        # - trailer : string (/home/user/trailer.avi)
        # - dateadded : string (Y-m-d h:m:s = 2009-04-05 23:16:04)

        if self.getMetaAddon() == 'true':
            self.getMetadonne()

        # tmdbid
        if self.getTmdbId():
            self.addItemProperties('TmdbId', str(self.getTmdbId()))
            self.addItemValues('DBID', str(self.getTmdbId()))

        # imdbid
        if self.getImdbId():
            self.addItemProperties('ImdbId', str(self.getImdbId()))

        # Utilisation des infos connues si non trouvées
        if not self.getItemValue('plot') and self.getDescription():
            self.addItemValues('plot', self.getDescription())
        if not self.getItemValue('year') and self.getYear():
            self.addItemValues('year', self.getYear())
        if not self.getItemValue('genre') and self.getGenre():
            self.addItemValues('genre', self.getGenre())
        # if not self.getItemValue('cover_url') and self.getThumbnail():
            # self.addItemValues('cover_url', self.getThumbnail())
        # if not self.getItemValue('backdrop_url') and self.getPoster():
            # self.addItemValues('backdrop_url', self.getPoster())
        if not self.getItemValue('trailer'):
            if self.getTrailer():
                self.addItemValues('trailer', self.getTrailer())
            # else:
                # self.addItemValues('trailer', self.getDefaultTrailer())

        # Used only if there is data in db, overwrite getMetadonne()
        w = self.getWatched()
        if w == 1:
            self.addItemValues('playcount', w)

        self.addItemProperties('siteUrl', self.getSiteUrl())
        self.addItemProperties('sCleanTitle', self.getFileName())
        self.addItemProperties('sId', self.getSiteName())
        self.addItemProperties('sFav', self.getFunction())
        self.addItemProperties('sCat', str(self.getCat()))
        self.addItemProperties('sMeta', str(self.getMeta()))

        return self.__aItemValues

    def addItemProperties(self, sPropertyKey, mPropertyValue):
        self.__aProperties[sPropertyKey] = mPropertyValue

    def getItemProperties(self):
        return self.__aProperties

    def addContextItem(self, oContextElement):
        self.__aContextElements.append(oContextElement)

    def getContextItems(self):
        return self.__aContextElements
    
    # Des vidéos pour remplacer des bandes annnonces manquantes
    def getDefaultTrailer(self):
        from resources.lib.tmdb import cTMDb
        trailers = ['WWkYjM3ZXxU',
                    'LpvKI7I5rF4',
                    'svTVRDgI08Y',
                    'DUpVqwceQaA',
                    'mnsMnskJ3cQ',
                    'M0_vxs6FPbQ']

        trailer_id = random.choice(trailers)
        return cTMDb.URL_TRAILER % trailer_id
