from django.db import models
from django.utils.text import slugify


class InventoryStatus(models.TextChoices):
    IN_STOCK = "IN_STOCK", "In stock"
    LIMITED_STOCK = "LIMITED_STOCK", "Limited stock"
    OUT_OF_STOCK = "OUT_OF_STOCK", "Out of stock"
    TEST_RIDE_ONLY = "TEST_RIDE_ONLY", "Test ride only"
    COMING_SOON = "COMING_SOON", "Coming soon"


class BookingStatus(models.TextChoices):
    PENDING = "PENDING", "Pending"
    CONFIRMED = "CONFIRMED", "Confirmed"
    COMPLETED = "COMPLETED", "Completed"
    CANCELLED = "CANCELLED", "Cancelled"


class AssetStatus(models.TextChoices):
    PENDING = "PENDING", "Pending"
    UPLOADED = "UPLOADED", "Uploaded"
    NEEDS_OPTIMIZATION = "NEEDS_OPTIMIZATION", "Needs optimization"
    OPTIMIZED = "OPTIMIZED", "Optimized"
    PUBLISHED = "PUBLISHED", "Published"


class LeadStatus(models.TextChoices):
    NEW = "NEW", "New"
    CONTACTED = "CONTACTED", "Contacted"
    QUALIFIED = "QUALIFIED", "Qualified"
    CLOSED = "CLOSED", "Closed"


class Brand(models.Model):
    name = models.CharField(max_length=120)
    slug = models.SlugField(max_length=140, unique=True, blank=True)
    short_description = models.TextField(blank=True)
    logo_text = models.CharField(max_length=40, blank=True)
    key_strength = models.CharField(max_length=180, blank=True)
    popular_models = models.JSONField(default=list, blank=True)
    is_featured = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["name"]
        verbose_name = "Brand"
        verbose_name_plural = "Brands"

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        if not self.logo_text:
            self.logo_text = self.name[:3].upper()
        super().save(*args, **kwargs)

    def __str__(self) -> str:
        return self.name


class Branch(models.Model):
    name = models.CharField(max_length=160)
    slug = models.SlugField(max_length=180, unique=True, blank=True)
    type = models.CharField(max_length=80, default="Branch")
    city = models.CharField(max_length=120)
    district = models.CharField(max_length=120)
    phone = models.CharField(max_length=30)
    whatsapp = models.CharField(max_length=30)
    opening_hours = models.CharField(max_length=160, blank=True)
    map_link = models.URLField(blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["city"]
        verbose_name = "Branch"
        verbose_name_plural = "Branches"

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(f"{self.city}-{self.district}")
        super().save(*args, **kwargs)

    def __str__(self) -> str:
        return f"{self.city}, {self.district}"


class Scooter(models.Model):
    brand = models.ForeignKey(Brand, related_name="scooters", on_delete=models.CASCADE)
    name = models.CharField(max_length=160)
    slug = models.SlugField(max_length=180, unique=True, blank=True)
    short_description = models.TextField()
    long_description = models.TextField()
    price = models.PositiveIntegerField(default=0)
    offer_price = models.PositiveIntegerField(default=0)
    range_km = models.PositiveIntegerField(default=0)
    top_speed_kmph = models.PositiveIntegerField(default=0)
    charging_time = models.CharField(max_length=80)
    battery = models.CharField(max_length=120)
    motor_power = models.CharField(max_length=120)
    warranty = models.CharField(max_length=120)
    colors = models.JSONField(default=list, blank=True)
    hero_image = models.ImageField(upload_to="scooters/hero/", blank=True)
    thumbnail_image = models.ImageField(upload_to="scooters/thumbs/", blank=True)
    poster_image = models.ImageField(upload_to="scooters/posters/", blank=True)
    ar_enabled = models.BooleanField(default=False)
    is_featured = models.BooleanField(default=False)
    published = models.BooleanField(default=True)
    specs = models.JSONField(default=list, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["name"]
        verbose_name = "Product"
        verbose_name_plural = "Products"

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        super().save(*args, **kwargs)

    def __str__(self) -> str:
        return self.name


class ScooterImage(models.Model):
    scooter = models.ForeignKey(Scooter, related_name="gallery_images", on_delete=models.CASCADE)
    image = models.ImageField(upload_to="scooters/gallery/")
    alt = models.CharField(max_length=180, blank=True)
    sort_order = models.PositiveIntegerField(default=0)

    class Meta:
        ordering = ["sort_order", "id"]
        verbose_name = "Product Image"
        verbose_name_plural = "Product Images"

    def __str__(self) -> str:
        return self.alt or f"{self.scooter.name} image"


class ScooterAsset3D(models.Model):
    scooter = models.OneToOneField(Scooter, related_name="asset_3d", on_delete=models.CASCADE)
    glb_file = models.FileField(upload_to="models/glb/", blank=True)
    usdz_file = models.FileField(upload_to="models/usdz/", blank=True)
    poster_image = models.ImageField(upload_to="models/posters/", blank=True)
    status = models.CharField(max_length=40, choices=AssetStatus.choices, default=AssetStatus.PENDING)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self) -> str:
        return f"3D assets for {self.scooter.name}"

    class Meta:
        verbose_name = "3D Asset"
        verbose_name_plural = "3D Assets"


class Inventory(models.Model):
    scooter = models.ForeignKey(Scooter, related_name="inventory", on_delete=models.CASCADE)
    branch = models.ForeignKey(Branch, related_name="inventory", on_delete=models.CASCADE)
    status = models.CharField(max_length=40, choices=InventoryStatus.choices, default=InventoryStatus.COMING_SOON)
    quantity = models.PositiveIntegerField(default=0)
    test_ride_available = models.BooleanField(default=False)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        constraints = [
            models.UniqueConstraint(fields=["scooter", "branch"], name="unique_scooter_branch_inventory")
        ]
        ordering = ["scooter__name", "branch__city"]
        verbose_name = "Inventory"
        verbose_name_plural = "Inventory"

    def __str__(self) -> str:
        return f"{self.scooter.name} at {self.branch.city}"


class Part(models.Model):
    name = models.CharField(max_length=160)
    category = models.CharField(max_length=120)
    price = models.PositiveIntegerField(default=0)
    image = models.ImageField(upload_to="parts/", blank=True)
    compatibility = models.JSONField(default=list, blank=True)
    inquiry_only = models.BooleanField(default=False)
    stock_status = models.CharField(max_length=40, choices=InventoryStatus.choices, default=InventoryStatus.IN_STOCK)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["category", "name"]
        verbose_name = "Part"
        verbose_name_plural = "Parts"

    def __str__(self) -> str:
        return self.name


class Offer(models.Model):
    category = models.CharField(max_length=120)
    title = models.CharField(max_length=180)
    description = models.TextField()
    discount_label = models.CharField(max_length=80)
    starts_at = models.DateField(null=True, blank=True)
    valid_until = models.DateField()
    active = models.BooleanField(default=True)
    brand = models.ForeignKey(Brand, related_name="offers", null=True, blank=True, on_delete=models.SET_NULL)
    scooter = models.ForeignKey(Scooter, related_name="offers", null=True, blank=True, on_delete=models.SET_NULL)
    branch = models.ForeignKey(Branch, related_name="offers", null=True, blank=True, on_delete=models.SET_NULL)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-valid_until"]
        verbose_name = "Offer"
        verbose_name_plural = "Offers"

    def __str__(self) -> str:
        return self.title


class GalleryImage(models.Model):
    category = models.CharField(max_length=80)
    title = models.CharField(max_length=160)
    image = models.ImageField(upload_to="gallery/")
    alt = models.CharField(max_length=180, blank=True)
    featured = models.BooleanField(default=False)
    branch = models.ForeignKey(Branch, related_name="gallery_images", null=True, blank=True, on_delete=models.SET_NULL)
    scooter = models.ForeignKey(Scooter, related_name="gallery_images_public", null=True, blank=True, on_delete=models.SET_NULL)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-featured", "-created_at"]
        verbose_name = "Gallery"
        verbose_name_plural = "Gallery"

    def __str__(self) -> str:
        return self.title


class Testimonial(models.Model):
    customer_name = models.CharField(max_length=120)
    location = models.CharField(max_length=120)
    rating = models.PositiveSmallIntegerField(default=5)
    comment = models.TextField()
    scooter_name = models.CharField(max_length=160, blank=True)
    image = models.ImageField(upload_to="testimonials/", blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-created_at"]
        verbose_name = "Testimonial"
        verbose_name_plural = "Testimonials"

    def __str__(self) -> str:
        return self.customer_name


class TestRideBooking(models.Model):
    full_name = models.CharField(max_length=120)
    phone = models.CharField(max_length=30)
    email = models.EmailField(blank=True)
    branch = models.ForeignKey(Branch, related_name="bookings", null=True, blank=True, on_delete=models.SET_NULL)
    scooter = models.ForeignKey(Scooter, related_name="bookings", null=True, blank=True, on_delete=models.SET_NULL)
    preferred_date = models.DateField(null=True, blank=True)
    preferred_time = models.CharField(max_length=40, blank=True)
    message = models.TextField(blank=True)
    status = models.CharField(max_length=40, choices=BookingStatus.choices, default=BookingStatus.PENDING)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-created_at"]
        verbose_name = "Test Ride"
        verbose_name_plural = "Test Rides"

    def __str__(self) -> str:
        return f"{self.full_name} - {self.phone}"


class Lead(models.Model):
    source = models.CharField(max_length=80, default="CONTACT_PAGE")
    full_name = models.CharField(max_length=120)
    phone = models.CharField(max_length=30)
    email = models.EmailField(blank=True)
    subject = models.CharField(max_length=180, blank=True)
    message = models.TextField()
    branch = models.ForeignKey(Branch, related_name="leads", null=True, blank=True, on_delete=models.SET_NULL)
    scooter = models.ForeignKey(Scooter, related_name="leads", null=True, blank=True, on_delete=models.SET_NULL)
    status = models.CharField(max_length=40, choices=LeadStatus.choices, default=LeadStatus.NEW)
    notes = models.TextField(blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-created_at"]
        verbose_name = "Lead"
        verbose_name_plural = "Leads"

    def __str__(self) -> str:
        return f"{self.full_name} - {self.source}"
