"""
Analytics API Routes - API blueprint

Migrated from app.py as part of the blueprint refactoring.
Contains public API routes for user analytics tracking.
"""

import hashlib
import logging
from datetime import datetime

from flask import jsonify, request, session, current_app
from flask_login import current_user

from database import SessionLocal, UserSession, UserClick, PageView, JSError
from extensions import limiter
from . import bp

logger = logging.getLogger(__name__)


def exempt_from_csrf(app):
    """Exempt analytics routes from CSRF protection."""
    csrf = app.extensions.get('csrf')
    if csrf:
        csrf.exempt(bp)


# ============================================================
# USER ANALYTICS API ROUTES
# ============================================================

@bp.route('/analytics/track', methods=['POST'])
def api_analytics_track():
    """Track clicks and interactions from frontend"""
    # Exempt from CSRF for analytics tracking
    data = request.get_json()
    if not data:
        return jsonify({'error': 'No data'}), 400

    analytics_session_id = session.get('analytics_session_id')
    if not analytics_session_id:
        return jsonify({'error': 'No session'}), 400

    db = SessionLocal()
    try:
        user_session = db.query(UserSession).filter_by(session_id=analytics_session_id).first()
        if not user_session:
            return jsonify({'error': 'Session not found'}), 404

        event_type = data.get('type')

        if event_type == 'click':
            click = UserClick(
                session_id=user_session.id,
                page_view_id=data.get('page_view_id'),
                user_id=current_user.id if current_user.is_authenticated else None,
                element_type=data.get('element_type', '')[:50] if data.get('element_type') else None,
                element_id=data.get('element_id', '')[:100] if data.get('element_id') else None,
                element_text=(data.get('element_text', '') or '')[:255],
                element_class=(data.get('element_class', '') or '')[:500],
                target_url=data.get('target_url', '')[:2000] if data.get('target_url') else None,
                x_position=data.get('x'),
                y_position=data.get('y')
            )
            db.add(click)

            user_session.clicks_count = (user_session.clicks_count or 0) + 1
            db.commit()

        elif event_type == 'page_time':
            # Update time on page
            page_view_id = data.get('page_view_id')
            time_seconds = data.get('time_seconds')
            if page_view_id and time_seconds:
                page_view = db.query(PageView).filter_by(id=page_view_id).first()
                if page_view:
                    page_view.time_on_page_seconds = min(time_seconds, 86400)  # Max 24h
                    db.commit()

        return jsonify({'success': True}), 200

    except Exception as e:
        logger.error(f"Analytics track error: {e}")
        db.rollback()
        return jsonify({'error': 'Internal error'}), 500
    finally:
        db.close()


@bp.route('/analytics/heartbeat', methods=['POST'])
@limiter.exempt
def api_analytics_heartbeat():
    """Keep session alive and update duration"""
    analytics_session_id = session.get('analytics_session_id')
    if not analytics_session_id:
        return jsonify({'success': False}), 200

    db = SessionLocal()
    try:
        user_session = db.query(UserSession).filter_by(session_id=analytics_session_id).first()
        if user_session:
            user_session.last_activity_at = datetime.now()
            user_session.duration_seconds = int(
                (datetime.now() - user_session.started_at).total_seconds()
            )
            db.commit()
        return jsonify({'success': True}), 200
    except Exception as e:
        logger.error(f"Analytics heartbeat error: {e}")
        db.rollback()
        return jsonify({'success': False}), 200
    finally:
        db.close()


@bp.route('/analytics/scroll', methods=['POST'])
def api_analytics_scroll():
    """Track scroll depth from frontend"""
    data = request.get_json()
    if not data:
        return jsonify({'error': 'No data'}), 400

    page_view_id = data.get('page_view_id')
    scroll_depth = data.get('scroll_depth')

    if not page_view_id or scroll_depth is None:
        return jsonify({'error': 'Missing data'}), 400

    db = SessionLocal()
    try:
        page_view = db.query(PageView).filter_by(id=page_view_id).first()
        if page_view:
            # Zapisz tylko jeśli większe niż poprzednie (max scroll depth)
            current_depth = page_view.scroll_depth_percent or 0
            if scroll_depth > current_depth:
                page_view.scroll_depth_percent = min(scroll_depth, 100)
                db.commit()
        return jsonify({'success': True}), 200
    except Exception as e:
        logger.error(f"Analytics scroll error: {e}")
        db.rollback()
        return jsonify({'success': False}), 200
    finally:
        db.close()


@bp.route('/analytics/error', methods=['POST'])
def api_analytics_error():
    """Track JavaScript errors from frontend"""
    data = request.get_json()
    if not data:
        return jsonify({'error': 'No data'}), 400

    message = data.get('message', '')[:2000]
    if not message:
        return jsonify({'error': 'No message'}), 400

    analytics_session_id = session.get('analytics_session_id')

    db = SessionLocal()
    try:
        # Znajdź session ID
        session_db_id = None
        if analytics_session_id:
            user_session = db.query(UserSession).filter_by(session_id=analytics_session_id).first()
            if user_session:
                session_db_id = user_session.id

        # Utwórz hash dla agregacji
        error_key = f"{message}|{data.get('source', '')}|{data.get('lineno', '')}"
        error_hash = hashlib.sha256(error_key.encode()).hexdigest()

        js_error = JSError(
            session_id=session_db_id,
            message=message,
            source=data.get('source', '')[:500] if data.get('source') else None,
            lineno=data.get('lineno'),
            colno=data.get('colno'),
            stack=data.get('stack', '')[:5000] if data.get('stack') else None,
            url=data.get('url', '')[:2000] if data.get('url') else None,
            user_agent=request.headers.get('User-Agent', '')[:500],
            error_hash=error_hash
        )
        db.add(js_error)
        db.commit()
        return jsonify({'success': True}), 200
    except Exception as e:
        logger.error(f"Analytics error tracking error: {e}")
        db.rollback()
        return jsonify({'success': False}), 200
    finally:
        db.close()


@bp.route('/analytics/performance', methods=['POST'])
def api_analytics_performance():
    """Track page performance metrics from frontend"""
    data = request.get_json()
    if not data:
        return jsonify({'error': 'No data'}), 400

    page_view_id = data.get('page_view_id')
    if not page_view_id:
        return jsonify({'error': 'Missing page_view_id'}), 400

    db = SessionLocal()
    try:
        page_view = db.query(PageView).filter_by(id=page_view_id).first()
        if page_view:
            # Zapisz metryki performance (tylko jeśli jeszcze nie zapisane)
            if page_view.dom_content_loaded_ms is None:
                page_view.dom_content_loaded_ms = data.get('dom_content_loaded_ms')
            if page_view.load_time_ms is None:
                page_view.load_time_ms = data.get('load_time_ms')
            if page_view.first_paint_ms is None:
                page_view.first_paint_ms = data.get('first_paint_ms')
            if page_view.first_contentful_paint_ms is None:
                page_view.first_contentful_paint_ms = data.get('first_contentful_paint_ms')
            db.commit()
        return jsonify({'success': True}), 200
    except Exception as e:
        logger.error(f"Analytics performance error: {e}")
        db.rollback()
        return jsonify({'success': False}), 200
    finally:
        db.close()


@bp.route('/analytics/conversion', methods=['POST'])
def api_analytics_conversion():
    """Track conversion events from frontend (contact clicks)"""
    # Import track_conversion from app module
    from app import track_conversion

    data = request.get_json()
    if not data:
        return jsonify({'error': 'No data'}), 400

    event_type = data.get('event_type')
    if not event_type:
        return jsonify({'error': 'Missing event_type'}), 400

    track_conversion(
        event_type=event_type,
        company_id=data.get('company_id'),
        target_type=data.get('target_type'),
        target_value=data.get('target_value'),
        metadata=data.get('metadata')
    )

    return jsonify({'success': True}), 200
