__filename__ = "webapp_headerbuttons.py"
__author__ = "Bob Mottram"
__license__ = "AGPL3+"
__version__ = "1.1.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@freedombone.net"
__status__ = "Production"


import os
import time
from datetime import datetime
from happening import todaysEventsCheck
from happening import thisWeeksEventsCheck
from webapp_utils import htmlHighlightLabel


def headerButtonsTimeline(defaultTimeline: str,
                          boxName: str,
                          pageNumber: int,
                          translate: {},
                          usersPath: str,
                          mediaButton: str,
                          blogsButton: str,
                          featuresButton: str,
                          newsButton: str,
                          inboxButton: str,
                          dmButton: str,
                          newDM: str,
                          repliesButton: str,
                          newReply: str,
                          minimal: bool,
                          sentButton: str,
                          sharesButtonStr: str,
                          bookmarksButtonStr: str,
                          eventsButtonStr: str,
                          moderationButtonStr: str,
                          newPostButtonStr: str,
                          baseDir: str,
                          nickname: str, domain: str,
                          timelineStartTime,
                          iconsAsButtons: bool,
                          userPages: []) -> str:
    """Returns the header at the top of the timeline, containing
    buttons for inbox, outbox, search, calendar, etc
    """
    # start of the button header with inbox, outbox, etc
    # TODO: [rename] containerHeader -> menu (or similar)

    tlStr = '\t<div class="containerHeader">\n'


    # TODO: Group _all_ items that are hidden in 'minimal' mode ?
    #       - Are there others elsewhere in the code ?

    # All menu items default to text buttons
    # Add class "icon-button" to overwrite default behaviour
    # NOTE: Currently handled further down in loops over navButtonList and navIconList

    # Menu buttons are split into two sections
    #   - Navigation buttons    :   Informational pages, e.g. Inbox
    #   - Action buttons        :   More clear action, e.g. Search, Create Post
    #                               default appearance text; use CSS class(es) to re-style

    # A list of buttons to be rendered as html,
    # each item being a tuple containing
    #   - ref name
    #   - dictionary of unique config
    # Each dict has:
    #   - pageRef           :   the url snippet
    #   - translationText   :   text to be displayed
    #   - highlightLabel    :   boolean to determine highlight
    #   - isIcon            :   boolean to trigger specific CSS class addition(s) for icon buttons
    #   - class             :   string of class(es) to append
    #   - iconClass         :   string of class(es) to append, only regarding icons

    # Buttons should be added in the order you wish them to appear in the menu
    navButtonList = []
    navIconList = []

    # Use this to selectively append to one or other of the above lists
    activeButtonList = navButtonList

    # Too many buttons - some visibility can be toggled
    # TODO: Show/Hide menu buttons should not require page reload!
    #       Implement checkbox method
    #       Requires grouping the buttons that are shown/hidden ?
    # TODO: The 'minimal' attribute could be done using CSS class ?

    # Minimal View only shows:
    # - Inbox
    # - Outbox
    # - DM
    # - Replies
    # - News        # TODO: Should this be in minimal view? 'Media' and 'Blogs' are not ...

    # NOTE: "Action" buttons (icons in default Epicyon) are always visible

    activeButtonList.append(('inbox',
        {'pageRef': '/inbox',
        'translateText': 'Inbox'}
    ))
    activeButtonList.append(('outbox',
        {'pageRef': '/outbox',
        'translateText': 'Outbox'}
    ))
    activeButtonList.append(('dm',
        {'pageRef': '/dm',
        'translateText': 'DM',
        'highlightLabel': newDM}
    ))
    activeButtonList.append(('tlreplies',
        {'pageRef': '/tlreplies',
        'translateText': 'Replies',
        'highlightLabel': newReply}
    ))

    if (defaultTimeline == 'tlfeatures' and boxName in userPages) \
            or (not defaultTimeline == 'tlfeatures' and not minimal):
        activeButtonList.append(('tlblogs',
            {'pageRef': '/tlblogs',
            'translateText': 'Blogs'}
        ))
        # The blog translation text should be 'Article' for News instances
        if defaultTimeline == 'tlfeatures':
            activeButtonList[-1][1]['translateText'] = 'Article'
        activeButtonList.append(('tlmedia',
            {'pageRef': '/tlmedia',
            'translateText': 'Media'}
        ))
        activeButtonList.append(('tlshares',
            {'pageRef': '/tlshares',
            'translateText': 'Shares',
            'highlightLabel': newShare}
        ))
        activeButtonList.append(('tlbookmarks',
            {'pageRef': '/tlbookmarks',
            'translateText': 'Bookmarks'}
        ))
        activeButtonList.append(('tlevents',
            {'pageRef': '/tlevents',
            'translateText': 'Events'}
        ))
        if moderator:
            activeButtonList.append(('moderation',
                {'pageRef': '/moderation',
                'translateText': 'Mod',
                'highlightLabel': newReport}
            ))

    # Single out the "instance-type" button, and move to front of list
    # NOTE: Current instance types are: 'tlblogs', 'tlmedia', 'tlfeatures'
    for i, (name, config) in enumerate(activeButtonList):
        if name == defaultTimeline:
            tmp = activeButtonList.pop(i)
            activeButtonList.insert(0, tmp)
            break


    # start of headericons list

    # Override iconsAsButtons setting for News instance
    if defaultTimeline == 'tlfeatures':
        iconsAsButtons = True

    # Only append to iconList if necessary
    if not iconsAsButtons:
        activeButtonList = navIconList

    # show an icon for new follow approvals
    followApprovals = False
    followRequestsFilename = \
        baseDir + '/accounts/' + \
        nickname + '@' + domain + '/followrequests.txt'
    if os.path.isfile(followRequestsFilename):
        with open(followRequestsFilename, 'r') as f:
            for line in f:
                if len(line) > 0:
                    # show follow approvals icon
                    followApprovals = True
                    break

    # NOTE: Certain buttons only appear when relevant

    # TODO: Determine if approvals (currently appended at end of activeButtonList)
    #       and events should be in a separate list;
    #       e.g. notificationButtonList
    #       Having its' own <div> for instance would allow more versatile styling
    if followApprovals:
        activeButtonList.append(('followers',
            {'pageRef': '/followers',
            'translateText': 'Approve follow requests',
            'iconClass': 'icon-newfollow'}
        ))

    # Only show todays events buttons on the first inbox page
    if boxName == 'inbox' and pageNumber == 1:
        if todaysEventsCheck(baseDir, nickname, domain):
            now = datetime.now()
            todayRef = '/calendar?year=' + str(now.year) + \
                    '?month=' + str(now.month) + \
                    '?day=' + str(now.day)
            activeButtonList.append(('today-event',
                {'pageRef': todayRef,
                'translateText': 'Happening Today',
                'class': 'button-event'}
            ))
        if thisWeeksEventsCheck(baseDir, nickname, domain):
            activeButtonList.append(('week-event',
                {'pageRef': '/calendar',
                'translateText': 'Happening Today',
                'class': 'button-event'}
            ))


    # NOTE: CSS used to show or hide these based on screen size
    activeButtonList.append(('newswire',
        {'pageRef': '/newswiremobile',
        'translateText': 'Newswire',
        'class': 'mobile-view',
        'iconClass': 'icon-newswire'}
    ))
    activeButtonList.append(('links',
        {'pageRef': '/linksmobile',
        'translateText': 'Links',
        'class': 'mobile-view',
        'iconClass': 'icon-links'}
    ))

    # what screen to go to when a new post is created
    # The following produces one button/icon for "new post" dependent on current viewed page
    if boxName == 'dm':
        activeButtonList.append(('newdm',
            {'pageRef': '/newdm',
            'translateText': 'Create a new DM'}
        ))
    elif boxName == 'tlblogs' or boxName == 'tlfeatures':
        activeButtonList.append(('newblog',
            {'pageRef': '/newblog',
            'translateText': 'Create a new post'}
        ))
    elif boxName == 'tlevents':
        activeButtonList.append(('newevent',
            {'pageRef': '/newevent',
            'translateText': 'Create a new event'}
        ))
    else:
        if not manuallyApproveFollowers:
            activeButtonList.append(('newpost',
                {'pageRef': '/newpost',
                'translateText': 'Create a new post'}
            ))
        else:
            activeButtonList.append(('newfollowers',
                {'pageRef': '/newfollowers',
                'translateText': 'Create a new post'}
            ))
    # 'icon-<type>' is solely used for the CSS to load appropriate icon
    activeButtonList[-1][1]['iconClass'] = 'icon-newpost'

    activeButtonList.append(('calendar',
        {'pageRef': calendarPath,
        'translateText': 'Calendar',
        'iconClass': 'icon-calendar'}
    ))
    activeButtonList.append(('search',
        {'pageRef': '/search',
        'translateText': 'Search',
        'iconClass': 'icon-search'}
    ))

    # TODO: Less hacky solution - or make sure "settings" button has an icon
    if defaultTimeline == 'tlfeatures':
        activeButtonList.append(('editprofile',
            {'pageRef': '/editprofile',
            'translateText': 'Settings'}
        ))
    else:
        activeButtonList.append(('minimal',
            {'pageRef': '/minimal',
            'translateText': 'Show/Hide Buttons',
            'iconClass': 'icon-showhide'}
        ))


    # Generate HTML lists

    navButtonStr = ""
    if navButtonList:
        navButtonStr += '\t\t<div class="navbuttons">\n'
        navButtonStr += '\t\t\t<ul class="button-bar">\n'
        for name, config in navButtonList:
            classStr = 'button'
            textStr = ''
    
            if 'class' in config:
                classStr += ' ' + config['class']
    
            if 'highlightLabel' in config and config['highlightLabel']:
                if name == boxName:
                    classStr += ' button-selected-highlighted'
                else:
                    classStr += ' button-highlighted'
                # TODO: Replace 'config' dereference with 'True' as it always will be by this point ?
                textStr = htmlHighlightLabel(translate[config['translateText']], \
                                config['highlightLabel'])
            else:
                if name == boxName:
                    classStr += ' button-selected'
                textStr += translate[config['translateText']]
    
            navButtonStr += (f"\t\t\t\t<a class=\"{classStr}\" href=\"{usersPath}{config['pageRef']}\">\n"
                             f'\t\t\t\t\t<li>{textStr}</li>\n'
                             f'\t\t\t\t</a>\n')
        navButtonStr += '\t\t\t</ul>\n\t\t</div>\n'

    navIconStr = ""
    if navIconList:
        navIconStr += '\t\t<div class="actionbuttons">\n'
        navIconStr += '\t\t\t<ul class="button-bar">\n'

        # TODO: [rename] 'timelineicon' should maybe be more generic, e.g 'icon-button'

        # Generate HTML list
        for name, config in navIconList:
            if iconsAsButtons:
                classStr = 'button'
            else:
                # Currently 'timelineicon' denotes an icon instead of text button
                classStr = 'timelineicon'
                # NOTE: If iconClass is missing, expect some kind of failed output
                #       CSS alone is responsible for what image will be displayed, etc
                if 'iconClass' in config:
                    classStr += ' ' + config['iconClass']

            if 'class' in config:
                classStr += ' ' + config['class']

            if 'highlightLabel' in config:
                textStr = htmlHighlightLabel(translate[config['translateText']], config['highlightLabel'])
            else:
                textStr = translate[config['translateText']]

            navIconStr += (f"\t\t\t\t<a class=\"{classStr}\" href=\"{usersPath}{config['pageRef']}\">\n"
                                f'\t\t\t\t\t<li>{textStr}</li>\n'
                                f'\t\t\t\t</a>\n')

        navIconStr += '\t\t\t</ul>\n\t\t</div>\n'

    # benchmark 5
    if timelineStartTime:
        timeDiff = int((time.time() - timelineStartTime) * 1000)
        if timeDiff > 100:
            print('TIMELINE TIMING ' + boxName + ' 5 = ' + str(timeDiff))


    # Compile HTML parts
    tlStr += navButtonStr + navIconStr

    # End header button section
    tlStr += '\t</div>\n'

    return tlStr


def headerNewsTabs(boxName: str,
                   translate: {},
                   usersPath: str,
                   baseDir: str,
                   authorized: bool,
                   userPages: []) -> str:
    navTabList = []

    navTabList.append(('tlfeatures',
        {'pageRef': '/tlfeatures',
        'translateText': 'Features'}
    ))
    navTabList.append(('newswiremobile',
        {'pageRef': '/newswiremobile',
        'translateText': 'Newswire',
        'class': 'tab-news'}
    ))
#    navTabList.append(('calendar',
#        {'pageRef': '/calendar',
#        'translateText': 'Calendar'}
#    ))
    navTabList.append(('linksmobile',
        {'pageRef': '/linksmobile',
        'translateText': 'Links',
        'class': 'tab-links'}
    ))

    if authorized:
        navTabList.append(('inbox',
            {'pageRef': '/inbox',
            'translateText': 'User'}
        ))

    navStr = '\t\t<div class="section navtabs">\n'
    navStr += '\t\t\t<ul>\n'

    for name, config in navTabList:
        classStr = ''

        if name == boxName:
            classStr = 'tab-highlight'
        elif name == 'inbox' and userPages and boxName in userPages:
            classStr = 'tab-highlight'

        if 'class' in config:
            classStr += ' ' + config['class']

        textStr = translate[config['translateText']]

        navStr += (f"\t\t\t\t<a class=\"{classStr}\" href=\"{usersPath}{config['pageRef']}\">\n"
                   f'\t\t\t\t\t<li>{textStr}</li>\n'
                   f'\t\t\t\t</a>\n')

    navStr += '\t\t\t</ul>\n\t\t</div>\n'
    
    return navStr