import re
from django import forms
from .validators import (
    ece_id_is_not_031YY000, last_login_is_selected_from_provided_list, platform_exists_in_DB, platform_is_SLUB_or_exists_in_DB
)

# Create your forms here.
# https://docs.djangoproject.com/en/2.0/ref/forms/

# Each (programmatic) form from the ones defined below is based format-wise on the similarly named template form (e.g. LoginForm is based on the login_form of login.html, UserProfileEditForm is based on the user_profile_edit_form of user_profile_edit.html, etc.) and constraint-wise on the application models (see models.py).

class LoginForm(forms.Form):
    platform = forms.CharField(error_messages = {'required': 'Το όνομα πλατφόρμας πρέπει απαραίτητα να επιλεχθεί και να είναι μη-κενό!'},
                               validators = [platform_is_SLUB_or_exists_in_DB])
    username = forms.CharField(min_length = 8, max_length = 50,
                               error_messages = {'required': 'Το όνομα χρήστη πρέπει απαραίτητα να συμπληρωθεί!',
                                                 'min_length': 'Το όνομα χρήστη πρέπει να έχει τουλάχιστον 8 χαρακτήρες!',
                                                 'max_length': 'Το όνομα χρήστη δεν πρέπει να υπερβαίνει τους 50 χαρακτήρες!'})
    password = forms.CharField(min_length = 8, max_length = 50,
                               error_messages = {'required': 'Ο κωδικός πρόσβασης πρέπει απαραίτητα να συμπληρωθεί!',
                                                 'min_length': 'Ο κωδικός πρόσβασης πρέπει να έχει τουλάχιστον 8 χαρακτήρες!',
                                                 'max_length': 'Ο κωδικός πρόσβασης δεν πρέπει να υπερβαίνει τους 50 χαρακτήρες!'})

class UserProfileEditForm(forms.Form):
    first_name = forms.CharField(max_length = 50,
                                 error_messages = {'required': 'Το όνομα πρέπει απαραίτητα να συμπληρωθεί!',
                                                   'max_length': 'Το όνομα δεν πρέπει να υπερβαίνει τους 50 χαρακτήρες!'})
    last_name = forms.CharField(max_length = 50,
                                error_messages = {'required': 'Το επώνυμο πρέπει απαραίτητα να συμπληρωθεί!',
                                                  'max_length': 'Το επώνυμο δεν πρέπει να υπερβαίνει τους 50 χαρακτήρες!'})
    ece_id = forms.RegexField(required = False, max_length = 8, regex = '031[0-9]{5}',
                              # The empty value '' (empty string) becomes None in order to be interpreted as NULL in usermergeDB.
                              empty_value = None, error_messages = {'max_length': 'Ο αριθμός μητρώου πρέπει να είναι της μορφής '
                                                                                  '031YYSSS (YY: έτος, SSS: αύξων αριθμός)!',
                                                                    'invalid': 'Ο αριθμός μητρώου πρέπει να είναι της μορφής '
                                                                               '031YYSSS (YY: έτος, SSS: αύξων αριθμός)!'},
                              validators = [ece_id_is_not_031YY000])
    email = forms.EmailField(max_length = 100,
                             error_messages = {'required': 'Το ηλεκτρονικό ταχυδρομείο πρέπει απαραίτητα να συμπληρωθεί!',
                                               'max_length': 'Το ηλεκτρονικό ταχυδρομείο δεν πρέπει να υπερβαίνει τους 100 χαρακτήρες!',
                                               'invalid': 'Το ηλεκτρονικό ταχυδρομείο πρέπει να είναι της μορφής local-part@domain που\n'
                                                          'περιγράφεται στην ιστοσελίδα https://en.wikipedia.org/wiki/Email_address !'})

class UserProfileRecoveryForm(UserProfileEditForm):
    first_name = None
    last_name = None

class UserCredentialsImportForm(forms.Form):
    platform = forms.CharField(error_messages = {'required': 'Το όνομα πλατφόρμας πρέπει απαραίτητα να επιλεχθεί και να είναι μη-κενό!'},
                               validators = [platform_exists_in_DB])
    credentials_file = forms.FileField(max_length = 50,
                                       error_messages = {'required': 'Το αρχείο διαπιστευτηρίων πρέπει απαραίτητα να υποβληθεί και να '
                                                                     'έχει μη-κενό όνομα!',
                                                         'invalid': 'Η υποβολή του αρχείου διαπιστευτηρίων απέτυχε! Παρακαλούμε '
                                                                    'ελέγξτε την ορθότητα του\n'
                                                                    'τύπου κωδικοποίησης στη φόρμα προσθήκης διαπιστευτηρίων '
                                                                    'και δοκιμάστε ξανά!',
                                                         'missing': 'Η υποβολή του αρχείου διαπιστευτηρίων απέτυχε!',
                                                         'max_length': 'Το όνομα του αρχείου διαπιστευτηρίων δεν πρέπει '
                                                                       'να υπερβαίνει τους 50 χαρακτήρες!',
                                                         'empty': 'Το περιεχόμενο του αρχείου διαπιστευτηρίων δεν πρέπει να είναι κενό!'})

    def clean_credentials_file(self):
        credentials_file = self.cleaned_data['credentials_file']
        # Ensure that the credentials file is a plain text file whose size does not exceed 40KB.
        # Otherwise, close it and raise a ValidationError exception with the appropriate error message and code.
        if credentials_file.content_type != 'text/plain':
            credentials_file.close()
            raise forms.ValidationError('Το αρχείο διαπιστευτηρίων πρέπει να είναι ένα απλό αρχείο κειμένου!',
                                        code = 'credentials_file_content_type_is_not_plain_text')
        elif credentials_file.size > 1024 * 40:
            credentials_file.close()
            raise forms.ValidationError('Το μέγεθος του αρχείου διαπιστευτηρίων δεν πρέπει να υπερβαίνει τα 40KB!',
                                        code = 'credentials_file_size_exceeds_40KB')
        else:
            return credentials_file

class UserReportCreationForm(forms.Form):
    platform = forms.CharField(error_messages = {'required': 'Το όνομα πλατφόρμας πρέπει απαραίτητα να επιλεχθεί και να είναι μη-κενό!'},
                               validators = [platform_exists_in_DB])
    last_login = forms.CharField(error_messages = {'required': 'Η περίοδος αναζήτησης τελευταίας εισόδου πρέπει απαραίτητα να επιλεχθεί '
                                                               'και να είναι μη-κενή!'},
                                 validators = [last_login_is_selected_from_provided_list])