"""Permanent job custody, consumption, and return evidence."""
from django.conf import settings
from django.db import models
from django.utils import timezone
from .models import InventoryRecord


class PartsIssue(InventoryRecord):
    reservation = models.OneToOneField("inventory.StockReservation", on_delete=models.PROTECT, related_name="issue")
    service_case = models.ForeignKey("service.ServiceCase", on_delete=models.PROTECT)
    engineer_assignment = models.ForeignKey("service.ServiceEngineerAssignment", on_delete=models.PROTECT)
    recipient = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, related_name="+")
    issuer = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, related_name="+")
    issued_at = models.DateTimeField(default=timezone.now, editable=False)
    custody_location = models.OneToOneField("inventory.InventoryLocation", on_delete=models.PROTECT)
    movement = models.OneToOneField("inventory.StockMovement", on_delete=models.PROTECT)
    note = models.TextField(blank=True, max_length=2000)

    class Meta:
        permissions = [("issue_parts", "Issue reserved job parts"), ("consume_parts", "Consume issued parts in repair"), ("return_parts", "Return unused issued parts")]


class PartsDisposition(InventoryRecord):
    issue = models.ForeignKey(PartsIssue, on_delete=models.PROTECT, related_name="dispositions")
    kind = models.CharField(max_length=16, choices=[("CONSUMED", "Consumed in repair"), ("RETURNED", "Returned unused")])
    quantity = models.PositiveIntegerField()
    movement = models.OneToOneField("inventory.StockMovement", on_delete=models.PROTECT)
    repair_action = models.ForeignKey("service.ServiceRepairAction", null=True, blank=True, on_delete=models.PROTECT)
    actor = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT)
    recorded_at = models.DateTimeField(default=timezone.now, editable=False)
    note = models.TextField(blank=True, max_length=2000)

    class Meta:
        constraints = [models.CheckConstraint(condition=models.Q(quantity__gte=1, quantity__lte=1000000000), name="inventory_disposition_qty"),
            models.CheckConstraint(condition=(models.Q(kind="CONSUMED", repair_action__isnull=False) | models.Q(kind="RETURNED", repair_action=None)), name="inventory_disposition_kind")]


class DefectiveRecovery(InventoryRecord):
    """Removed customer components are separate from replacement-parts stock."""
    company = models.ForeignKey("organization.Company", on_delete=models.PROTECT)
    service_case = models.ForeignKey("service.ServiceCase", on_delete=models.PROTECT)
    device = models.ForeignKey("devices.Device", on_delete=models.PROTECT)
    repair_action = models.ForeignKey("service.ServiceRepairAction", on_delete=models.PROTECT)
    replacement = models.ForeignKey(PartsDisposition, null=True, blank=True, on_delete=models.PROTECT)
    location = models.ForeignKey("inventory.InventoryLocation", on_delete=models.PROTECT)
    component_description = models.CharField(max_length=200)
    observed_identifier = models.CharField(max_length=128, blank=True)
    quantity = models.PositiveIntegerField(default=1)
    actor = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT)
    recovered_at = models.DateTimeField(default=timezone.now, editable=False)
    command_key = models.UUIDField()
    note = models.TextField(max_length=2000, blank=True)

    class Meta:
        permissions = [("recover_defective_parts", "Record removed defective customer components")]
        constraints = [models.UniqueConstraint(fields=["company", "command_key"], name="inventory_recovery_command"),
            models.CheckConstraint(condition=models.Q(quantity__gte=1, quantity__lte=1000000000), name="inventory_recovery_qty"),
            models.CheckConstraint(condition=models.Q(observed_identifier="") | models.Q(quantity=1), name="inventory_recovery_identifier_qty"),
            models.CheckConstraint(condition=~models.Q(component_description=""), name="inventory_recovery_description")]
