from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth import login, authenticate, logout, get_user_model
from django.contrib import messages
from django.core.mail import send_mail
from django.conf import settings
from django.urls import reverse
from django.shortcuts import redirect
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.utils.encoding import force_bytes, force_str
from django.contrib.auth.tokens import default_token_generator
from django.contrib.auth.decorators import login_required
from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.forms import PasswordChangeForm
from django.db import connection
from .forms import PasswordResetForm
from .models import CustomUser
import uuid


def login_view(request):
    """
    Страница входа для пользователей тенанта (CustomUser).

    SECURITY: Работает ТОЛЬКО на tenant доменах!
    На public домене перенаправляет на страницу логина PlatformAdmin.
    """
    # Проверяем что мы НЕ на public домене
    schema_name = getattr(connection, 'schema_name', 'public')
    if schema_name == 'public':
        messages.info(
            request,
            'Вход для пользователей магазинов доступен только на домене вашего магазина. '
            'Если вы администратор платформы, используйте /platform/login/'
        )
        return redirect('platform_admin:login')

    if request.method == 'POST':
        email = request.POST.get('email')
        password = request.POST.get('password')

        # Используем email как логин
        user = authenticate(request, username=email, password=password)

        if user is not None:
            # Проверяем, что это CustomUser (пользователь магазина), а не PlatformAdmin
            if not isinstance(user, CustomUser):
                # Не раскрываем информацию о существовании других типов пользователей
                messages.error(request, 'Пользователь не найден.')
            elif not user.is_email_confirmed:
                messages.error(request, 'Пожалуйста, подтвердите ваш email для входа.')
            else:
                login(request, user, backend='accounts.backends.TenantUserBackend')
                # Перенаправляем на главную страницу после успешного входа
                next_page = request.GET.get('next', 'index')  # Если есть параметр next, переходим туда
                return redirect(next_page)
        else:
            messages.error(request, 'Неверный email или пароль.')

    return render(request, 'login.html')


def logout_view(request):
    logout(request)
    return redirect('/')


@login_required
def profile_view(request):
    return render(request, 'profile.html', {'user': request.user})


@login_required
def change_password_view(request):
    if request.method == 'POST':
        form = PasswordChangeForm(request.user, request.POST)
        if form.is_valid():
            user = form.save()
            update_session_auth_hash(request, user)  # Important for keeping the user logged in
            messages.success(request, 'Ваш пароль был успешно изменен!')
            return redirect('profile')
        else:
            messages.error(request, 'Пожалуйста, исправьте ошибки в форме.')
    else:
        form = PasswordChangeForm(request.user)
    
    return render(request, 'change_password.html', {'form': form})


def confirm_email(request, token):
    user = get_object_or_404(CustomUser, email_confirmation_token=token)
    
    if user.is_email_confirmed:
        messages.info(request, 'Email уже был подтвержден.')
    else:
        user.confirm_email()
        user.is_active = True  # Активируем пользователя
        user.save()
        messages.success(request, 'Email успешно подтвержден! Теперь вы можете войти.')
    
    return redirect('accounts:login')


def password_reset_request(request):
    if request.method == 'POST':
        form = PasswordResetForm(request.POST)
        if form.is_valid():
            email = form.cleaned_data['email']
            try:
                user = CustomUser.objects.get(email=email)
                
                # Генерируем токен восстановления
                user.password_reset_token = uuid.uuid4()
                user.save()
                
                # Отправляем письмо с инструкциями по восстановлению
                reset_url = request.build_absolute_uri(
                    reverse('accounts:password_reset_confirm', kwargs={'token': user.password_reset_token})
                )
                
                subject = 'Восстановление пароля'
                message = f'Привет {user.name}!\n\nДля восстановления пароля перейдите по следующей ссылке: {reset_url}\n\nЕсли вы не запрашивали восстановление пароля, проигнорируйте это письмо.'
                from_email = settings.DEFAULT_FROM_EMAIL
                recipient_list = [user.email]
                
                # Выводим письмо в консоль
                print(f"Письмо для восстановления пароля:\nТема: {subject}\nСообщение:\n{message}\nПолучатель: {recipient_list}")
                
                messages.success(request, f'Инструкции по восстановлению пароля отправлены на {email}')
            except CustomUser.DoesNotExist:
                # Для безопасности не сообщаем, что пользователя не существует
                messages.success(request, 'Если аккаунт с таким email существует, инструкции по восстановлению пароля были отправлены на него.')
            
            return redirect('accounts:login')
    else:
        form = PasswordResetForm()
    
    return render(request, 'accounts/password_reset_request.html', {'form': form})


def password_reset_confirm(request, token):
    try:
        user = CustomUser.objects.get(password_reset_token=token)
    except CustomUser.DoesNotExist:
        messages.error(request, 'Ссылка для восстановления пароля недействительна.')
        return redirect('/')
    
    if request.method == 'POST':
        password1 = request.POST.get('password1')
        password2 = request.POST.get('password2')
        
        if password1 and password2 and password1 == password2:
            user.set_password(password1)
            user.password_reset_token = None  # Обнуляем токен
            user.save()
            messages.success(request, 'Пароль успешно изменен. Теперь вы можете войти.')
            return redirect('accounts:login')
        else:
            messages.error(request, 'Пароли не совпадают.')
    
    # Отображаем форму смены пароля
    return render(request, 'accounts/password_reset_confirm.html', {'user': user})


def password_setup_confirm(request, token):
    """
    Позволить владельцу тенанта установить начальный пароль после одобрения регистрации.
    Похоже на сброс пароля, но для новых аккаунтов.
    """
    from tenants.models import TenantRegistration
    from datetime import timedelta
    from django.utils import timezone

    # Найти регистрацию по токену
    try:
        registration = TenantRegistration.objects.get(
            password_setup_token=token,
            status=TenantRegistration.STATUS_APPROVED
        )
    except TenantRegistration.DoesNotExist:
        messages.error(request, 'Ссылка для настройки пароля недействительна.')
        return redirect('/')

    # Проверить истечение токена (7 дней)
    if registration.password_setup_token_created_at:
        expires_at = registration.password_setup_token_created_at + timedelta(days=7)
        if timezone.now() > expires_at:
            messages.error(
                request,
                'Ссылка для настройки пароля истекла. Пожалуйста, свяжитесь с поддержкой.'
            )
            return redirect('/')

    # Получить тенант и пользователя-владельца
    from django.db import connection
    tenant = registration.tenant
    if not tenant:
        messages.error(request, 'Тенант не найден.')
        return redirect('/')

    # Переключиться на схему тенанта чтобы найти владельца
    connection.set_tenant(tenant)
    from accounts.models import CustomUser

    # Создаём пользователя если он не существует (для случаев когда активация прошла без создания пользователя)
    owner, created = CustomUser.objects.get_or_create(
        email=registration.owner_email,
        defaults={
            'name': registration.owner_name,
            'is_active': False,
        }
    )
    if created:
        owner.is_email_confirmed = True
        owner.save()

    # Обработать POST - установить пароль
    if request.method == 'POST':
        password1 = request.POST.get('password1')
        password2 = request.POST.get('password2')

        if password1 and password2 and password1 == password2:
            # Установить пароль и активировать аккаунт
            owner.set_password(password1)
            owner.is_active = True
            owner.save()

            # Очистить токен
            connection.set_schema_to_public()
            registration.password_setup_token = None
            registration.password_setup_token_created_at = None
            registration.save()

            # Автоматический вход (используем TenantUserBackend)
            connection.set_tenant(tenant)
            login(request, owner, backend='accounts.backends.TenantUserBackend')

            messages.success(
                request,
                f'Пароль успешно установлен! Добро пожаловать в {tenant.name}!'
            )

            # Перенаправить на домен тенанта
            # Получаем домен из базы (без порта, порт добавляется в URL только для localhost)
            from tenants.models import Domain
            from django.conf import settings
            connection.set_schema_to_public()
            try:
                domain_obj = Domain.objects.filter(tenant=tenant, is_primary=True).first()
                if domain_obj:
                    domain_name = domain_obj.domain
                    # Убираем порт из домена если он есть (для совместимости со старыми записями)
                    if ':' in domain_name:
                        domain_name = domain_name.split(':')[0]
                else:
                    # Fallback если домен не найден
                    domain_base = settings.TENANT_DOMAIN_BASE
                    if ':' in domain_base:
                        domain_base = domain_base.split(':')[0]
                    domain_name = f"{tenant.schema_name}.{domain_base}"
            except:
                domain_base = settings.TENANT_DOMAIN_BASE
                if ':' in domain_base:
                    domain_base = domain_base.split(':')[0]
                domain_name = f"{tenant.schema_name}.{domain_base}"
            
            # Формируем URL с правильным протоколом и портом
            protocol = 'https' if settings.USE_HTTPS else 'http'
            # Добавляем порт только для localhost
            if 'localhost' in domain_name:
                tenant_url = f'{protocol}://{domain_name}:8000/'
            else:
                tenant_url = f'{protocol}://{domain_name}/'
            
            return redirect(tenant_url)
        else:
            messages.error(request, 'Пароли не совпадают.')

    connection.set_schema_to_public()

    # Отрисовать форму установки пароля
    return render(request, 'accounts/password_setup_confirm.html', {
        'registration': registration,
        'tenant': tenant
    })