from django.core.exceptions import ValidationError
from django.db import models
from django.utils.text import slugify

from apps.core.utils import CONTENT_FORMAT_CHOICES, FORMAT_MARKDOWN, FORMAT_PLAIN, render_content
from apps.core.video import VideoBlockMixin
from apps.pages.contact_uploads import (
    contact_attachment_storage,
    contact_attachment_upload_to,
)

RESERVED_PAGE_SLUGS = frozenset({
    "admin",
    "about",
    "contact",
    "faq",
    "home",
    "products",
    "projects",
    "accounts",
    "static",
    "media",
})


class HeroSection(models.Model):
    badge = models.CharField(max_length=200, blank=True, help_text="Small label above the title (e.g. 'Developing since 2021').")
    title = models.CharField(max_length=300, blank=True, help_text="Main title line (e.g. 'Advanced Solutions').")
    title_highlight = models.CharField(max_length=300, blank=True, help_text="Second title line shown in gradient colour (e.g. 'A Powerful Workflow Generator').")
    subtitle = models.CharField(max_length=500, blank=True, help_text="Short line below the title (e.g. 'for Standardized Radiomics Analysis…').")
    description = models.TextField(blank=True, help_text="Longer paragraph below the subtitle.")
    primary_cta_text = models.CharField(max_length=100, blank=True, help_text="Primary button label.")
    primary_cta_url = models.CharField(max_length=300, blank=True, help_text="Primary button URL (relative or absolute).")
    secondary_cta_text = models.CharField(max_length=100, blank=True, help_text="Secondary (ghost) button label.")
    secondary_cta_url = models.CharField(max_length=300, blank=True, help_text="Secondary (ghost) button URL.")
    image = models.ImageField(upload_to="hero/", blank=True, null=True, help_text="App preview screenshot shown on the right.")
    image_alt = models.CharField(max_length=300, blank=True, help_text="Alt text for the preview image.")

    class Meta:
        verbose_name = "Hero Section"
        verbose_name_plural = "Hero Section"

    def __str__(self):
        return "Hero Section"


class HomepageSection(VideoBlockMixin, models.Model):
    TYPE_FEATURES = "features"
    TYPE_SCREENSHOTS = "screenshots"
    TYPE_PRODUCTS = "products"
    TYPE_PRODUCTS_CATALOG = "products_catalog"
    TYPE_PROBLEMS = "problems"
    TYPE_PROJECTS = "projects"
    TYPE_EXPERIENCE = "experience"
    TYPE_ABOUT_STRIP = "about_strip"
    TYPE_SUPPORTERS = "supporters"
    TYPE_VIDEO = "video"

    TYPE_CHOICES = [
        (TYPE_FEATURES, "Features"),
        (TYPE_SCREENSHOTS, "Screenshots Gallery"),
        (TYPE_PRODUCTS, "Products"),
        (TYPE_PRODUCTS_CATALOG, "Products with Sub-products"),
        (TYPE_PROBLEMS, "Problems / Value Proposition"),
        (TYPE_PROJECTS, "Projects Showcase"),
        (TYPE_EXPERIENCE, "Experience / Benefits"),
        (TYPE_ABOUT_STRIP, "About Strip"),
        (TYPE_SUPPORTERS, "Supporters"),
        (TYPE_VIDEO, "Video"),
    ]

    section_type = models.CharField(max_length=30, choices=TYPE_CHOICES)
    badge = models.CharField(max_length=100, blank=True)
    title = models.CharField(max_length=300, blank=True)
    title_highlight = models.CharField(
        max_length=300,
        blank=True,
        help_text="Second title line shown in accent colour (e.g. 'Outstanding Projects').",
    )
    description = models.TextField(blank=True)
    link_text = models.CharField(max_length=100, blank=True, help_text="CTA button label (About Strip).")
    link_url = models.CharField(max_length=300, blank=True, help_text="CTA button URL (About Strip).")
    order = models.PositiveIntegerField(default=0)
    is_active = models.BooleanField(default=True)

    class Meta:
        ordering = ["order"]
        verbose_name = "Homepage Section"
        verbose_name_plural = "Homepage Sections"

    def clean(self):
        super().clean()
        if self.section_type == self.TYPE_VIDEO:
            self.clean_video_fields(require=True)

    def __str__(self):
        return f"[{self.get_section_type_display()}] {self.title or self.badge}"


class HomepageSectionItem(models.Model):
    STATUS_NEW = "new"
    STATUS_ONGOING = "ongoing"
    STATUS_DONE = "done"

    PROJECT_STATUS_CHOICES = [
        ("", "—"),
        (STATUS_NEW, "New"),
        (STATUS_ONGOING, "Ongoing"),
        (STATUS_DONE, "Done"),
    ]

    section = models.ForeignKey(HomepageSection, on_delete=models.CASCADE, related_name="items")
    icon = models.CharField(max_length=20, blank=True, help_text="Emoji or short symbol (e.g. ⚗️).")
    title = models.CharField(max_length=300, blank=True)
    content = models.TextField(blank=True)
    url = models.CharField(max_length=300, blank=True, help_text="Optional link; makes this item clickable.")
    image = models.ImageField(upload_to="homepage/items/", blank=True, null=True, help_text="Card image or icon.")
    image_alt = models.CharField(max_length=200, blank=True)
    tags = models.CharField(
        max_length=300,
        blank=True,
        help_text="Comma-separated tags shown on project cards (e.g. Web Development, Publication).",
    )
    project_status = models.CharField(
        max_length=10,
        choices=PROJECT_STATUS_CHOICES,
        blank=True,
        help_text="Project filter category (Projects Showcase section).",
    )
    order = models.PositiveIntegerField(default=0)

    class Meta:
        ordering = ["order"]
        verbose_name = "Homepage Section Item"
        verbose_name_plural = "Homepage Section Items"

    def __str__(self):
        return f"{self.section} › {self.title or self.icon or '(item)'}"

    @property
    def tag_list(self):
        if not self.tags.strip():
            return []
        return [tag.strip() for tag in self.tags.split(",") if tag.strip()]


class AboutSection(VideoBlockMixin, models.Model):
    TYPE_HERO = "hero"
    TYPE_INTRO = "intro"
    TYPE_GRID = "grid"
    TYPE_HISTORY = "history"
    TYPE_CUSTOM = "custom"
    TYPE_SUPPORTERS = "supporters"
    TYPE_VIDEO = "video"

    TYPE_CHOICES = [
        (TYPE_HERO, "Hero"),
        (TYPE_INTRO, "Intro Card"),
        (TYPE_GRID, "Grid Cards"),
        (TYPE_HISTORY, "History Block"),
        (TYPE_CUSTOM, "Custom Content"),
        (TYPE_SUPPORTERS, "Supporters"),
        (TYPE_VIDEO, "Video"),
    ]

    section_type = models.CharField(max_length=30, choices=TYPE_CHOICES, default=TYPE_CUSTOM)
    badge = models.CharField(max_length=100, blank=True)
    title = models.CharField(max_length=300, blank=True)
    subtitle = models.CharField(max_length=500, blank=True, help_text="Used as subtitle in Hero and year in History.")
    content = models.TextField(blank=True)
    content_format = models.CharField(max_length=20, choices=CONTENT_FORMAT_CHOICES, default=FORMAT_MARKDOWN)
    order = models.PositiveIntegerField(default=0)
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["order"]
        verbose_name = "About Section"
        verbose_name_plural = "About Sections"

    @property
    def rendered_content(self):
        return render_content(self.content, self.content_format)

    def clean(self):
        super().clean()
        if self.section_type == self.TYPE_VIDEO:
            self.clean_video_fields(require=True)

    def __str__(self):
        label = self.title or self.badge or self.get_section_type_display()
        return f"[{self.get_section_type_display()}] {label}"


class AboutSectionItem(models.Model):
    section = models.ForeignKey(AboutSection, on_delete=models.CASCADE, related_name="items")
    icon = models.CharField(max_length=20, blank=True, help_text="Emoji or short symbol (e.g. ⚗️).")
    badge = models.CharField(max_length=100, blank=True)
    title = models.CharField(max_length=300, blank=True)
    content = models.TextField(blank=True, help_text="Description text or link label for History links.")
    url = models.CharField(max_length=300, blank=True, help_text="Optional link; makes this item clickable.")
    image = models.ImageField(
        upload_to="about/items/",
        blank=True,
        null=True,
        help_text="Logo or image (used for Supporters cards).",
    )
    image_alt = models.CharField(max_length=200, blank=True)
    is_featured = models.BooleanField(default=False, help_text="Mark as featured item (e.g. large screenshot).")
    order = models.PositiveIntegerField(default=0)

    class Meta:
        ordering = ["order"]
        verbose_name = "About Section Item"
        verbose_name_plural = "About Section Items"

    def __str__(self):
        return f"{self.section} › {self.title or self.icon or self.badge or '(item)'}"


class ContactSubmission(models.Model):
    name = models.CharField(max_length=200)
    title = models.CharField(max_length=300)
    description = models.TextField()
    email = models.EmailField(blank=True)
    submitted_at = models.DateTimeField(auto_now_add=True)
    is_read = models.BooleanField(default=False)

    class Meta:
        ordering = ["-submitted_at"]
        verbose_name = "Contact Submission"
        verbose_name_plural = "Contact Submissions"

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


class ContactSubmissionAttachment(models.Model):
    submission = models.ForeignKey(
        ContactSubmission,
        on_delete=models.CASCADE,
        related_name="attachments",
    )
    file = models.FileField(
        upload_to=contact_attachment_upload_to,
        storage=contact_attachment_storage,
    )
    original_filename = models.CharField(max_length=255)
    uploaded_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["uploaded_at"]
        verbose_name = "Contact Attachment"
        verbose_name_plural = "Contact Attachments"

    def __str__(self):
        return self.original_filename


class FAQEntry(models.Model):
    question = models.CharField(max_length=500)
    answer = models.TextField()
    answer_format = models.CharField(
        max_length=20, choices=CONTENT_FORMAT_CHOICES, default=FORMAT_PLAIN
    )
    order = models.PositiveIntegerField(default=0)
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["order"]
        verbose_name = "FAQ Entry"
        verbose_name_plural = "FAQ Entries"

    def __str__(self):
        return self.question

    @property
    def rendered_answer(self):
        return render_content(self.answer, self.answer_format)


class DownloadItem(models.Model):
    PLATFORM_WINDOWS = "windows"
    PLATFORM_MACOS = "macos"
    PLATFORM_LINUX = "linux"

    PLATFORM_CHOICES = [
        (PLATFORM_WINDOWS, "Windows"),
        (PLATFORM_MACOS, "macOS"),
        (PLATFORM_LINUX, "Linux"),
    ]

    name = models.CharField(max_length=200)
    platform = models.CharField(max_length=20, choices=PLATFORM_CHOICES)
    version = models.CharField(max_length=50)
    download_url = models.URLField()
    description = models.TextField(blank=True)
    is_active = models.BooleanField(default=True)
    order = models.PositiveIntegerField(default=0)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["order", "platform"]
        verbose_name = "Download Item"
        verbose_name_plural = "Download Items"

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


class CustomPage(models.Model):
    title = models.CharField(max_length=200)
    slug = models.SlugField(max_length=200, unique=True)
    menu_label = models.CharField(
        max_length=100,
        blank=True,
        help_text="Nav label when shown in menu. Defaults to title.",
    )
    meta_description = models.CharField(max_length=300, blank=True)
    show_in_nav = models.BooleanField(default=True)
    menu_order = models.PositiveIntegerField(default=0)
    is_published = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["menu_order", "title"]
        verbose_name = "Custom Page"
        verbose_name_plural = "Custom Pages"

    def __str__(self):
        return self.title

    @property
    def nav_label(self):
        return self.menu_label or self.title

    def clean(self):
        super().clean()
        if self.slug in RESERVED_PAGE_SLUGS:
            raise ValidationError({"slug": f'"{self.slug}" is reserved and cannot be used.'})

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


class CustomPageSection(VideoBlockMixin, models.Model):
    TYPE_HERO = "hero"
    TYPE_INTRO = "intro"
    TYPE_GRID = "grid"
    TYPE_HISTORY = "history"
    TYPE_CUSTOM = "custom"
    TYPE_FEATURES = "features"
    TYPE_SCREENSHOTS = "screenshots"
    TYPE_PRODUCTS = "products"
    TYPE_PRODUCTS_CATALOG = "products_catalog"
    TYPE_PROBLEMS = "problems"
    TYPE_SUPPORTERS = "supporters"
    TYPE_ABOUT_STRIP = "about_strip"
    TYPE_FAQ = "faq"
    TYPE_VIDEO = "video"

    TYPE_CHOICES = [
        (TYPE_HERO, "Hero"),
        (TYPE_INTRO, "Intro Card"),
        (TYPE_GRID, "Grid Cards"),
        (TYPE_HISTORY, "History Block"),
        (TYPE_CUSTOM, "Custom Content"),
        (TYPE_FEATURES, "Features Grid"),
        (TYPE_SCREENSHOTS, "Screenshots Gallery"),
        (TYPE_PRODUCTS, "Products Grid"),
        (TYPE_PRODUCTS_CATALOG, "Products with Sub-products"),
        (TYPE_PROBLEMS, "Problems / Value Proposition"),
        (TYPE_SUPPORTERS, "Supporters"),
        (TYPE_ABOUT_STRIP, "About Strip"),
        (TYPE_FAQ, "FAQ Accordion"),
        (TYPE_VIDEO, "Video"),
    ]

    page = models.ForeignKey(CustomPage, on_delete=models.CASCADE, related_name="sections")
    section_type = models.CharField(max_length=30, choices=TYPE_CHOICES, default=TYPE_CUSTOM)
    badge = models.CharField(max_length=100, blank=True)
    title = models.CharField(max_length=300, blank=True)
    subtitle = models.CharField(max_length=500, blank=True)
    description = models.TextField(blank=True, help_text="Short intro text (homepage-style sections).")
    content = models.TextField(blank=True)
    content_format = models.CharField(max_length=20, choices=CONTENT_FORMAT_CHOICES, default=FORMAT_MARKDOWN)
    link_text = models.CharField(max_length=100, blank=True)
    link_url = models.CharField(max_length=300, blank=True)
    order = models.PositiveIntegerField(default=0)
    is_active = models.BooleanField(default=True)

    class Meta:
        ordering = ["order"]
        verbose_name = "Custom Page Section"
        verbose_name_plural = "Custom Page Sections"

    @property
    def rendered_content(self):
        return render_content(self.content, self.content_format)

    def clean(self):
        super().clean()
        if self.section_type == self.TYPE_VIDEO:
            self.clean_video_fields(require=True)

    def __str__(self):
        label = self.title or self.badge or self.get_section_type_display()
        return f"{self.page} › [{self.get_section_type_display()}] {label}"


class PageVideo(VideoBlockMixin, models.Model):
    PAGE_CONTACT = "contact"
    PAGE_FAQ = "faq"

    PAGE_CHOICES = [
        (PAGE_CONTACT, "Contact"),
        (PAGE_FAQ, "FAQ"),
    ]

    page = models.CharField(max_length=20, choices=PAGE_CHOICES)
    badge = models.CharField(max_length=100, blank=True)
    title = models.CharField(max_length=300, blank=True)
    description = models.TextField(blank=True)
    order = models.PositiveIntegerField(default=0)
    is_active = models.BooleanField(default=True)

    class Meta:
        ordering = ["page", "order"]
        verbose_name = "Page Video"
        verbose_name_plural = "Page Videos"

    def clean(self):
        super().clean()
        self.clean_video_fields(require=True)

    def __str__(self):
        label = self.title or self.badge or self.get_page_display()
        return f"{self.get_page_display()} › {label}"


class CustomPageSectionItem(models.Model):
    page = models.ForeignKey(
        CustomPage,
        on_delete=models.CASCADE,
        related_name="section_items",
    )
    section = models.ForeignKey(CustomPageSection, on_delete=models.CASCADE, related_name="items")
    icon = models.CharField(max_length=20, blank=True)
    badge = models.CharField(max_length=100, blank=True)
    title = models.CharField(max_length=300, blank=True)
    content = models.TextField(blank=True)
    content_format = models.CharField(max_length=20, choices=CONTENT_FORMAT_CHOICES, default=FORMAT_PLAIN)
    url = models.CharField(max_length=300, blank=True, help_text="Optional link; makes this item clickable.")
    image = models.ImageField(upload_to="pages/custom/", blank=True, null=True)
    image_alt = models.CharField(max_length=200, blank=True)
    is_featured = models.BooleanField(default=False)
    order = models.PositiveIntegerField(default=0)

    class Meta:
        ordering = ["order"]
        verbose_name = "Custom Page Section Item"
        verbose_name_plural = "Custom Page Section Items"

    @property
    def rendered_content(self):
        return render_content(self.content, self.content_format)

    def save(self, *args, **kwargs):
        if self.section_id:
            self.page_id = self.section.page_id
        super().save(*args, **kwargs)

    def __str__(self):
        return f"{self.section} › {self.title or self.icon or '(item)'}"
