import secrets
from datetime import timedelta
from django.db import models
from django.utils import timezone
from core.models import TenantScopedModel
from modules.authentication.models import User


class ClientAccount(TenantScopedModel):
    """A client organization that can view their own transactions in the portal."""

    name = models.CharField(max_length=255)
    email = models.EmailField(unique=True, max_length=255)
    phone = models.CharField(max_length=32, blank=True, null=True)
    logo_url = models.URLField(max_length=500, blank=True, null=True)
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name_plural = "Client accounts"
        ordering = ["-created_at"]

    def __str__(self):
        return self.name


class ClientPortalUser(TenantScopedModel):
    """Links a portal client account to a User (for login & auth)."""

    client_account = models.ForeignKey(
        ClientAccount, on_delete=models.CASCADE, related_name="portal_users"
    )
    user = models.OneToOneField(
        User, on_delete=models.CASCADE, related_name="client_portal_profile"
    )
    role = models.CharField(
        max_length=32,
        choices=[
            ("VIEWER", "Viewer"),
            ("MANAGER", "Manager"),
            ("ADMIN", "Admin"),
        ],
        default="VIEWER",
    )
    is_active = models.BooleanField(default=True)
    last_login_at = models.DateTimeField(null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        unique_together = ("client_account", "user")

    def __str__(self):
        return f"{self.client_account.name} / {self.user.email}"


class ClientTransaction(TenantScopedModel):
    """
    A transaction that a client can view in the portal.
    Mirrors bookings/quotes and aggregates tracking events.
    """

    STATUS_CHOICES = [
        ("PENDING", "Pending"),
        ("CONFIRMED", "Confirmed"),
        ("IN_TRANSIT", "In Transit"),
        ("DELIVERED", "Delivered"),
        ("CANCELLED", "Cancelled"),
        ("REJECTED", "Rejected"),
    ]

    TRANSACTION_TYPE_CHOICES = [
        ("SHIPMENT", "Shipment"),
        ("FREIGHT_QUOTE", "Freight Quote"),
        ("BOOKING", "Booking"),
        ("INVOICE", "Invoice"),
        ("CUSTOMS_ENTRY", "Customs Entry"),
    ]

    client_account = models.ForeignKey(
        ClientAccount, on_delete=models.CASCADE, related_name="transactions"
    )
    transaction_type = models.CharField(
        max_length=32, choices=TRANSACTION_TYPE_CHOICES
    )
    transaction_ref = models.CharField(max_length=128, db_index=True)
    reference_url = models.URLField(max_length=500, blank=True, null=True)
    title = models.CharField(max_length=255)
    description = models.TextField(blank=True, null=True)
    status = models.CharField(max_length=32, choices=STATUS_CHOICES, default="PENDING")
    origin = models.CharField(max_length=255, blank=True, null=True)
    destination = models.CharField(max_length=255, blank=True, null=True)
    carrier = models.CharField(max_length=255, blank=True, null=True)
    voyage_number = models.CharField(max_length=50, blank=True, null=True)
    incident_code = models.CharField(max_length=64, blank=True, null=True)
    estimated_delivery = models.DateTimeField(null=True, blank=True)
    actual_delivery = models.DateTimeField(null=True, blank=True)
    tracking_url = models.URLField(max_length=500, blank=True, null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-created_at"]
        verbose_name_plural = "Client transactions"

    def __str__(self):
        return f"{self.client_account.name} / {self.transaction_ref or self.title}"


class TrackingEvent(TenantScopedModel):
    """Realtime tracking events for a client transaction."""

    transaction = models.ForeignKey(
        ClientTransaction, on_delete=models.CASCADE, related_name="tracking_events"
    )
    event_type = models.CharField(max_length=32)
    location = models.CharField(max_length=255, blank=True, null=True)
    description = models.TextField(blank=True, null=True)
    event_date = models.DateTimeField()
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["event_date"]

    def __str__(self):
        return f"{self.transaction.transaction_ref} / {self.event_type}"
