from flask import Flask, request, Response
from flask_cors import CORS
import os
import yaml
from hook.hook import hook
from hook.pubsub import pubsub
from job.unify import unify
from job.event import event
from job.ad import adRoute
from job.profile import profile
from account.user import user
from account.property import property
from account.channel import channel
from account.keyword import keyword
from account.sender import sender
from query.query import query
from offline.schema import schema
from offline.event import schema_event
from offline.data import schema_data
from feature.automation.facebook import feature_facebook
from job.batch import batch
from feature.audience.audience import feature_audience
from feature.audience.builder import feature_audience_builder
from feature.content.content import feature_content
from feature.contentV2.content import feature_content_v2
from feature.automation.automation import feature_automation
from feature.ad_integration.AdConnect import ad_connect
from feature.utm_generator.utm_generator import short_link
from feature.automationV2.automation import feature_automation_v2
from feature.execute.execute import execute
from feature.conversation_analytics.conversation_analytics import conversation_analytics
from dashboard.profile.query import dashboard_profile
from job.automation import automation_scheduled
from job.audience import audience_scheduled
from document.doc import document
import logging
from utility.authorization import TokenAuthorization as tAuth
from flasgger import Swagger, swag_from
import markdown
logging.basicConfig(level=logging.INFO)

app = Flask(__name__)

# BASE_DIR = os.path.abspath(os.path.dirname(__file__))
# MAIN_SWAGGER_FILE_PATH = os.path.join(BASE_DIR, 'swagger_docs/swagger.yml')
# with open(MAIN_SWAGGER_FILE_PATH, 'r') as f:
#     main_swagger_template = yaml.safe_load(f)


# swagger_config = {
#     "headers": [],
#     "specs": [
#         {
#             "endpoint": 'apispec_2',
#             "route": '/apispec_2.json',
#             "rule_filter": lambda rule: True,  # all in
#             "model_filter": lambda tag: True,  # all in
#         }
#     ],
#     "static_url_path": "/flasgger_static",
#     "swagger_ui": True,
#     "specs_route": "/apidocs/",
#     "template": main_swagger_template
# }
# swagger = Swagger(app, config=swagger_config)

@app.route('/docs')
def docs():
    with open('API_DOCUMENTATION.md', 'r') as f:
        content = f.read()
    html = markdown.markdown(content, extensions=['fenced_code', 'tables'])
    # Optionally wrap in a simple HTML template
    return Response(f"""
    <html>
    <head>
        <title>API Documentation</title>
        <meta charset="utf-8">
        <style>
            body {{ max-width: 900px; margin: 2em auto; font-family: Arial, sans-serif; background: #f9f9f9; color: #222; }}
            pre, code {{ background: #eee; border-radius: 4px; padding: 2px 6px; }}
            h1, h2, h3 {{ color: #2c3e50; }}
            table {{ border-collapse: collapse; width: 100%; }}
            th, td {{ border: 1px solid #ccc; padding: 6px 10px; }}
        </style>
    </head>
    <body>
    {html}
    </body>
    </html>
    """, mimetype='text/html')
app.register_blueprint(document)
app.register_blueprint(hook)
app.register_blueprint(pubsub)
app.register_blueprint(unify)
app.register_blueprint(event)
app.register_blueprint(adRoute)
app.register_blueprint(profile)
app.register_blueprint(user)
app.register_blueprint(property)
app.register_blueprint(channel)
app.register_blueprint(query)
app.register_blueprint(schema)
app.register_blueprint(schema_event)
app.register_blueprint(schema_data)
app.register_blueprint(feature_facebook)
app.register_blueprint(keyword)
app.register_blueprint(batch)
app.register_blueprint(feature_audience)
app.register_blueprint(feature_content)
app.register_blueprint(feature_content_v2)
app.register_blueprint(feature_automation)
app.register_blueprint(feature_audience_builder)
app.register_blueprint(ad_connect)
app.register_blueprint(dashboard_profile)
app.register_blueprint(short_link)
app.register_blueprint(execute)
app.register_blueprint(automation_scheduled)
app.register_blueprint(feature_automation_v2)
app.register_blueprint(conversation_analytics)
app.register_blueprint(audience_scheduled)
app.register_blueprint(sender)

# Add a simple test endpoint
@app.route('/test', methods=['GET'])
def test_endpoint():
    return {'status': 'ok', 'message': 'Test endpoint working'}, 200

CORS(app,
     resources={r"/*": {"origins": "*"}},
     supports_credentials=True,
     allow_headers=["Content-Type", "Authorization"],
     methods=['POST', 'PUT', 'DELETE', 'GET', 'OPTIONS']
)

@app.before_request
def check_auth():
    bypass_paths = ['/user/login', '/user/register', '/user/validate', '/hook/facebook', '/hook/line',
                    '/profile', '/facebook-ad/event', '/event/facebook',
                    '/unify/facebook/event/raw', '/unify/line/event/raw/', '/unify/facebook/unify', "/unify/allchannel/unify",
                    '/unify/real-time/event', '/schema', '/schema/event',
                    "/pubsub", "/pubsub/gotmessage", '/apispec_2.json', '/apispec_2', '/test', '/docs', '/document', 
                    '/keyword','/keyword/message_labeling',
                    '/feature/audience/preset/recalculate', '/automation/scheduled','/feature/facebook', 
                    '/feature/automation/v2/trigger-manager', '/feature/automation/v2/trigger-waiting', '/audience/scheduled/calculate']
    
    # Debug logging
    logging.info(f"Request path: {request.path}")
    logging.info(f"Request method: {request.method}")
    
    if request.path in bypass_paths:
        logging.info(f"Bypassing auth for path: {request.path}")
        return
    if request.path.startswith("/hook/line"):
        return
    if request.path.startswith("/flasgger_static"):
        return
    if request.path.startswith("/apidocs"):
        return
    if request.path.startswith("/swagger"):
        return
    if request.path.startswith("/favicon.ico"):
        return
    if request.path.startswith("/unify"):
        return
    if request.path.startswith("/feature/facebook"):
        return
    if request.path.startswith("/batch"):
        return
    if request.path.startswith("/event/webhook"):
        return
    if request.path.startswith("/automation/scheduled"):
        return
    if request.path.startswith("/keyword/message_labeling"):
        return
    if request.method in ['POST', 'PUT', 'DELETE', 'GET', 'OPTIONS']:
        logging.info(request.headers.get('Authorization'))
        local_key = request.headers.get('Authorization')
        
        # Check if Authorization header exists
        if not local_key:
            logging.warning("No Authorization header provided")
            return {'status': "error", 'error': 'Authorization header required'}, 401
            
        bearer = local_key.replace("Bearer ", "")
        auth = tAuth(access_token=bearer)

        #Check auth
        validate = auth.validate()
        if not validate:
            # if not local_key or local_key != "Bearer " + LOCAL_API_KEY:
            logging.warning(f"Unauthorized access attempt with key: {bearer}")
            return {'status': "error", 'error': 'Unauthorized'}, 401
    else:
        return {'status': "error", 'error': 'Not support this method'}, 415

@app.errorhandler(404)
def not_found(e):
    return {'status': 'error', 'message': 'Not found'}, 404

if __name__ == '__main__':
    print("Starting Flask app...")
    print(f"Swagger UI available at: http://localhost:{os.environ.get('PORT', 8080)}/apidocs/")
    print(f"API spec available at: http://localhost:{os.environ.get('PORT', 8080)}/apispec_2.json")
    app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))