import re
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views import View
from django.utils.crypto import get_random_string
from django.http import Http404
from django.contrib.auth import login, logout, authenticate, get_user_model

from project_utils.email_service import send_email
from project_utils.sms_service import send_otp_sms

from account_module.forms import (
    RegisterForm,
    LoginForm,
    OTPVerificationForm,
    ForgetPasswordForm,
    ResetPasswordForm
)

User = get_user_model()
MOBILE_REGEX = r'^09\d{9}$'

def normalize_identifier(value):
    return str(value or '').strip()

def find_user_by_identifier(identifier):
    """کاربر را بر اساس ایمیل یا شماره تماس پیدا می‌کند."""
    identifier = normalize_identifier(identifier)
    if not identifier:
        return None

    if '@' in identifier:
        return User.objects.filter(email__iexact=identifier).first()

    if re.match(MOBILE_REGEX, identifier):
        # تغییر در اینجا: استفاده از phone_number به جای mobile
        return User.objects.filter(phone_number=identifier).first()

    return None

class RegisterView(View):
    def get(self, request):
        return render(request, 'account_module/register.html', {
            'register_form': RegisterForm(prefix='register')
        })

    def post(self, request):
        form = RegisterForm(request.POST, prefix='register')
        if form.is_valid():
            email = normalize_identifier(form.cleaned_data.get('email'))
            # در فرم شما احتمالاً هنوز نام فیلد 'mobile' است، آن را می‌گیریم
            mobile_val = normalize_identifier(form.cleaned_data.get('mobile'))
            password = form.cleaned_data.get('password')

            if email and User.objects.filter(email__iexact=email).exists():
                form.add_error('email', 'ایمیل وارد شده قبلاً ثبت شده است')

            if mobile_val and User.objects.filter(phone_number=mobile_val).exists():
                form.add_error('mobile', 'شماره موبایل وارد شده قبلاً ثبت شده است')

            if form.errors:
                return render(request, 'account_module/register.html', {'register_form': form})

            user = User(
                email=email if email else None,
                phone_number=mobile_val if mobile_val else None, # تغییر در اینجا
                is_active=True,
                email_active_code=get_random_string(72)
            )

            if hasattr(user, 'username'):
                user.username = email or mobile_val

            user.set_password(password)
            user.save()
            return redirect(reverse('account:login_page'))

        return render(request, 'account_module/register.html', {'register_form': form})


class LoginView(View):
    def get(self, request):
        return render(request, 'account_module/login.html', {
            'login_form': LoginForm(prefix='login')
        })

    def post(self, request):
        form = LoginForm(request.POST, prefix='login')
        if not form.is_valid():
            return render(request, 'account_module/login.html', {'login_form': form})

        identifier = normalize_identifier(form.cleaned_data.get('identifier'))
        password = form.cleaned_data.get('password')

        user_obj = find_user_by_identifier(identifier)

        if not user_obj:
            form.add_error('identifier', 'کاربری با این مشخصات یافت نشد.')
            return render(request, 'account_module/login.html', {'login_form': form})

        if not user_obj.is_active:
            form.add_error(None, 'حساب کاربری شما فعال نیست.')
            return render(request, 'account_module/login.html', {'login_form': form})

        if re.match(MOBILE_REGEX, identifier):
            otp_code = get_random_string(5, allowed_chars='0123456789')
            request.session['otp_code'] = otp_code
            request.session['otp_mobile'] = identifier

            is_sent = send_otp_sms(identifier, f"کد ورود شما: {otp_code}")
            if is_sent:
                return redirect(reverse('account:otp_verify'))

            form.add_error('identifier', 'خطا در ارسال پیامک.')
            return render(request, 'account_module/login.html', {'login_form': form})

        if '@' in identifier:
            if not password:
                form.add_error('password', 'رمز عبور الزامی است.')
                return render(request, 'account_module/login.html', {'login_form': form})

            user = authenticate(request, username=user_obj.get_username(), password=password)
            if user:
                login(request, user)
                return redirect('/')

            form.add_error('password', 'رمز عبور نادرست است.')
            return render(request, 'account_module/login.html', {'login_form': form})

        form.add_error('identifier', 'فرمت معتبر نیست.')
        return render(request, 'account_module/login.html', {'login_form': form})


class OTPVerificationView(View):
    def get(self, request):
        mobile = normalize_identifier(request.session.get('otp_mobile'))
        if not mobile:
            return redirect(reverse('account:login_page'))
        return render(request, 'account_module/otp_verify.html', {'otp_form': OTPVerificationForm()})

    def post(self, request):
        form = OTPVerificationForm(request.POST)
        if not form.is_valid():
            return render(request, 'account_module/otp_verify.html', {'otp_form': form})

        entered_code = normalize_identifier(form.cleaned_data.get('otp_code'))
        session_code = normalize_identifier(request.session.get('otp_code'))
        mobile = normalize_identifier(request.session.get('otp_mobile'))

        if entered_code != session_code:
            form.add_error('otp_code', 'کد نادرست است.')
            return render(request, 'account_module/otp_verify.html', {'otp_form': form})

        # تغییر در اینجا: استفاده از phone_number
        user = User.objects.filter(phone_number=mobile).first()
        if not user:
            form.add_error('otp_code', 'کاربر یافت نشد.')
            return render(request, 'account_module/otp_verify.html', {'otp_form': form})

        login(request, user)
        request.session.pop('otp_code', None)
        request.session.pop('otp_mobile', None)
        return redirect('/')

# --- سایر متدها (Activate, Forget, Reset) تغییری نیاز ندارند چون از mobile استفاده نمی‌کنند ---
class ActivateAccountView(View):
    def get(self, request, email_active_code):
        email_active_code = normalize_identifier(email_active_code)
        user = User.objects.filter(email_active_code__iexact=email_active_code).first()
        if user is None: raise Http404
        if not user.is_active:
            user.is_active = True
            user.email_active_code = get_random_string(72)
            user.save()
        return redirect(reverse('account:login_page'))

class ForgetPasswordView(View):
    def get(self, request):
        return render(request, 'account_module/forgot_password.html', {'forget_pass_form': ForgetPasswordForm(prefix='forget')})
    def post(self, request):
        form = ForgetPasswordForm(request.POST, prefix='forget')
        if form.is_valid():
            identifier = normalize_identifier(form.cleaned_data.get('identifier'))
            user = find_user_by_identifier(identifier)
            if user and user.email:
                send_email('بازیابی کلمه عبور', user.email, {'user': user}, 'emails/forgot_password.html')
            return redirect(reverse('home_page'))
        return render(request, 'account_module/forgot_password.html', {'forget_pass_form': form})

class ResetPasswordView(View):
    def get(self, request, active_code):
        active_code = normalize_identifier(active_code)
        user = User.objects.filter(email_active_code__iexact=active_code).first()
        if not user: return redirect(reverse('account:login_page'))
        return render(request, 'account_module/reset_password.html', {'reset_pass_form': ResetPasswordForm(prefix='reset'), 'user': user})
    def post(self, request, active_code):
        active_code = normalize_identifier(active_code)
        form = ResetPasswordForm(request.POST, prefix='reset')
        user = User.objects.filter(email_active_code__iexact=active_code).first()
        if not user: return redirect(reverse('account:login_page'))
        if form.is_valid():
            user.set_password(form.cleaned_data.get('password'))
            user.email_active_code = get_random_string(72)
            user.is_active = True
            user.save()
            return redirect(reverse('account:login_page'))
        return render(request, 'account_module/reset_password.html', {'reset_pass_form': form, 'user': user})

class LogoutView(View):
    def get(self, request):
        logout(request)
        return redirect(reverse('account:login_page'))
