from flask import render_template, jsonify, request, send_from_directory, current_app
import logging
import os
from sqlalchemy.exc import SQLAlchemyError, OperationalError, IntegrityError

logger = logging.getLogger(__name__)

def register_error_handlers(app):
    @app.errorhandler(400)
    def handle_400_error(e):
        logger.error(f'400 error: {str(e)}')
        if request.path.startswith('/calculate'):
            return jsonify({'error': 'Invalid request parameters'}), 400
        return render_template('errors/400.html'), 400
    
    @app.errorhandler(403)
    def handle_403_error(e):
        logger.error(f'403 error: {str(e)}')
        if request.path.startswith('/calculate'):
            return jsonify({'error': 'Access forbidden'}), 403
        return render_template('errors/403.html'), 403
    
    @app.errorhandler(404)
    def handle_404_error(e):
        logger.error(f'404 error: {str(e)}')
        if request.path.startswith('/calculate'):
            return jsonify({'error': 'Resource not found'}), 404
        if request.path.startswith('/static/'):
            app.logger.warning(f'Static file not found: {request.path}')
            return '', 404
        return render_template('errors/404.html'), 404
    
    @app.errorhandler(500)
    def handle_500_error(e):
        logger.error(f'500 error: {str(e)}')
        app.logger.error(f'Server error: {str(e)}')
        if request.path.startswith('/calculate'):
            return jsonify({'error': 'Internal server error'}), 500
        if request.path.startswith('/static/'):
            app.logger.error(f'Error serving static file {request.path}: {str(e)}')
            return '', 404
        return render_template('errors/500.html'), 500
    
    @app.errorhandler(OperationalError)
    def handle_db_operational_error(error):
        logger.error(f'Database operational error: {str(error)}', exc_info=True)
        if request.path.startswith('/api/'):
            return jsonify({
                'error': 'Database connection error',
                'message': 'Unable to connect to the database. Please try again later.'
            }), 503
        return render_template('errors/503.html', 
                             message='Database connection error. Please try again later.'), 503

    @app.errorhandler(IntegrityError)
    def handle_db_integrity_error(error):
        logger.error(f'Database integrity error: {str(error)}', exc_info=True)
        if request.path.startswith('/api/'):
            return jsonify({
                'error': 'Database integrity error',
                'message': 'The operation could not be completed due to data constraints.'
            }), 409
        return render_template('errors/409.html', 
                             message='The operation could not be completed due to data constraints.'), 409

    @app.errorhandler(SQLAlchemyError)
    def handle_db_error(error):
        logger.error(f'Database error: {str(error)}', exc_info=True)
        if request.path.startswith('/api/'):
            return jsonify({
                'error': 'Database error',
                'message': 'An unexpected database error occurred.'
            }), 500
        return render_template('errors/500.html', 
                             message='An unexpected database error occurred.'), 500

    @app.errorhandler(Exception)
    def handle_unhandled_exception(e):
        logger.error(f'Unhandled exception: {str(e)}', exc_info=True)
        app.logger.error(f'Unhandled exception: {str(e)}', exc_info=True)
        if request.path.startswith('/calculate'):
            return jsonify({'error': 'Internal server error'}), 500
        if request.path.startswith('/static/'):
            app.logger.error(f'Error serving static file {request.path}: {str(e)}')
            return '', 404
        return render_template('errors/500.html'), 500 