from django.db import models

from staff.departments.models import Department, Vacancy
from staff.emission.logbroker.models import LogbrokerLog  # noqa ignore=F401
from staff.lib.models.base import TrackableModel
from staff.lib.utils.enum_choices import EnumChoices
from staff.person.models import Staff

from staff.budget_position.models.reward import Reward


class BudgetPositionType(EnumChoices):
    REGULAR = 'regular'
    INTERN = 'intern'
    MATERNITY = 'maternity'
    CREDIT = 'credit'


class BudgetPosition(models.Model):
    code = models.IntegerField(unique=True)

    # TODO: make both required after moving BP creation to staff
    headcount = models.IntegerField(null=True)
    type = models.CharField(choices=BudgetPositionType.choices(), null=True, max_length=32)

    def __str__(self):
        return f'BudgetPosition {self.code} ({self.type})'


class BudgetPositionComment(models.Model):
    person = models.ForeignKey(Staff, null=False, related_name='+', on_delete=models.PROTECT)
    budget_position = models.ForeignKey(BudgetPosition, null=False, related_name='+', on_delete=models.PROTECT)

    comment = models.TextField(null=False)

    class Meta:
        unique_together = (('person', 'budget_position'),)


class BudgetPositionAssignmentStatus(EnumChoices):
    OCCUPIED = 'occupied'
    OFFER = 'offer'
    VACANCY_OPEN = 'vacancy_open'
    VACANCY_PLAN = 'vacancy_plan'
    RESERVE = 'reserve'
    MATERNITY = 'maternity'


class ReplacementType(EnumChoices):
    HAS_REPLACEMENT = 'has_replacement'
    BUSY = 'busy'
    HAS_REPLACEMENT_AND_BUSY = 'has_replacement_and_busy'
    WITHOUT_REPLACEMENT = 'without_replacement'


class BudgetPositionAssignment(TrackableModel):
    change_reason = models.CharField(max_length=64, null=True)
    oebs_assignment_id = models.BigIntegerField(null=True, db_index=True)
    change_registry = models.ForeignKey(
        'budget_position.ChangeRegistry',
        null=True,
        related_name='+',
        on_delete=models.PROTECT,
    )

    budget_position = models.ForeignKey(BudgetPosition, on_delete=models.PROTECT)
    status = models.CharField(choices=BudgetPositionAssignmentStatus.choices(), max_length=32)
    creates_new_position = models.BooleanField()

    previous_assignment = models.ForeignKey(
        'BudgetPositionAssignment',
        null=True,
        unique=True,
        related_name='next_assignment',
    )
    replacement_type = models.CharField(choices=ReplacementType.choices(), max_length=32)
    person = models.ForeignKey(Staff, null=True, related_name='assignments', on_delete=models.PROTECT)
    vacancy = models.ForeignKey(Vacancy, null=True, related_name='+', on_delete=models.PROTECT)

    main_assignment = models.BooleanField(default=True)
    department = models.ForeignKey(Department, related_name='+', on_delete=models.PROTECT)
    value_stream = models.ForeignKey(Department, related_name='+', on_delete=models.PROTECT)
    geography = models.ForeignKey(Department, related_name='+', on_delete=models.PROTECT)

    bonus_id = models.IntegerField()   # TODO: fk
    reward = models.ForeignKey(Reward, null=True, related_name='+', on_delete=models.PROTECT)  # TODO: Set obligatory
    review_id = models.IntegerField()  # TODO: fk

    # TODO: Remove
    name = models.CharField(null=False, default='', max_length=128)

    @property
    def is_in_total_headcount(self):
        return self.next_assignment is None

    @property
    def is_crossing_headcount(self):
        return not self.is_in_total_headcount

    def __str__(self):
        return f'Budget Assignment #{self.id} {self.status} for {self.budget_position.code} in {self.department.url}'


class Permissions(models.Model):
    class Meta:
        managed = False  # No database table creation or deletion operations will be performed for this model
        permissions = (
            ('can_manage_market_budget_positions', 'Permission for managing budget positions in Market'),
        )
