"""
ENT Routes - GMAO Collège
Intégration ENT77
"""
from flask import Blueprint, render_template, redirect, url_for, request, flash, jsonify
from flask_login import login_required, current_user
from app_new.extensions import db
from app_new.ent.models import EntCredential, EntMessage, EntConfig
from app_new.ent.interpretation_models import EntMessageInterpretation
from app_new.lib_ext.ent_service import login_ent
from app_new.lib_ext.ent_crypto import encrypt_value, decrypt_value
from flask import current_app
import requests

ent_bp = Blueprint('ent', __name__, template_folder='templates')


@ent_bp.route('/', methods=['GET', 'POST'])
@login_required
def index():
    """Page principale ENT - formulaire de connexion avec vérification."""
    credentials = EntCredential.query.first()
    connection_status = None  # None, 'success', 'error'
    error_message = None
    
    if request.method == 'POST':
        action = request.form.get('action', 'create')
        username = request.form.get('ent_username')
        password = request.form.get('ent_password')
        
        if action == 'create':
            # Créer un nouveau credential - vérifier d'abord la connexion
            if not username or not password:
                flash('Veuillez remplir tous les champs.', 'danger')
            else:
                # Vérifier que les identifiants fonctionnent
                session = requests.Session()
                headers = login_ent(session, username, password)
                
                if headers is None:
                    flash('Connexion échouée. Vérifiez vos identifiants ENT77.', 'danger')
                    flash('Assurez-vous que le nom d\'utilisateur et le mot de passe sont corrects.', 'warning')
                else:
                    # Connexion réussie - sauvegarder les identifiants chiffrés
                    credential = EntCredential(
                        user_id=current_user.id,
                        ent_username_encrypted=encrypt_value(username, current_app._get_current_object()),
                        ent_password_encrypted=encrypt_value(password, current_app._get_current_object())
                    )
                    db.session.add(credential)
                    db.session.commit()
                    flash('Connexion ENT77 réussie ! Identifiants sauvegardés.', 'success')
                    return redirect(url_for('ent.index'))
        
        elif action == 'update':
            # Mettre à jour le credential existant - vérifier d'abord
            if credentials:
                new_password = password if password else None
                test_username = username if username else credentials.ent_username_encrypted.decode('utf-8')
                
                if new_password:
                    # Nouveau mot de passe fourni - vérifier la connexion
                    session = requests.Session()
                    headers = login_ent(session, test_username, new_password)
                    
                    if headers is None:
                        flash('Connexion échouée avec le nouveau mot de passe.', 'danger')
                    else:
                        if username:
                            credentials.ent_username_encrypted = encrypt_value(username, current_app._get_current_object())
                        credentials.ent_password_encrypted = encrypt_value(new_password, current_app._get_current_object())
                        db.session.commit()
                        flash('Identifiants ENT mis à jour avec succès.', 'success')
                else:
                    # Juste changer le nom d'utilisateur (mot de passe inchangé)
                    if username:
                        credentials.ent_username_encrypted = encrypt_value(username, current_app._get_current_object())
                        db.session.commit()
                        flash('Nom d\'utilisateur mis à jour.', 'success')
                return redirect(url_for('ent.index'))
    
    # Décoder les credentials pour l'affichage
    display_credentials = None
    if credentials:
        try:
            decrypted_username = decrypt_value(credentials.ent_username_encrypted, current_app._get_current_object()) if credentials.ent_username_encrypted else ''
        except:
            decrypted_username = credentials.ent_username_encrypted.decode('utf-8') if credentials.ent_username_encrypted else ''
        display_credentials = type('DisplayCredentials', (), {
            'id': credentials.id,
            'ent_username': decrypted_username
        })()
    
    return render_template('ent/index.html', credentials=display_credentials)


@ent_bp.route('/messages')
@login_required
def messages():
    """Liste des messages ENT."""
    page = request.args.get('page', 1, type=int)
    messages = EntMessage.query.order_by(EntMessage.date.desc()).paginate(page=page, per_page=20)
    return render_template('ent/messages.html', messages=messages)


@ent_bp.route('/inbox')
@login_required
def inbox():
    """Boîte de réception ENT."""
    messages = EntMessage.query.order_by(EntMessage.date.desc()).limit(50).all()
    return render_template('ent/messages.html', messages=messages)


@ent_bp.route('/sync')
@login_required
def sync():
    """Synchronisation des messages."""
    flash('Synchronisation ENT non implémentée.', 'info')
    return redirect(url_for('ent.index'))


@ent_bp.route('/staff')
@login_required
def staff():
    """Liste du personnel depuis ENT."""
    from app_new.core.models.user import Staff
    staff_list = Staff.query.order_by(Staff.last_name, Staff.first_name).all()
    return render_template('ent/staff.html', staff_list=staff_list)


@ent_bp.route('/check', methods=['POST'])
@login_required
def check():
    """Vérification manuelle des messages ENT."""
    from app_new.lib_ext.ent_service import _process_credential
    from flask import current_app
    
    creds = EntCredential.query.filter_by(is_active=True).all()
    config = EntConfig.query.first()
    app = current_app._get_current_object()
    total = 0
    for cred in creds:
        try:
            result = _process_credential(cred, config, app)
            if isinstance(result, int):
                total += result
        except Exception as e:
            flash(f'Erreur: {str(e)[:100]}', 'danger')
    
    if total > 0:
        flash(f'{total} nouveau(x) message(s) traite(s).', 'success')
    else:
        flash('Aucun nouveau message.', 'info')
    return redirect(url_for('ent.inbox'))


@ent_bp.route('/check-all', methods=['POST'])
@login_required
def check_all():
    """Vérification de TOUS les messages (lus et non lus)."""
    import re
    from datetime import datetime, timezone
    from app_new.lib_ext.ent_service import login_ent, extract_sender, is_intervention_request
    from app_new.lib_ext.ent_crypto import decrypt_value
    from app_new.core.models import Intervention
    
    credential = EntCredential.query.filter_by(user_id=current_user.id, is_active=True).first()
    if not credential:
        flash('Aucun identifiant ENT actif configuré.', 'danger')
        return redirect(url_for('ent.inbox'))
    
    # Login ENT
    try:
        username = credential.get_username()
        password = credential.get_password()
    except Exception:
        flash('Impossible de déchiffrer les identifiants ENT.', 'danger')
        return redirect(url_for('ent.index'))
    
    sess = requests.Session()
    headers = login_ent(sess, username, password)
    if not headers:
        flash('Connexion ENT échouée.', 'danger')
        return redirect(url_for('ent.inbox'))
    
    # Récupérer TOUS les messages
    all_messages = []
    page = 0
    while True:
        url_page = f'https://ent77.seine-et-marne.fr/conversation/list/inbox?page={page}'
        try:
            resp = sess.get(url_page, headers=headers, timeout=10)
            if resp.status_code != 200:
                break
            messages = resp.json()
        except Exception:
            break
        if not isinstance(messages, list) or len(messages) == 0:
            break
        for m in messages:
            if m.get('id') not in {x.get('id') for x in all_messages}:
                all_messages.append(m)
        if len(messages) < 25:
            break
        page += 1
    
    if not all_messages:
        flash('Aucun message dans la boîte de réception.', 'info')
        return redirect(url_for('ent.inbox'))
    
    config = EntConfig.query.first()
    imported = 0
    
    for msg in all_messages:
        msg_id = str(msg.get('id'))
        
        # Vérifier si le message existe déjà
        existing = EntMessage.query.get(msg_id)
        if existing:
            continue
        
        # Récupérer le détail
        try:
            detail = sess.get(f'https://ent77.seine-et-marne.fr/conversation/detail/{msg_id}', 
                            headers=headers, timeout=10)
            if detail.status_code != 200:
                continue
            detail_json = detail.json()
        except Exception:
            continue
        
        body_html = detail_json.get('body', '')
        body_text = re.sub('<[^<]+?>', '', body_html)
        sender_display, is_forwarded, original_sender = extract_sender(detail_json)
        subject = detail_json.get('subject', 'N/A')
        ts = detail_json.get('date')
        msg_date = datetime.fromtimestamp(ts / 1000) if ts else datetime.now(timezone.utc)
        
        # Créer le message
        ent_msg = EntMessage(
            id=msg_id,
            credential_id=credential.id,
            subject=subject,
            sender_name=sender_display,
            sender_id=detail_json.get('from', {}).get('id', '') if isinstance(detail_json.get('from'), dict) else '',
            date=msg_date,
            body=body_html,
            is_forwarded=is_forwarded,
            original_sender=original_sender,
            is_unread=msg.get('unread') is True or msg.get('unread') == 1,
            has_attachment=detail_json.get('has_attachment', False)
        )
        db.session.add(ent_msg)
        imported += 1
    
    db.session.commit()
    flash(f'{imported} message(s) importé(s).', 'success')
    return redirect(url_for('ent.inbox'))


@ent_bp.route('/message/<msg_id>')
@login_required
def message_detail(msg_id):
    """Détail d'un message ENT."""
    from .interpretation_models import EntMessageInterpretation
    
    message = EntMessage.query.get_or_404(msg_id)
    
    # Récupérer les interprétations
    interpretations = EntMessageInterpretation.query.filter_by(message_id=msg_id).order_by(EntMessageInterpretation.created_at.desc()).all()
    
    return render_template('ent/message_detail.html', 
                         message=message, 
                         attachments=[], 
                         interpretations=interpretations)


@ent_bp.route('/interpretations')
@login_required
def interpretations():
    """Liste des interprétations ENT."""
    # Filtres
    status = request.args.get('status', 'pending')
    interpretation_type = request.args.get('type', '')
    
    # Requête de base
    query = EntMessageInterpretation.query.join(EntMessage)
    
    # Appliquer les filtres
    if status != 'all':
        query = query.filter(EntMessageInterpretation.status == status)
    if interpretation_type:
        query = query.filter(EntMessageInterpretation.analysis_type == interpretation_type)
    
    # Trier par date du message
    interpretations = query.order_by(EntMessage.date.desc()).limit(50).all()
    
    return render_template('ent/interpretations.html', 
                         interpretations=interpretations,
                         status=status,
                         interpretation_type=interpretation_type)


# ─── API Interprétation ─────────────────────────────────────────────────────

@ent_bp.route('/api/interpret/<msg_id>', methods=['POST'])
@login_required
def api_interpret_message(msg_id):
    """API pour interpréter un message ENT."""
    from .interpretation_models import EntMessageInterpretation
    from app_new.outlook.models import GmaoContext
    from app_new.core.models.settings import AppSettings
    import requests
    
    message = EntMessage.query.get_or_404(msg_id)
    data = request.get_json() or {}
    user_context = data.get('context', '')
    
    # Récupérer le contexte GMAO
    gmao_context = GmaoContext.get_for_user(current_user.id)
    if not gmao_context:
        return jsonify({'error': 'Contexte GMAO non configuré'}), 400
    
    # Récupérer la clé API
    api_key = AppSettings.get('openrouter_api_key')
    if not api_key:
        return jsonify({'error': 'Clé API non configurée'}), 400
    
    # Construire le prompt
    prompt = f"""Analyse ce message de la plateforme ENT77 et propose une action GMAO.

Contexte de l'établissement:
{gmao_context.establishment_name or 'Non défini'}
{gmao_context.technical_context or ''}
{gmao_context.equipment_context or ''}

Message:
Sujet: {message.subject}
Expéditeur: {message.sender_name}
Contenu: {message.body[:1000] if message.body else ''}

{"Contexte additionnel: " + user_context if user_context else ""}

Réponds en JSON avec:
- type: curative/preventive/administrative/formation/information
- action: create/update/inform
- priority: low/medium/high/critical
- summary: résumé court
- equipment: équipement concerné (optionnel)
- description: description détaillée
"""
    
    # Récupérer le modèle
    from app_new.core.models.settings import AppSettings as AS2
    model = AS2.get('openrouter_model', 'poolside/laguna-m.1:free')
    
    # Appeler l'API
    try:
        response = requests.post(
            'https://openrouter.ai/api/v1/chat/completions',
            headers={
                'Authorization': f'Bearer {api_key}',
                'Content-Type': 'application/json',
                'HTTP-Referer': 'https://gmao-college.fr',
                'X-Title': 'GMAO College'
            },
            json={
                'model': model,
                'messages': [{'role': 'user', 'content': prompt}],
                'max_tokens': 2000
            },
            timeout=30
        )
        
        content = response.json()['choices'][0]['message']['content']
        
        # Parser le JSON
        import json
        content = content.strip()
        if content.startswith('```json'):
            content = content[7:]
        if content.startswith('```'):
            content = content[3:]
        if content.endswith('```'):
            content = content[:-3]
        
        data = json.loads(content)
        
        # Créer l'interprétation
        interpretation = EntMessageInterpretation(
            message_id=message.id,
            analysis_type=data.get('type', 'information'),
            analysis_action=data.get('action', 'inform'),
            analysis_priority=data.get('priority', 'medium'),
            analysis_summary=data.get('summary'),
            suggested_equipment=data.get('equipment'),
            suggested_description=data.get('description'),
            status='pending'
        )
        db.session.add(interpretation)
        db.session.commit()
        
        return jsonify({'success': True, 'interpretation_id': interpretation.id})
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@ent_bp.route('/api/interpretation/<int:interp_id>/reject', methods=['POST'])
@login_required
def reject_ent_interpretation(interp_id):
    """Rejette une interprétation ENT, déplace le message vers 'Traités' et supprime de la base."""
    from app_new.lib_ext.ent_service import move_ent_message_to_processed
    
    interpretation = EntMessageInterpretation.query.get_or_404(interp_id)
    message = interpretation.message
    move_result = None
    
    # Déplacer le message vers "Traités"
    if message:
        move_result = move_ent_message_to_processed(interpretation.message_id)
    
    # Supprimer l'interprétation
    db.session.delete(interpretation)
    
    # Supprimer le message de la base GMAO
    if message:
        db.session.delete(message)
    
    db.session.commit()
    
    if move_result and move_result.get('success'):
        return jsonify({'success': True, 'message': 'Interprétation rejetée. Message déplacé et supprimé de la base.'})
    elif move_result:
        return jsonify({'success': True, 'warning': f'Interprétation rejetée. Attention: {move_result.get("error")}'})
    else:
        return jsonify({'success': True, 'message': 'Interprétation rejetée.'})
