import django.forms as forms
from django.forms import ModelForm
from django.forms.models import modelformset_factory

from troggle.core.models.caves import Cave, CaveAndEntrance, Entrance
from troggle.core.views.editor_helpers import HTMLarea

from django.core.exceptions import ValidationError

# from tinymce.widgets import TinyMCE
import re


"""These are all the class-based Forms used by troggle.
There are other, simpler, upload forms in view/uploads.py
Some are not used and need renovating or destroying.
"""

todo = """
"""


class CaveForm(ModelForm):
    """Only those fields for which we want to override defaults are listed here
    the other fields are present on the form, but use the default presentation style
    """

    official_name = forms.CharField(required=False, widget=forms.TextInput(attrs={"size": "45"}))
    underground_description = forms.CharField(
        required=False,
        widget=HTMLarea(attrs={"height": "80%", "rows": 20, "placeholder": "Enter page content (using HTML)"}),
    )
    explorers = forms.CharField(
        required=False,
        widget=HTMLarea(attrs={"height": "80%", "rows": 20, "placeholder": "Enter page content (using HTML)"}),
    )
    equipment = forms.CharField(
        required=False,
        widget=HTMLarea(attrs={"height": "80%", "rows": 20, "placeholder": "Enter page content (using HTML)"}),
    )
    survey = forms.CharField(
        required=False,
        widget=HTMLarea(attrs={"height": "80%", "rows": 20, "placeholder": "Enter page content (using HTML)"}),
    )
    # survey = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 10}))
    kataster_status = forms.CharField(required=False)
    underground_centre_line = forms.CharField(
        required=False,
        widget=HTMLarea(attrs={"height": "80%", "rows": 20, "placeholder": "Enter page content (using HTML)"}),
    )
    notes = forms.CharField(
        required=False,
        widget=HTMLarea(attrs={"height": "80%", "rows": 20, "placeholder": "Enter page content (using HTML)"}),
    )
    references = forms.CharField(
        required=False,
        widget=HTMLarea(attrs={"height": "80%", "rows": 20, "placeholder": "Enter page content (using HTML)"}),
    )
    description_file = forms.CharField(required=False, label="Path of top-level description file for this cave, when a separate file is used. Otherwise blank.", widget=forms.TextInput(attrs={"size": "45"}), help_text="")
    survex_file = forms.CharField(
        required=False, label="Survex file eg. caves-1623/000/000.svx", widget=forms.TextInput(attrs={"size": "45"})
    )
    #url = forms.CharField(required=True, label="URL eg. 1623/000/000 (no .html)", widget=forms.TextInput(attrs={"size": "45"}))
    length = forms.CharField(required=False, label="Length (m)")
    depth = forms.CharField(required=False, label="Depth (m)")
    extent = forms.CharField(required=False, label="Extent (m)")
    
    #cave_slug = forms.CharField()

    class Meta:
        model = Cave
        exclude = ("filename",)
       
    field_order = ['area', 'unofficial_number', 'kataster_number', 'official_name', 'underground_description', 'explorers', 'equipment', 'survey', 'kataster_status', 'underground_centre_line', 'notes', 'references', 'description_file', 'survex_file', 'url', 'length', 'depth', 'extent']
    
    def get_area(self):
        for a in self.cleaned_data["area"]:
            if a.kat_area():
                return a.kat_area()
    
    def clean_cave_slug(self):
        if self.cleaned_data["cave_slug"] == "":
            myArea = ""
            for a in self.cleaned_data["area"]:
                if a.kat_area():
                    myArea = a.kat_area()
            if self.data["kataster_number"]:
                cave_slug = f"{myArea}-{self.cleaned_data['kataster_number']}"
            else:
                cave_slug = f"{myArea}-{self.cleaned_data['unofficial_number']}"
        else:
            cave_slug = self.cleaned_data["cave_slug"]
	# Converting a PENDING cave to a real cave by saving this form
        print("EEE", cave_slug.replace("-PENDING-", "-"))
        return cave_slug.replace("-PENDING-", "-")
        
#    def clean_url(self):
#        data = self.cleaned_data["url"] 
#        if not re.match("\d\d\d\d/.", data):
#            raise ValidationError("URL must start with a four digit Kataster area.")
#        return data
            
    
    def clean(self):
        cleaned_data = super(CaveForm, self).clean()
        if self.data.get("kataster_number") == "" and self.data.get("unofficial_number") == "":
            self._errors["unofficial_number"] = self.error_class(
                ["Either the kataster or unoffical number is required."]
            )
        #        if self.cleaned_data.get("kataster_number") != "" and self.cleaned_data.get("official_name") == "":
        #            self._errors["official_name"] = self.error_class(["This field is required when there is a kataster number."])
        if cleaned_data.get("area") == []:
            self._errors["area"] = self.error_class(["This field is required."])
        if cleaned_data.get("url") and cleaned_data.get("url").startswith("/"):
            self._errors["url"] = self.error_class(["This field cannot start with a /."])
        return cleaned_data


class EntranceForm(ModelForm):
    """Only those fields for which we want to override defaults are listed here
    the other fields are present on the form, but use the default presentaiton style
    """

    name = forms.CharField(required=False, widget=forms.TextInput(attrs={"size": "45"}))
    entrance_description = forms.CharField(
        required=False,
        widget=HTMLarea(attrs={"height": "80%", "rows": 20, "placeholder": "Enter page content (using HTML)"}),
    )
    explorers = forms.CharField(required=False, widget=forms.TextInput(attrs={"size": "45"}))
    # explorers = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 10}))
    map_description = forms.CharField(
        required=False,
        widget=HTMLarea(attrs={"height": "80%", "rows": 20, "placeholder": "Enter page content (using HTML)"}),
    )
    location_description = forms.CharField(
        required=False,
        widget=HTMLarea(attrs={"height": "80%", "rows": 20, "placeholder": "Enter page content (using HTML)"}),
    )
    lastvisit = forms.CharField(
        required=False, widget=forms.TextInput(attrs={"size": "10"}), label="Date of last visit"
    )
    approach = forms.CharField(
        required=False,
        widget=HTMLarea(attrs={"height": "80%", "rows": 20, "placeholder": "Enter page content (using HTML)"}),
    )
    underground_description = forms.CharField(
        required=False,
        widget=HTMLarea(attrs={"height": "80%", "rows": 20, "placeholder": "Enter page content (using HTML)"}),
    )
    photo = forms.CharField(
        required=False,
        widget=HTMLarea(attrs={"height": "80%", "rows": 20, "placeholder": "Enter page content (using HTML)"}),
    )
    marking_comment = forms.CharField(
        required=False,
        widget=HTMLarea(attrs={"height": "80%", "rows": 20, "placeholder": "Enter page content (using HTML)"}),
    )
    findability_description = forms.CharField(
        required=False,
        widget=HTMLarea(attrs={"height": "80%", "rows": 20, "placeholder": "Enter page content (using HTML)"}),
    )
    other_description = forms.CharField(
        required=False,
        widget=HTMLarea(attrs={"height": "80%", "rows": 20, "placeholder": "Enter page content (using HTML)"}),
    )
    bearings = forms.CharField(
        required=False,
        widget=HTMLarea(attrs={"height": "80%", "rows": 20, "placeholder": "Enter page content (using HTML)"}),
    )
    other_station = forms.CharField(required=False)
    tag_station = forms.CharField(required=False)
    exact_station = forms.CharField(required=False)
    northing = forms.CharField(required=False)
    easting = forms.CharField(required=False)
    lat_wgs84 = forms.CharField(required=False, widget=forms.TextInput(attrs={"size": "10"}), label="Latitude (WSG84)")
    long_wgs84 = forms.CharField(
        required=False, widget=forms.TextInput(attrs={"size": "10"}), label="Longitude (WSG84)"
    )
    alt = forms.CharField(required=False, label="Altitude (m)")
    url = forms.CharField(required=False, label="URL [usually blank]", widget=forms.TextInput(attrs={"size": "45"}))

    field_order = ['name', 'entrance_description', 'explorers', 'map_description', 'location_description', 'lastvisit', 'approach', 'underground_description', 'photo', 'marking_comment', 'findability_description', 'other_description', 'bearings', 'other_station', 'tag_station', 'exact_station', 'northing', 'easting', 'lat_wgs84', 'long_wgs84', 'alt', 'url']

    class Meta:
        model = Entrance
        exclude = (
            "cached_primary_slug",
            "filename",
        )

    def clean(self):
        if self.cleaned_data.get("url").startswith("/"):
            self._errors["url"] = self.error_class(["This field cannot start with a /."])
        return self.cleaned_data


# This next line is called from the templates/edit_cave.html template.
# This is sufficient to create an entire entry for for the cave fields automatically
# http://localhost:8000/cave/new/
# using django built-in Deep Magic. https://docs.djangoproject.com/en/dev/topics/forms/modelforms/
# for forms which map directly onto a Django Model
CaveAndEntranceFormSet = modelformset_factory(CaveAndEntrance, exclude=("cave",))
# This is used only in edit_entrance() in views/caves.py

class EntranceLetterForm(ModelForm):
    """Form to link entrances to caves, along with an entrance number.

    Nb. The relationship between caves and entrances has historically been a many to many relationship.
    With entrances gaining new caves and letters when caves are joined.
    """

    class Meta:
        model = CaveAndEntrance
        exclude = ("cave", "entrance")

    def full_clean(self):
        super(EntranceLetterForm, self).full_clean()
        try:
            self.instance.validate_unique()
        except forms.ValidationError as e:
            self._update_errors(e)