# -*- coding: utf-8 -*-
from django.db import models
from django.utils.translation import ugettext_lazy as _

from .rbac import Role
from .. import fields

class StatusManager(models.Manager):
    def get_after_start_statuses(self):
        start_ids = set(self.filter(start=True).values_list('id', flat=True))
        transitions = Transition.objects.values_list('source_id', 'destination_id')
        while True:
            last_len = len(start_ids)
            for a, b in transitions:
                if a in start_ids:
                    start_ids.add(b)
            if len(start_ids) == last_len:
                break
        return self.filter(id__in=start_ids)


class Status(models.Model):
    class Meta:
        app_label = 'base'
        verbose_name_plural = _('Statut')
        ordering = ('order', 'name',)

    def __unicode__(self):
        return self.name

    objects = StatusManager()

    code = models.CharField(max_length=40, unique=True, verbose_name=_(u'Code statut'))
    visible = models.BooleanField(verbose_name=_('Visible dans les listings'),
            blank=True, default=True)
    order = models.IntegerField(verbose_name=_(u'Ordre'), blank=True, default=0)
    name = models.CharField(max_length=128, verbose_name=_(u"Nom du status"))
    default = models.BooleanField(
            verbose_name=_(u"Statut par défaut des nouvelles requêtes"),
            blank=True, default=False)
    start = models.BooleanField(
            verbose_name=_(u"Statut débutant le traitement d'une demande"),
            help_text=_(u"Ce n'est pas forcément un statut "
                u"desintation d'aucune transition."),
            blank=True, default=False)
    end = models.BooleanField(
            verbose_name=_(u"Staut finissant le traitement d'une demande"),
            help_text=_(u"Ce n'est pas forcément un statut source "
                u"d'aucune transition."),
            default=False)
    description = models.TextField(verbose_name=_('Description'), blank=True)
    visible_by = models.ManyToManyField(Role, verbose_name=_(u'Visible par'),
            help_text=_(u'Mettre ici la liste des rôles qui pourront voir les demandes dans cet état dans leur tableau de bord'),
            blank=True)

class Action(models.Model):
    class Meta:
        app_label = 'base'
        ordering = ('name',)

    def __unicode__(self):
        return self.name

    def edit_pages(self):
        return self.edit_pages_csv

    SPECIALS = (
            ('show_in_details', _(u"Afficher l'auteur dans le récapitulatif'")),
            ('edit', _(u'Éditer')),
            ('duplicate', _(u'Dupliquer')),
            ('delete', _(u'Supprimer')),
    )
    PAGES = (
        ('document_upload', _(u'Envoi du document')),
        ('document_details', _(u'Détails sur le document')),
        ('repro_origin', _(u'Affectation de la demande')),
        ('reprography', _(u'Choix de reprographie')),
        ('delivery', _(u"Options de livraison")),
        ('document_copyrights', _(u"Droits d'auteur")),
        ('financial_information', _(u"Données financières")),
        ('real_cost', _(u"Coût réel")),
    )

    code = models.CharField(max_length=40, unique=True, verbose_name=_(u'Code action'))
    name = models.CharField(max_length=128, verbose_name=_(u"Nom de l'action"))
    ui_message = models.TextField(verbose_name=_("Message pour l'utilisateur"), blank=True)
    comment = models.BooleanField(verbose_name=_('Permettre les commentaires'),
            blank=True, default=False)
    special_type = models.CharField(max_length=32, choices=SPECIALS,
            verbose_name=_(u"Type d'action spéciale"), blank=True)
    edit_pages_csv = fields.MultiSelectField(max_length=1024,
            verbose_name=_(u"Liste des pages de l'assistant"),
            blank=True, choices=PAGES)
    validate_request = models.BooleanField(default=True,
            verbose_name=_(u"N'autoriser l'action que sur une requête valide"),
            blank=True)

    def pages(self):
        PAGES = dict(self.PAGES)
        return ', '.join([unicode(PAGES[page]) for page in self.edit_pages_csv if page in PAGES])

class MailNotification(models.Model):
    class Meta:
        app_label = 'base'
        verbose_name = _('Notification par mail')
        verbose_name_plural = _('Notifications par mail')
    TO = (
            ('requestor', _(u'le demandeur')),
            ('last_actor', _(u'le dernier acteur')),
            ('all_actors', _(u'tous les acteurs')),
            ('next_actors', _(u'les prochains acteurs')),
         )

    action = models.ForeignKey(Action)
    to = models.CharField(max_length=16, choices=TO, verbose_name=_('Destinataire du mail'))
    subject_template = models.TextField(
            verbose_name=_(u'Template du sujet du mail'),
            help_text=_(u'ne pas mettre de saut de ligne'))
    body_template = models.TextField(
            verbose_name=_(u'Template du corps du mail'))

class Transition(models.Model):
    class Meta:
        app_label = 'base'
        unique_together = (('role', 'source', 'action'),)
        ordering = ('role', 'source')

    role = models.ForeignKey(Role)
    name_override = models.CharField(max_length=128,
            verbose_name=_(u"Label du bouton"),
            help_text=_(u"Si vide c'est le nom de l'action qui est utilisé."),
            blank=True)
    source = models.ForeignKey(Status, verbose_name=_(u'Statut source'),
            related_name='out_transitions', on_delete=models.PROTECT)
    destination = models.ForeignKey(Status,
            verbose_name=_(u'Statut destination'),
            related_name='in_transitions',
            on_delete=models.PROTECT)
    action = models.ForeignKey(Action, on_delete=models.PROTECT)
    default = models.BooleanField(verbose_name=_('Action normale dans ce contexte'), blank=True,
            default=False)
    warn = models.BooleanField(verbose_name=_('Action dangereuse'), blank=True,
            default=False)
    show_on_detail = models.BooleanField(
        verbose_name=_(u'Afficher en page de détail'), default=True,
            blank=True)

    @property
    def is_edit(self):
        return self.action.special_type == 'edit'

    @property
    def is_duplicate(self):
        return self.action.special_type == 'duplicate'

    @property
    def is_delete(self):
        return self.action.special_type == 'delete'

    def get_name(self):
        return self.name_override or self.action.name
    get_name.short_description = _('Label')
    name = property(get_name)

    @property
    def edit_pages(self):
        return filter(bool, map(unicode.strip, self.action.edit_pages_csv.split(',')))

    @property
    def comment(self):
        return self.action.comment
