# w.c.s. - web application for online forms
# Copyright (C) 2005-2019  Entr'ouvert
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.

from quixote import get_request, get_response, get_session, redirect
from quixote.html import TemplateIO, htmltext, htmlescape

from ..qommon import _
from ..qommon import errors
from ..qommon.backoffice.menu import html_top

from wcs.carddef import CardDef
from .management import ManagementDirectory, FormPage, FormFillPage, FormBackOfficeStatusPage


class DataManagementDirectory(ManagementDirectory):
    _q_exports = ['']

    def _q_traverse(self, path):
        get_response().breadcrumb.append(('data/', _('Cards')))
        return super(ManagementDirectory, self)._q_traverse(path)

    def is_accessible(self, user):
        if not user.can_go_in_backoffice():
            return False
        # only include data management if there are accessible cards
        for carddef in CardDef.select(ignore_errors=True, lightweight=True, iterator=True):
            for role_id in user.get_roles():
                if role_id in (carddef.backoffice_submission_roles or []):
                    return True
                if role_id in (carddef.workflow_roles or {}).values():
                    return True
        return False

    def _q_index(self):
        html_top('data_management', _('Cards'))
        formdefs = CardDef.select(order_by='name', ignore_errors=True, lightweight=True)
        if len(formdefs) == 0:
            return self.empty_site_message(_('Cards'))
        r = TemplateIO(html=True)
        r += get_session().display_message()

        r += htmltext('<div id="appbar">')
        r += htmltext('<h2>%s</h2>') % _('Cards')
        r += htmltext('</div>')

        user = get_request().user
        if user:
            cards = []
            for formdef in formdefs:
                if user.is_admin or formdef.is_of_concern_for_user(user):
                    cards.append(formdef)
            r += htmltext('<ul class="biglist">')
            for carddef in cards:
                r += htmltext('<li><strong><a href="%s/">%s</a></strong></li>') % (carddef.url_name, carddef.name)
            r += htmltext('</ul>')

        return r.getvalue()

    def _q_lookup(self, component):
        return CardPage(component)


class CardPage(FormPage):
    _q_exports = ['', 'csv', 'xls', 'ods', 'json', 'export', 'map', 'geojson', 'add']

    def __init__(self, component):
        try:
            self.formdef = CardDef.get_by_urlname(component)
        except KeyError:
            raise errors.TraversalError()
        self.add = CardFillPage(component)

    def listing_top_actions(self):
        if not self.formdef.backoffice_submission_roles:
            return ''
        for role in get_request().user.get_roles():
            if role in self.formdef.backoffice_submission_roles:
                break
        else:
            return ''
        return htmltext('<span class="actions"><a href="./add/">%s</a></span>') % _('Add')

    def get_default_filters(self, mode):
        return ()

    def get_default_columns(self):
        field_ids = ['id', 'time']
        for field in self.formdef.get_all_fields():
            if hasattr(field, 'get_view_value') and field.include_in_listing:
                field_ids.append(field.id)
        return field_ids

    def get_filter_from_query(self, default='waiting'):
        return 'all'

    def _q_lookup(self, component):
        try:
            filled = self.formdef.data_class().get(component)
        except KeyError:
            raise errors.TraversalError()
        return CardBackOfficeStatusPage(self.formdef, filled)


class CardFillPage(FormFillPage):
    formdef_class = CardDef

    def submitted(self, form, *args):
        super(CardFillPage, self).submitted(form, *args)
        if get_response().get_header('location').endswith('/backoffice/submission/'):
            return redirect('..')


class CardBackOfficeStatusPage(FormBackOfficeStatusPage):
    form_page_class = CardFillPage

    sidebar_recorded_message = N_(
        'The card has been recorded on %(date)s with the number %(number)s.')
    sidebar_recorded_by_agent_message = N_(
        'The card has been recorded on %(date)s with the number %(number)s by %(agent)s.')

    def html_top(self, title=None):
        return html_top('data_management', title)

    def should_fold_summary(self, mine, request_user):
        return False

    def should_fold_history(self):
        return True
