from django.conf import settings
from django.db import models


class Conversation(models.Model):
    """Thread between employer and candidate (via application or direct profile contact)."""

    class Status(models.TextChoices):
        OPEN = 'open', 'Open'
        CLOSED = 'closed', 'Closed'

    application = models.OneToOneField(
        'jobs.JobApplication',
        on_delete=models.CASCADE,
        related_name='conversation',
        null=True,
        blank=True,
    )
    direct_employer = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        related_name='direct_employer_conversations',
    )
    direct_seeker = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        related_name='direct_seeker_conversations',
    )
    status = models.CharField(
        max_length=10,
        choices=Status.choices,
        default=Status.OPEN,
        db_index=True,
    )
    closed_at = models.DateTimeField(null=True, blank=True)
    closed_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='closed_conversations',
    )
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['-updated_at']
        constraints = [
            models.UniqueConstraint(
                fields=['direct_employer', 'direct_seeker'],
                condition=models.Q(application__isnull=True),
                name='messaging_unique_direct_conversation',
            ),
        ]

    def __str__(self):
        if self.application_id:
            return f'Conversation: {self.application}'
        return f'Direct conversation: {self.direct_employer_id} and {self.direct_seeker_id}'

    @property
    def is_direct(self):
        return self.application_id is None

    @property
    def employer(self):
        if self.application_id:
            return self.application.job.posted_by
        return self.direct_employer

    @property
    def seeker(self):
        if self.application_id:
            return self.application.applicant
        return self.direct_seeker

    @property
    def job(self):
        if self.application_id:
            return self.application.job
        return None

    def other_participant(self, user):
        if user == self.employer:
            return self.seeker
        return self.employer

    def involves(self, user):
        return user in (self.employer, self.seeker)

    @property
    def is_open(self):
        return self.status == self.Status.OPEN

    @property
    def is_closed(self):
        return self.status == self.Status.CLOSED


class Message(models.Model):
    conversation = models.ForeignKey(
        Conversation,
        on_delete=models.CASCADE,
        related_name='messages',
    )
    sender = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='sent_messages',
    )
    body = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    read_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        ordering = ['created_at']

    def __str__(self):
        return f'Message from {self.sender} at {self.created_at:%Y-%m-%d %H:%M}'

    @property
    def is_read(self):
        return self.read_at is not None
