from django.db import models
from apps.accounts.models import User


class Ticket(models.Model):
    SOURCE_CONTACT     = 'contact'
    SOURCE_AUCTION     = 'auction'
    SOURCE_MARKETPLACE = 'marketplace'
    SOURCE_STARTUP     = 'startup'
    SOURCE_CHAT        = 'chat'        # AI chat handoff

    SOURCE_DOMAIN  = 'domain'
    SOURCE_ORDER   = 'order'

    SOURCE_CHOICES = [
        (SOURCE_CONTACT,     'Contact Form'),
        (SOURCE_AUCTION,     'Auction Interest'),
        (SOURCE_MARKETPLACE, 'Marketplace Request'),
        (SOURCE_STARTUP,     'Startup Enquiry'),
        (SOURCE_CHAT,        'AI Chat Handoff'),
        (SOURCE_DOMAIN,      'Domain Enquiry'),
        (SOURCE_ORDER,       'Order / Purchase'),
    ]

    PRIORITY_LOW    = 'low'
    PRIORITY_MEDIUM = 'medium'
    PRIORITY_HIGH   = 'high'
    PRIORITY_URGENT = 'urgent'

    PRIORITY_CHOICES = [
        (PRIORITY_LOW,    'Low'),
        (PRIORITY_MEDIUM, 'Medium'),
        (PRIORITY_HIGH,   'High'),
        (PRIORITY_URGENT, 'Urgent'),
    ]

    # Auction action types
    ACTION_INTEREST = 'interest'
    ACTION_OFFER    = 'offer'
    ACTION_BUY_NOW  = 'buy_now'

    ACTION_CHOICES = [
        (ACTION_INTEREST, 'Show Interest'),
        (ACTION_OFFER,    'Make an Offer'),
        (ACTION_BUY_NOW,  'Buy Now'),
    ]

    STATUS_NEW         = 'new'
    STATUS_OPEN        = 'open'
    STATUS_IN_PROGRESS = 'in_progress'
    STATUS_WAITING     = 'waiting'
    STATUS_RESOLVED    = 'resolved'
    STATUS_CLOSED      = 'closed'

    STATUS_CHOICES = [
        (STATUS_NEW,         'New'),
        (STATUS_OPEN,        'Open'),
        (STATUS_IN_PROGRESS, 'In Progress'),
        (STATUS_WAITING,     'Waiting on Client'),
        (STATUS_RESOLVED,    'Resolved'),
        (STATUS_CLOSED,      'Closed'),
    ]

    # Which tenant this ticket belongs to
    tenant  = models.ForeignKey(
        'tenants.Tenant', on_delete=models.CASCADE,
        null=True, blank=True, related_name='tickets'
    )

    ticket_number = models.CharField(max_length=20, unique=True, editable=False)

    source   = models.CharField(max_length=20, choices=SOURCE_CHOICES)
    status   = models.CharField(max_length=20, choices=STATUS_CHOICES, default=STATUS_NEW)
    priority = models.CharField(max_length=20, choices=PRIORITY_CHOICES, default=PRIORITY_MEDIUM)

    # Sender info
    user          = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
    sender_name   = models.CharField(max_length=150)
    sender_email  = models.EmailField()
    sender_phone  = models.CharField(max_length=30, blank=True)
    sender_company = models.CharField(max_length=150, blank=True)

    subject  = models.CharField(max_length=300)
    category = models.CharField(max_length=100, blank=True)
    message  = models.TextField()

    # Auction-specific
    action_type  = models.CharField(max_length=20, choices=ACTION_CHOICES, blank=True)
    offer_amount = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)

    # Source-specific links
    auction_listing = models.ForeignKey(
        'auction.AuctionListing',
        on_delete=models.SET_NULL, null=True, blank=True,
        related_name='tickets'
    )
    marketplace_service = models.ForeignKey(
        'marketplace.MarketplaceService',
        on_delete=models.SET_NULL, null=True, blank=True,
        related_name='tickets'
    )

    # Assignment
    assigned_to = models.ForeignKey(
        User, on_delete=models.SET_NULL, null=True, blank=True,
        related_name='assigned_tickets'
    )

    internal_note    = models.TextField(blank=True)
    email_sent       = models.BooleanField(default=False)
    client_notified  = models.BooleanField(default=False)

    created_at  = models.DateTimeField(auto_now_add=True)
    updated_at  = models.DateTimeField(auto_now=True)
    resolved_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        ordering = ['-created_at']
        verbose_name = 'Ticket'
        verbose_name_plural = 'Tickets'

    def __str__(self):
        return f'#{self.ticket_number} — {self.subject}'

    @classmethod
    def inbox(cls):
        """
        The tickets the inbox actually shows.

        Closed and resolved tickets live in the archive, and anything from a
        blocked sender is hidden entirely. Anything counting tickets for a
        badge or an alert has to ask this question rather than counting every
        row, otherwise the count promises something the list will not show and
        the link lands on an empty page.
        """
        blocked = BlockedEmail.objects.values_list('email', flat=True)
        return (cls.objects
                .exclude(status__in=[cls.STATUS_CLOSED, cls.STATUS_RESOLVED])
                .exclude(sender_email__in=blocked))

    def save(self, *args, **kwargs):
        if not self.ticket_number:
            # Was six random digits behind a hardcoded prefix. Random meant
            # two tickets could collide and nobody could tell from a number
            # when it was raised. Now it counts, and the T says what it is.
            from apps.tenants.refs import next_for, TICKET
            self.ticket_number = next_for(
                Ticket, 'ticket_number', TICKET, getattr(self, 'tenant', None)
            )
        super().save(*args, **kwargs)


class BlockedEmail(models.Model):
    """Email addresses blocked from submitting tickets or chat handoffs."""
    email      = models.EmailField(db_index=True)
    blocked_at = models.DateTimeField(auto_now_add=True)
    blocked_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
    note       = models.CharField(max_length=200, blank=True)

    class Meta:
        ordering = ['-blocked_at']
        verbose_name = 'Blocked Email'

    def __str__(self):
        return self.email

    @classmethod
    def is_blocked(cls, email):
        return cls.objects.filter(email__iexact=email.strip()).exists()


class TicketReply(models.Model):
    ticket      = models.ForeignKey(Ticket, on_delete=models.CASCADE, related_name='replies')
    author      = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
    author_name = models.CharField(max_length=150, blank=True)
    message     = models.TextField()
    is_internal = models.BooleanField(default=False, help_text='Not visible to client')
    sent_by_email = models.BooleanField(default=False)
    created_at  = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['created_at']
        verbose_name = 'Ticket Reply'
        verbose_name_plural = 'Ticket Replies'

    def __str__(self):
        return f'Reply to #{self.ticket.ticket_number}'
