"""
Chat Routes
===========

AI Chat interface, API, and analytics.
"""

import logging
from datetime import datetime, date

from flask import render_template, request, redirect, url_for, flash, jsonify, session
from flask_login import login_required, current_user
from sqlalchemy import func, desc

from . import bp
from database import (
    SessionLocal, AIChatConversation, AIChatMessage, AIChatFeedback, AIAPICostLog,
    SystemRole
)
from nordabiz_chat import NordaBizChatEngine
from utils.decorators import member_required

# Logger
logger = logging.getLogger(__name__)


# ============================================================
# AI CHAT ROUTES
# ============================================================

@bp.route('/chat')
@login_required
def chat():
    """AI Chat interface - requires MEMBER role"""
    # SECURITY: NordaGPT is only for members (MEMBER role or higher)
    if not current_user.has_role(SystemRole.MEMBER):
        return render_template('chat_members_only.html'), 403
    return render_template('chat.html')


@bp.route('/api/chat/settings', methods=['GET', 'POST'])
@login_required
@member_required
def chat_settings():
    """Get or update chat settings (model selection, monthly cost)"""
    if request.method == 'GET':
        # Get current model from session or default to flash-lite
        model = session.get('chat_model', 'flash')

        # Calculate monthly cost for current user
        monthly_cost = 0.0
        try:
            db = SessionLocal()
            # Get first day of current month
            first_day = datetime.now().replace(day=1, hour=0, minute=0, second=0, microsecond=0)
            costs = db.query(AIAPICostLog).filter(
                AIAPICostLog.user_id == current_user.id,
                AIAPICostLog.timestamp >= first_day
            ).all()
            monthly_cost = sum(float(c.total_cost or 0) for c in costs)
            db.close()
        except Exception as e:
            logger.warning(f"Error calculating monthly cost: {e}")

        return jsonify({
            'success': True,
            'model': model,
            'monthly_cost': round(monthly_cost, 4)
        })

    # POST - update settings
    try:
        data = request.get_json()
        model = data.get('model', 'flash')

        # Validate model
        valid_models = ['flash', 'pro']
        if model not in valid_models:
            model = 'flash'

        # Store in session
        session['chat_model'] = model

        logger.info(f"User {current_user.id} set chat_model to: {model}")

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

    except Exception as e:
        logger.error(f"Error updating chat settings: {e}")
        return jsonify({'success': False, 'error': str(e)}), 500


@bp.route('/api/chat/start', methods=['POST'])
@login_required
@member_required
def chat_start():
    """Start new chat conversation"""
    try:
        data = request.get_json()
        title = data.get('title', f"Rozmowa - {datetime.now().strftime('%Y-%m-%d %H:%M')}")

        chat_engine = NordaBizChatEngine()
        conversation = chat_engine.start_conversation(
            user_id=current_user.id,
            title=title
        )

        return jsonify({
            'success': True,
            'conversation_id': conversation.id,
            'title': conversation.title
        })

    except Exception as e:
        logger.error(f"Error starting chat: {e}")
        return jsonify({'success': False, 'error': str(e)}), 500


@bp.route('/api/chat/<int:conversation_id>/message', methods=['POST'])
@login_required
@member_required
def chat_send_message(conversation_id):
    """Send message to AI chat"""
    try:
        data = request.get_json()
        message = data.get('message', '').strip()

        if not message:
            return jsonify({'success': False, 'error': 'Wiadomość nie może być pusta'}), 400

        # Verify conversation belongs to user
        db = SessionLocal()
        try:
            conversation = db.query(AIChatConversation).filter_by(
                id=conversation_id,
                user_id=current_user.id
            ).first()

            if not conversation:
                return jsonify({'success': False, 'error': 'Conversation not found'}), 404
        finally:
            db.close()

        # Get model from request or session (flash = default with thinking, pro = premium)
        model_choice = data.get('model') or session.get('chat_model', 'flash')

        # Check Pro model limits (Flash is free - no limits)
        if model_choice == 'pro':
            # Users without limits (admins)
            UNLIMITED_USERS = ['maciej.pienczyn@inpi.pl', 'artur.wiertel@waterm.pl']

            if current_user.email not in UNLIMITED_USERS:
                # Check daily and monthly limits for Pro
                db_check = SessionLocal()
                try:
                    # Daily limit: $2.00
                    today_start = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                    daily_costs = db_check.query(AIAPICostLog).filter(
                        AIAPICostLog.user_id == current_user.id,
                        AIAPICostLog.timestamp >= today_start,
                        AIAPICostLog.model_name.like('%pro%')
                    ).all()
                    daily_total = sum(float(c.total_cost or 0) for c in daily_costs)

                    if daily_total >= 2.0:
                        return jsonify({
                            'success': False,
                            'error': 'Osiągnięto dzienny limit Pro ($2.00). Spróbuj jutro lub użyj darmowego modelu Flash.',
                            'limit_exceeded': 'daily',
                            'daily_used': round(daily_total, 2)
                        }), 429

                    # Monthly limit: $20.00
                    month_start = datetime.now().replace(day=1, hour=0, minute=0, second=0, microsecond=0)
                    monthly_costs = db_check.query(AIAPICostLog).filter(
                        AIAPICostLog.user_id == current_user.id,
                        AIAPICostLog.timestamp >= month_start,
                        AIAPICostLog.model_name.like('%pro%')
                    ).all()
                    monthly_total = sum(float(c.total_cost or 0) for c in monthly_costs)

                    if monthly_total >= 20.0:
                        return jsonify({
                            'success': False,
                            'error': 'Osiągnięto miesięczny limit Pro ($20.00). Użyj darmowego modelu Flash.',
                            'limit_exceeded': 'monthly',
                            'monthly_used': round(monthly_total, 2)
                        }), 429
                finally:
                    db_check.close()

        # Map model choice to actual model name and thinking level
        model_map = {
            'flash': '3-flash',           # Gemini 3 Flash - 10K RPD, thinking mode
            'pro': '3-pro'                # Gemini 3 Pro - 250 RPD, premium
        }
        thinking_map = {
            'flash': 'high',
            'pro': 'high'
        }
        model_key = model_map.get(model_choice, '3-flash')

        chat_engine = NordaBizChatEngine(model=model_key)
        response = chat_engine.send_message(
            conversation_id=conversation_id,
            user_message=message,
            user_id=current_user.id,
            thinking_level=thinking_map.get(model_choice, 'high')
        )

        # Get actual cost from response
        tokens_in = response.tokens_input or 0
        tokens_out = response.tokens_output or 0
        actual_cost = response.cost_usd or 0.0

        return jsonify({
            'success': True,
            'message': response.content,
            'message_id': response.id,
            'created_at': response.created_at.isoformat(),
            # Technical metadata
            'tech_info': {
                'model': model_choice,
                'tokens_input': tokens_in,
                'tokens_output': tokens_out,
                'tokens_total': tokens_in + tokens_out,
                'latency_ms': response.latency_ms or 0,
                'cost_usd': round(actual_cost, 6)
            }
        })

    except Exception as e:
        logger.error(f"Error sending message: {e}")
        return jsonify({'success': False, 'error': str(e)}), 500


@bp.route('/api/chat/<int:conversation_id>/history', methods=['GET'])
@login_required
@member_required
def chat_get_history(conversation_id):
    """Get conversation history"""
    try:
        # Verify conversation belongs to user
        db = SessionLocal()
        try:
            conversation = db.query(AIChatConversation).filter_by(
                id=conversation_id,
                user_id=current_user.id
            ).first()

            if not conversation:
                return jsonify({'success': False, 'error': 'Conversation not found'}), 404
        finally:
            db.close()

        chat_engine = NordaBizChatEngine()
        # SECURITY: Pass user_id for defense-in-depth ownership validation
        history = chat_engine.get_conversation_history(conversation_id, user_id=current_user.id)

        return jsonify({
            'success': True,
            'messages': history
        })

    except Exception as e:
        logger.error(f"Error getting history: {e}")
        return jsonify({'success': False, 'error': str(e)}), 500


@bp.route('/api/chat/conversations', methods=['GET'])
@login_required
@member_required
def chat_list_conversations():
    """Get list of user's conversations for sidebar"""
    db = SessionLocal()
    try:
        conversations = db.query(AIChatConversation).filter_by(
            user_id=current_user.id
        ).order_by(AIChatConversation.updated_at.desc()).limit(50).all()

        return jsonify({
            'success': True,
            'conversations': [
                {
                    'id': c.id,
                    'title': c.title,
                    'created_at': c.started_at.isoformat() if c.started_at else None,
                    'updated_at': c.updated_at.isoformat() if c.updated_at else None,
                    'message_count': len(c.messages) if c.messages else 0
                }
                for c in conversations
            ]
        })
    except Exception as e:
        logger.error(f"Error listing conversations: {e}")
        return jsonify({'success': False, 'error': str(e)}), 500
    finally:
        db.close()


@bp.route('/api/chat/<int:conversation_id>/delete', methods=['DELETE'])
@login_required
@member_required
def chat_delete_conversation(conversation_id):
    """Delete a conversation"""
    db = SessionLocal()
    try:
        conversation = db.query(AIChatConversation).filter_by(
            id=conversation_id,
            user_id=current_user.id
        ).first()

        if not conversation:
            return jsonify({'success': False, 'error': 'Conversation not found'}), 404

        # Delete messages first
        db.query(AIChatMessage).filter_by(conversation_id=conversation_id).delete()
        db.delete(conversation)
        db.commit()

        return jsonify({'success': True})
    except Exception as e:
        logger.error(f"Error deleting conversation: {e}")
        db.rollback()
        return jsonify({'success': False, 'error': str(e)}), 500
    finally:
        db.close()


# ============================================================
# AI CHAT FEEDBACK & ANALYTICS
# ============================================================

@bp.route('/api/chat/feedback', methods=['POST'])
@login_required
@member_required
def chat_feedback():
    """API: Submit feedback for AI response"""
    try:
        data = request.get_json()
        message_id = data.get('message_id')
        rating = data.get('rating')  # 1 = thumbs down, 2 = thumbs up

        if not message_id or rating not in [1, 2]:
            return jsonify({'success': False, 'error': 'Invalid data'}), 400

        db = SessionLocal()
        try:
            # Verify message exists and belongs to user's conversation
            message = db.query(AIChatMessage).filter_by(id=message_id).first()
            if not message:
                return jsonify({'success': False, 'error': 'Message not found'}), 404

            conversation = db.query(AIChatConversation).filter_by(
                id=message.conversation_id,
                user_id=current_user.id
            ).first()
            if not conversation:
                return jsonify({'success': False, 'error': 'Not authorized'}), 403

            # Update message feedback
            message.feedback_rating = rating
            message.feedback_at = datetime.now()
            message.feedback_comment = data.get('comment', '')

            # Create detailed feedback record if provided
            if data.get('is_helpful') is not None or data.get('comment'):
                existing_feedback = db.query(AIChatFeedback).filter_by(message_id=message_id).first()
                if existing_feedback:
                    existing_feedback.rating = rating
                    existing_feedback.is_helpful = data.get('is_helpful')
                    existing_feedback.is_accurate = data.get('is_accurate')
                    existing_feedback.found_company = data.get('found_company')
                    existing_feedback.comment = data.get('comment')
                else:
                    feedback = AIChatFeedback(
                        message_id=message_id,
                        user_id=current_user.id,
                        rating=rating,
                        is_helpful=data.get('is_helpful'),
                        is_accurate=data.get('is_accurate'),
                        found_company=data.get('found_company'),
                        comment=data.get('comment'),
                        original_query=data.get('original_query'),
                        expected_companies=data.get('expected_companies')
                    )
                    db.add(feedback)

            db.commit()
            logger.info(f"Feedback received: message_id={message_id}, rating={rating}")

            return jsonify({'success': True})

        finally:
            db.close()

    except Exception as e:
        logger.error(f"Error saving feedback: {e}")
        return jsonify({'success': False, 'error': str(e)}), 500


@bp.route('/admin/chat-analytics')
@login_required
def chat_analytics():
    """Admin dashboard for chat analytics"""
    # Only users with admin panel access can view chat analytics
    if not current_user.can_access_admin_panel():
        flash('Brak uprawnień do tej strony.', 'error')
        return redirect(url_for('dashboard'))

    db = SessionLocal()
    try:
        # Basic stats
        total_conversations = db.query(AIChatConversation).count()
        total_messages = db.query(AIChatMessage).count()
        total_user_messages = db.query(AIChatMessage).filter_by(role='user').count()

        # Feedback stats
        feedback_count = db.query(AIChatMessage).filter(AIChatMessage.feedback_rating.isnot(None)).count()
        positive_feedback = db.query(AIChatMessage).filter_by(feedback_rating=2).count()
        negative_feedback = db.query(AIChatMessage).filter_by(feedback_rating=1).count()

        # Recent conversations with feedback
        recent_feedback = db.query(AIChatMessage).filter(
            AIChatMessage.feedback_rating.isnot(None)
        ).order_by(desc(AIChatMessage.feedback_at)).limit(20).all()

        # SECURITY: Query statistics only - do NOT expose raw user content
        # This protects user privacy while still providing useful analytics
        # Raw message content is NOT passed to the template

        # Query categories/stats instead of raw content
        from sqlalchemy import case
        query_stats = {
            'total_today': db.query(AIChatMessage).filter(
                AIChatMessage.role == 'user',
                func.date(AIChatMessage.created_at) == date.today()
            ).count(),
            'avg_length': db.query(func.avg(func.length(AIChatMessage.content))).filter(
                AIChatMessage.role == 'user'
            ).scalar() or 0,
            'queries_with_company': db.query(AIChatMessage).filter(
                AIChatMessage.role == 'user',
                AIChatMessage.content.ilike('%firma%')
            ).count(),
            'queries_with_contact': db.query(AIChatMessage).filter(
                AIChatMessage.role == 'user',
                AIChatMessage.content.ilike('%kontakt%') | AIChatMessage.content.ilike('%telefon%') | AIChatMessage.content.ilike('%email%')
            ).count()
        }

        # Recent queries - anonymized (show only metadata, not content)
        recent_queries_raw = db.query(AIChatMessage).filter_by(role='user').order_by(
            desc(AIChatMessage.created_at)
        ).limit(50).all()

        # Anonymize: show length and timestamp only
        recent_queries = [
            {
                'length': len(q.content) if q.content else 0,
                'created_at': q.created_at,
                'has_company_mention': 'firma' in (q.content or '').lower(),
                'has_contact_request': any(kw in (q.content or '').lower() for kw in ['kontakt', 'telefon', 'email', 'www'])
            }
            for q in recent_queries_raw
        ]

        # Calculate satisfaction rate
        satisfaction_rate = (positive_feedback / feedback_count * 100) if feedback_count > 0 else 0

        return render_template(
            'admin/chat_analytics.html',
            total_conversations=total_conversations,
            total_messages=total_messages,
            total_user_messages=total_user_messages,
            feedback_count=feedback_count,
            positive_feedback=positive_feedback,
            negative_feedback=negative_feedback,
            satisfaction_rate=round(satisfaction_rate, 1),
            recent_feedback=recent_feedback,
            recent_queries=recent_queries,
            query_stats=query_stats  # SECURITY: Aggregated stats only
        )
    finally:
        db.close()
