from flask import request
from watchup_py.client import WatchupClient

class WatchupMiddleware:
    def __init__(self, app, client: WatchupClient):
        self.app = app
        self.client = client
        self.register_hooks()

    def register_hooks(self):
        @self.app.before_request
        def start_timer():
            # Try to get the rule name (e.g. /user/<id>)
            # If not available yet, fallback to endpoint or path
            route = "unknown"
            if request.url_rule:
                route = request.url_rule.rule
            elif request.endpoint:
                route = request.endpoint
            else:
                route = request.path
                
            tx_name = f"{request.method} {route}"
            tx = self.client.start_transaction(tx_name)
            request._watchup_tx = tx

        @self.app.teardown_request
        def teardown_request(exception=None):
            tx = getattr(request, "_watchup_tx", None)
            if tx:
                tx.finish()
                self.client.capture_transaction(tx)
            return

        @self.app.errorhandler(Exception)
        def handle_exception(e):
            # Capture the exception
            context = {
                "url": request.url,
                "userAgent": request.headers.get("User-Agent", ""),
            }
            self.client.capture_exception(e, context)
            
            # Since we want to be a transparent middleware, we 
            # shouldn't necessarily return a custom JSON if the user 
            # hasn't configured it. But for now we'll stick to a generic error.
            # Reraising would be better but Flask might not call teardown properly 
            # if we just raise here without a response.
            return {"error": "Internal server error", "message": str(e)}, 500

# For backward compatibility
WatchupErrorMiddleware = WatchupMiddleware
