from django.db import models
from django.utils import timezone
from modelcluster.contrib.taggit import ClusterTaggableManager
from modelcluster.fields import ParentalKey
from taggit.models import ItemBase, TagBase
from wagtail.admin.panels import (
    FieldPanel,
    InlinePanel,
    MultiFieldPanel,
    ObjectList,
    TabbedInterface,
)
from wagtail.blocks import PageChooserBlock
from wagtail.contrib.routable_page.models import RoutablePageMixin, path
from wagtail.contrib.settings.models import BaseSiteSetting, register_setting
from wagtail.documents import get_document_model
from wagtail.fields import RichTextField, StreamField
from wagtail.models import Page
from wagtail_color_panel.edit_handlers import NativeColorPanel
from wagtail_color_panel.fields import ColorField

from .blocks import PersonBlock

# --- BEGIN Tags ---


class Tag(TagBase):
    bg_color = ColorField(verbose_name="Barva pozadí", default="#fafafa")
    fg_color = ColorField(verbose_name="Barva textu", default="#000000")

    panels = [
        FieldPanel("name"),
        FieldPanel("slug"),
        NativeColorPanel("bg_color"),
        NativeColorPanel("fg_color"),
    ]


class TaggedArticle(ItemBase):
    content_object = ParentalKey(
        "home.HomeArticlePage", on_delete=models.CASCADE, related_name="tagged_items"
    )

    tag = models.ForeignKey(Tag, on_delete=models.CASCADE, related_name="article_tags")


# --- END Tags ---


class HomePage(RoutablePageMixin, Page):
    heading_text = RichTextField(verbose_name="Hlavní text stránky")

    # --- Donations ---

    donation_text = RichTextField(verbose_name="Text pro dary")

    # --- Contact info ---

    address = models.CharField(verbose_name="Sídlo", max_length=128)
    branch = models.CharField(verbose_name="Pobočka", max_length=128)
    email = models.EmailField(verbose_name="Email", max_length=128)
    ds_id = models.CharField(verbose_name="Datová schránka", max_length=128)

    # --- People ---

    director = StreamField(
        [
            ("person", PersonBlock()),
            (
                "person_page",
                PageChooserBlock(
                    page_type="home.HomePersonPage", label="Stránka osoby", icon="user"
                ),
            ),
        ],
        verbose_name="Ředitel",
        use_json_field=True,
        blank=True,
        null=True,
    )
    director_description = RichTextField(verbose_name="Ředitel - popis")

    academic_council = StreamField(
        [
            ("person", PersonBlock()),
            (
                "person_page",
                PageChooserBlock(
                    page_type="home.HomePersonPage", label="Stránka osoby", icon="user"
                ),
            ),
        ],
        verbose_name="Akademická rada",
        use_json_field=True,
        blank=True,
        null=True,
    )
    academic_council_description = RichTextField(verbose_name="Akademická rada - popis")

    controller = StreamField(
        [
            ("person", PersonBlock()),
            (
                "person_page",
                PageChooserBlock(
                    page_type="home.HomePersonPage", label="Stránka osoby", icon="user"
                ),
            ),
        ],
        verbose_name="Kontrolor",
        use_json_field=True,
        blank=True,
        null=True,
    )
    controller_description = RichTextField(verbose_name="Kontrolor - popis")

    council_members = StreamField(
        [
            ("person", PersonBlock()),
            (
                "person_page",
                PageChooserBlock(
                    page_type="home.HomePersonPage", label="Stránka osoby", icon="user"
                ),
            ),
        ],
        verbose_name="Správní rada",
        use_json_field=True,
        blank=True,
        null=True,
    )
    council_members_description = RichTextField(verbose_name="Správní rada - popis")

    volunteers = StreamField(
        [
            ("person", PersonBlock()),
            (
                "person_page",
                PageChooserBlock(
                    page_type="home.HomePersonPage", label="Stránka osoby", icon="user"
                ),
            ),
        ],
        verbose_name="Dobrovolníci",
        use_json_field=True,
        blank=True,
        null=True,
    )
    volunteers_description = RichTextField(verbose_name="Dobrovolníci - popis")

    employees = StreamField(
        [
            ("person", PersonBlock()),
            (
                "person_page",
                PageChooserBlock(
                    page_type="home.HomePersonPage", label="Stránka osoby", icon="user"
                ),
            ),
        ],
        verbose_name="Zaměstnanci",
        use_json_field=True,
        blank=True,
        null=True,
    )
    employees_description = RichTextField(verbose_name="Zaměstnanci - popis")

    subpage_types = [
        "home.HomeArticlesPage",
        "home.HomeEventsPage",
        "home.HomeDocumentsPage",
        "home.HomeVideosPage",
        "home.HomePeoplePage",
    ]

    intro_panels = Page.content_panels + [
        FieldPanel("heading_text", icon="pilcrow"),
        FieldPanel("donation_text", icon="pilcrow"),
        MultiFieldPanel(
            [
                FieldPanel("address", icon="home"),
                FieldPanel("branch", icon="home"),
                FieldPanel("email", icon="pilcrow"),
                FieldPanel("ds_id", icon="mail"),
            ],
            heading="Kontaktní údaje",
        ),
    ]

    people_panels = [
        FieldPanel("director_description", icon="pilcrow"),
        FieldPanel("director", icon="user"),
        FieldPanel("academic_council_description"),
        FieldPanel("academic_council", icon="user"),
        FieldPanel("controller_description", icon="pilcrow"),
        FieldPanel("controller", icon="user"),
        FieldPanel("council_members_description", icon="pilcrow"),
        FieldPanel("council_members", icon="group"),
        FieldPanel("volunteers_description", icon="pilcrow"),
        FieldPanel("volunteers", icon="group"),
        FieldPanel("employees_description", icon="pilcrow"),
        FieldPanel("employees", icon="group"),
    ]

    edit_handler = TabbedInterface(
        [
            ObjectList(intro_panels, heading="Základy"),
            ObjectList(people_panels, heading="Lidé"),
            ObjectList(Page.promote_panels, heading="Propagace"),
        ]
    )

    # Articles

    @property
    def articles_page(self) -> "HomeArticlesPage":
        return HomeArticlesPage.objects.live().first()

    @property
    def latest_articles(self) -> "QuerySet":
        return HomeArticlePage.objects.order_by("-date").live().all()[:3]

    # Events

    @property
    def events_page(self) -> "HomeEventsPage":
        return HomeEventsPage.objects.live().first()

    @property
    def latest_events(self) -> "QuerySet":
        return HomeEventPage.objects.order_by("-date").live().all()[:8]

    # Documents

    @property
    def documents_page(self) -> "HomeDocumentsPage":
        return HomeDocumentsPage.objects.child_of(self).live().first()

    @property
    def latest_documents(self) -> list:
        documents = list(
            HomeDocumentPage.objects.child_of(self.documents_page)
            .order_by("-date")
            .live()
            .all()[:4]
        )

        # Pad documents list so it's always 4 items long
        documents += [None] * (4 - len(documents))

        document_directories = list(
            HomeDocumentsPage.objects.child_of(self.documents_page).live().all()[:4]
        )

        # Replace 0-4 last items in the list with directories
        position_in_documents = 3

        for document_directory in document_directories:
            documents[position_in_documents] = document_directory
            position_in_documents -= 1

        # Then remove the Nones we padded the list with
        return list(filter(lambda document: document is not None, documents))

    # Feed

    @path("feeds/atom/")
    def view_feed(self, request):
        # Avoid circular import
        from .feeds import LatestArticlesFeed  # noqa

        return LatestArticlesFeed()(request, self.articles_page.id)

    class Meta:
        verbose_name = "Domovská stránka"


# --- BEGIN Articles, events, videos and documents ---


class HomeArticlesPage(Page):
    content = RichTextField(verbose_name="Obsah", blank=True, null=True)

    parent_page_type = ["home.HomePage"]
    subpage_types = ["home.HomeArticlePage"]

    content_panels = Page.content_panels + [
        FieldPanel("content", icon="pilcrow"),
    ]

    @property
    def articles(self):
        return HomeArticlePage.objects.live().order_by("-date")

    def get_context(self, request):
        context = super().get_context(request)
        articles = self.articles

        # Filter by tag
        tag = request.GET.get("tag")
        if tag:
            articles = articles.filter(tags__name=tag)
            context["filtered_tag"] = tag

        context["articles"] = articles

        return context

    class Meta:
        verbose_name = "Rozcestník článků"


class HomeEventsPage(Page):
    content = RichTextField(verbose_name="Obsah", blank=True, null=True)

    parent_page_type = ["home.HomePage"]
    subpage_types = ["home.HomeEventPage"]

    content_panels = Page.content_panels + [
        FieldPanel("content", icon="pilcrow"),
    ]

    @property
    def events(self):
        return HomeEventPage.objects.live().order_by("-date").all()

    class Meta:
        verbose_name = "Rozcestník akcí"


class HomeDocumentsPage(Page):
    content = RichTextField(verbose_name="Obsah", blank=True, null=True)

    parent_page_type = ["home.HomePage"]
    subpage_types = ["home.HomeDocumentPage", "home.HomeDocumentsPage"]

    content_panels = Page.content_panels + [
        FieldPanel("content", icon="pilcrow"),
    ]

    @property
    def documents(self):
        documents = list(
            HomeDocumentPage.objects.child_of(self).order_by("-date").live().all()
        )

        document_directories = list(
            HomeDocumentsPage.objects.child_of(self).live().all()
        )

        return documents + document_directories

    class Meta:
        verbose_name = "Rozcestník dokumentů"


class HomeVideosPage(Page):
    content = RichTextField(verbose_name="Obsah", blank=True, null=True)

    parent_page_type = ["home.HomePage"]
    subpage_types = ["home.HomeVideoPage"]

    content_panels = Page.content_panels + [
        FieldPanel("content", icon="pilcrow"),
    ]

    @property
    def videos(self):
        return HomeVideoPage.objects.live().order_by("-date").all()

    class Meta:
        verbose_name = "Rozcestník videí"


class HomeContentPageMixin(Page):
    author_page = models.ForeignKey(
        "home.HomePersonPage",
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
        verbose_name="Stránka autora",
        help_text="Pokud je vybrána stránka, není nutno vyplňovat jméno autora níže.",
    )

    author = models.CharField(
        verbose_name="Jméno autora",
        max_length=128,
        blank=True,
        null=True,
    )

    date = models.DateField(verbose_name="Datum vytvoření", default=timezone.now)

    content = RichTextField(verbose_name="Obsah")

    parent_page_type = ["home.HomeArticlesPage"]

    content_panels = Page.content_panels + [
        MultiFieldPanel(
            [
                FieldPanel("author_page", icon="user"),
                FieldPanel("author", icon="user"),
            ],
            heading="Autor",
        ),
        FieldPanel("date", icon="calendar"),
        FieldPanel("content", icon="pilcrow"),
    ]

    @property
    def shortened_perex(self) -> str:
        if len(self.perex) > 310:
            return self.perex[:300] + "..."

        return self.perex

    class Meta:
        abstract = True


class HomeArticlePage(HomeContentPageMixin):
    image = models.ForeignKey(
        "wagtailimages.Image",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
        verbose_name="Obrázek",
    )

    content = RichTextField(
        verbose_name="Obsah",
        features=[
            "h2",
            "h3",
            "h4",
            "bold",
            "italic",
            "ol",
            "ul",
            "hr",
            "link",
            "document-link",
            "image",
            "embed",
            "footnotes",
        ],
    )

    show_image_on_homepage = models.BooleanField(
        verbose_name="Zobrazovat obrázek na homepage",
        default=False,
    )

    tags = ClusterTaggableManager(
        through=TaggedArticle, blank=True, verbose_name="Štítky"
    )

    perex = models.TextField(verbose_name="Perex")

    content_panels = Page.content_panels + [
        MultiFieldPanel(
            [
                FieldPanel("author_page", icon="user"),
                FieldPanel("author", icon="user"),
            ],
            heading="Autor",
        ),
        MultiFieldPanel(
            [
                FieldPanel("image", icon="image", heading=" "),
                FieldPanel("show_image_on_homepage"),
            ],
            heading="Obrázek",
        ),
        FieldPanel("date", icon="calendar"),
        FieldPanel("perex", icon="pilcrow"),
        FieldPanel("tags", icon="tag"),
        FieldPanel("content", icon="pilcrow"),
        InlinePanel("footnotes", label="Footnotes", icon="pilcrow"),
    ]

    class Meta:
        verbose_name = "Článek"


class HomeEventPage(HomeContentPageMixin):
    date = models.DateField(verbose_name="Datum konání", blank=True, null=True)
    location = models.CharField(
        verbose_name="Místo konání", blank=True, null=True, max_length=64
    )

    content = RichTextField(verbose_name="Obsah", blank=True, null=True)

    content_panels = Page.content_panels + [
        FieldPanel("date", icon="calendar"),
        FieldPanel("location", icon="globe"),
        MultiFieldPanel(
            [
                FieldPanel("author_page", icon="user"),
                FieldPanel("author", icon="user"),
            ],
            heading="Autor",
        ),
        FieldPanel("content", icon="pilcrow"),
    ]

    class Meta:
        verbose_name = "Akce"


class HomeDocumentPage(HomeContentPageMixin):
    document = models.ForeignKey(
        get_document_model(), on_delete=models.PROTECT, verbose_name="Dokument"
    )

    content = RichTextField(verbose_name="Obsah", blank=True, null=True)

    subpage_types = ["home.HomeDocumentPage"]

    content_panels = Page.content_panels + [
        FieldPanel("document", icon="doc-full"),
        MultiFieldPanel(
            [
                FieldPanel("author_page", icon="user"),
                FieldPanel("author", icon="user"),
            ],
            heading="Autor",
        ),
        FieldPanel("date", icon="calendar"),
        FieldPanel("content", icon="pilcrow"),
    ]

    class Meta:
        verbose_name = "Dokument"


class HomeVideoPage(HomeContentPageMixin):
    embed_url = models.URLField(
        verbose_name="URL Embedu",
        help_text="Pro získání adresy zmáčkni tlačítko Sdílet, vyber záložku Embed a zaškrtní zobrazování pouze URL.",
    )

    thumbnail = models.ForeignKey(
        "wagtailimages.Image",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
        verbose_name="Náhledový obrázek",
    )

    content = RichTextField(verbose_name="Obsah", blank=True, null=True)

    content_panels = Page.content_panels + [
        FieldPanel("embed_url", icon="link"),
        FieldPanel("thumbnail", icon="image"),
        MultiFieldPanel(
            [
                FieldPanel("author_page", icon="user"),
                FieldPanel("author", icon="user"),
            ],
            heading="Autor",
        ),
        FieldPanel("date", icon="calendar"),
        FieldPanel("content", icon="pilcrow"),
    ]

    class Meta:
        verbose_name = "Video"


# --- END Articles, events, videos and documents ---
# --- BEGIN People ---


class HomePeoplePage(Page):
    content = RichTextField(verbose_name="Obsah", blank=True, null=True)

    parent_page_type = ["home.HomePage"]
    subpage_types = ["home.HomePersonPage"]

    content_panels = Page.content_panels + [
        FieldPanel("content", icon="pilcrow"),
    ]

    @property
    def people(self):
        return HomePersonPage.objects.live().order_by("title").all()

    class Meta:
        verbose_name = "Rozcestník osob"


class HomePersonPage(Page):
    image = models.ForeignKey(
        "wagtailimages.Image",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
        verbose_name="Profilový obrázek",
    )

    name_titles = models.CharField(
        max_length=32,
        blank=True,
        null=True,
        verbose_name="Tituly",
    )

    position = models.TextField(verbose_name="Pracovní pozice", blank=True, null=True)

    email = models.EmailField(verbose_name="Emailová adresa", blank=True, null=True)

    description = RichTextField(verbose_name="Popis", blank=True, null=True)

    content_panels = Page.content_panels + [
        FieldPanel("name_titles", icon="pilcrow"),
        FieldPanel("image", icon="image"),
        FieldPanel("position", icon="pilcrow"),
        FieldPanel("email", icon="mail"),
        FieldPanel("description", icon="pilcrow"),
    ]

    @property
    def full_name(self) -> str:
        name = self.title

        if self.name_titles is not None:
            name = f"{self.name_titles} {name}"

        return name

    @property
    def inline_position(self) -> str:
        """Returns this person's position formatted to fit on a single line."""

        if self.position is None:
            return None

        split_positions = self.position.split("\n")
        split_positions = [position.strip() for position in split_positions]

        return ", ".join(split_positions)

    class Meta:
        verbose_name = "Osoba"


# --- END People ---
# --- BEGIN Settings ---


@register_setting
class SocialMediaSettings(BaseSiteSetting):
    mastodon = models.URLField(blank=True, null=True, help_text="Mastodon URL")
    twitter = models.URLField(blank=True, null=True, help_text="Twitter URL")
    linkedin = models.URLField(blank=True, null=True, help_text="LinkedIn URL")
    facebook = models.URLField(blank=True, null=True, help_text="Facebook URL")

    panels = [
        MultiFieldPanel(
            [
                FieldPanel("mastodon"),
                FieldPanel("twitter"),
                FieldPanel("linkedin"),
                FieldPanel("facebook"),
            ],
            heading="Nastavení sociálních sítí",
        )
    ]

    class Meta:
        verbose_name = "Sociální sítě"


# --- END Settings ---