import datetime
import os
from django.contrib.auth.models import User , Group , Permission
from django.contrib.contenttypes.models import ContentType
from django.conf import settings
from django.urls import URLPattern, URLResolver
from django.urls import get_resolver
import phonenumbers
from main.models import Language, Links
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
from django.db.models import Sum, Q
from django.urls import resolve
import phonenumbers
from phonenumbers import geocoder


def log_func(func,txt):
    
    dt = datetime.datetime.now()
    nm = dt.strftime("%Y%m")
    path = os.path.join(settings.BASE_DIR, f'log/functions/{nm}/')
    if not os.path.exists(path):
        os.makedirs(path)
    fname = f"{path}{func}.log"
    txt = f"{txt}"
    try:
        ft = "a" if os.path.exists(fname) else "w"
        with open(fname, ft) as outfile:
            outfile.write(f'{dt.strftime("%Y/%m/%d %H:%M:%S")}: {txt.decode("utf-8")}\r\n')
    except Exception as e:
        pass
    


def set_page_title(language="en", **kwargs):
    lang = Language.objects.filter(code=language).first()
    if lang is None:
        lang = Language.objects.filter(code="en").first()
    if lang.code == "en":
        out = "Entralon | international online real estate platform"
    elif lang.code == "fa":
        out = "انترالون | پلتفرم آنلاین مشاور املاک بین المللی"
    elif lang.code == "ar":
        out = "انترالون | منصة مشاورة العقارات الدولية"
    elif lang.code == "ru":
        out = "Entralon | международная онлайн-платформа недвижимости"

    
    return out
    
    


def extract_urls():
    urls = []
    def recursive_urls(url_patterns, parent_path=''):
        for pattern in url_patterns:
            if isinstance(pattern, URLPattern):
                path = parent_path + str(pattern.pattern)
                urls.append({
                    'path': path,
                    'name': pattern.name,
                    'view': pattern.callback.__name__
                })
            elif isinstance(pattern, URLResolver):
                recursive_urls(pattern.url_patterns, parent_path + str(pattern.pattern))
    
    recursive_urls(get_resolver().url_patterns)
    return urls


def create_links():
    urls = extract_urls()
    ct = ContentType.objects.get_for_model(User)
    for url in urls:
        if url['path'].startswith('master'):
            permission,_ = Permission.objects.get_or_create(codename=url['view'], content_type = ct)
            try:link = Links.objects.get(views=url['view'], link=url['path'])
            except ObjectDoesNotExist:
                link = Links.objects.create(views=url['view'], link=url['path'], name=url['view'].replace("_", " "), permission=permission)
            except MultipleObjectsReturned:
                link = Links.objects.filter(views=url['view'], link=url['path']).first()
                Links.objects.filter(views=url['view'], link=url['path']).exclude(id=link.id).delete()
            link.permission = permission
            link.use_for = "master"
            if (permission.name is None or permission.name == '') and link.name is not None:
                permission.name = link.name
            permission.save()
            link.save()
    try: permission = Permission.objects.get(codename="main_pages")
    except: permission = Permission.objects.create(codename="main_pages",name="main pages",content_type = ct)
    Links.objects.filter(link__in=["#","","/","/master/","/master/login/","/master/login/submit/"]).update(permission=permission)
    for link in Links.objects.filter(permission=None, views__startswith="master_"):
        name = link.views
        try:
            permission = Permission.objects.get(codename=name)
        except Exception:
            permission = Permission.objects.create(codename=name, content_type = ct)
        link.permission=permission
        link.use_for = "master"
        if (permission.name is None or permission.name == '') and link.name is not None:
            permission.name = link.name
        permission.save()
        link.save()
    default_group = [
        ("super_user","super user"),
        ("master","master"),
    ]
    for x in default_group:
        group,_ = Group.objects.get_or_create(name=x[1])
        un = x[0]
        if x[0] == "super_user":
            permissions = Permission.objects.filter(Q(codename__startswith="master") | Q(codename="main_pages"))
        elif x[0] in ["master"]:
            permissions = Permission.objects.filter(Q(codename__in=["master","master_panel", "master_dashboard"]) | Q(codename="main_pages"))
        else:
            permissions = Permission.objects.filter(Q(codename__startswith=x[0]) | Q(codename="main_pages"))

        users = User.objects.filter(groups=None, username__icontains=un)
        group.user_set.add(*users)
        group.permissions.add(*permissions)
        
def user_control(request):
    """
    Check user permissions based on Links model configuration
    """
    current_url = resolve(request.path_info).url_name
    result = {
        'has_perm': False,
        'redirect_uri': '/login/'
    }
    
    if not request.user.is_authenticated:
        return result
        
    link = Links.objects.filter(views=current_url).first()
    
    if link and link.permission:
        if request.user.has_perm(link.permission):
            result['has_perm'] = True
    else:
        result['has_perm'] = True
        
    return result

def analyze_phone_number(phone_number):
    if not phone_number:
        return ""
    if not isinstance(phone_number, str):
        phone_number = str(phone_number)
    if not phone_number.startswith("+"):
        phone_number = f"+{phone_number}"
    try:
        parsed_number = phonenumbers.parse(phone_number)     
        r = geocoder.region_code_for_country_code(parsed_number.country_code)
        country = geocoder._region_display_name(r, "en")
        return f"{country}({parsed_number.country_code})"
    except Exception as e: 
        print(f"""error on {datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")} : analyze phone number {phone_number}: {e}""")
        return ""
