from typing import Self
from django.db import models
from django.contrib.auth import get_user_model

from django.db.models.signals import m2m_changed
from django.dispatch import receiver
from django.utils import timezone

import uuid

from sync.models import BaseModel

User = get_user_model()

class Status(models.TextChoices):
    NONE = 'NONE', 'None'
    INBOUND = 'INBOUND', 'Inbound'
    CONTACTED = 'CONTACTED', 'Contacted'
    RESPONDED = 'RESPONDED', 'Responded'
    SHOULD_TEST = 'SHOULD_TEST', 'Should test'
    TESTING = 'TESTING', 'Testing'
    CUSTOMER = 'CUSTOMER', 'Customer'
    LOST = 'LOST', 'Lost customer'
    DECLINED = 'DECLINED', 'Declined'
    # DECLINED_UNRELATED = 'DECLINED_UNRELATED', 'Declined without significance'
    NOT_CONCERNED = 'NOT_CONCERNED', 'Not concerned'
    SHOULD_BUY = 'SHOULD_BUY', 'Should buy'
    HAVE_CREATED_ACCOUNT = 'HAVE_CREATED_ACCOUNT', 'Have created account'

class DeclinationReason(models.TextChoices):
    TOO_EXPENSIVE = 'TOO_EXPENSIVE', 'Too expensive'
    USE_OTHER_PRODUCT = 'USE_OTHER_PRODUCT', 'Use other product'
    USE_ANDROID = 'USE_ANDROID', 'Use Android'
    UNKNOWN = 'UNKNOWN', 'Unknown'

class ActivityType(models.TextChoices):
    MAIL = 'MAIL', 'Mail'
    SMS = 'SMS', 'SMS'
    CALL = 'CALL', 'Call'
    PRESS = 'PRESS', 'Press Release'
    WORD_OF_MOUTH = 'WORD_OF_MOUTH', 'Word of mouth'

class Entity(BaseModel):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True)
    name = models.CharField(max_length=200, null=True, blank=True)
    address = models.CharField(max_length=200, null=True, blank=True)
    zip_code = models.CharField(max_length=20, null=True, blank=True)
    city = models.CharField(max_length=500, null=True, blank=True)
    official_user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
    # status = models.IntegerField(default=Status.NONE, choices=Status.choices)

    def delete_dependencies(self):
        pass

    class Meta:
        verbose_name_plural = "Entities"

    def __str__(self):
        return self.name

class Prospect(BaseModel):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True)
    first_name = models.CharField(max_length=200, null=True, blank=True)
    last_name = models.CharField(max_length=200, null=True, blank=True)
    email = models.EmailField(unique=True, null=True, blank=True)
    phone = models.CharField(max_length=25, null=True, blank=True)
    name_unsure = models.BooleanField(default=False)
    official_user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)

    entities = models.ManyToManyField(Entity, blank=True, related_name='prospects')
    source = models.CharField(max_length=100, null=True, blank=True)
    contact_again = models.DateTimeField(null=True, blank=True)

    def delete_dependencies(self):
        pass

    # class Meta:
    #     permissions = [
    #         ("manage_prospects", "Can manage prospects"),
    #         ("view_prospects", "Can view prospects"),
    #     ]

    def current_status(self):
        last_activity = self.activities.exclude(status=None).order_by('-creation_date').first()
        if last_activity:
            return last_activity.status
        return Status.NONE

    def current_text(self):
        last_activity = self.activities.exclude(status=None).order_by('-creation_date').first()
        if last_activity:
            return last_activity.attachment_text
        return ''

    def current_declination_reason(self):
        last_activity = self.activities.exclude(status=None).order_by('-creation_date').first()
        if last_activity:
            return last_activity.declination_reason
        return None

    def entity_names(self):
        entity_names = [entity.name for entity in self.entities.all()]
        return " - ".join(entity_names)

    def full_name(self):
        if self.first_name and self.last_name:
            return f'{self.first_name} {self.last_name}'
        elif self.first_name:
            return self.first_name
        elif self.last_name:
            return self.last_name
        else:
            return 'no name'

    def __str__(self):
        return self.full_name()

class Activity(BaseModel):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True)
    status = models.CharField(max_length=50, choices=Status.choices, null=True, blank=True)
    declination_reason = models.CharField(max_length=50, choices=DeclinationReason.choices, null=True, blank=True)
    type = models.CharField(max_length=20, choices=ActivityType.choices, null=True, blank=True)
    description = models.TextField(null=True, blank=True)
    attachment_text = models.TextField(null=True, blank=True)
    prospects = models.ManyToManyField(Prospect, related_name='activities')

    def __str__(self):
        if self.status:
            return self.status
        elif self.type:
            return self.type
        else:
            return f'desc = {self.description}, attachment_text = {self.attachment_text}'

    def delete_dependencies(self):
        pass

    class Meta:
        verbose_name_plural = "Activities"
        ordering = ['-creation_date']

    # def __str__(self):
    #     return f"{self.get_type_display()} - {self.creation_date.date()}"

    def html_desc(self):
        fields = [field for field in [self.creation_date.strftime("%d/%m/%Y %H:%M"), self.status, self.declination_reason, self.attachment_text, self.description, self.type] if field is not None]
        html = '<table><tr>'
        for field in fields:
            html += f'<td style="padding:0px 5px;">{field}</td>'
        html += '</tr></table>'
        return html

    def prospect_names(self):
        prospect_names = [prospect.full_name() for prospect in self.prospects.all()]
        return ", ".join(prospect_names)

@receiver(m2m_changed, sender=Activity.prospects.through)
def update_prospect_last_update(sender, instance, action, pk_set, **kwargs):
    instance.prospects.update(last_update=timezone.now(),contact_again=None)

class EmailTemplate(BaseModel):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True)
    name = models.CharField(max_length=100)
    subject = models.CharField(max_length=200)
    body = models.TextField(null=True, blank=True)
    activities = models.ManyToManyField(Activity, blank=True, related_name='email_templates')

    def __str__(self):
        return self.name

    def delete_dependencies(self):
        pass

class ProspectGroup(BaseModel):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True)
    name = models.CharField(max_length=200, null=True, blank=True)
    prospects = models.ManyToManyField(Prospect, blank=True, related_name='prospect_groups')

    def user_count(self):
        return self.prospects.count()

    def __str__(self):
        return self.name

    def delete_dependencies(self):
        pass

# class EmailCampaign(models.Model):
#     event = models.OneToOneField(Event, on_delete=models.CASCADE)
#     subject = models.CharField(max_length=200)
#     content = models.TextField()
#     sent_at = models.DateTimeField(null=True, blank=True)

# class EmailTracker(models.Model):
#     campaign = models.ForeignKey(EmailCampaign, on_delete=models.CASCADE)
#     prospect = models.ForeignKey(Prospect, on_delete=models.CASCADE)
#     tracking_id = models.UUIDField(default=uuid.uuid4, editable=False)
#     sent = models.BooleanField(default=False)
#     sent_at = models.DateTimeField(null=True, blank=True)
#     opened = models.BooleanField(default=False)
#     opened_at = models.DateTimeField(null=True, blank=True)
#     clicked = models.BooleanField(default=False)
#     clicked_at = models.DateTimeField(null=True, blank=True)
#     error_message = models.TextField(blank=True)

#     class Meta:
#         unique_together = ['campaign', 'prospect']
