"""UI components for accesscodes.
"""
import grok
from datetime import datetime
from waeup.sirp.browser import WAeUPPage, WAeUPAddFormPage
from waeup.sirp.browser.breadcrumbs import Breadcrumb
from waeup.sirp.browser.pages import UniversityPage
from waeup.sirp.browser.viewlets import (
    AdminTask, AddActionButton, SearchActionButton, LeftSidebar, BatchOpButton)
from waeup.sirp.interfaces import IWAeUPObject, IUniversity

from waeup.sirp.accesscodes.accesscodes import AccessCodeBatch
from waeup.sirp.accesscodes.interfaces import (
    IAccessCodeBatchContainer, IAccessCodeBatch,
    )

grok.context(IWAeUPObject)

class BatchContainerPage(WAeUPPage):
    grok.name('index')
    grok.context(IAccessCodeBatchContainer)
    grok.template('batchcontainer')
    grok.require('waeup.manageACBatches')

    title = 'Access Code Batches'
    pnav = 0

    def update(self, batches=None, archive=None, delete=None):
        if archive is None and delete is None:
            return
        if not batches:
            self.flash('No batch selected.')
            return
        if isinstance(batches, basestring):
            batches = [batches]
        for name in batches:
            batch = self.context[name]
            csv_file = batch.archive()
            self.flash('Archived %s (%s)' % (name, csv_file))
            if delete is None:
                continue
            del self.context[name]
            self.flash('Deleted batch %s' % name)

class AddBatchPage(WAeUPAddFormPage):
    grok.name('add')
    grok.context(IAccessCodeBatchContainer)
    grok.require('waeup.manageACBatches')

    title = label = 'Create a WAeUP Scratch Card Batch'
    pnav = 0

    form_fields = grok.AutoFields(IAccessCodeBatch).select(
        'batch_prefix', 'entry_num', 'cost')

    @grok.action('Cancel')
    def cancel(self, *args, **kw):
        self.flash('Batch creation cancelled.')
        self.redirect(self.url(self.context))

    @grok.action('Create batch')
    def createBatch(self, **data):
        creator = self.request.principal.id
        creation_date = datetime.now()
        data.update(creation_date=creation_date, creator=creator)
        batch = self.context.createBatch(**data)
        csv_file = batch.createCSVLogFile()
        self.context._p_changed = True
        self.flash('Batch created (%s entries)' % data['entry_num'])
        self.flash('Data written to %s' % csv_file)
        self.redirect(self.url(self.context))

class ReimportBatchPage(WAeUPPage):
    """Screen for reimporting AC batches.
    """
    grok.name('reimport')
    grok.context(IAccessCodeBatchContainer)
    grok.template('reimportbatchpage')
    grok.require('waeup.manageACBatches')

    title = 'Reimport Access Code Batches'
    pnav = 0

    def update(self, filenames=None, reimport=None, cancel=None):
        if cancel is not None:
            self.flash('Reimport cancelled.')
            self.redirect(self.url(self.context))
            return
        if reimport is None:
            return
        if not filenames:
            self.flash('No file chosen. Action cancelled.')
            self.redirect(self.url(self.context))
            return
        if isinstance(filenames, basestring):
            filenames = [filenames]
        userid = self.request.principal.id
        for filename in filenames:
            try:
                self.context.reimport(filename, userid)
            except KeyError:
                self.flash('This batch already exists: %s' % filename)
                continue
            self.flash('Successfully reimported: %s' % filename)
        self.redirect(self.url(self.context))
        
class BatchContainerSearchPage(WAeUPPage):
    grok.name('search')
    grok.context(IAccessCodeBatchContainer)
    grok.template('searchpage')
    grok.require('waeup.manageACBatches')

    title = 'Search Scratch Cards'
    pnav = 0

    def update(self, search=None, searchterm=None, searchtype=None,
               entries=None, disable=None, enable=None):
        self.searchresults = None
        if search is not None:
            searchresults = self.context.search(searchterm, searchtype)
            if len(searchresults) == 0:
                return
            self.searchresults = []
            for result in searchresults:
                status = u'unused'
                if result.disabled is True:
                    status = u'disabled by %s on %s' % (
                        result.student_id,
                        result.invalidation_date.strftime('%c')
                        )
                elif result.invalidation_date is not None:
                    status = u'invalidated by %s on %s' % (
                        result.student_id,
                        result.invalidation_date.strftime('%c')
                        )
                entry = dict(
                    serial = result.batch_serial,
                    code = result.representation,
                    status = status)
                self.searchresults.append(entry)
        if entries is None:
            return
        if isinstance(entries, basestring):
            entries = [entries]
        for entry in entries:
            if disable is not None:
                self.context.disable(entry, self.request.principal.id)
                self.flash('disabled %s' % entry)
            elif enable is not None:
                self.context.enable(entry)
                self.flash('(re-)enabled %s' % entry)
        return

class BatchContainerBreadcrumb(Breadcrumb):
    """A breadcrumb for ac batch containers.
    """
    grok.require('waeup.manageACBatches')
    grok.context(IAccessCodeBatchContainer)
    title = u'Access Code Batches'
    parent_viewname = 'administration'

class BatchContainerSearchBreadcrumb(Breadcrumb):
    """A breadcrumb for ac batch containers search page.
    """
    grok.require('waeup.manageACBatches')
    grok.context(IAccessCodeBatchContainer)
    grok.name('search')
    title = u'Search Scratch Cards'
    viewname = 'search'
    parent_viewname = 'index'

class AdminTaskManageACBatches(AdminTask):
    """Entry on administration page that links to batch container.
    """
    grok.order(5)
    grok.require('waeup.manageACBatches')
    grok.template('admintaskacbatches')

    link_title = 'Manage access-code batches'
    target_viewname = 'accesscodes'

class CreateBatchButton(AddActionButton):
    """Action button on batch container page which links to batch creation.
    """
    grok.context(IAccessCodeBatchContainer)
    grok.view(BatchContainerPage)
    grok.require('waeup.manageACBatches')
    text = 'Add Scratch Card Batch'

class ReimportBatchButton(BatchOpButton):
    """Action button on batch container page which links to batch reimport.
    """
    grok.context(IAccessCodeBatchContainer)
    grok.view(BatchContainerPage)
    grok.require('waeup.manageACBatches')
    target = 'reimport'
    text = 'Reimport Scratch Card Batch'

class SearchAccessCodeButton(SearchActionButton):
    """Action button on batch container page which links to search.
    """
    grok.context(IAccessCodeBatchContainer)
    grok.view(BatchContainerPage)
    grok.require('waeup.manageACBatches')
    text = 'Search Scratch Cards'    
    
class ManageAccessCodes(grok.Viewlet):
    """Link on front page to access code management.
    """
    grok.viewletmanager(LeftSidebar)
    grok.context(IUniversity)
    grok.view(UniversityPage)
    grok.order(6)
    grok.require('waeup.manageACBatches')

    def render(self):
        return u'<div class="portlet"><a href="accesscodes">Manage access-codes</a></div>'
