from django.db import models
from django.utils.translation import ugettext_lazy as _

from staff.lib.utils.ordered_choices import OrderedChoices
from staff.lib.models.base import I18nModel, DisSoftDeletedModel

from staff.dismissal.managers import DismissalManager


INITIATOR = OrderedChoices(
    ('EMPLOYEE', 'employee', 'dismissal.initiator.employee'),
    ('COMPANY', 'company', 'dismissal.initiator.company'),
    ('CONTRACT', 'contract', 'dismissal.initiator.contract'),
    ('OTHER', 'other', 'dismissal.initiator.other'),
)

IMPRESSION = OrderedChoices(
    ('GOOD', 'good', 'dismissal.impression.good'),
    ('NEUTRAL', 'neutral', 'dismissal.impression.neutral'),
    ('EVIL', 'evil', 'dismissal.impression.evil'),
)

DELETE_FROM_SEARCH = OrderedChoices(
    ('IMMEDIATELY', 'immediately', 'dismissal.delete_from_search.immediately'),
    ('AFTER_2_WEEKS', 'after_2_weeks', 'dismissal.delete_from_search.after_2_weeks'),
)

DISMISSAL_STATUS = OrderedChoices(
    ('NEW', 'N', 'dismissal.status.new-option'),
    ('IN_PROGRESS', 'I', 'dismissal.status.in_progress-option'),
    ('CANCELLED', 'X', 'dismissal.status.cancelled-option'),
    ('DATE_PASSED', 'P', 'dismissal.status.date_passed-option'),
    ('CHIT_NOT_COMPLETE', 'C', 'dismissal.status.chit_not_complete-option'),
    ('DONE', 'D', 'dismissal.status.done-option'),
)

REHIRE_RECOMMENDATION = OrderedChoices(
    ('HIGHLY_RECOMMEND', 'highly_recommend', 'dismissal.rehire_recommendation.highly_recommend'),
    ('RECOMMEND', 'recommend', 'dismissal.rehire_recommendation.recommend'),
    ('NOT_MY_TEAM', 'not_my_team', 'dismissal.rehire_recommendation.not_my_team'),
    ('NO', 'no', 'dismissal.rehire_recommendation.no'),
)


class Dismissal(I18nModel, DisSoftDeletedModel):
    """Заявка на увольнение"""
    SEARCH_FIELDS = ('delete_from_search', 'comment')
    HR_FIELDS = ('need_hr_help',)
    NEW_FIELDS = SEARCH_FIELDS + HR_FIELDS

    objects = DismissalManager()

    status = models.CharField(
        choices=DISMISSAL_STATUS,
        max_length=1,
        default=DISMISSAL_STATUS.NEW,
        verbose_name=_('dismissal.status-label')
    )
    staff = models.ForeignKey(
        'django_intranet_stuff.Staff',
        related_name='dismissals',
        verbose_name=_('dismissal.staff-label')
    )
    department = models.ForeignKey(
        'django_intranet_stuff.Department',
        related_name='dismissals',
        verbose_name=_('dismissal.department-label'),
    )
    office = models.ForeignKey(
        'django_intranet_stuff.Office',
        related_name='dismissals',
        verbose_name=_('dismissal.office-label')
    )
    quit_date = models.DateField(null=True, verbose_name=_('dismissal.quit_date-label'))
    deadline = models.DateField(null=True, default=None, verbose_name='Крайний срок увольнения')
    note = models.TextField(blank=True, verbose_name=_('dismissal.note-label'))

    delete_email_address = models.BooleanField(
        verbose_name=_('dismissal.delete_email_address-label'),
        default=False,
    )
    delete_correspondence = models.BooleanField(
        verbose_name=_('dismissal.delete_correspondence-label'),
        default=False,
    )
    forward_correspondence_to = models.ForeignKey(
        'django_intranet_stuff.Staff',
        blank=True,
        null=True,
        related_name='dismissals_mail_forward',
        verbose_name=_('dismissal.forward_correspondence_to-label'),
    )
    give_correspondence_to = models.ForeignKey(
        'django_intranet_stuff.Staff',
        blank=True,
        null=True,
        related_name='dismissals_mail_given',
        verbose_name=_('dismissal.give_correspondence_to-label'),
    )

    delete_files = models.BooleanField(
        verbose_name=_('dismissal.delete_files-label'),
        default=False,
    )
    keep_files = models.BooleanField(verbose_name=_('dismissal.keep_files-label'), default=False)
    give_files_to = models.ForeignKey(
        'django_intranet_stuff.Staff',
        blank=True,
        null=True,
        related_name='dismissals_files_given',
        verbose_name=_('dismissal.give_files_to-label'),
    )

    move_to_ext = models.BooleanField(verbose_name='Сделать внешним', default=False)
    move_to_ext_issue = models.CharField(max_length=512, verbose_name='Тикет перевода во внешние', default='')

    created_by = models.ForeignKey(
        'django_intranet_stuff.Staff',
        related_name='created_dismissals',
        verbose_name=_('dismissal.created_by-label'),
    )
    quit_datetime_real = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name=_('dismissal.quit_datetime_real-label'),
    )
    completed_by = models.ForeignKey(
        'django_intranet_stuff.Staff',
        blank=True,
        null=True,
        related_name='completed_dismissals',
        verbose_name=_('dismissal.completed_by-label'),
    )
    initiator = models.CharField(
        max_length=16,
        choices=INITIATOR,
        default='',
        verbose_name=_('dismissal.initiator-label'),
    )
    need_hr_help = models.BooleanField(
        null=False,
        blank=True,
        default=False,
        verbose_name=_('dismissal.need_hr_help-label'),
    )
    reason = models.CharField(
        max_length=512,
        default='',
        verbose_name=_('dismissal.reason-label'),
        blank=True,
    )
    new_employer = models.CharField(
        max_length=512,
        default='',
        verbose_name=_('dismissal.new_employer-label'),
        blank=True,
    )
    impression = models.CharField(
        max_length=16,
        choices=IMPRESSION,
        default='',
        verbose_name=_('dismissal.impression-label'),
    )
    delete_from_search = models.CharField(
        max_length=16,
        choices=DELETE_FROM_SEARCH,
        default='',
        verbose_name=_('dismissal.delete_from_search-label'),
        blank=True,
    )
    comment = models.CharField(
        max_length=512,
        default='',
        verbose_name=_('dismissal.comment-label'),
        blank=True,
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name=_('dismissal.created_at-label'),
    )
    modified_at = models.DateTimeField(
        auto_now=True,
        verbose_name=_('dismissal.modified_at-label'),
    )
    rehire_recommendation = models.CharField(
        max_length=32,
        choices=REHIRE_RECOMMENDATION,
        default='',
        verbose_name=_('dismissal.rehire-label'),
    )

    class Meta:
        verbose_name = _('dismissal.dismissal_request')
        verbose_name_plural = _('dismissal.dismissal_request_plural')

        permissions = (
            ("can_dismiss_from_anketa", 'Can dismiss employees from anketa'),
            ("can_dismiss_from_chit", 'Can dismiss employees from chit'),
            ("can_create_dismissal", 'Can create dismissal requests'),
            ("can_update_dismissal", 'Can update dismissal requests'),
            ("can_cancel_dismissal", 'Can cancel dismissal requests'),
            ("can_see_hr_note", 'Can see hr note'),
        )

    def __str__(self):
        return 'Dismissal of %s' % self.staff

    def iter_hr_fields(self):
        return self._iter_fields(self.HR_FIELDS)

    def iter_search_fields(self):
        return self._iter_fields(self.SEARCH_FIELDS)

    # noinspection PyProtectedMember
    def _iter_fields(self, names):
        for name in names:
            # TODO: use staff.lib.models.verbose_name when it's merged
            field = self._meta.get_field(name)
            choices = field._choices
            value = getattr(self, name, None)
            if value and choices:
                value = choices[value]
            yield field.verbose_name, value


class MaillistDuty(models.Model):
    """Ответственность за рассылку"""
    dismissal = models.ForeignKey(
        'Dismissal',
        related_name='maillists',
        verbose_name=_('dismissal.dismissal_request'),
    )
    maillist = models.CharField(
        max_length=255,
        verbose_name=_('dismissal.maillist-label'),
    )
    responsible = models.ForeignKey(
        'django_intranet_stuff.Staff',
        blank=True,
        null=True,
        verbose_name=_('dismissal.maillist_responsibles-label'),
    )

    class Meta:
        verbose_name = _('dismissal.maillist_duty')
        verbose_name_plural = _('dismissal.maillist_duty')

    def __str__(self):
        return '%s@' % self.maillist


class ClearanceChitTemplate(models.Model):
    """Шаблон обходного листа"""
    department = models.ForeignKey(
        'django_intranet_stuff.Department',
        null=True,
        blank=True,
        related_name='chit_templates',
        verbose_name=_('dismissal.department-label'),
    )
    office = models.ForeignKey(
        'django_intranet_stuff.Office',
        null=True,
        blank=True,
        related_name='chit_templates',
        verbose_name=_('dismissal.office-label'),
    )
    checkpoints = models.ManyToManyField(
        'CheckPointTemplate',
        blank=True,
        related_name='chit_templates',
        verbose_name=_('dismissal.checkpoints-label'),
    )

    class Meta:
        verbose_name = _('dismissal.chit_template-label')
        verbose_name_plural = _('dismissal.chit_template_plural-label')

    def __str__(self):
        return 'department: %s, office: %s' % (
            self.department or '*',
            self.office or '*',
        )


class CheckPointTemplate(I18nModel, DisSoftDeletedModel):
    """Шаблон пункта обходного листа"""
    name = models.CharField(
        max_length=255,
        blank=True,
        verbose_name=_('dismissal.checkpoint_name-label'),
    )
    name_en = models.CharField(
        max_length=255,
        blank=True,
        verbose_name=_('dismissal.checkpoint_name_en-label'),
    )
    description = models.TextField(
        blank=True,
        verbose_name=_('dismissal.checkpoint_description-label'),
    )
    description_en = models.TextField(
        blank=True,
        verbose_name=_('dismissal.checkpoint_description_en-label'),
    )
    responsibles = models.ManyToManyField(
        'django_intranet_stuff.Staff',
        blank=True,
        related_name='checkpoint_templates',
        verbose_name=_('dismissal.checkpoint_responsibles-label'),
    )
    position = models.PositiveSmallIntegerField(
        default=1,
        verbose_name=_('dismissal.checkpoint_position-label'),
    )

    class Meta:
        verbose_name = _('dismissal.checkpoint_template')
        verbose_name_plural = _('dismissal.checkpoint_template_plural')

    def __str__(self):
        return self.name or self.name_en


class CheckPoint(I18nModel):
    """Пункт конкретного обходного листа. Формируется на основе шаблона"""
    dismissal = models.ForeignKey(
        'Dismissal',
        related_name='checkpoints',
        verbose_name=_('dismissal.dismissal_request'),
    )
    name = models.CharField(
        max_length=255,
        blank=True,
        verbose_name=_('dismissal.checkpoint_name-label'),
    )
    name_en = models.CharField(
        max_length=255,
        blank=True,
        verbose_name=_('dismissal.checkpoint_name_en-label'),
    )
    description = models.TextField(
        blank=True,
        verbose_name=_('dismissal.checkpoint_description_en-label'),
    )
    description_en = models.TextField(
        blank=True,
        verbose_name=_('dismissal.checkpoint_description_en-label'),
    )
    template = models.ForeignKey(
        'CheckPointTemplate',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        verbose_name=_('dismissal.checkpoint_template'),
    )
    position = models.PositiveSmallIntegerField(
        default=1,
        verbose_name=_('dismissal.checkpoint_position-label'),
    )
    checked = models.BooleanField(
        verbose_name=_('dismissal.checkpoint_checked-label'),
        default=False,
    )
    checked_at = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name=_('dismissal.checkpoint_checked_at-label'),
    )
    checked_by = models.ForeignKey(
        'django_intranet_stuff.Staff',
        null=True,
        blank=True,
        related_name='checked_points',
        verbose_name=_('dismissal.checkpoint_checked_by-label'),
    )

    class Meta:
        verbose_name = _('dismissal.checkpoint')
        verbose_name_plural = _('dismissal.checkpoint_plural')
        ordering = ('position',)

    def __str__(self):
        return '%s for %s' % (self.name, self.dismissal)
