import logging

from typing import Optional
from django.http import HttpRequest
from .models import PageView, Visitor
from django.utils import timezone

logger = logging.getLogger(__name__)


def get_client_ip(request: HttpRequest) -> str:
    """Получаем реальный IP клиента."""
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR', '')
    return ip


def should_track_request(request: HttpRequest) -> bool:
    """Определяем, нужно ли отслеживать запрос."""
    client_ip = get_client_ip(request)
    path = request.path

    ignored_paths = [
        '/static/', '/admin/', '/index.php', '/status.php',
        '/cron', '/remote.php', '/ocs', '/apps/', '/custom_apps/',
    ]

    docker_ips = [
        '192.168.64.1', '192.168.65.1',
        '172.17.0.1', '172.18.0.1', '172.19.0.1',
    ]

    if any(path.startswith(p) for p in ignored_paths):
        return False
    if client_ip in docker_ips:
        return False

    return True


def track_page_view(request: HttpRequest) -> None:
    """Основная функция отслеживания просмотров."""
    if not should_track_request(request):
        return

    try:
        PageView.objects.create(
            url=request.path,
            ip_address=get_client_ip(request),
            user_agent=request.META.get('HTTP_USER_AGENT', '')[:500],
            referer=request.META.get('HTTP_REFERER', '')[:500],
        )

        ip = get_client_ip(request)
        visitor, created = Visitor.objects.get_or_create(
            ip_address=ip,
            defaults={
                'first_visit': timezone.now(),
                'last_visit': timezone.now(),
            }
        )

        if not created:
            visitor.last_visit = timezone.now()
            visitor.visit_count += 1
            visitor.save()

    except Exception:
        logger.exception('Ошибка при трекинге просмотра страницы: %s', request.path)


def get_published_queryset(model_class, order_by: str = '-time_create'):
    """
    Возвращает QuerySet опубликованных записей для модели.
    """
    if hasattr(model_class, 'is_published'):
        return model_class.objects.filter(is_published=True).order_by(order_by)
    return model_class.objects.none()