import re
from django.utils import timezone
from .models import PageVisit, VisitorProfile


BOT_PATTERN = re.compile(
    r'bot|crawl|spider|slurp|search|monitor|fetch|wget|curl|python-requests|headless',
    re.IGNORECASE,
)

SKIP_PATHS = (
    '/static/', '/media/', '/favicon.ico',
    '/chatbot/', '/ckeditor/',
    '/admin-panel/',   # custom admin — not public traffic
    '/django-admin/',  # Django built-in admin — not public traffic
)


def _get_ip(request):
    forwarded = request.META.get('HTTP_X_FORWARDED_FOR', '')
    return forwarded.split(',')[0].strip() or request.META.get('REMOTE_ADDR', '') or None


def _parse_ua(ua):
    """Return (device_type, browser, os) from a User-Agent string."""
    u = ua.lower()

    if re.search(r'bot|crawl|spider|slurp|fetch|headless|python-requests|wget|curl', u):
        device = 'Bot'
    elif re.search(r'mobile|iphone|android.*mobile|windows phone|blackberry', u):
        device = 'Mobile'
    elif re.search(r'ipad|tablet|android(?!.*mobile)', u):
        device = 'Tablet'
    else:
        device = 'Desktop'

    if 'edg/' in u or 'edge/' in u:
        browser = 'Edge'
    elif 'opr/' in u or 'opera' in u:
        browser = 'Opera'
    elif 'chrome/' in u:
        browser = 'Chrome'
    elif 'firefox/' in u:
        browser = 'Firefox'
    elif 'safari/' in u:
        browser = 'Safari'
    else:
        browser = 'Other'

    if 'android' in u:
        os_name = 'Android'
    elif 'iphone' in u or 'ipad' in u:
        os_name = 'iOS'
    elif 'windows' in u:
        os_name = 'Windows'
    elif 'macintosh' in u or 'mac os' in u:
        os_name = 'macOS'
    elif 'linux' in u:
        os_name = 'Linux'
    else:
        os_name = 'Other'

    return device, browser, os_name


class VisitorTrackingMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        try:
            self._track(request, response)
        except Exception:
            pass
        return response

    def _track(self, request, response):
        path = request.path
        if any(path.startswith(p) for p in SKIP_PATHS):
            return
        if response.status_code >= 400:
            return
        if request.method != 'GET':
            return

        ua = request.META.get('HTTP_USER_AGENT', '')[:500]
        is_bot = bool(BOT_PATTERN.search(ua))
        device, browser, os_name = _parse_ua(ua)

        if not request.session.session_key:
            request.session.save()
        session_key = request.session.session_key or ''

        ip = _get_ip(request)
        referrer = request.META.get('HTTP_REFERER', '')[:500]

        PageVisit.objects.create(
            path=path[:500],
            ip_address=ip or None,
            user_agent=ua,
            referrer=referrer,
            session_key=session_key,
            is_bot=is_bot,
            device_type=device,
            browser=browser,
            os=os_name,
        )

        if is_bot or not session_key:
            return

        profile, created = VisitorProfile.objects.get_or_create(
            session_key=session_key,
            defaults={
                'ip_address': ip or None,
                'user_agent': ua,
                'device_type': device,
                'browser': browser,
                'os': os_name,
                'referrer': referrer,
            },
        )

        pages = list(profile.pages_list or [])
        pages = pages[-29:] + [path[:200]]
        VisitorProfile.objects.filter(pk=profile.pk).update(
            pages_count=profile.pages_count + 1,
            pages_list=pages,
            last_seen=timezone.now(),
        )
