from dateutil.relativedelta import relativedelta
from django.conf import settings
from django.contrib import messages
from django.core.paginator import Paginator
from django.db import models
from django.forms.models import model_to_dict
from django.http import HttpResponseRedirect, JsonResponse
from django.shortcuts import render
from django.utils import timezone
from modelcluster.contrib.taggit import ClusterTaggableManager
from modelcluster.fields import ParentalKey
from taggit.models import Tag, TaggedItemBase
from wagtail.admin.panels import (
    FieldPanel,
    HelpPanel,
    MultiFieldPanel,
    ObjectList,
    PageChooserPanel,
    TabbedInterface,
)
from wagtail.blocks import PageChooserBlock, RichTextBlock
from wagtail.contrib.routable_page.models import RoutablePageMixin, route
from wagtail.fields import RichTextField, StreamField
from wagtail.models import Page
from wagtail.search import index
from wagtailmetadata.models import MetadataPageMixin

from calendar_utils.models import CalendarMixin
from shared import blocks as shared_blocks
from shared.forms import SubscribeForm
from shared.models import (  # MenuMixin,
    ArticleMixin,
    ArticlesMixin,
    ArticlesPageMixin,
    ExtendedMetadataHomePageMixin,
    ExtendedMetadataPageMixin,
    MainArticlePageMixin,
    MainArticlesPageMixin,
    MainContactPageMixin,
    MainHomePageMixin,
    MainSearchPageMixin,
    MainSimplePageMixin,
    PageInMenuMixin,
    SharedTaggedMainArticle,
    SubpageMixin,
)
from shared.utils import make_promote_panels, subscribe_to_newsletter
from tuning import admin_help

from . import blocks
from .forms import JekyllImportForm


class MainHomePage(MainHomePageMixin):
    # content
    content = StreamField(
        [
            ("carousel", blocks.HomePageCarouseSlideBlock()),
            (
                "news",
                shared_blocks.NewsBlock(
                    template="styleguide2/includes/organisms/articles/articles_section.html"
                ),
            ),
            ("europarl_news", blocks.EuroparlNewsBlock()),
            ("people", blocks.PeopleOverviewBlock()),
            ("regions", blocks.RegionsBlock()),
            ("boxes", blocks.BoxesBlock()),
        ],
        verbose_name="Hlavní obsah",
        blank=True,
        use_json_field=True,
    )
    # settings
    gdpr_and_cookies_page = models.ForeignKey(
        "main.MainSimplePage",
        verbose_name="Stránka pro GDPR",
        on_delete=models.PROTECT,
        blank=True,
        null=True,
    )

    subpage_types = [
        "main.MainArticlesPage",
        "main.MainProgramPage",
        "main.MainPeoplePage",
        "main.MainPersonPage",
        "main.MainSimplePage",
        "main.MainContactPage",
        "main.MainCrossroadPage",
        "main.MainHoaxPage",
        "main.MainSearchPage",
    ]

    ### OTHERS

    class Meta:
        verbose_name = "HomePage pirati.cz"

    @property
    def article_page_model(self):
        return MainArticlePage

    @property
    def articles_page_model(self):
        return MainArticlesPage

    @property
    def contact_page_model(self):
        return MainContactPage

    @property
    def search_page_model(self):
        return MainSearchPage

    @property
    def people_page(self):
        return self._first_subpage_of_type(MainPeoplePage)

    @property
    def root_page(self):
        return self

    def _first_subpage_of_type(self, page_type) -> Page or None:
        try:
            return self.get_descendants().type(page_type).live().specific()[0]
        except IndexError:
            return None

    @route(r"^sdilene/$", name="shared")
    def shared(self, request):
        return self.setup_article_page_context(request)


class MainArticlesPage(MainArticlesPageMixin):
    base_form_class = JekyllImportForm

    parent_page_types = ["main.MainHomePage"]
    subpage_types = ["main.MainArticlePage"]


class MainArticleTag(TaggedItemBase):
    content_object = ParentalKey(
        "main.MainArticlePage",
        on_delete=models.CASCADE,
        related_name="main_tagged_items",
    )


class MainArticlePage(MainArticlePageMixin):
    author_page = models.ForeignKey(
        "main.MainPersonPage",
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        verbose_name="Stránka autora (osoby)",
    )
    tags = ClusterTaggableManager(
        through=MainArticleTag, related_name="main_tagged_articles", blank=True
    )
    shared_tags = ClusterTaggableManager(
        verbose_name="Tagy pro sdílení mezi weby",
        through=SharedTaggedMainArticle,
        blank=True,
    )

    parent_page_types = ["main.MainArticlesPage"]
    subpage_types = []


class MainProgramPage(
    ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin, PageInMenuMixin, Page
):
    ### FIELDS

    program = StreamField(
        [
            ("program_group", blocks.ProgramGroupBlock()),
            ("program_group_crossroad", blocks.ProgramGroupBlockCrossroad()),
            ("program_group_popout", blocks.ProgramGroupBlockPopout()),
        ],
        verbose_name="Program",
        blank=True,
        use_json_field=True,
    )

    ### PANELS

    content_panels = Page.content_panels + [FieldPanel("program")]

    promote_panels = make_promote_panels()

    settings_panels = []

    ### RELATIONS

    parent_page_types = ["main.MainHomePage"]
    subpage_types = []

    ### OTHERS

    class Meta:
        verbose_name = "Program"


class MainPeoplePage(
    ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin, PageInMenuMixin, Page
):
    ### FIELDS

    perex_col_1 = models.TextField(
        verbose_name="Perex - první sloupec",
    )
    perex_col_2 = models.TextField(
        verbose_name="Perex - druhý sloupec",
    )

    people = StreamField(
        [
            ("people_group", blocks.PeopleGroupBlock(label="Seznam osob")),
            ("team_group", blocks.TeamBlock()),
        ],
        verbose_name="Lidé a týmy",
        blank=True,
        use_json_field=True,
    )

    ### PANELS

    content_panels = Page.content_panels + [
        FieldPanel("perex_col_1"),
        FieldPanel("perex_col_2"),
        FieldPanel("people"),
    ]

    promote_panels = make_promote_panels()

    settings_panels = []

    ### RELATIONS

    parent_page_types = ["main.MainHomePage"]
    subpage_types = [
        "main.MainPersonPage",
        "main.MainSimplePage",
    ]

    ### OTHERS

    @property
    def perex(self) -> str:
        return self.perex_col_1 + " \n" + self.perex_col_2

    class Meta:
        verbose_name = "Lidé a týmy"


class MainPersonPage(
    ExtendedMetadataPageMixin,
    SubpageMixin,
    MetadataPageMixin,
    CalendarMixin,
    PageInMenuMixin,
    Page,
):
    ### FIELDS
    main_image = models.ForeignKey(
        "wagtailimages.Image",
        on_delete=models.PROTECT,
        blank=True,
        null=True,
        verbose_name="Hlavní obrázek",
        related_name="+",
    )

    profile_image = models.ForeignKey(
        "wagtailimages.Image",
        on_delete=models.PROTECT,
        blank=True,
        null=True,
        verbose_name="Profilový obrázek",
        related_name="+",
    )
    before_name = models.CharField(
        "Tituly před jménem", max_length=32, blank=True, null=True
    )
    after_name = models.CharField(
        "Tituly za jménem", max_length=16, blank=True, null=True
    )
    position = models.CharField(
        "Pozice/povolání", max_length=200, blank=True, null=True
    )
    primary_group = models.CharField(
        "Kategorie",
        help_text="např. 'Europarlament' nebo 'Sněmovna'",
        max_length=32,
        blank=True,
        null=True,
    )
    perex = models.TextField()
    text = RichTextField()

    social_links = StreamField(
        [
            ("social_links", shared_blocks.SocialLinkBlock()),
        ],
        verbose_name="Odkazy na sociální sítě",
        blank=True,
        use_json_field=True,
    )

    related_people = StreamField(
        [
            (
                "person",
                PageChooserBlock(page_type="main.MainPersonPage", label="Detail osoby"),
            )
        ],
        verbose_name="Další lidé",
        blank=True,
        use_json_field=True,
    )

    email = models.CharField("E-mail", max_length=128, blank=True, null=True)
    phone = models.CharField("Telefonní kontakt", max_length=16, blank=True, null=True)

    settings_panels = []

    ### RELATIONS

    parent_page_types = ["main.MainPeoplePage"]
    subpage_types = []

    ### PANELS
    content_panels = Page.content_panels + [
        FieldPanel("main_image"),
        FieldPanel("profile_image"),
        FieldPanel("before_name"),
        FieldPanel("after_name"),
        FieldPanel("position"),
        FieldPanel("perex"),
        FieldPanel("text"),
        FieldPanel("email"),
        FieldPanel("phone"),
        FieldPanel("calendar_url"),
        FieldPanel("social_links"),
        FieldPanel("related_people"),
    ]

    def get_context(self, request) -> dict:
        context = super().get_context(request)

        context["article_page_list"] = (
            MainArticlePage.objects.filter(author_page=self.id)
            .order_by("-timestamp")
            .live()[:3]
        )

        return context

    ### OTHERS

    class Meta:
        verbose_name = "Detail osoby"
        # ordering = ("title",)

    def get_background_photo(self):
        """
        Vrací background_photo pro pozadí na stránce, pokud není nastaveno,
        vezme falbback z homepage
        """
        return (
            self.background_photo
            if self.background_photo
            else self.root_page.fallback_image
        )


class MainSimplePage(MainSimplePageMixin):
    parent_page_types = [
        "main.MainHomePage",
        "main.MainSimplePage",
        "main.MainCrossroadPage",
        "main.MainPeoplePage",
    ]
    subpage_types = ["main.MainSimplePage"]


class MainContactPage(MainContactPageMixin):
    ### RELATIONS

    parent_page_types = ["main.MainHomePage"]
    subpage_types = []


class MainCrossroadPage(
    ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin, PageInMenuMixin, Page
):
    ### FIELDS

    headlined_cards_content = StreamField(
        [(("headlined_cards"), blocks.CardLinkWithHeadlineBlock())],
        verbose_name="Karty rozcestníku s nadpisem",
        blank=True,
        use_json_field=True,
    )
    cards_content = StreamField(
        [("cards", blocks.CardLinkBlock())],
        verbose_name="Karty rozcestníku",
        blank=True,
        use_json_field=True,
    )

    ### PANELS

    content_panels = Page.content_panels + [
        FieldPanel("headlined_cards_content"),
        FieldPanel("cards_content"),
    ]

    promote_panels = make_promote_panels()

    settings_panels = []

    ### RELATIONS

    parent_page_types = [
        "main.MainHomePage",
        "main.MainCrossroadPage",
    ]
    subpage_types = [
        "main.MainSimplePage",
        "main.MainCrossroadPage",
    ]
    ### OTHERS

    class Meta:
        verbose_name = "Rozcestník s kartami"


class MainHoaxPage(
    ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin, PageInMenuMixin, Page
):
    ### FIELDS

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

    content = StreamField(
        [(("hoax"), blocks.HoaxBlock())],
        verbose_name="Hoaxy a jejich vysvětlení",
        blank=True,
        use_json_field=True,
    )

    ### PANELS

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

    promote_panels = make_promote_panels()

    settings_panels = []

    ### RELATIONS

    parent_page_types = ["main.MainHomePage"]
    subpage_types = []

    ### OTHERS

    class Meta:
        verbose_name = "Hoaxy"


class MainSearchPage(MainSearchPageMixin):
    parent_page_types = ["main.MainHomePage"]
    subpage_types = []

    @property
    def searchable_models(self) -> list:
        return [
            MainArticlePage,
            MainPersonPage,
            MainSimplePage,
        ]