from .exception import ValidationError
from django.core.validators import validate_email as django_validate_email
import json 
import re 
from .data import validation_msg
from datetime import datetime, timezone
from django.conf import settings


def validate_required_params(request, required_params):
    request_data = {}

    if request.method == "GET":
        request_data.update(request.GET)
    elif request.method in ["POST", "PUT"]:
        request_data.update(request.data)
    elif request.method in ["PUT", "DELETE"]:
        try:
            request_body = request.body.decode("utf-8")
            request_data.update(json.loads(request_body))
        except (json.JSONDecodeError, UnicodeDecodeError):
            raise ValidationError(f"{validation_msg['json']}")

    missing_params = [param for param in required_params if param not in request_data or not request_data[param]]
    if missing_params:
        raise ValidationError(f"Missing required parameters: {', '.join(missing_params)}")
 

def validate_file_type(file,valid_type):
    file_split = file.name.split(".")
    file_type = file_split [len(file_split)-1].lower()
    if file_type not in valid_type:
        raise ValidationError(f"{validation_msg['file']}")
    
def validate(key,val,validations):
    for validation  in validations:
        if validation =="email":
            is_email(val)
        elif re.search('length',validation):
            len_str = validation.split(':')
            if len_str[1] =='max':
                has_length(key,val,None,None,int(len_str[2]))
            elif len_str[2]=='min':
                has_length(key,val,None,int(len_str[2]),None)

            else:
                has_length(key,val,int(len_str[1]),None,None)

        elif validation =="capital_letter":
            has_capital_letter(key,val)
        elif validation =="small_letter":
            has_small_letter(key,val)
        elif validation =="number":
            has_number(key,val)
        elif validation =="special_characters":
            has_special_character(key,val)

def is_email(value):
    try:
        django_validate_email(value)
        return True
    except Exception as e:
        raise ValidationError(validation_msg["email"])
    
def has_length(key,val, exact_length=None, min_length=None, max_length=None):
    if exact_length is not None and len(val) != exact_length:
        raise ValidationError(f"{validation_msg['length']}: {key} length should be exactly {exact_length}")
    

    if min_length is not None and len(val)<min_length:
        raise ValidationError(f"{validation_msg['length']}: {key} must be at least {min_length} characters long.")
    
    if max_length is not None and len(val)>max_length:
        raise ValidationError(f"{validation_msg['length']}:{key} must be at least {max_length} characters long.")
    

def has_capital_letter(key,val):
    if not any(c.isupper() for c in val):
        raise ValidationError(validation_msg['capital_letter'])
    
def has_small_letter(key,val):
    if not any(c.islower() for c in val):
        raise ValidationError(validation_msg['small_letter'])
    
    
def has_number(key,val):
    if not any(c.isdigit() for c in val):
        raise ValidationError(validation_msg['number'])
 
 
def has_special_character(key,val):
    if not any(c in "!@#$%^&*()-_=+[{]};:'\",<.>/?\\|`~" for c in val):
         raise ValidationError(validation_msg['special_characters'])


def is_valid_foreign_key(model_class, field_value, field_name=1):
    filter_kwargs = {field_name: field_value}
    if not model_class.objects.filter(**filter_kwargs).exists():
        raise ValidationError(f"{validation_msg['foreign_key']}")

def validate_deadline(key, val):
    if not isinstance(val, datetime):
        raise ValidationError(f"{key} must be a valid datetime.")
    
    
    if val < timezone.now():
        raise ValidationError(f"{key}: The deadline must be in the future.")

def validate_url(key, val):
    url_pattern = re.compile(
        r'^(?:http|ftp)s?://' 
        r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|' 
        r'localhost|' 
        r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|' 
        r'\[?[A-F0-9]*:[A-F0-9:]+\]?)' 
        r'(?::\d+)?' 
        r'(?:/?|[/?]\S+)$', re.IGNORECASE)
    if not url_pattern.match(val):
        raise ValidationError(f"{validation_msg['url']}")



