import xbmc
import xbmcgui
import os
import re

try:
    from urllib.parse import quote_plus
except ImportError:
    from urllib import quote_plus

from resources.libs.common import logging
from resources.libs.common import tools
from resources.libs.common.config import CONFIG

ACTION_PREVIOUS_MENU = 10  # ESC action
ACTION_NAV_BACK = 92  # Backspace action
ACTION_MOVE_LEFT = 1  # Left arrow key
ACTION_MOVE_RIGHT = 2  # Right arrow key
ACTION_MOVE_UP = 3  # Up arrow key
ACTION_MOVE_DOWN = 4  # Down arrow key
ACTION_MOUSE_WHEEL_UP = 104	 # Mouse wheel up
ACTION_MOUSE_WHEEL_DOWN = 105  # Mouse wheel down
ACTION_MOVE_MOUSE = 107  # Down arrow key
ACTION_SELECT_ITEM = 7  # Number Pad Enter
ACTION_BACKSPACE = 110  # ?
ACTION_MOUSE_LEFT_CLICK = 100
ACTION_MOUSE_LONG_CLICK = 108

BACK_ACTIONS = [ACTION_PREVIOUS_MENU, ACTION_NAV_BACK, ACTION_BACKSPACE]

def highlight_text(msg):
    msg = msg.replace('\n', '[NL]')
    matches = re.compile("-->Python callback/script returned the following error<--(.+?)-->End of Python script error report<--").findall(msg)
    for item in matches:
        string = '-->Python callback/script returned the following error<--{0}-->End of Python script error report<--'.format(item)
        msg = msg.replace(string, '[COLORred]{0}[/COLOR]'.format(string))
    msg = msg.replace('WARNING', '[COLORyellow]WARNING[/COLOR]').replace('ERROR', '[COLORred]ERROR[/COLOR]').replace('[NL]', '\n').replace(': EXCEPTION Thrown (PythonToCppException) :', '[COLORred]: EXCEPTION Thrown (PythonToCppException) :[/COLOR]')
    msg = msg.replace('\\\\', '\\').replace(CONFIG.HOME, '')
    return msg

def while_window(window, active=False, count=0, counter=15):
    windowopen = xbmc.getCondVisibility('Window.IsActive({0})'.format(window))
    logging.log("{0} is {1}".format(window, windowopen))
    while not windowopen and count < counter:
        logging.log("{0} is {1}({2})".format(window, windowopen, count))
        windowopen = xbmc.getCondVisibility('Window.IsActive({0})'.format(window))
        count += 1
        xbmc.sleep(500)

    while windowopen:
        active = True
        logging.log("{0} is {1}".format(window, windowopen))
        windowopen = xbmc.getCondVisibility('Window.IsActive({0})'.format(window))
        xbmc.sleep(250)
        
    return active

def show_text_box(title, msg):
    class TextBox(xbmcgui.WindowXMLDialog):
        def onInit(self):
            self.title = 101
            self.msg = 102
            self.scrollbar = 103
            self.closebutton = 201
            
            self.setProperty('texture.color1', CONFIG.COLOR1)
            self.setProperty('texture.color2', CONFIG.COLOR2)
            self.setProperty('message.title', title)
            self.setProperty('message.msg', msg)

        def onClick(self, controlid):
            if controlid == self.closebutton:
                self.close()

        def onAction(self, action):
            if action.getId() in BACK_ACTIONS:
                self.close()

    tb = TextBox("text_box.xml", CONFIG.ADDON_PATH, 'Default', title=title, msg=msg)
    tb.doModal()
    del tb

def show_qr_code(layout, imagefile, message):
    class QRCode(xbmcgui.WindowXMLDialog):
        def __init__(self, *args, **kwargs):
            self.image = kwargs["image"]
            self.text = kwargs["text"]

        def onInit(self):
            self.imagecontrol = 501
            self.textbox = 502
            self.okbutton = 503
            self.title = 504
            self.show_dialog()

        def show_dialog(self):
            self.getControl(self.imagecontrol).setImage(self.image)
            self.getControl(self.textbox).setText(self.text)
            self.getControl(self.title).setLabel(CONFIG.ADDONTITLE)
            self.setFocus(self.getControl(self.okbutton))

        def onClick(self, controlid):
            if controlid == self.okbutton:
                self.close()

        def onAction(self, action):
            if action.getId() in BACK_ACTIONS:
                self.close()

    qr = QRCode(layout, CONFIG.ADDON_PATH, 'Default', image=imagefile, text=message)
    qr.doModal()
    del qr

def show_save_data_settings():
    class FirstRun(xbmcgui.WindowXMLDialog):

        def __init__(self, *args, **kwargs):
            self.whitelistcurrent = kwargs['current']

        def onInit(self):
            self.title = 101
            self.okbutton = 201
            self.login = 303
            self.sources = 304
            self.profiles = 305
            self.playercore = 314
            self.guisettings = 315
            self.advanced = 306
            self.favourites = 307
            self.superfav = 308
            self.repo = 309
            self.whitelist = 310
            self.cache = 311
            self.packages = 312
            self.thumbs = 313
            self.show_dialog()
            self.controllist = [self.login,
                                    self.sources, self.profiles, self.playercore, self.guisettings, self.advanced,
                                    self.favourites, self.superfav, self.repo,
                                    self.whitelist, self.cache, self.packages,
                                    self.thumbs]
            self.controlsettings = ['keeplogin',
                                    'keepsources', 'keepprofiles', 'keepplayercore', 'keepguisettings', 'keepadvanced',
                                    'keepfavourites', 'keeprepos', 'keepsuper',
                                    'keepwhitelist', 'clearcache', 'clearpackages',
                                    'clearthumbs']
            for item in self.controllist:
                if CONFIG.get_setting(self.controlsettings[self.controllist.index(item)]) == 'true':
                    self.getControl(item).setSelected(True)

        def show_dialog(self):
            self.getControl(self.title).setLabel(CONFIG.ADDONTITLE)
            self.setFocus(self.getControl(self.okbutton))

        def onClick(self, controlid):
            if controlid == self.okbutton:

                for item in self.controllist:
                    at = self.controllist.index(item)
                    if self.getControl(item).isSelected():
                        CONFIG.set_setting(self.controlsettings[at], 'true')
                    else:
                        CONFIG.set_setting(self.controlsettings[at], 'false')

                if self.getControl(self.whitelist).isSelected() and not self.whitelistcurrent == 'true':
                    from resources.libs import whitelist
                    whitelist.whitelist('edit')
                
                self.close()

        def onAction(self, action):
            if action.getId() in BACK_ACTIONS:
                self.close()

    fr = FirstRun("FirstRunSaveData.xml", CONFIG.ADDON_PATH, 'Default', current=CONFIG.KEEPWHITELIST)
    fr.doModal()
    CONFIG.set_setting('first_install', 'false')
    del fr

def show_build_prompt():
    class BuildPrompt(xbmcgui.WindowXMLDialog):

        def onInit(self):
            #self.image = 101
            #self.titlebox = 102
            #self.textbox = 103
            self.buildmenu = 201
            self.ignore = 202
            #self.show_dialog()

        def show_dialog(self):
            #self.getControl(self.image).setImage(CONFIG.ADDON_FANART)
            #self.getControl(self.image).setColorDiffuse('9FFFFFFF')
            self.getControl(self.textbox).setText(self.msg)
            self.getControl(self.titlebox).setLabel(self.title)
            self.setFocusId(self.buildmenu)

        def do_build_menu(self):
            logging.log("[Current Build Check] [User Selected: Open Build Menu] [Next Check: {0}]".format(CONFIG.BUILDCHECK),
                        level=xbmc.LOGINFO)
            CONFIG.set_setting('nextbuildcheck', tools.get_date(days=CONFIG.UPDATECHECK, formatted=True))
            CONFIG.set_setting('installed', 'ignored')
            
            url = 'plugin://{0}/?mode=builds'.format(CONFIG.ADDON_ID)
            
            self.close()
            
            xbmc.executebuiltin('ActivateWindow(Programs, {0}, return)'.format(url))

        def do_ignore(self):
            logging.log("[Current Build Check] [User Selected: Ignore Build Menu] [Next Check: {0}]".format(CONFIG.BUILDCHECK),
                        level=xbmc.LOGINFO)
            CONFIG.set_setting('nextbuildcheck', tools.get_date(days=CONFIG.UPDATECHECK, formatted=True))
            CONFIG.set_setting('installed', 'ignored')
            
            self.close()

        def onAction(self, action):
            if action.getId() in BACK_ACTIONS:
                self.do_ignore()

        def onClick(self, controlid):
            if controlid == self.buildmenu:
                self.do_build_menu()
            elif controlid == self.ignore:
                self.do_ignore()

    fr = BuildPrompt("FirstRunBuild.xml", CONFIG.ADDON_PATH, 'Default')
    fr.doModal()
    del fr

def show_update_window(name='Testing Window', current='1.0', new='1.1', icon=CONFIG.ADDON_ICON, fanart=CONFIG.ADDON_FANART):
    class UpdateWindow(xbmcgui.WindowXMLDialog):

        def onAction(self, action):
            id = action.getId()
            if action.getId() in BACK_ACTIONS:
                self.do_ignore()

        def onClick(self, controlid):
            if controlid == self.fresh:
                self.do_fresh_install()
            elif controlid == self.normal:
                self.do_normal_install()
            elif controlid == self.ignore:
                self.do_ignore()

    # update = UpdateWindow("build_update_prompt.xml", CONFIG.ADDON_PATH, 'Default', name=name, current=current, new=new, icon=icon, fanart=fanart)
    # update.doModal()
    # del update
    msgcurrent = 'Die neueste Version des installierten Builds wird verwendet:[CR][COLORdeepskyblue]{1}[/COLOR]'.format(CONFIG.COLOR1, name)
    msgupdate = 'Update für das installierte Build verfügbar:[CR][COLORdeepskyblue]{1}[/COLOR]'.format(CONFIG.COLOR1, name)
    build_name = ''.format(CONFIG.COLOR1, name)
    current_version = 'Aktuelle Version: [COLORdeepskyblue]v.{1}[/COLOR]'.format(CONFIG.COLOR1, current)
    latest_version = 'Neuste Version: [COLORdeepskyblue]v.{1}[/COLOR]'.format(CONFIG.COLOR1, new)
    
    final_msg = '{0}{1}\n{2}\n{3}\n'.format(msgcurrent if current >= new else msgupdate,
                                        build_name, current_version, latest_version)
    
    install = xbmcgui.Dialog().yesno(CONFIG.ADDONTITLE, final_msg, yeslabel='[COLORlime]INSTALLIEREN[/COLOR]', nolabel='[COLORred]IGNORIEREN[/COLOR]')
    if install:
        from resources.libs.wizard import Wizard
        Wizard().build(CONFIG.BUILDNAME)      

def show_log_viewer(window_title="Viewing Log File", window_msg=None, log_file=None, ext_buttons=False):
    class LogViewer(xbmcgui.WindowXMLDialog):
        def __init__(self, *args, **kwargs):
            self.log_file = kwargs['log_file']

        def onInit(self):
            self.title = 101
            self.msg = 102
            self.scrollbar = 103
            self.upload = 201
            self.kodilog = 202
            self.oldlog = 203
            self.wizardlog = 204
            self.closebutton = 205

            if window_msg is None:
                self.logmsg = tools.read_from_file(self.log_file)
            else:
                self.logmsg = window_msg
            self.logfile = os.path.basename(self.log_file)
            
            self.buttons = 'true' if ext_buttons else 'false'
            
            self.setProperty('texture.color1', CONFIG.COLOR1)
            self.setProperty('texture.color2', CONFIG.COLOR2)
            self.setProperty('message.title', window_title)
            self.setProperty('message.logmsg', highlight_text(self.logmsg))
            self.setProperty('message.logfile', self.logfile)
            self.setProperty('message.buttons', self.buttons)

        def onClick(self, controlId):
            if controlId == self.closebutton:
                self.close()
            elif controlId == self.upload:
                self.close()
                logging.upload_log()
            elif controlId in [self.kodilog, self.oldlog, self.wizardlog]:
                if controlId == self.kodilog:
                    newmsg = logging.grab_log()
                    filename = logging.grab_log(file=True)
                elif controlId == self.oldlog:
                    newmsg = logging.grab_log(old=True)
                    filename = logging.grab_log(file=True, old=True)
                elif controlId == self.wizardlog:
                    newmsg = logging.grab_log(wizard=True)
                    filename = logging.grab_log(file=True, wizard=True)
                
                if not newmsg:
                    self.setProperty('message.title', "Error Viewing Log File")
                    self.setProperty('message.logmsg', "File does not exist or could not be read.")
                else:
                    self.logmsg = newmsg
                    self.logfile = os.path.basename(filename)
                
                    self.setProperty('message.logmsg', highlight_text(self.logmsg))
                    self.setProperty('message.logfile', self.logfile)

        def onAction(self, action):
            if action.getId() in BACK_ACTIONS:
                self.close()

    if log_file is None:
        log_file = logging.grab_log(file=True)
        
    lv = LogViewer("log_viewer.xml", CONFIG.ADDON_PATH, 'Default', log_file=log_file)
    lv.doModal()
    del lv

##############################################################
#                                                            #
#  Copyright (C) 2025 SGKodi / Kodi Unlimited Support Group  #
#                                                            #
##############################################################	