import os
import tempfile

from django import forms
from django.core.exceptions import ValidationError

from shared.forms import ArticlesPageForm as SharedArticlesPageForm
from shared.forms import JekyllImportForm as SharedJekyllImportForm

from .tasks import import_jekyll_articles


class MultipleFileInput(forms.ClearableFileInput):
    allow_multiple_selected = True


class MultipleFileField(forms.FileField):
    def __init__(self, *args, **kwargs):
        kwargs.setdefault("widget", MultipleFileInput())
        super().__init__(*args, **kwargs)

    TOTAL_MAX_FILE_SIZE = 5 * 1024 * 1024  # 5 MB

    def clean(self, data, initial=None):
        single_file_clean = super().clean

        if isinstance(data, (list, tuple)):
            total_size = 0

            for file in data:
                total_size += file.size

            if total_size > self.TOTAL_MAX_FILE_SIZE:
                raise ValidationError(
                    "Celková velikost nahraných souborů je příliš velká."
                )

            result = [single_file_clean(d, initial) for d in data]
        else:
            result = [single_file_clean(data, initial)]

        return result


# Allowed MIME types
ALLOWED_FILE_TYPES = [
    "application/pdf",  # PDF
    "application/msword",  # DOC
    "application/vnd.openxmlformats-officedocument.wordprocessingml.document",  # DOCX
    "image/png",  # PNG
    "application/vnd.oasis.opendocument.text",  # ODT
]


def validate_file_type(file):
    if file.content_type not in ALLOWED_FILE_TYPES:
        raise ValidationError(
            f"Chybný formát souboru: {file.content_type}. Povolené jsou pouze PDF, DOC, DOCX, PNG, and ODT."
        )


def validate_file_size(file, max_size=5 * 1024 * 1024):  # Default: 5 MB
    if file.size > max_size:
        raise ValidationError(
            f"Soubory mohou být max. {max_size / (1024 * 1024)} MB velké."
        )


class CareerSubmissionForm(forms.Form):
    name = forms.CharField(
        min_length=1,
        max_length=256,
        required=True,
        widget=forms.TextInput(
            attrs={
                "placeholder": "Jméno",
                "class": "lg:w-auto w-full",
                "value": "",
                "autocomplete": "",
            }
        ),
    )

    surname = forms.CharField(
        min_length=1,
        max_length=256,
        required=True,
        widget=forms.TextInput(
            attrs={
                "placeholder": "Příjmení",
                "class": "lg:w-auto w-full",
                "value": "",
                "autocomplete": "",
            }
        ),
    )

    email = forms.EmailField(
        min_length=1,
        max_length=256,
        required=True,
        widget=forms.EmailInput(
            attrs={
                "placeholder": "Email",
                "class": "w-full",
                "value": "",
                "autocomplete": "",
            }
        ),
    )

    phone = forms.IntegerField(
        required=True,
        widget=forms.NumberInput(
            attrs={
                "type": "tel",
                "placeholder": "Telefon",
                "class": "w-full",
                "value": "",
                "autocomplete": "",
            }
        ),
    )

    own_text = forms.CharField(
        widget=forms.Textarea(
            attrs={
                "placeholder": "Vlastní text (nepovinný)",
                "class": "w-full",
                "rows": 3,
            }
        ),
        max_length=65535,
        required=False,
    )

    cv_file = forms.FileField(
        required=True,
        validators=[validate_file_type, validate_file_size],
        widget=forms.FileInput(
            attrs={
                "class": "max-w-64 mr-auto overflow-hidden break-words",
                "accept": ".pdf,.doc,.docx,.png,.odt",
            }
        ),
    )

    cover_letter_file = forms.FileField(
        required=True,
        validators=[validate_file_type, validate_file_size],
        widget=forms.FileInput(
            attrs={
                "class": "max-w-64 mr-auto overflow-hidden break-words",
                "accept": ".pdf,.doc,.docx,.png,.odt",
            }
        ),
    )

    other_files = MultipleFileField(
        required=False,
        validators=[validate_file_type, validate_file_size],
        widget=MultipleFileInput(
            attrs={
                "class": "max-w-64 mr-auto overflow-hidden break-words",
                "accept": ".pdf,.doc,.docx,.png,.odt",
            }
        ),
    )

    personal_data_agreement = forms.BooleanField(required=True)

    other_offers_agreement = forms.BooleanField(required=False)


class JekyllImportForm(SharedJekyllImportForm):
    def handle_import(self):
        lock_file_name = os.path.join(
            tempfile.gettempdir(), f".{self.instance.id}.articles-import-lock"
        )

        if os.path.isfile(lock_file_name):
            return

        open(lock_file_name, "w").close()

        import_jekyll_articles.delay(
            article_parent_page_id=self.instance.id,
            collection_id=self.cleaned_data["collection"].id,
            url=self.cleaned_data["jekyll_repo_url"],
            dry_run=self.cleaned_data["dry_run"],
            use_git=True,
        )


class MainArticlesPageForm(SharedArticlesPageForm, JekyllImportForm):
    def __init__(self, *args, **kwargs):
        from shared.models import SharedTag

        from .models import MainArticleTag

        super().__init__(*args, **kwargs)

        self.fields["shared_tags"].queryset = SharedTag.objects.order_by("name")

        if self.instance.pk:
            valid_tag_ids = (
                MainArticleTag.objects.filter(
                    content_object__in=self.instance.get_children().specific()
                )
                .values_list("tag_id", flat=True)
                .distinct()
            )
            valid_shared_tag_ids = (
                self.instance.shared_tags.values_list("id", flat=True).distinct().all()
            )

            self.fields["displayed_tags"].queryset = (
                MainArticleTag.objects.filter(id__in=valid_tag_ids)
                .order_by("tag__name")
                .distinct("tag__name")
            )
            self.fields["displayed_shared_tags"].queryset = (
                SharedTag.objects.filter(id__in=valid_shared_tag_ids)
                .order_by("name")
                .distinct("name")
            )
        else:
            self.fields["displayed_tags"].queryset = MainArticleTag.objects.filter(
                id=-1
            )
            self.fields["displayed_shared_tags"].queryset = SharedTag.objects.filter(
                id=-1
            )