"""Interventions Crud Routes - GMAO Collège"""
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 ..core.models.maintenance import Intervention, InterventionComment
from ..core.models.equipment import Equipment, EquipmentCategory
from ..core.models.user import User
from datetime import datetime

interventions_bp = Blueprint("interventions", __name__, url_prefix="/interventions", template_folder="templates")

"""
Interventions Routes - GMAO Collège
Gestion des interventions de maintenance
"""
from flask import Blueprint, render_template, redirect, url_for, request, flash
from flask_login import login_required, current_user
from datetime import datetime, timezone
from app_new.extensions import db
from ..core.models.maintenance import Intervention, StatusChange, InterventionComment, Lot
from ..core.models.planning import ScheduledTask
from ..core.models.equipment import Equipment
from ..core.models.college import Building, Zone, Room
from ..core.models.company import Service, Company
from app_new.constants import INTERVENTION_STATUSES, INTERVENTION_TRANSITIONS, PRIORITIES, WORKFLOW_TYPES, WORKFLOW_STATUS_ORDERS
from ..core.authorization import has_permission, permission_required

interventions_bp = Blueprint('interventions', __name__, template_folder='templates')


@interventions_bp.route('/')
@login_required
def index():
    """Liste des interventions avec filtres avances et tri par colonne."""
    page = request.args.get('page', 1, type=int)
    status = request.args.get('status', '')
    priority = request.args.get('priority', '')
    intervention_type = request.args.get('type', '')
    workflow_type = request.args.get('workflow_type', '')
    lot_id = request.args.get('lot', type=int)
    assigned_to_id = request.args.get('assigned_to_id', type=int)
    frequency = request.args.get('frequency', '')
    date_from = request.args.get('date_from', '')
    date_to = request.args.get('date_to', '')
    sort_col = request.args.get('sort', 'created_at')
    sort_dir = request.args.get('dir', 'desc')
    show_trashed = request.args.get('trashed', '0') == '1'
    
    query = Intervention.query
    
    if show_trashed:
        query = query.filter_by(is_deleted=True)
    else:
        query = query.filter_by(is_deleted=False)
    
    if status:
        query = query.filter_by(status=status)
    if priority:
        query = query.filter_by(priority=priority)
    if intervention_type:
        query = query.filter(Intervention.type == intervention_type)
    if workflow_type in WORKFLOW_TYPES:
        query = query.filter_by(workflow_type=workflow_type)
    if lot_id:
        query = query.filter_by(lot_id=lot_id)
    if assigned_to_id:
        query = query.filter_by(assigned_to_id=assigned_to_id)
    if date_from:
        try:
            d = datetime.strptime(date_from, '%Y-%m-%d').date()
            query = query.filter(Intervention.scheduled_date >= d)
        except ValueError:
            pass
    if date_to:
        try:
            d = datetime.strptime(date_to, '%Y-%m-%d').date()
            query = query.filter(Intervention.scheduled_date <= d)
        except ValueError:
            pass
    if frequency:
        if frequency == 'recurring':
            query = query.filter(Intervention.is_recurring == True)
        elif frequency == 'ponctuel':
            query = query.filter(Intervention.is_recurring == False)
        elif frequency.isdigit():
            query = query.filter(Intervention.frequency_days == int(frequency))
    
    # Tri par colonne (avec validation pour eviter injection)
    valid_sort_cols = {'created_at', 'scheduled_date', 'priority', 'status', 'title'}
    if sort_col not in valid_sort_cols:
        sort_col = 'created_at'
    sort_dir = 'asc' if sort_dir == 'asc' else 'desc'
    order_clause = getattr(Intervention, sort_col).asc() if sort_dir == 'asc' else getattr(Intervention, sort_col).desc()
    query = query.order_by(order_clause)
    
    interventions = query.paginate(page=page, per_page=20)
    lots = Lot.query.order_by(Lot.name).all()
    users = User.query.filter_by(is_active=True).order_by(User.username).all()
    
    # Compter les interventions par statut
    status_counts = {}
    for status_key in INTERVENTION_STATUSES.keys():
        status_counts[status_key] = Intervention.query.filter_by(status=status_key, is_deleted=False).count()
    
    # Compter les interventions à jeter
    trashed_count = Intervention.query.filter_by(is_deleted=True).count()
    
    return render_template('interventions/index.html',
                         interventions=interventions,
                         lots=lots,
                         users=users,
                         statuses=INTERVENTION_STATUSES,
                         workflow_types=WORKFLOW_TYPES,
                         priorities=PRIORITIES,
                         status_counts=status_counts,
                         trashed_count=trashed_count,
                         show_trashed=show_trashed,
                         sort_col=sort_col,
                         sort_dir=sort_dir)


def _render_intervention_form(prefilled=None, form_data=None, **extra):
    """Render the intervention form consistently, including validation errors."""
    from ..core.models.user import User
    return render_template(
        'interventions/new.html',
        lots=Lot.query.order_by(Lot.name).all(),
        equipments=Equipment.query.filter_by(status='en_service').order_by(Equipment.name).all(),
        rooms=Room.query.order_by(Room.name).all(),
        users=User.query.filter_by(is_active=True).order_by(User.username).all(),
        statuses=INTERVENTION_STATUSES,
        priorities=PRIORITIES,
        workflow_types=WORKFLOW_TYPES,
        prefilled=prefilled or {},
        form_data=form_data or {},
        **extra,
    )


@interventions_bp.route('/new', methods=['GET', 'POST'])
@login_required
@permission_required('intervention.create')
def create():
    """Créer une intervention."""
    from ..core.models.user import User
    from ..outlook.models import OutlookMailInterpretation
    
    if request.method == 'POST':
        title = (request.form.get('title') or '').strip()
        if not title:
            flash('Le titre de l’intervention est obligatoire.', 'danger')
            return _render_intervention_form(form_data=request.form), 400
        # Une intervention générale peut cibler une salle sans équipement.
        equipment_value = request.form.get('equipment_id')
        equipment_id = int(equipment_value) if equipment_value and equipment_value.isdigit() else None
        
        # Déterminer le demandeur
        requester_name = request.form.get('requester_name', '').strip()
        if not requester_name:
            # Si pas de demandeur fourni, utiliser le nom de l'utilisateur connecté
            requester_name = current_user.username if hasattr(current_user, 'username') else 'Inconnu'
        
        selected_type = request.form.get('intervention_type', 'curatif')
        workflow_type = request.form.get('workflow_type') or {
            'preventif': 'preventive', 'amelioratif': 'travaux',
            'prevention': 'prevention', 'administratif': 'prevention',
        }.get(selected_type, 'corrective')
        try:
            scheduled_date = datetime.strptime(request.form.get('intervention_date'), '%Y-%m-%d').date() if request.form.get('intervention_date') else None
            scheduled_start = datetime.strptime(request.form.get('scheduled_start'), '%H:%M').time() if request.form.get('scheduled_start') else None
            scheduled_end = datetime.strptime(request.form.get('scheduled_end'), '%H:%M').time() if request.form.get('scheduled_end') else None
        except ValueError:
            flash('La date ou l’heure saisie est invalide.', 'danger')
            return _render_intervention_form(form_data=request.form), 400
        intervention = Intervention(
            title=title,
            description=request.form.get('description') or '',
            lot_id=request.form.get('lot_id') or None,
            equipment_id=equipment_id,
            room_id=request.form.get('room_id') or None,
            assigned_to_id=request.form.get('assigned_to_id') or None,
            author_id=current_user.id,
            status=request.form.get('status', 'brouillon'),
            priority=request.form.get('priority', 'normale'),
            type=selected_type,
            workflow_type=workflow_type if workflow_type in WORKFLOW_TYPES else 'corrective',
            notes=request.form.get('notes') or '',
            requester_name=requester_name,
            scheduled_date=scheduled_date,
            scheduled_start=scheduled_start,
            scheduled_end=scheduled_end
        )
        db.session.add(intervention)
        db.session.commit()
        
        # Marquer l'interprétation comme acceptée si fournie
        from_interpretation_id = request.form.get('from_interpretation')
        source = request.form.get('source', 'outlook')  # 'outlook' ou 'ent'
        if from_interpretation_id:
            if source == 'ent':
                from app_new.ent.interpretation_models import EntMessageInterpretation
                from app_new.lib_ext.ent_service import move_ent_message_to_processed
                interpretation = EntMessageInterpretation.query.get(from_interpretation_id)
                if interpretation:
                    message = interpretation.message
                    # Déplacer le message ENT vers "Traités"
                    if message:
                        move_result = move_ent_message_to_processed(interpretation.message_id)
                        if move_result.get('success'):
                            flash('Intervention créée. Message ENT déplacé vers Traités.', 'success')
                        else:
                            flash(f'Intervention créée. Erreur déplacement ENT: {move_result.get("error")}', 'warning')
                    interpretation.status = 'accepted'
                    if message:
                        message.intervention_id = intervention.id
                    db.session.commit()
            else:
                from app_new.outlook.models import OutlookMail
                from app_new.outlook.routes import move_mail_to_processed
                interpretation = OutlookMailInterpretation.query.get(from_interpretation_id)
                if interpretation:
                    mail = interpretation.mail
                    # Déplacer le mail Outlook vers "Traités"
                    if mail:
                        move_result = move_mail_to_processed(mail)
                        if move_result.get('success'):
                            flash('Intervention créée. Mail déplacé vers Traités.', 'success')
                        else:
                            flash(f'Intervention créée. Erreur déplacement mail: {move_result.get("error")}', 'warning')
                    interpretation.status = 'accepted'
                    if mail:
                        mail.intervention_id = intervention.id
                    db.session.commit()
            # Flash déjà envoyé ci-dessus
        else:
            flash('Intervention créée avec succès.', 'success')
        
        return redirect(url_for('interventions.detail', id=intervention.id))
    
    # GET - Pré-remplir depuis interprétation ou tâche planifiée
    from_interpretation = request.args.get('from_interpretation')
    scheduled_task_id = request.args.get('scheduled_task_id', type=int)
    
    # Valeurs par défaut
    prefilled = {
        'title': '',
        'description': '',
        'priority': 'normale',
        'type': 'curatif',
        'location': '',
        'equipment': '',
        'assignee': '',
        'date': None,
        'requester_name': ''
        , 'workflow_type': request.args.get('workflow', 'corrective')
    }
    
    interpretation = None
    json_suggestions = None
    
    if from_interpretation:
        source = request.args.get('source', 'outlook')
        
        if source == 'ent':
            from app_new.ent.interpretation_models import EntMessageInterpretation
            interpretation = EntMessageInterpretation.query.get(from_interpretation)
        else:
            interpretation = OutlookMailInterpretation.query.get(from_interpretation)
        
        if interpretation:
            # Adapter selon la source
            if source == 'ent':
                json_suggestions = {
                    'title': interpretation.message.subject if interpretation.message else '',
                    'description': interpretation.suggested_description,
                    'priority': interpretation.analysis_priority,
                    'type': interpretation.analysis_type,
                    'location': '',
                    'equipment': interpretation.suggested_equipment,
                    'assignee': '',
                    'date': None
                }
                
                prefilled['title'] = interpretation.message.subject if interpretation.message else ''
                prefilled['description'] = interpretation.suggested_description or ''
                prefilled['priority'] = interpretation.analysis_priority or 'normale'
                # Demandeur = sender du message ENT
                prefilled['requester_name'] = interpretation.message.sender_name if interpretation.message else ''
                
                type_map = {
                    'curative': 'curatif',
                    'preventive': 'preventif',
                    'administrative': 'administratif',
                    'formation': 'formation',
                    'information': 'curatif'
                }
                prefilled['type'] = type_map.get(interpretation.analysis_type, 'curatif')
                prefilled['workflow_type'] = 'preventive' if interpretation.analysis_type == 'preventive' else prefilled.get('workflow_type', 'corrective')
                prefilled['equipment'] = interpretation.suggested_equipment or ''
            else:
                json_suggestions = {
                    'title': interpretation.suggested_title,
                    'description': interpretation.suggested_description,
                    'priority': interpretation.suggested_urgency,
                    'type': interpretation.analysis_type,
                    'location': interpretation.suggested_location,
                    'equipment': interpretation.suggested_equipment,
                    'assignee': interpretation.suggested_assignee,
                    'date': interpretation.suggested_date.strftime('%d/%m/%Y') if interpretation.suggested_date else None
                }
                
                # Pré-remplir avec les valeurs de l'interprétation
                prefilled['title'] = interpretation.suggested_title or ''
                prefilled['description'] = interpretation.suggested_description or ''
                prefilled['priority'] = interpretation.suggested_urgency or 'normale'
                # Demandeur = sender du mail Outlook
                prefilled['requester_name'] = interpretation.mail.from_name if interpretation.mail else ''
                
                # Mapper le type
                type_map = {
                    'curative': 'curatif',
                    'preventive': 'preventif',
                    'administrative': 'administratif',
                    'formation': 'formation',
                    'information': 'curatif'
                }
                prefilled['type'] = type_map.get(interpretation.analysis_type, 'curatif')
                prefilled['location'] = interpretation.suggested_location or ''
                prefilled['equipment'] = interpretation.suggested_equipment or ''
                prefilled['assignee'] = interpretation.suggested_assignee or ''
                prefilled['date'] = interpretation.suggested_date
    
    # Chercher l'équipement correspondant si spécifié
    equipment_id = None
    equipment_match = None
    if prefilled['equipment']:
        eq = Equipment.query.filter(Equipment.name.ilike(f"%{prefilled['equipment']}%")).first()
        if eq:
            equipment_id = eq.id
            equipment_match = eq
    
    # Pré-remplir depuis tâche planifiée si fourni
    if scheduled_task_id and not from_interpretation:
        task = ScheduledTask.query.get(scheduled_task_id)
        if task:
            prefilled['title'] = f"Intervention: {task.preventive_task.name if task.preventive_task else task.lot_task.name if task.lot_task else 'Tâche planifiée'}"
            prefilled['description'] = task.notes or ''
            prefilled['date'] = task.scheduled_date.strftime('%Y-%m-%d') if task.scheduled_date else None
            prefilled['scheduled_start'] = task.scheduled_start.strftime('%H:%M') if task.scheduled_start else None
            prefilled['scheduled_end'] = task.scheduled_end.strftime('%H:%M') if task.scheduled_end else None
    
    # Chercher la salle correspondante si spécifiée
    room_id = None
    room_match = None
    if prefilled['location']:
        room = Room.query.filter(Room.name.ilike(f"%{prefilled['location']}%")).first()
        if room:
            room_id = room.id
            room_match = room
    
    return _render_intervention_form(prefilled=prefilled,
                                     equipment_id=equipment_id,
                                     equipment_match=equipment_match,
                                     room_id=room_id,
                                     room_match=room_match,
                                     from_interpretation=from_interpretation,
                                     interpretation=interpretation,
                                     json_suggestions=json_suggestions,
                                     source=source if from_interpretation else 'outlook')


@interventions_bp.route('/create-for-group', methods=['GET'])
@login_required
def create_for_group_select():
    """Sélection d'équipements pour création groupée."""
    equipments = Equipment.query.filter_by(status='en_service').order_by(Equipment.name).all()
    return render_template('interventions/create_for_group_select.html', equipments=equipments)


@interventions_bp.route('/create-for-group', methods=['POST'])
@login_required
def create_for_group():
    """Créer des interventions pour plusieurs équipements."""
    equipment_ids = request.form.getlist('equipment_ids')
    title = request.form.get('title')
    description = request.form.get('description', '')
    priority = request.form.get('priority', 'normale')
    lot_id = request.form.get('lot_id')
    
    if not equipment_ids:
        flash('Aucun équipement sélectionné.', 'error')
        return redirect(url_for('interventions.create_for_group_select'))
    
    created_count = 0
    for eq_id in equipment_ids:
        equipment = Equipment.query.get(eq_id)
        if equipment:
            intervention = Intervention(
                title=title,
                description=description,
                priority=priority,
                lot_id=lot_id if lot_id else None,
                equipment_id=equipment.id,
                room_id=equipment.room_id,
                status='brouillon',
                intervention_type='corrective'
            )
            db.session.add(intervention)
            created_count += 1
    
    db.session.commit()
    flash(f'{created_count} intervention(s) créée(s) avec succès.', 'success')
    return redirect(url_for('interventions.index'))


@interventions_bp.route('/<int:id>')
@login_required
def detail(id):
    """Détail d'une intervention."""
    intervention = Intervention.query.get_or_404(id)
    allowed_workflow_statuses = set(WORKFLOW_STATUS_ORDERS.get(intervention.workflow_type, WORKFLOW_STATUS_ORDERS['corrective'])) | {'refusee', 'annulee', 'reportee'}
    transitions = [(key, value['label']) for key, value in INTERVENTION_STATUSES.items()
                   if key in INTERVENTION_TRANSITIONS.get(intervention.status, set()) and key in allowed_workflow_statuses]
    history = intervention.status_history.order_by(StatusChange.created_at.desc()).all()
    # Utiliser explicitement le template du module. Une ancienne copie globale
    # de ``interventions/detail.html`` est conservée pour compatibilité.
    return render_template('interventions_module/detail.html',
                         intervention=intervention,
                         documents=intervention.documents.all(),
                         statuses=INTERVENTION_STATUSES,
                         transitions=transitions,
                         history=history,
                         workflow_status_order=WORKFLOW_STATUS_ORDERS.get(intervention.workflow_type, WORKFLOW_STATUS_ORDERS['corrective']),
                         buildings=Building.query.order_by(Building.name).all(),
                         zones=Zone.query.order_by(Zone.name).all(),
                         rooms=Room.query.order_by(Room.name).all(),
                         categories=EquipmentCategory.query.order_by(EquipmentCategory.name).all(),
                         equipment_choices=Equipment.query.filter_by(is_deleted=False).order_by(Equipment.name).all(),
                         services=Service.query.filter_by(is_active=True).order_by(Service.name).all(),
                         companies=Company.query.filter_by(is_active=True).order_by(Company.name).all())


@interventions_bp.route('/<int:id>/work-details', methods=['POST'])
@login_required
def save_work_details(id):
    """Enregistre les informations de travaux depuis la fiche intervention."""
    intervention = Intervention.query.get_or_404(id)
    if 'execution_mode' in request.form:
        intervention.execution_mode = request.form.get('execution_mode') or 'interne'
    if 'department_service_id' in request.form:
        service_id = request.form.get('department_service_id')
        intervention.department_service_id = int(service_id) if service_id and service_id.isdigit() else None
    if 'company_id' in request.form:
        company_id = request.form.get('company_id')
        intervention.company_id = int(company_id) if company_id and company_id.isdigit() else None
    if 'quote_status' in request.form:
        intervention.quote_status = request.form.get('quote_status') or 'non_requis'
    if 'quote_reference' in request.form:
        intervention.quote_reference = request.form.get('quote_reference') or None
    for field in ('quote_amount_ht', 'quote_amount_ttc'):
        if field in request.form:
            setattr(intervention, field, float(request.form[field]) if request.form.get(field) else None)
    for field in ('department_request_date', 'chief_validation_date', 'department_validation_date', 'quote_date', 'quote_valid_until'):
        if field in request.form:
            value = request.form.get(field)
            setattr(intervention, field, datetime.strptime(value, '%Y-%m-%d').date() if value else None)
    if 'work_notes' in request.form:
        intervention.work_notes = request.form.get('work_notes') or None
    db.session.commit()
    flash('Workflow travaux enregistré.', 'success')
    return redirect(url_for('interventions.detail', id=id))


@interventions_bp.route('/<int:id>/location', methods=['POST'])
@login_required
def update_location(id):
    """Modifie la localisation en cascade bâtiment -> zone -> salle -> équipement."""
    intervention = Intervention.query.get_or_404(id)
    building_id = request.form.get('building_id', type=int)
    zone_id = request.form.get('zone_id', type=int)
    room_id = request.form.get('room_id', type=int)
    category_id = request.form.get('category_id', type=int)
    equipment_id = request.form.get('equipment_id', type=int)
    room = Room.query.get(room_id) if room_id else None
    category = EquipmentCategory.query.get(category_id) if category_id else None
    equipment = Equipment.query.get(equipment_id) if equipment_id else None
    if room_id and not room:
        flash('Salle invalide.', 'danger')
        return redirect(url_for('interventions.detail', id=id))
    if room and building_id and room.building_id != building_id:
        flash("La salle ne correspond pas au bâtiment sélectionné.", 'danger')
        return redirect(url_for('interventions.detail', id=id))
    if room and zone_id and room.zone_id != zone_id:
        flash("La salle ne correspond pas à la zone sélectionnée.", 'danger')
        return redirect(url_for('interventions.detail', id=id))
    if equipment:
        if room_id and equipment.room_id != room_id:
            flash("L'équipement choisi n'est pas dans la salle sélectionnée.", 'danger')
            return redirect(url_for('interventions.detail', id=id))
        if category_id and equipment.effective_category_id != category_id:
            flash("L'équipement choisi ne correspond pas à la catégorie sélectionnée.", 'danger')
            return redirect(url_for('interventions.detail', id=id))
    intervention.room_id = room.id if room else None
    intervention.equipment_id = equipment.id if equipment else None
    db.session.commit()
    flash('Salle et équipement concernés mis à jour.', 'success')
    return redirect(url_for('interventions.detail', id=id))


@interventions_bp.route('/<int:id>/edit', methods=['GET', 'POST'])
@login_required
@permission_required('intervention.edit')
def edit(id):
    """Modifier une intervention."""
    from ..core.models.user import User
    
    intervention = Intervention.query.get_or_404(id)
    
    if request.method == 'POST':
        old_status = intervention.status
        
        intervention.title = request.form.get('title')
        intervention.description = request.form.get('description')
        intervention.lot_id = request.form.get('lot_id') or None
        intervention.equipment_id = request.form.get('equipment_id') or None
        intervention.room_id = request.form.get('room_id') or None
        intervention.assigned_to_id = request.form.get('assigned_to_id') or None
        # Ne pas changer le statut si le formulaire ne le contient pas
        new_status = request.form.get('status')
        if new_status:
            intervention.status = new_status
        intervention.priority = request.form.get('priority')
        intervention.type = request.form.get('intervention_type', intervention.type)
        workflow_type = request.form.get('workflow_type')
        if workflow_type in WORKFLOW_TYPES:
            intervention.workflow_type = workflow_type
        intervention.scheduled_date = request.form.get('scheduled_date') or None
        intervention.notes = request.form.get('notes')
        intervention.requester_name = request.form.get('requester_name') or None
        
        # Enregistrer le changement de statut seulement si le statut a changé
        if new_status and old_status != intervention.status:
            status_change = StatusChange(
                intervention_id=intervention.id,
                from_status=old_status,
                to_status=intervention.status,
                changed_by_id=current_user.id
            )
            db.session.add(status_change)
        
        db.session.commit()
        flash('Intervention modifiée avec succès.', 'success')
        return redirect(url_for('interventions.detail', id=intervention.id))
    
    lots = Lot.query.order_by(Lot.name).all()
    equipments = Equipment.query.filter_by(status='en_service').order_by(Equipment.name).all()
    rooms = Room.query.order_by(Room.name).all()
    users = User.query.filter_by(is_active=True).order_by(User.username).all()
    
    # Pré-remplir avec les valeurs existantes pour l'édition
    prefilled = {
        'title': intervention.title,
        'description': intervention.description or '',
        'priority': intervention.priority,
        'type': intervention.type,
        'location': intervention.equipment.room.name if intervention.equipment and intervention.equipment.room else '',
        'equipment': intervention.equipment.name if intervention.equipment else '',
        'assignee': intervention.assigned_to.username if intervention.assigned_to else '',
        'date': intervention.scheduled_date,
        'requester_name': intervention.requester_name or ''
        , 'workflow_type': intervention.workflow_type
    }
    
    return render_template('interventions/new.html',
                         intervention=intervention,
                         lots=lots,
                         equipments=equipments,
                         rooms=rooms,
                         users=users,
                         statuses=INTERVENTION_STATUSES,
                         priorities=PRIORITIES,
                         workflow_types=WORKFLOW_TYPES,
                         prefilled=prefilled,
                         title="Modifier l'intervention")


@interventions_bp.route('/<int:id>/status', methods=['POST'])
@login_required
@permission_required('intervention.change_status')
def change_status(id):
    """Changer le statut d'une intervention."""
    intervention = Intervention.query.get_or_404(id)
    old_status = intervention.status
    # Les anciennes fiches utilisent ``to_status`` ; accepter aussi ``status``
    # pour les formulaires d'édition et conserver une transition réellement modifiable.
    new_status = request.form.get('to_status') or request.form.get('status')
    comment = request.form.get('comment', '')

    allowed = INTERVENTION_TRANSITIONS.get(old_status, set())
    workflow_statuses = set(WORKFLOW_STATUS_ORDERS.get(intervention.workflow_type, WORKFLOW_STATUS_ORDERS['corrective'])) | {'refusee', 'annulee', 'reportee'}
    if new_status not in workflow_statuses:
        flash(f'Le statut « {new_status} » ne correspond pas au workflow {intervention.workflow_label}.', 'danger')
        return redirect(url_for('interventions.detail', id=intervention.id))
    if new_status in {'terminee', 'cloturee'} and not has_permission('intervention.close', current_user):
        flash('Vous ne disposez pas du droit de clôturer cette intervention.', 'danger')
        return redirect(url_for('interventions.detail', id=intervention.id))
    if new_status != old_status and new_status not in allowed:
        flash(f'Transition interdite : {old_status} → {new_status}.', 'danger')
        return redirect(url_for('interventions.detail', id=intervention.id))

    if new_status == 'en_cours':
        from ..core.services.planning_service import PlanningService
        reason = PlanningService.maintenance_unavailability(
            datetime.now(timezone.utc).date(), user_id=current_user.id
        )
        if reason:
            flash(f'Impossible de démarrer une maintenance aujourd’hui : {reason}.', 'danger')
            return redirect(url_for('interventions.detail', id=intervention.id))
    
    if new_status != old_status:
        intervention.status = new_status
        
        status_change = StatusChange(
            intervention_id=intervention.id,
            from_status=old_status,
            to_status=new_status,
            changed_by_id=current_user.id,
            comment=comment
        )
        db.session.add(status_change)
        
        if new_status == 'terminee':
            now = datetime.now(timezone.utc)
            intervention.completed_date = now.date()
            intervention.completed_at = now
        
        db.session.commit()
        flash('Statut modifié.', 'success')
    
    return redirect(url_for('interventions.detail', id=intervention.id))


@interventions_bp.route('/<int:id>/refuse', methods=['POST'])
@login_required
@permission_required('intervention.reject')
def refuse(id):
    """Refuse une demande avec un motif obligatoire."""
    intervention = Intervention.query.get_or_404(id)
    reason = (request.form.get('refusal_reason') or '').strip()
    if not reason:
        flash('Le motif du refus est obligatoire.', 'danger')
        return redirect(url_for('interventions.detail', id=id))
    if intervention.status in {'terminee', 'cloturee', 'refusee'}:
        flash('Cette intervention ne peut plus être refusée depuis son statut actuel.', 'danger')
        return redirect(url_for('interventions.detail', id=id))
    old_status = intervention.status
    intervention.status = 'refusee'
    intervention.refusal_reason = reason
    intervention.refused_at = datetime.now(timezone.utc)
    intervention.refused_by_id = current_user.id
    db.session.add(StatusChange(intervention_id=id, from_status=old_status, to_status='refusee', changed_by_id=current_user.id, comment=reason))
    db.session.commit()
    flash('Intervention refusée et motif enregistré.', 'success')
    return redirect(url_for('interventions.detail', id=id))


@interventions_bp.route('/<int:id>/comment', methods=['POST'])
@login_required
@permission_required('intervention.comment')
def add_comment(id):
    """Ajouter un commentaire à une intervention."""
    intervention = Intervention.query.get_or_404(id)
    content = request.form.get('content')
    
    if content:
        comment = InterventionComment(
            intervention_id=intervention.id,
            author_id=current_user.id,
            content=content
        )
        db.session.add(comment)
        db.session.commit()
        flash('Commentaire ajouté.', 'success')
    
    return redirect(url_for('interventions.detail', id=intervention.id))


@interventions_bp.route('/<int:id>/soft-delete', methods=['POST'])
@login_required
@permission_required('intervention.delete')
def soft_delete(id):
    """Mettre une intervention en corbeille (soft delete)."""
    intervention = Intervention.query.get_or_404(id)
    intervention.is_deleted = True
    intervention.deleted_at = datetime.now(timezone.utc)
    intervention.deleted_by_id = current_user.id
    db.session.commit()
    flash('Intervention mise en corbeille.', 'success')
    return redirect(url_for('interventions.index'))


@interventions_bp.route('/<int:id>/postpone', methods=['POST'])
@login_required
@permission_required('intervention.postpone')
def postpone(id):
    """Reporter une intervention : motif, compteur, conservation date originale."""
    intervention = Intervention.query.get_or_404(id)
    new_date_str = request.form.get('new_scheduled_date')
    reason = request.form.get('reason', '').strip()
    
    if not new_date_str:
        flash('Nouvelle date requise.', 'danger')
        return redirect(url_for('interventions.detail', id=id))
    
    try:
        new_date = datetime.strptime(new_date_str, '%Y-%m-%d').date()
    except ValueError:
        flash('Format de date invalide.', 'danger')
        return redirect(url_for('interventions.detail', id=id))
    
    # Conserver la date originale à la première reprogrammation
    if intervention.postpone_count == 0 and intervention.scheduled_date:
        intervention.original_scheduled_date = intervention.scheduled_date
    
    intervention.scheduled_date = new_date
    intervention.postpone_count += 1
    intervention.last_postpone_reason = reason
    intervention.last_postpone_at = datetime.now(timezone.utc)
    
    # Commentaire d'historique
    comment_text = f"Report #{intervention.postpone_count}"
    if intervention.original_scheduled_date:
        comment_text += f" (date originale {intervention.original_scheduled_date.strftime('%d/%m/%Y')})"
    comment_text += f" → {new_date.strftime('%d/%m/%Y')}"
    if reason:
        comment_text += f" — {reason}"
    
    status_change = StatusChange(
        intervention_id=intervention.id,
        from_status=intervention.status,
        to_status='reportee',
        changed_by_id=current_user.id,
        comment=comment_text
    )
    db.session.add(status_change)
    db.session.commit()
    
    flash(f"Intervention reportée au {new_date.strftime('%d/%m/%Y')}.", 'success')
    return redirect(url_for('interventions.detail', id=id))
