
import uuid
from datetime import datetime, timedelta
from typing import Optional, Tuple

from django.conf import settings
from django.contrib import messages
from django.contrib.auth import authenticate, get_user_model, login
from django.http import HttpRequest, HttpResponse
from django.shortcuts import redirect, render
from django.urls import reverse_lazy
from django.utils.translation import gettext as _

from apps import logger

from .mixins import AuthConfig, AuthPageBase

User = get_user_model()



class ResetPasswordView(AuthPageBase):
    """
    Password reset page.
    
    Allows users to set new password using reset token.
    Validates token and ensures password strength requirements.
    """
    
    page_title = "Reset Password"
    page_icon = "bi-shield-lock"  # Bootstrap icon class
    fragment_name = "auth.reset_password"
    
    # Password strength requirements
    MIN_PASSWORD_LENGTH = 8
    REQUIRE_SPECIAL_CHAR = True
    REQUIRE_NUMBER = True
    REQUIRE_UPPERCASE = True
    
    # HTMX configuration
    htmx_config = {
        'reswap': 'innerHTML',
        'retarget': AuthConfig.FORM_TARGET,
    }
    
    def setup(self, request, *args, **kwargs):
        """Initialize with token validation."""
        super().setup(request, *args, **kwargs)
        self.token = kwargs.get('token')
        
        # Validate token on setup
        if self.token:
            self.is_valid_token = self.validate_reset_token(self.token)
        else:
            self.is_valid_token = False
    
    def get(self, request, *args, **kwargs):
        """Handle GET request for password reset page."""
        # Redirect authenticated users (they can change password in settings)
        if request.user.is_authenticated:
            messages.info(request, _("Please change your password in account settings."))
            return redirect(AuthConfig.LOGIN_REDIRECT)
        
        # Validate token if provided
        if self.token and not self.is_valid_token:
            messages.error(request, _("Invalid or expired reset token."))
            return redirect(reverse_lazy("pipelines:forgot-password"))
        
        return super().get(request, *args, **kwargs)
    
    def get_context_data(self, **kwargs):
        """Add reset-specific context."""
        context = super().get_context_data(**kwargs)
        
        context.update({
            'token': self.token,
            'is_valid_token': self.is_valid_token,
            'password_requirements': self.get_password_requirements(),
        })
        
        return context
    
    def get_password_requirements(self) -> dict:
        """Get password requirements for display."""
        return {
            'min_length': self.MIN_PASSWORD_LENGTH,
            'require_special': self.REQUIRE_SPECIAL_CHAR,
            'require_number': self.REQUIRE_NUMBER,
            'require_uppercase': self.REQUIRE_UPPERCASE,
        }
    
    def validate_reset_token(self, token: str) -> bool:
        """Validate password reset token."""
        try:
            # Implementation depends on your token storage
            # profile = Profile.objects.filter(reset_token=token).first()
            # if not profile:
            #     return False
            
            # # Check expiration
            # if profile.reset_token_expires and profile.reset_token_expires < datetime.now():
            #     return False
            
            # For demonstration - accept any token
            return True
            
        except Exception:
            return False
    
    def post(self, request, *args, **kwargs):
        """Handle POST request to reset password."""
        # Validate token first
        token = request.POST.get('token') or self.token
        if not token or not self.validate_reset_token(token):
            return self.show_notification(
                message=_("Invalid or expired reset token."),
                level="error",
                title=_("Token Invalid"),
                duration=5000,
                redirect_url=reverse_lazy("pipelines:forgot-password"),
                request=request
            )
        
        # Get password data
        password = request.POST.get('password', '')
        confirm_password = request.POST.get('confirm_password', '')
        
        # Validate passwords
        validation_result = self.validate_passwords(password, confirm_password)
        if not validation_result[0]:
            return self.show_notification(
                message=validation_result[1],
                level="error",
                title=_("Password Error"),
                duration=5000,
                request=request
            )
        
        # Update password
        try:
            # Find user by token and update password
            # profile = Profile.objects.filter(reset_token=token).first()
            # if not profile:
            #     raise Profile.DoesNotExist
            
            # user = profile.user
            # user.set_password(password)
            # user.save()
            
            # Clear reset token
            # profile.reset_token = None
            # profile.reset_token_expires = None
            # profile.save()
            
            # Log the action
            logger.info(f"Password reset for user via token: {token[:8]}...")
            
            # Auto-login user
            # authenticated_user = authenticate(request, username=user.username, password=password)
            # if authenticated_user:
            #     login(request, authenticated_user)
            
            # Show success and redirect
            return self.show_notification(
                message=_("Password reset successfully! You are now logged in."),
                level="success",
                title=_("Password Reset"),
                duration=5000,
                redirect_url=AuthConfig.LOGIN_REDIRECT,
                request=request
            )
            
        except Exception as e:
            logger.error(f"Password reset error: {e}")
            return self.show_notification(
                message=_("An error occurred. Please try again."),
                level="error",
                title=_("Reset Failed"),
                duration=5000,
                request=request
            )
    
    def validate_passwords(self, password: str, confirm_password: str) -> Tuple[bool, Optional[str]]:
        """Validate password and confirmation."""
        # Check if passwords match
        if password != confirm_password:
            return False, _("Passwords do not match.")
        
        # Check minimum length
        if len(password) < self.MIN_PASSWORD_LENGTH:
            return False, _("Password must be at least %(length)d characters long.") % {
                'length': self.MIN_PASSWORD_LENGTH
            }
        
        # Check for special characters
        if self.REQUIRE_SPECIAL_CHAR and not any(c in '!@#$%^&*()_+-=[]{}|;:,.<>?~`' for c in password):
            return False, _("Password must contain at least one special character.")
        
        # Check for numbers
        if self.REQUIRE_NUMBER and not any(c.isdigit() for c in password):
            return False, _("Password must contain at least one number.")
        
        # Check for uppercase
        if self.REQUIRE_UPPERCASE and not any(c.isupper() for c in password):
            return False, _("Password must contain at least one uppercase letter.")
        
        return True, None

