from django.shortcuts import render
import json
from django.conf import settings
from django.shortcuts import render
from masters.models import *
from privilege.forms import *
from privilege.models import *
from common.models import *
import hashlib
import os
from django.conf import settings
from datetime import datetime
from django.utils import timezone
from django.db.models import Max, F, Q
import base64
from django.shortcuts import render
from io import BytesIO
from django.conf import settings
from django.template.loader import get_template
from django.http import HttpResponse,JsonResponse,HttpResponseRedirect,HttpResponseForbidden
from django.shortcuts import get_object_or_404
from django.templatetags.static import static
from xhtml2pdf import pisa
from num2words import num2words
from django.contrib.staticfiles import finders
from common.utils import *
from django.db import transaction


#```````````````````````````````````````````````````````````**USER ROLE**````````````````````````````````````````````````````````````````````````````````

def user_privilege(request):
    if 'user_id' in request.session:
        user_type = request.session.get('user_type')
        if user_type == 'admin' or  user_type == 'stores':
            cmpy = select_row(company_table, {'id':1})
            role = selectList(role_table, order_by='name')
            return render(request, 'user_role.html', {'company': cmpy,'role':role})
        else:
            return HttpResponseRedirect("/")
    else:
        return HttpResponseRedirect("/")
    

def store_roles(request):
    if 'user_id' in request.session:
        user_type = request.session.get('user_type')
        if user_type == 'admin' or  user_type == 'stores':
            cmpy = select_row(company_table, {'id':1})
            role = selectList(role_table, order_by='name')
            return render(request, 'store_roles.html', {'company': cmpy,'role':role})
        else:
            return HttpResponseRedirect("/")
    else:
        return HttpResponseRedirect("/")
    

def wholesale_roles(request):
    if 'user_id' in request.session:
        user_type = request.session.get('user_type')
        if user_type == 'admin' or  user_type == 'wholesale' or user_type == 'stores':
            cmpy = select_row(company_table, {'id':1})
            role = selectList(role_table, order_by='name')
            return render(request, 'wholesale_roles.html', {'company': cmpy,'role':role})
        else:
            return HttpResponseRedirect("/")
    else:
        return HttpResponseRedirect("/")

def get_roles(request):
    if 'user_id' in request.session:
        role_type = request.POST.get('role_type')
        
        query = Q(status=1)
        if role_type == 'store':
            query &= Q(role_type= role_type)

        if role_type == 'admin':
            query &= Q(role_type=role_type)

        if role_type == 'wholesale':
            query &= Q(role_type=role_type)

        roles  = selectList(role_table, query,order_by='name')   

        roles_data = [{'id': role.id, 'name': role.name} for role in roles]
        return JsonResponse(roles_data, safe=False)       

    else:
        return HttpResponseForbidden(render(request, '403.html'))
    




def view_roles(request):
    user_role_id = request.POST.get('role_id')
    role_type = request.POST.get('role_type')

    user_type = request.session.get('user_type')
    role_id = request.session.get('role_id')
    branch_id = request.session.get('branch_id')

    if role_type == 'admin':
        all_modules = selectList(module_table, {'is_admin':1}, order_by='sort_order_no', fields =['id', 'name'])
        has_access, error_message = check_user_access(role_id, 'admin_roles', "read")

        if not has_access:
            return JsonResponse({'message': 'permission', 'error_message': 'You do not have permission to view the user Role'})

   
    if role_type == 'store':
        all_modules = selectList(module_table, {'is_branch':1},order_by='sort_order_no', fields =['id', 'name'])
        
        has_access, error_message = check_user_access(role_id, 'store_roles', "read")

        if not has_access:
            return JsonResponse({'message': 'permission', 'error_message': 'You do not have permission to view the store Role'})


    if role_type == 'wholesale':
        all_modules = selectList(module_table, {'is_wholesale':1},order_by='sort_order_no', fields =['id', 'name'])
        
        has_access, error_message = check_user_access(role_id, 'wholesale_roles', "read")

        if not has_access:
            return JsonResponse({'message': 'permission', 'error_message': 'You do not have permission to view the wholesale Role'})
        
    if user_type == 'stores' and branch_id:
        all_modules = all_modules.filter(is_branch=1)
    if user_type == 'wholesale':
        all_modules = all_modules.filter(is_wholesale=1)

    privilege_data = []

    if user_role_id:
        privileges = privilege_table.objects.filter(role_id=user_role_id).values(
            'module_id', 'is_create', 'is_read', 'is_update', 'is_delete'
        )
        privilege_dict = {priv['module_id']: priv for priv in privileges}

        for module in all_modules:
            module_id = module['id']
            privilege_info = privilege_dict.get(module_id, None)
            privilege_data.append({
                'module_id': module_id,
                'module': module['name'],
                'is_create': privilege_info['is_create'] if privilege_info else 0,
                'is_read': privilege_info['is_read'] if privilege_info else 0,
                'is_update': privilege_info['is_update'] if privilege_info else 0,
                'is_delete': privilege_info['is_delete'] if privilege_info else 0,
            })
    else:
        privilege_data = [
            {
                'module_id': module['id'],
                'module': module['name'],
                'is_create': 0,
                'is_read': 0,
                'is_update': 0,
                'is_delete': 0,
            }
            for module in all_modules
        ]

    return JsonResponse({'data': privilege_data})


def edit_roles(request):
    if request.method == "POST":
        data = role_table.objects.filter(id=request.POST.get('id'))
    return JsonResponse(data.values()[0])



def duplicate_add(request):
    if request.method == "POST":
        data = role_table.objects.filter(id=request.POST.get('id'))
    
    return JsonResponse(data.values()[0])




def add_roles(request):
    if request.method == 'POST':
        try:
            user_id = request.session.get('user_id')           
            company_id = request.session.get('company_id')           
            branch_id = int(request.session.get('branch_id') or 0)
            form = Userform(request.POST, request.FILES)

            role_id = request.session.get('role_id')           
            if form.is_valid():
                category = form.save(commit=False)
                role_type = request.POST.get('role_type')
                
                if role_type == 'admin':
                    has_access, error_message = check_user_access(role_id, 'admin_roles', "create")
                    
                if role_type == 'store':
                    has_access, error_message = check_user_access(role_id, 'store_roles', "create")

                if role_type == 'wholesale':
                    has_access, error_message = check_user_access(role_id, 'wholesale_roles', "create")

                if not has_access:
                    return JsonResponse({'message': 'permission', 'error_message': 'You do not have permission to add the user Role'})
                    


                category.name = request.POST.get('role')
                category.description = request.POST.get('description')
                category.role_type = role_type
                category.created_by = user_id
                category.updated_by = user_id
                category.company_id = company_id
                category.branch_id= branch_id
                category.is_active = 1
                category.status = 1
                category.created_on = timezone.now().strftime('%Y-%m-%d %H:%M:%S')
                category.updated_on = timezone.now().strftime('%Y-%m-%d %H:%M:%S')
                category.save()
                return JsonResponse({'message': 'success'})
            else:
                errors = form.errors.as_json()
                return JsonResponse({'message': 'form_error', 'errors': errors}, status=400)

        except Exception as e:
            return JsonResponse({'message': 'exception', 'error': str(e)}, status=500)





def update_roles(request):
    if request.method == "POST":
        try:
            category_id = request.POST.get('id')
            category = role_table.objects.get(id=category_id)
            form = Userform(request.POST, request.FILES, instance=category)
            
            role_id = request.session.get('role_id')


            
            if form.is_valid():
                updated_category = form.save(commit=False)
                desc = request.POST.get('description')
                name = request.POST.get('role')
                role_type = request.POST.get('role_type')
                is_active = request.POST.get('is_active')

                if role_type == 'admin':
                    has_access, error_message = check_user_access(role_id, 'admin_roles', "update")
                    
                if role_type == 'store':
                    has_access, error_message = check_user_access(role_id, 'store_roles', "update")

                if role_type == 'wholesale':
                    has_access, error_message = check_user_access(role_id, 'wholesale_roles', "update")

                if not has_access:
                    return JsonResponse({'message': 'permission', 'error_message': 'You do not have permission to update the user Role'})

                    

                updated_category.name = name            
                updated_category.role_type = role_type            
                updated_category.is_active = 1            
                updated_category.descriptions = desc
                updated_category.updated_by = request.session.get('user_id')
                updated_category.updated_on = timezone.now().strftime('%Y-%m-%d %H:%M:%S')
                updated_category.save()
                return JsonResponse({'message': 'success'})
            else:
                errors = form.errors.as_json()
                return JsonResponse({'message': 'error', 'errors': errors})
        except Exception as e:
            return JsonResponse({'message': 'exception', 'error': str(e)})




def role_duplicate(request):
    if request.headers.get('x-requested-with') == 'XMLHttpRequest':
        user_id = request.session.get('user_id')
        role_id = request.session.get('role_id')

        original_role_id = request.POST.get('duplicate_id')
        new_role_name = request.POST.get('role')
        new_role_desc = request.POST.get('description')
        new_role_type = request.POST.get('duplicate_role')

        if new_role_type == 'admin':
            has_access, error_message = check_user_access(role_id, 'admin_roles', "create")
            
        if new_role_type == 'store':
            has_access, error_message = check_user_access(role_id, 'store_roles', "create")

        if not has_access:
            return JsonResponse({'message': 'permission', 'error_message': 'You do not have permission to duplicate the user role'})



        if not original_role_id or not new_role_name:
            return JsonResponse({'message': 'invalid input'})

        try:
            with transaction.atomic():
                original_role = role_table.objects.get(id=original_role_id)

                new_role = role_table.objects.create(
                    name=new_role_name,
                    descriptions=new_role_desc,
                    created_on=original_role.created_on,
                    created_by=original_role.created_by,
                    role_type=new_role_type,
                    updated_on=timezone.now(),
                    updated_by=user_id
                )

                original_privileges = privilege_table.objects.filter(role_id=original_role.id)
                for privilege in original_privileges:
                    privilege_table.objects.create(
                        role_id=new_role.id,
                        module_id=privilege.module_id,
                        is_create=privilege.is_create,
                        is_read=privilege.is_read,
                        is_update=privilege.is_update,
                        is_delete=privilege.is_delete,
                        created_on=timezone.now(),
                        updated_on=timezone.now(),
                        created_by=user_id,
                        updated_by=user_id
                    )

                return JsonResponse({"message": "success"})

        except Exception as e:
            return JsonResponse({'message': 'exception', 'error': str(e)})
    
    return JsonResponse({'message': 'invalid request'})




def delete_roles(request):
    if request.method == 'POST':
        data_id = request.POST.get('id')     
        role_id = request.session.get('role_id')
        role = select_row(role_table, {'id':data_id})
        
        if role.role_type == 'admin':
            has_access, error_message = check_user_access(role_id, 'admin_roles', "delete")
        if role.role_type == 'store':
            has_access, error_message = check_user_access(role_id, 'store_roles', "delete")

        if not has_access:
            return JsonResponse({'message': 'permission', 'error_message': 'You do not have permission to delete the user Role'})  
        
        try:
            updated = role_table.objects.filter(id=data_id).update(status=0)
            if updated:
                return JsonResponse({'message': 'yes'})
            else:
                return JsonResponse({'message': 'no such data'})
        except Exception as e:
            return JsonResponse({'message': 'exception', 'error': str(e)})

    return JsonResponse({'message': 'Invalid request method'})




def refresh_privileges(request):
    user_type = request.session.get('user_type')
    if user_type in ['stores', 'admin']:
        if request.method == 'POST':
            role_id = request.POST.get('id')
            modules = module_table.objects.filter(status=1).values('id')
            existing_privileges = privilege_table.objects.filter(role_id=role_id).values_list('module_id', flat=True)
            existing_privileges_set = set(existing_privileges)  
            new_privileges = []
            for module in modules:
                module_id = module['id']
                if module_id not in existing_privileges_set:
                    new_privileges.append(privilege_table(
                        role_id=role_id,
                        module_id=module_id,
                        is_create=0,
                        is_read=0,
                        is_update=0,
                        is_delete=0,
                        is_active=1,
                        status=1,
                        created_on=format_date(timezone.now()),
                        updated_on=format_date(timezone.now()),
                        created_by=request.session['user_id'],  
                        updated_by=request.session['user_id']
                    ))
            if new_privileges:
                privilege_table.objects.bulk_create(new_privileges)
            return JsonResponse({'message': 'yes'})
    
        return JsonResponse({'error': 'Invalid request method'}, status=400)
    else:
        return HttpResponseForbidden(render(request, '403.html'))



def privileges_update(request):
    if request.method == 'POST':
        role_id = request.session['role_id']

        user_role_id = request.POST.get('role_id')
        print('user rile', user_role_id)
        privileges_json = request.POST.get('privileges')
        user_id = request.session['user_id']

        privileges = json.loads(privileges_json)

        role = select_row(role_table, {'id':user_role_id})
        print('Role', role)
        
        if role.role_type == 'admin':
            has_access, error_message = check_user_access(role_id, 'admin_roles', "update")
        if role.role_type == 'store':
            has_access, error_message = check_user_access(role_id, 'store_roles', "update")

        if role.role_type == 'wholesale':
            has_access, error_message = check_user_access(role_id, 'wholesale_roles', "update")

        if not has_access:
            return JsonResponse({'message': 'permission', 'error_message': error_message})

        try:
            role = role_table.objects.get(id=user_role_id)
        except role_table.DoesNotExist:
            return JsonResponse({'error': 'Role with ID {} does not exist'.format(user_role_id)}, status=404)

        privilege_table.objects.filter(role_id=role.id).delete()

        for privilege_data in privileges:
            module_id = privilege_data.get('module_id')  
            is_create = privilege_data.get('create', 0)
            is_read = privilege_data.get('read', 0)
            is_update = privilege_data.get('update', 0)
            is_delete = privilege_data.get('delete', 0)

            privilege = privilege_table.objects.create(
                role_id=role.id,
                module_id=module_id,
                is_create=is_create,
                is_read=is_read,
                is_update=is_update,
                is_delete=is_delete,
                created_on=format_date(timezone.now()),
                updated_on=format_date(timezone.now()),
                created_by=user_id,
                updated_by=user_id
            )
            privilege.save()
        response_data = {
            'message': 'Privileges updated successfully for role ID: {}'.format(user_role_id)
        }
        return JsonResponse(response_data)
    else:
        return JsonResponse({'error': 'Invalid request method'}, status=400)





from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse

@csrf_exempt
def check_role_name(request):
    if request.method == 'POST':
        name = request.POST.get('name', '').strip()
        role_type = request.POST.get('role_type', '').strip()
        role_id = request.POST.get('id')  # for edit, to exclude current row

        query = role_table.objects.filter(name__iexact=name, role_type=role_type, is_active=1)

        if role_id:
            query = query.exclude(id=role_id)

        exists = query.exists()

        return JsonResponse({'exists': exists})
    return JsonResponse({'exists': False})
