"""
API REST v1 - GMAO Collège
Endpoints publics avec authentification par clé API.
"""
from flask import Blueprint, request, jsonify, current_app
from flask_login import login_required, current_user
from functools import wraps
from werkzeug.security import check_password_hash
from app_new.extensions import db

api_bp = Blueprint('api_v1', __name__, url_prefix='/api/v1')


def api_key_required(permission=None):
    """Authentification par clé API (header X-API-Key) ou session login."""
    def decorator(f):
      @wraps(f)
      def decorated(*args, **kwargs):
        # Accepter soit un header X-API-Key, soit une session Flask-Login
        api_key = request.headers.get('X-API-Key')
        if api_key:
            from app_new.core.models.settings import AppSettings
            api_key_hash = AppSettings.get('api_key_hash')
            if api_key_hash and check_password_hash(api_key_hash, api_key):
                # La clé historique reste une clé de service à accès complet.
                return f(*args, **kwargs)
            return jsonify({'error': 'Clé API invalide'}), 401
        # Sinon, fallback sur session login
        if not current_user.is_authenticated:
            return jsonify({'error': 'Authentification requise (X-API-Key ou login)'}), 401
        from app_new.core.authorization import has_permission
        if permission and not has_permission(permission, current_user):
            return jsonify({'error': 'Permission insuffisante', 'permission': permission}), 403
        return f(*args, **kwargs)
      return decorated
    return decorator


@api_bp.route('/status')
@api_key_required('dashboard.view')
def status():
    """État global du système."""
    from app_new.core.models.maintenance import Intervention
    from app_new.core.models.equipment import Equipment
    from app_new.core.models.college import Room, Building
    
    return jsonify({
        'interventions_total': Intervention.query.count(),
        'interventions_en_cours': Intervention.query.filter_by(status='en_cours').count(),
        'interventions_en_attente': Intervention.query.filter_by(status='en_attente').count(),
        'equipments_total': Equipment.query.count(),
        'equipments_panne': Equipment.query.filter(Equipment.status.in_(['en_panne', 'hors_service', 'hs'])).count(),
        'rooms_total': Room.query.count(),
        'buildings_total': Building.query.count(),
    })


@api_bp.route('/interventions')
@api_key_required('intervention.view')
def list_interventions():
    """Liste des interventions avec pagination."""
    from app_new.core.models.maintenance import Intervention
    
    page = max(request.args.get('page', 1, type=int) or 1, 1)
    per_page = min(max(request.args.get('per_page', 20, type=int) or 20, 1), 100)
    status = request.args.get('status')
    
    query = Intervention.query
    if status:
        query = query.filter_by(status=status)
    
    total = query.count()
    items = query.order_by(Intervention.created_at.desc())\
                 .offset((page - 1) * per_page)\
                 .limit(per_page).all()
    
    return jsonify({
        'total': total,
        'page': page,
        'per_page': per_page,
        'items': [{
            'id': i.id,
            'title': i.title,
            'description': (i.description or '')[:200],
            'type': i.type,
            'status': i.status,
            'priority': i.priority,
            'created_at': i.created_at.isoformat() if i.created_at else None,
            'equipment_id': i.equipment_id,
            'room_id': i.room_id,
        } for i in items]
    })


@api_bp.route('/interventions/<int:intervention_id>')
@api_key_required('intervention.view')
def get_intervention(intervention_id):
    """Détail d'une intervention."""
    from app_new.core.models.maintenance import Intervention
    
    intervention = Intervention.query.get_or_404(intervention_id)
    return jsonify({
        'id': intervention.id,
        'title': intervention.title,
        'description': intervention.description,
        'type': intervention.type,
        'status': intervention.status,
        'priority': intervention.priority,
        'created_at': intervention.created_at.isoformat() if intervention.created_at else None,
        'started_at': intervention.started_at.isoformat() if intervention.started_at else None,
        'completed_at': intervention.completed_at.isoformat() if intervention.completed_at else None,
        'equipment_id': intervention.equipment_id,
        'room_id': intervention.room_id,
        'company_id': intervention.company_id,
        'assigned_to_id': intervention.assigned_to_id,
    })


@api_bp.route('/equipments')
@api_key_required('patrimoine.view')
def list_equipments():
    """Liste des équipements avec pagination."""
    from app_new.core.models.equipment import Equipment
    
    page = max(request.args.get('page', 1, type=int) or 1, 1)
    per_page = min(max(request.args.get('per_page', 20, type=int) or 20, 1), 100)
    status = request.args.get('status')
    
    query = Equipment.query
    if status:
        query = query.filter_by(status=status)
    
    total = query.count()
    items = query.order_by(Equipment.name)\
                 .offset((page - 1) * per_page)\
                 .limit(per_page).all()
    
    return jsonify({
        'total': total,
        'page': page,
        'per_page': per_page,
        'items': [{
            'id': e.id,
            'name': e.name,
            'status': e.status,
            'category_id': e.category_id,
            'room_id': e.room_id,
        } for e in items]
    })


@api_bp.route('/equipments/<int:equipment_id>')
@api_key_required('patrimoine.view')
def get_equipment(equipment_id):
    """Détail d'un équipement."""
    from app_new.core.models.equipment import Equipment
    
    equipment = Equipment.query.get_or_404(equipment_id)
    return jsonify({
        'id': equipment.id,
        'name': equipment.name,
        'status': equipment.status,
        'serial_number': getattr(equipment, 'serial_number', None),
        'category_id': equipment.category_id,
        'room_id': equipment.room_id,
        'description': getattr(equipment, 'description', None),
    })
