"""Plugin introspection + enable/disable API."""

from flask import Blueprint, current_app, request
from flask_jwt_extended import jwt_required

from shopdb.utils.responses import success_response, error_response, ErrorCodes

from shopdb.utils.authz import require_role

plugins_bp = Blueprint('plugins', __name__)


@plugins_bp.route('', methods=['GET'])
@jwt_required(optional=True)
def list_plugins():
    """List all discovered plugins (enabled or not) with their metadata and
    the framework contract version."""
    from shopdb import __contract_version__
    pm = current_app.extensions.get('plugin_manager')
    plugins = pm.discover_available() if pm else []
    plugins.sort(key=lambda p: p['name'])
    return success_response({
        'contract_version': __contract_version__,
        'count': len(plugins),
        'plugins': plugins,
    })


@plugins_bp.route('/enabled', methods=['GET'])
@jwt_required(optional=True)
def list_enabled_plugins():
    """Return just the names of enabled plugins as a flat array.

    Cheap registry read (no DB). Exposed to anonymous callers on purpose:
    the navigation endpoint already leaks the same enabled/disabled signal,
    and the frontend needs it (including unauthenticated kiosk routes like
    /tv) to gate plugin-owned routes. No metadata beyond the names.
    """
    pm = current_app.extensions.get('plugin_manager')
    names = pm.registry.get_enabled_plugins() if pm else []
    return success_response(sorted(names))


@plugins_bp.route('/<name>', methods=['PUT'])
@jwt_required()
@require_role('admin')
def set_plugin_enabled(name: str):
    """Enable or disable a plugin. Takes effect on the next app restart for
    route/navigation changes."""
    data = request.get_json() or {}
    if 'enabled' not in data:
        return error_response(ErrorCodes.VALIDATION_ERROR, 'enabled is required')

    pm = current_app.extensions.get('plugin_manager')
    if not pm:
        return error_response(ErrorCodes.INTERNAL_ERROR,
                              'Plugin manager unavailable', http_code=500)

    want = bool(data['enabled'])
    ok = pm.enable_plugin(name) if want else pm.disable_plugin(name)
    if not ok:
        # enable/disable refused (unknown plugin, or a dependency conflict)
        return error_response(
            ErrorCodes.CONFLICT,
            f"Could not {'enable' if want else 'disable'} '{name}' "
            f"(check it exists and dependencies allow it)",
            http_code=409
        )

    return success_response(
        {'name': name, 'enabled': want},
        message=f"Plugin {'enabled' if want else 'disabled'} "
                f"(restart to apply route changes)"
    )
