from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib.admin.views.decorators import staff_member_required
from django.contrib.auth import login, logout, authenticate
from django.contrib import messages
from django.contrib.auth.views import (
    PasswordResetView, PasswordResetDoneView,
    PasswordResetConfirmView, PasswordResetCompleteView,
    PasswordChangeView
)
from django.urls import reverse_lazy
from django.contrib.auth.forms import AuthenticationForm, PasswordResetForm, UserChangeForm, UserCreationForm
from django.contrib.auth.models import User, Group
from django.http import JsonResponse
from django.core.mail import send_mail
from django.template.loader import render_to_string
from django.conf import settings
from .forms import CustomUserCreationForm, CustomUserChangeForm, GroupForm, GroupPermissionForm, EditProfileForm, TenantLoginForm
import secrets
import string

# Login view
def user_login(request):
    from datetime import datetime
    
    if request.method == 'POST':
        form = TenantLoginForm(request.POST)
        if form.is_valid():
            user = form.cleaned_data['user']
            tenant = form.cleaned_data['tenant']
            tenant_user = form.cleaned_data['tenant_user']
            
            login(request, user)
            
            # Store tenant code in session
            request.session['tenant_code'] = tenant.tenant_code
            
            # Check if user is staff or has staff groups
            staff_groups = ['Sales', 'Supervisor', 'Manager', 'Administrator']
            user_groups = [group.name for group in user.groups.all()]
            
            # Redirect based on user group
            if user.groups.exists():
                user_group = user.groups.first().name
                if user_group == 'Sales':
                    return redirect('sales:make_sale')
                elif user_group == 'Supervisor':
                    return redirect('sales:sale_dashboard')
                elif user_group in ['Manager', 'Administrator']:
                    return redirect('dashboard')
            
            return redirect('dashboard')
        else:
            for field, errors in form.errors.items():
                for error in errors:
                    messages.error(request, error)
    else:
        form = TenantLoginForm()
    
    context = {
        'form': form,
        'current_year': datetime.now().year
    }
    return render(request, 'authapp/login.html', context)


# Superadmin login view
def superadmin_login(request):
    from datetime import datetime
    
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        
        if username and password:
            # Authenticate user
            user = authenticate(username=username, password=password)
            if user and user.is_superuser:
                login(request, user)
                # Clear any existing tenant code from session
                if 'tenant_code' in request.session:
                    del request.session['tenant_code']
                messages.success(request, 'Welcome, System Administrator!')
                return redirect('tenants_admin:system_dashboard')
            else:
                messages.error(request, 'Invalid credentials or insufficient privileges.')
        else:
            messages.error(request, 'Please enter both username and password.')
    
    context = {
        'current_year': datetime.now().year
    }
    return render(request, 'authapp/superadmin_login.html', context)


@login_required(login_url='/auth/login/')
def user_edit(request, pk):
    user = get_object_or_404(User, pk=pk)

    if request.method == 'POST':
        form = CustomUserChangeForm(request.POST, instance=user)
        if form.is_valid():
            form.save()
            messages.success(request, 'User profile updated successfully.')
            return redirect('user_list')  # Redirect to the user list or another relevant page
    else:
        form = CustomUserChangeForm(instance=user)

    return render(request, 'authapp/user_edit.html', {'form': form, 'user': user})

# Logout view
@login_required(login_url='/auth/login/')
def user_logout(request):
    # Clear tenant code from session
    if 'tenant_code' in request.session:
        del request.session['tenant_code']
    logout(request)
    return redirect('landing:home')

# Profile view
@login_required(login_url='/auth/login/')
def profile(request):
    return render(request, 'authapp/profile.html')

# Password reset views
class CustomPasswordResetView(PasswordResetView):
    template_name = 'authapp/password_reset.html'
    success_url = reverse_lazy('password_reset_done')
    email_template_name = 'authapp/password_reset_email.html'
    subject_template_name = 'authapp/password_reset_subject.txt'

@staff_member_required
def admin_reset_user_password(request, user_id):
    """Admin function to reset user password and send email"""
    if request.method == 'POST':
        try:
            user = get_object_or_404(User, id=user_id)
            
            # Generate new password
            new_password = ''.join(secrets.choice(string.ascii_letters + string.digits) for _ in range(12))
            user.set_password(new_password)
            user.save()
            
            # Get user's tenant (if they have one)
            from tenants.models import TenantUser, Tenant
            tenant_user = TenantUser.objects.filter(user=user).first()
            tenant = tenant_user.tenant if tenant_user else None
            
            # Send password reset email
            try:
                subject = f'Password Reset - {tenant.name if tenant else "POS 254"}'
                login_url = f'http://{request.get_host()}/auth/login/'
                
                context = {
                    'user': user,
                    'tenant': tenant,
                    'tenant_code': tenant.tenant_code if tenant else 'N/A',
                    'new_password': new_password,
                    'login_url': login_url,
                    'support_email': 'support@posapp.co.ke',
                    'contact_phone': '+254 796374224',
                }
                
                html_message = render_to_string('tenants/emails/password_reset.html', context)
                plain_message = f'''Password Reset - {tenant.name if tenant else "POS 254"}

Hello {user.get_full_name() or user.username},

Your password has been reset by an administrator.

Your new login credentials:
Username: {user.username}
New Password: {new_password}
Tenant Code: {tenant.tenant_code if tenant else 'N/A'}

Login at: {login_url}

IMPORTANT: For security reasons, please change this password after your first login.

If you did not request this password reset, please contact our support team immediately.

Support: support@posapp.co.ke
Phone: +254 796374224

Best regards,
The POS 254 Team'''
                
                send_mail(
                    subject=subject,
                    message=plain_message,
                    from_email=settings.DEFAULT_FROM_EMAIL,
                    recipient_list=[user.email],
                    html_message=html_message,
                    fail_silently=False,
                )
                
                messages.success(request, f'Password reset for {user.username}. New password sent to {user.email}')
                messages.info(request, f'New password: {new_password}')
                
            except Exception as e:
                messages.success(request, f'Password reset for {user.username}')
                messages.warning(request, f'Email failed to send: {str(e)}')
                messages.info(request, f'New password: {new_password}')
            
            return JsonResponse({'success': True, 'message': f'Password reset successfully'})
            
        except Exception as e:
            return JsonResponse({'success': False, 'error': str(e)})
    
    return JsonResponse({'success': False, 'error': 'Invalid request method'})

class CustomPasswordResetDoneView(PasswordResetDoneView):
    template_name = 'authapp/password_reset_done.html'

class CustomPasswordResetConfirmView(PasswordResetConfirmView):
    template_name = 'authapp/password_reset_confirm.html'
    success_url = reverse_lazy('password_reset_complete')

class CustomPasswordResetCompleteView(PasswordResetCompleteView):
    template_name = 'authapp/password_reset_complete.html'

# View to list users

@login_required(login_url='/auth/login/')
def user_list(request):
    users = User.objects.all()
    available_groups = Group.objects.all()

    # Initialize forms
    add_user_form = CustomUserCreationForm()
    edit_user_forms = {}

    if request.method == 'POST':
        # Handle Add User
        if 'add_user' in request.POST:
            add_user_form = CustomUserCreationForm(request.POST, request.FILES)
            if add_user_form.is_valid():
                new_user = add_user_form.save(commit=False)
                new_user.save()  # Save the new user first
                # Manually handle the group assignment
                selected_groups = request.POST.getlist('groups')
                new_user.groups.set(selected_groups)
                new_user.save()
                messages.success(request, 'User added successfully')
                return redirect('user_list')

        # Handle Edit User
        elif 'edit_user' in request.POST:
            user_id = request.POST.get('user_id')
            user_instance = get_object_or_404(User, id=user_id)
            edit_user_form = CustomUserChangeForm(request.POST, request.FILES, instance=user_instance)
            if edit_user_form.is_valid():
                updated_user = edit_user_form.save(commit=False)
                updated_user.save()  # Save the updated user first
                # Manually handle the group assignment
                selected_groups = request.POST.getlist('groups')
                updated_user.groups.set(selected_groups)
                updated_user.save()
                messages.success(request, 'User updated successfully')
                return redirect('user_list')
            else:
                messages.error(request, 'Error updating user. Please check the form.')

        # Handle Advanced Edit User
        elif 'advanced_edit_user' in request.POST:
            user_id = request.POST.get('user_id')
            user_instance = get_object_or_404(User, id=user_id)
            
            # Check permissions
            if not request.user.has_perm('auth.change_user'):
                messages.error(request, 'You do not have permission to edit users.')
                return redirect('user_list')
            
            try:
                # Update basic fields
                user_instance.username = request.POST.get('username', user_instance.username)
                user_instance.first_name = request.POST.get('first_name', '')
                user_instance.last_name = request.POST.get('last_name', '')
                user_instance.email = request.POST.get('email', '')
                
                # Update status fields
                user_instance.is_active = 'is_active' in request.POST
                
                # Only superuser can change staff and superuser status
                if request.user.is_superuser:
                    user_instance.is_staff = 'is_staff' in request.POST
                    user_instance.is_superuser = 'is_superuser' in request.POST
                
                # Handle lock account
                if 'lock_account' in request.POST and user_instance != request.user:
                    user_instance.is_active = False
                
                user_instance.save()
                
                # Handle group assignments
                selected_groups = request.POST.getlist('groups')
                user_instance.groups.set(selected_groups)
                
                # Handle password reset flag
                if 'reset_password' in request.POST:
                    # You can implement password reset logic here
                    # For now, we'll just set a flag or send an email
                    messages.info(request, f'Password reset will be required for {user_instance.username} on next login.')
                
                messages.success(request, f'User {user_instance.username} has been updated successfully with all changes.')
                return redirect('user_list')
                
            except Exception as e:
                messages.error(request, f'Error updating user: {str(e)}')
                return redirect('user_list')

    # Initialize edit forms for each user
    for user in users:
        if user.id not in edit_user_forms:
            edit_user_forms[user.id] = CustomUserChangeForm(instance=user)

    context = {
        'users': users,
        'add_user_form': add_user_form,
        'edit_user_forms': edit_user_forms,
        'available_groups': available_groups,
    }

    return render(request, 'authapp/user_list.html', context)


# View to edit a user profile
@login_required(login_url='/auth/login/')
def edit_user(request, user_id):
    user = get_object_or_404(User, id=user_id)
    if request.method == 'POST':
        form = CustomUserChangeForm(request.POST, instance=user)
        if form.is_valid():
            form.save()
            messages.success(request, 'User updated successfully')
            return redirect('user_list')
    else:
        form = CustomUserChangeForm(instance=user)
    return render(request, 'authapp/edit_user.html', {'form': form, 'user_obj': user})

# View to add a new user
@login_required(login_url='/auth/login/')
def add_user(request):
    if request.method == 'POST':
        form = CustomUserCreationForm(request.POST)
        if form.is_valid():
            form.save()
            messages.success(request, 'User added successfully')
            return redirect('user_list')
    else:
        form = CustomUserCreationForm()
    return render(request, 'authapp/add_user.html', {'form': form})

# View to list and manage groups
@login_required(login_url='/auth/login/')
def group_list(request):
    groups = Group.objects.all()
    return render(request, 'authapp/group_list.html', {'groups': groups})

# View to edit a group
@login_required(login_url='/auth/login/')
def edit_group(request, group_id):
    group = get_object_or_404(Group, id=group_id)
    if request.method == 'POST':
        form = GroupForm(request.POST, instance=group)
        if form.is_valid():
            form.save()
            messages.success(request, 'Group updated successfully')
            return redirect('group_list')
    else:
        form = GroupForm(instance=group)
    return render(request, 'authapp/edit_group.html', {'form': form, 'group_obj': group})

# View to add a new group
@login_required(login_url='/auth/login/')
def add_group(request):
    if request.method == 'POST':
        form = GroupForm(request.POST)
        if form.is_valid():
            form.save()
            messages.success(request, 'Group added successfully')
            return redirect('group_list')
    else:
        form = GroupForm()
    return render(request, 'authapp/add_group.html', {'form': form})

@login_required(login_url='/auth/login/')
def delete_user(request, user_id):
    user = get_object_or_404(User, id=user_id)
    user.delete()
    messages.success(request, 'User deleted successfully')
    return redirect('user_list')



# List all groups
@login_required(login_url='/auth/login/')
def group_list(request):
    groups = Group.objects.all()
    return render(request, 'authapp/group_list.html', {'groups': groups})

# Create a new group
@login_required(login_url='/auth/login/')
def group_create(request):
    if request.method == 'POST':
        form = GroupForm(request.POST)
        if form.is_valid():
            form.save()
            messages.success(request, 'Group created successfully')
            return redirect('group_list')
    else:
        form = GroupForm()

    return render(request, 'authapp/group_create.html', {'form': form})

# Edit an existing group
@login_required(login_url='/auth/login/')
def group_edit(request, group_id):
    group = get_object_or_404(Group, id=group_id)
    if request.method == 'POST':
        form = GroupForm(request.POST, instance=group)
        if form.is_valid():
            form.save()
            messages.success(request, 'Group updated successfully')
            return redirect('group_list')
    else:
        form = GroupForm(instance=group)

    return render(request, 'authapp/group_edit.html', {'form': form, 'group': group})

# Delete a group
@login_required(login_url='/auth/login/')
def group_delete(request, group_id):
    group = get_object_or_404(Group, id=group_id)
    if request.method == 'POST':
        group.delete()
        messages.success(request, 'Group deleted successfully')
        return redirect('group_list')

    return render(request, 'authapp/group_delete_confirm.html', {'group': group})

# Group detail view to assign permissions
@login_required(login_url='/auth/login/')
def group_detail(request, group_id):
    group = get_object_or_404(Group, id=group_id)
    if request.method == 'POST':
        form = GroupPermissionForm(request.POST, instance=group)
        if form.is_valid():
            form.save()
            messages.success(request, 'Permissions updated successfully')
            return redirect('group_detail', group_id=group_id)
    else:
        form = GroupPermissionForm(instance=group)

    return render(request, 'authapp/group_detail.html', {'group': group, 'form': form})

# Edit profile view
@login_required(login_url='/auth/login/')
def edit_profile(request):
    if request.method == 'POST':
        form = EditProfileForm(request.POST, request.FILES, instance=request.user)
        if form.is_valid():
            user = form.save()
            
            # Handle profile picture upload
            if 'profile_picture' in request.FILES:
                profile_picture = request.FILES['profile_picture']
                # Save the profile picture to media/profile_pictures/
                import os
                from django.conf import settings
                from django.core.files.storage import default_storage
                
                # Create directory if it doesn't exist
                upload_dir = os.path.join(settings.MEDIA_ROOT, 'profile_pictures')
                os.makedirs(upload_dir, exist_ok=True)
                
                # Save file with user ID as filename
                file_extension = os.path.splitext(profile_picture.name)[1]
                filename = f'user_{user.id}{file_extension}'
                file_path = os.path.join('profile_pictures', filename)
                
                # Delete old profile picture if exists
                old_file_path = os.path.join(upload_dir, f'user_{user.id}.*')
                import glob
                for old_file in glob.glob(old_file_path.replace('.*', '*')):
                    try:
                        os.remove(old_file)
                    except:
                        pass
                
                # Save new file
                saved_path = default_storage.save(file_path, profile_picture)
                
                # You can add a profile_picture field to User model or create a UserProfile model
                # For now, we'll store the path in session or handle it differently
                request.session['profile_picture'] = saved_path
            
            messages.success(request, 'Your profile has been updated successfully.')
            return redirect('edit_profile')
        else:
            messages.error(request, 'Please correct the errors below.')
    else:
        form = EditProfileForm(instance=request.user)
    
    # Get profile picture from session if available
    profile_picture_url = None
    if 'profile_picture' in request.session:
        from django.conf import settings
        profile_picture_url = f"{settings.MEDIA_URL}{request.session['profile_picture']}"
    
    context = {
        'form': form,
        'profile_picture_url': profile_picture_url
    }
    
    return render(request, 'authapp/edit_profile.html', context)

# Password change view
class CustomPasswordChangeView(PasswordChangeView):
    template_name = 'authapp/change_password.html'
    success_url = reverse_lazy('authapp:profile')

@login_required(login_url='/auth/login/')
def user_change_password(request):
    view = CustomPasswordChangeView.as_view()
    return view(request)
