"""
Pronote Routes - GMAO Collège
Intégration Pronote
"""
import logging
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, csrf
from ..pronote.models import PronoteSession
from ..core.models.college import Room, RoomSchedule
import os
import json
from datetime import datetime, date, timedelta

logger = logging.getLogger(__name__)

pronote_bp = Blueprint('pronote', __name__, template_folder='templates')


@pronote_bp.route('/')
@login_required
def index():
    """Page principale Pronote."""
    session = PronoteSession.get()
    return render_template('pronote/index.html', session=session)


@pronote_bp.route('/connect', methods=['GET', 'POST'])
@login_required
def connect():
    """Connexion à Pronote via QR Code."""
    if request.method == 'POST':
        qr_code = request.form.get('qr_code', '').strip()
        pin = request.form.get('pin', '').strip()
        account_pin = request.form.get('account_pin', '').strip() or None
        
        if not qr_code or not pin:
            flash('QR Code et PIN sont requis.', 'danger')
            return redirect(url_for('pronote.connect'))
        
        try:
            from app_new.lib_ext.pronote_client import connect_with_qr, save_session_to_db
            client = connect_with_qr(qr_code, pin, account_pin)
            
            if client:
                try:
                    creds = client.export_credentials()
                    session_data = {
                        'token': creds.get('password') or creds.get('token'),
                        'url': creds.get('pronote_url') or creds.get('url'),
                        'username': creds.get('username'),
                        'device_uuid': str(client.uuid) if hasattr(client, 'uuid') else None,
                        'account_pin': account_pin  # Sauvegarder le PIN
                    }
                except Exception as ex:
                    logger.warning(f"export_credentials a échoué: {ex}")
                    session_data = {'url': getattr(client, 'url', None)}
                
                save_session_to_db(session_data)
                flash('Connexion PRONOTE réussie !', 'success')
                return redirect(url_for('pronote.index'))
            else:
                flash('Échec de la connexion PRONOTE.', 'danger')
                
        except Exception as e:
            flash(f'Erreur de connexion: {str(e)}', 'danger')
        
        return redirect(url_for('pronote.connect'))
    
    return render_template('pronote/connect.html')


@pronote_bp.route('/planning')
@pronote_bp.route('/planning_index')
@login_required
def planning():
    """Page principale des plannings."""
    teaching_rooms = Room.query.filter(Room.room_type.has(is_teaching=True)).order_by(
        Room.building_id, Room.name
    ).all()
    return render_template('pronote/planning_index.html', rooms=teaching_rooms)


@pronote_bp.route('/rooms')
@login_required
def rooms():
    """Liste des salles."""
    rooms_list = Room.query.order_by(Room.name).all()
    return render_template('pronote/rooms.html', rooms=rooms_list)


@pronote_bp.route('/sync-salles', methods=['POST'])
@login_required
def sync_salles():
    """Synchroniser les salles depuis Pronote."""
    from app_new.lib_ext.pronote_client import get_client, get_all_salles
    client = get_client()
    if not client:
        flash('Non connecté à Pronote.', 'warning')
        return redirect(url_for('pronote.connect'))
    
    try:
        salles_data = get_all_salles(client)
        created = 0
        for salle in salles_data:
            salle_nom = salle.get('L', '')
            if not Room.query.filter_by(name=salle_nom).first():
                from app_new.core.models.college import Building, RoomType
                building = Building.query.filter_by(name='Collège').first()
                if not building:
                    building = Building(name='Collège', description='Bâtiment principal')
                    db.session.add(building)
                    db.session.commit()
                
                cours_type = RoomType.query.filter_by(name='cours').first()
                if not cours_type:
                    cours_type = RoomType(name='cours', is_teaching=True)
                    db.session.add(cours_type)
                    db.session.commit()
                
                room = Room(name=salle_nom, code=salle_nom, floor=0, building_id=building.id, room_type_id=cours_type.id)
                db.session.add(room)
                created += 1
        db.session.commit()
        flash(f'{created} nouvelles salles synchronisées depuis Pronote.', 'success')
    except Exception as e:
        flash(f'Erreur synchronisation: {str(e)}', 'danger')
    
    return redirect(url_for('pronote.rooms'))


@pronote_bp.route('/planning/<int:room_id>')
@login_required
def room_planning(room_id):
    """Emploi du temps d'une salle spécifique."""
    from app_new.lib_ext.pronote_client import get_client
    room = Room.query.get_or_404(room_id)
    week_start = request.args.get("week", date.today().isoformat())
    try:
        monday = date.fromisoformat(week_start)
        if monday.weekday() != 0:
            monday = monday - timedelta(days=monday.weekday())
    except:
        monday = date.today() - timedelta(days=date.today().weekday())
    
    week_end = monday + timedelta(days=6)
    
    # Vérifier la connexion PRONOTE
    client = get_client()
    pronote_connected = client is not None
    
    # La page ne consulte pas Pronote pour calculer l'occupation : elle
    # affiche uniquement la vue interne résolue. Pronote est une source
    # facultative, déclenchée par l'import explicite ci-dessous.
    pronote_by_day = {}
    
    # Récupérer les cours importés depuis la base de données
    # Pronote reste une source facultative ; l'affichage des créneaux internes
    # passe par le service de résolution commun pour masquer les créneaux
    # supplantés/désactivés et conserver les protections manuelles.
    from app_new.core.services.room_planning import active_room_schedules
    db_schedules = active_room_schedules(room_id)
    db_schedules = [s for s in db_schedules if s.week_start == monday]
    
    db_by_day = {}
    for schedule in db_schedules:
        if schedule.day_of_week not in db_by_day:
            db_by_day[schedule.day_of_week] = []
        db_by_day[schedule.day_of_week].append({
            'start_time': schedule.start_time.strftime('%H:%M') if schedule.start_time else '',
            'end_time': schedule.end_time.strftime('%H:%M') if schedule.end_time else '',
            'subject': schedule.subject or '',
            'teacher': schedule.teacher or '',
            'class_name': schedule.class_name or '',
            'source': schedule.source,
            'protected': schedule.protected_from_sync,
            'conflict_note': schedule.conflict_note,
            'last_synced_at': schedule.last_synced_at,
        })

    last_sync_at = max((item['last_synced_at'] for values in db_by_day.values() for item in values
                        if item['last_synced_at']), default=None)
    
    return render_template('pronote/room_planning.html', room=room, week_start=monday, week_end=week_end, 
                           prev_week=monday - timedelta(days=7), next_week=monday + timedelta(days=7), 
                           today=date.today(), pronote_connected=pronote_connected, pronote_by_day=pronote_by_day,
                           db_by_day=db_by_day, last_sync_at=last_sync_at, timedelta=timedelta)


@pronote_bp.route('/planning/<int:room_id>/import', methods=['POST'])
@login_required
def import_room_planning(room_id):
    """Importer l'emploi du temps d'une salle depuis Pronote."""
    from app_new.lib_ext.pronote_client import get_client, get_lessons_for_room
    from app_new.core.services.room_planning import normalize_pronote_lessons, sync_pronote_schedules
    room = Room.query.get_or_404(room_id)
    client = get_client()
    if not client:
        flash('Pronote n’est pas connecté : le planning interne reste disponible.', 'warning')
        return redirect(url_for('pronote.room_planning', room_id=room_id))
    week_value = request.form.get('week') or request.args.get('week') or date.today().isoformat()
    try:
        monday = date.fromisoformat(week_value)
        monday -= timedelta(days=monday.weekday())
    except ValueError:
        monday = date.today() - timedelta(days=date.today().weekday())
    try:
        lessons = get_lessons_for_room(client, room.name, monday, monday + timedelta(days=6), strict=True)
        entries = normalize_pronote_lessons(lessons, monday)
        sync_pronote_schedules(room.id, entries, week_start=monday)
        flash(f'{len(entries)} créneaux Pronote synchronisés. Les protections locales ont été conservées.', 'success')
    except Exception:
        db.session.rollback()
        logger.exception('Synchronisation Pronote impossible pour la salle %s', room.id)
        flash('Pronote est momentanément indisponible. Les derniers créneaux connus sont conservés.', 'warning')
    return redirect(url_for('pronote.room_planning', room_id=room_id, week=monday.isoformat()))


@pronote_bp.route('/disconnect', methods=['POST'])
@login_required
def disconnect():
    """Déconnexion de Pronote."""
    session = PronoteSession.get()
    if session:
        session.session_token = None
        db.session.commit()
    flash('Déconnexion Pronote réussie.', 'info')
    return redirect(url_for('pronote.index'))


@pronote_bp.route('/personnels')
@login_required
def personnels():
    """Liste des personnels depuis Pronote."""
    from app_new.lib_ext.pronote_client import get_client
    client = get_client()
    if not client:
        flash('Non connecté à Pronote.', 'warning')
        return redirect(url_for('pronote.connect'))
    try:
        personnels = [{'name': 'Simulation Personnel 1', 'role': 'Admin'}, {'name': 'Simulation Personnel 2', 'role': 'Tech'}]
        return render_template('pronote/personnels.html', personnels=personnels)
    except Exception as e:
        flash(f'Erreur: {str(e)}', 'danger')
        return redirect(url_for('pronote.index'))


@pronote_bp.route('/professeurs')
@login_required
def professeurs():
    """Liste des professeurs depuis Pronote."""
    from app_new.lib_ext.pronote_client import get_client
    client = get_client()
    if not client:
        flash('Non connecté à Pronote.', 'warning')
        return redirect(url_for('pronote.connect'))
    try:
        profs = [{'name': 'Simulation Prof 1', 'matiere': 'Maths'}, {'name': 'Simulation Prof 2', 'matiere': 'Physique'}]
        return render_template('pronote/professeurs.html', profs=profs)
    except Exception as e:
        flash(f'Erreur: {str(e)}', 'danger')
        return redirect(url_for('pronote.index'))
