from django.conf import settings
from django.db import models
from django.utils import timezone

from core.choices import ClientStatus, PaymentMethod
from core.models import TimeStampedModel


class Client(TimeStampedModel):
    class ClientType(models.TextChoices):
        PERSON = "person", "Particular"
        COMPANY = "company", "Empresa / organização"

    client_type = models.CharField("Tipo", max_length=15, choices=ClientType.choices, default=ClientType.COMPANY)
    name = models.CharField("Nome / designação", max_length=180)
    legal_name = models.CharField("Nome fiscal", max_length=180, blank=True)
    nif = models.CharField("NIF", max_length=20, blank=True, db_index=True)
    email = models.EmailField("Email principal", blank=True, db_index=True)
    alternative_email = models.EmailField("Email alternativo", blank=True)
    phone = models.CharField("Telefone", max_length=40, blank=True, db_index=True)
    address = models.TextField("Morada", blank=True)
    status = models.CharField("Estado", max_length=20, choices=ClientStatus.choices, default=ClientStatus.ACTIVE, db_index=True)
    preferred_payment_method = models.CharField(
        "Pagamento preferido", max_length=30, choices=PaymentMethod.choices, blank=True
    )
    portal_access_enabled = models.BooleanField("Acesso ao portal ativo", default=False)
    internal_notes = models.TextField("Observações internas", blank=True)

    class Meta:
        verbose_name = "Cliente"
        verbose_name_plural = "Clientes"
        ordering = ["name"]
        indexes = [models.Index(fields=["status", "name"])]

    def __str__(self):
        return self.name


class ClientContact(TimeStampedModel):
    client = models.ForeignKey(Client, on_delete=models.CASCADE, related_name="contacts", verbose_name="Cliente")
    name = models.CharField("Nome", max_length=150)
    role = models.CharField("Função", max_length=100, blank=True)
    email = models.EmailField("Email", blank=True)
    phone = models.CharField("Telefone", max_length=40, blank=True)
    is_primary = models.BooleanField("Contacto principal", default=False)
    receives_billing = models.BooleanField("Recebe avisos financeiros", default=True)
    receives_technical = models.BooleanField("Recebe avisos técnicos", default=False)

    class Meta:
        verbose_name = "Contacto"
        verbose_name_plural = "Contactos"
        ordering = ["-is_primary", "name"]

    def __str__(self):
        return f"{self.name} — {self.client}"


class ClientNote(TimeStampedModel):
    client = models.ForeignKey(Client, on_delete=models.CASCADE, related_name="notes", verbose_name="Cliente")
    title = models.CharField("Título", max_length=150)
    body = models.TextField("Nota")
    is_important = models.BooleanField("Importante", default=False)
    created_by = models.ForeignKey(
        "auth.User", on_delete=models.SET_NULL, null=True, blank=True, related_name="client_notes", verbose_name="Criado por"
    )

    class Meta:
        verbose_name = "Nota do cliente"
        verbose_name_plural = "Notas dos clientes"
        ordering = ["-created_at"]

    def __str__(self):
        return self.title


class ClientPortalAccess(TimeStampedModel):
    class Role(models.TextChoices):
        OWNER = "owner", "Responsável principal"
        BILLING = "billing", "Financeiro"
        TECHNICAL = "technical", "Técnico"
        VIEWER = "viewer", "Consulta"

    client = models.ForeignKey(
        Client,
        on_delete=models.CASCADE,
        related_name="portal_accesses",
        verbose_name="Cliente",
    )
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="client_portal_access",
        verbose_name="Utilizador",
    )
    role = models.CharField("Perfil", max_length=20, choices=Role.choices, default=Role.OWNER)
    is_active = models.BooleanField("Acesso ativo", default=True, db_index=True)
    can_view_financial = models.BooleanField("Pode consultar pagamentos", default=True)
    can_view_documents = models.BooleanField("Pode consultar documentos", default=True)
    can_manage_tickets = models.BooleanField("Pode criar e responder a tickets", default=True)
    invited_at = models.DateTimeField("Convidado em", default=timezone.now)
    accepted_at = models.DateTimeField("Acesso aceite em", null=True, blank=True)
    last_portal_login_at = models.DateTimeField("Último acesso", null=True, blank=True)

    class Meta:
        verbose_name = "Acesso ao portal do cliente"
        verbose_name_plural = "Acessos ao portal dos clientes"
        ordering = ["client__name", "user__username"]
        constraints = [
            models.UniqueConstraint(fields=["client", "user"], name="unique_client_portal_user"),
        ]
        indexes = [models.Index(fields=["client", "is_active"])]

    @property
    def display_name(self):
        return self.user.get_full_name() or self.user.get_username()

    def __str__(self):
        return f"{self.client} — {self.display_name}"
