"""
VYNDR Security Logger
Logs suspicious requests. Detects SQL injection patterns.
Tracks request rates per IP. Stores events in security_events table.
"""

import logging
from datetime import datetime, timedelta
from collections import defaultdict

logger = logging.getLogger('vyndr.security')

_request_counts = defaultdict(list)
ALERT_THRESHOLD = 100  # requests per minute from same IP


def get_real_ip(req):
    """Extract real client IP from X-Forwarded-For or remote_addr."""
    forwarded = req.headers.get('X-Forwarded-For', '')
    if forwarded:
        return forwarded.split(',')[0].strip()
    return req.remote_addr or '127.0.0.1'


def log_request(req):
    """
    Log every API request with security-relevant info.
    Detects rate abuse and SQL injection patterns.
    Must not block request processing.

    Args:
        req: Flask request object.
    """
    try:
        ip = get_real_ip(req)
        path = req.path
        method = req.method

        # Track request rate per IP
        now = datetime.utcnow()
        _request_counts[ip] = [
            t for t in _request_counts[ip]
            if t > now - timedelta(minutes=1)
        ]
        _request_counts[ip].append(now)

        # Alert on rate abuse
        if len(_request_counts[ip]) > ALERT_THRESHOLD:
            logger.critical(
                f'[SECURITY] Rate abuse from {ip}: '
                f'{len(_request_counts[ip])} req/min on {path}'
            )
            log_security_event('rate_abuse', ip, path, len(_request_counts[ip]))

        # Check request body for SQL injection
        if req.data and method in ('POST', 'PUT', 'PATCH'):
            _check_injection(req, ip, path)

    except Exception as e:
        # Security logging must NEVER block request processing
        logger.error(f'[SECURITY] Logger error: {e}')


def _check_injection(req, ip, path):
    """Check request body for SQL injection patterns."""
    try:
        body = req.get_json(silent=True)
        if body:
            body_str = str(body).lower()
            injection_patterns = [
                'drop table', 'delete from', 'insert into',
                'union select', '--', ';--', 'or 1=1'
            ]
            for pattern in injection_patterns:
                if pattern in body_str:
                    logger.critical(
                        f'[SECURITY] SQL injection attempt from {ip}: '
                        f'{pattern} in {path}'
                    )
                    log_security_event('sql_injection', ip, path, body_str[:200])
                    break
    except Exception:
        pass


def log_security_event(event_type, ip, path, detail):
    """
    Store security event in database for review.

    Args:
        event_type: Category string (rate_abuse, sql_injection, etc.).
        ip: Client IP address.
        path: Request path.
        detail: Additional detail string (truncated to 500 chars).
    """
    try:
        from utils.supabase_client import get_supabase_client
        supabase = get_supabase_client()
        if supabase:
            supabase.table('security_events').insert({
                'event_type': event_type,
                'ip_address': ip,
                'path': path,
                'detail': str(detail)[:500],
                'created_at': datetime.utcnow().isoformat()
            }).execute()
    except Exception as e:
        logger.error(f'[SECURITY] Failed to log event: {e}')


def cleanup_old_security_events(retention_days=90):
    """
    Auto-delete security logs older than retention period.
    Called by nightly resolution job.

    Args:
        retention_days: Number of days to retain (default 90).
    """
    try:
        from utils.supabase_client import get_supabase_client
        supabase = get_supabase_client()
        if supabase:
            cutoff = (datetime.utcnow() - timedelta(days=retention_days)).isoformat()
            supabase.table('security_events').delete().lt('created_at', cutoff).execute()
            logger.info(f'[Security] Cleaned up events older than {retention_days} days')
    except Exception as e:
        logger.error(f'[Security] Cleanup failed: {e}')


def generate_security_digest():
    """
    Weekly summary of security events. Flags IPs with 50+ events.

    Returns:
        Dict with period, total_events, by_type, top_ips, action_required.
    """
    try:
        from utils.supabase_client import get_supabase_client
        supabase = get_supabase_client()
        if not supabase:
            return {'error': 'Supabase not available'}

        week_ago = (datetime.utcnow() - timedelta(days=7)).isoformat()
        result = supabase.table('security_events').select('*').gte(
            'created_at', week_ago
        ).execute()
        events = result.data if result else []

        summary = {
            'period': f'{week_ago} to now',
            'total_events': len(events),
            'by_type': {},
            'top_ips': {},
            'action_required': []
        }

        for event in events:
            t = event.get('event_type', 'unknown')
            summary['by_type'][t] = summary['by_type'].get(t, 0) + 1
            ip = event.get('ip_address', 'unknown')
            summary['top_ips'][ip] = summary['top_ips'].get(ip, 0) + 1

        for ip, count in summary['top_ips'].items():
            if count >= 50:
                summary['action_required'].append(f'Block IP {ip}: {count} events')

        return summary
    except Exception as e:
        logger.error(f'[Security] Digest failed: {e}')
        return {'error': str(e)}
