from flask import Blueprint, jsonify, send_from_directory
from server.database import Session
from models.models import EventMedia
import os

from flask import Response, abort, session as flask_session

# Blueprint for direct file downloads by media ID
files_bp = Blueprint("files", __name__, url_prefix="/api/files")

# Reuse the same media root convention as eventmedia.py
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_ROOT = os.path.join(BASE_DIR, "media")


@files_bp.route("/<int:media_id>/<path:filename>", methods=["GET"])
def download_media_file(media_id: int, filename: str):
    """
    Download the stored media file for a given EventMedia ID.

    URL format example:
      /api/files/26/LPUV4I_Folien_Nowitzki_Bewertungskriterien.pptx

    Behavior:
      - Looks up EventMedia by ID
      - Validates requested filename against stored metadata (best-effort)
      - Serves the file from server/media using the stored relative file_path
    """
    session = Session()
    media = session.query(EventMedia).get(media_id)
    if not media:
        session.close()
        return jsonify({"error": "Not found"}), 404

    # Prefer the stored relative file_path; fall back to the URL/filename
    rel_path = media.file_path or media.url

    # Basic filename consistency check to avoid leaking other files
    # Only enforce if media.url is present
    if media.url and os.path.basename(filename) != os.path.basename(media.url):
        session.close()
        return jsonify({
            "error": "Filename mismatch",
            "expected": os.path.basename(media.url),
            "got": os.path.basename(filename),
        }), 400

    abs_path = os.path.join(MEDIA_ROOT, rel_path)

    # Ensure file exists
    if not os.path.isfile(abs_path):
        session.close()
        return jsonify({"error": "File not found on server"}), 404

    # Serve as attachment (download)
    directory = os.path.dirname(abs_path)
    served_name = os.path.basename(abs_path)
    session.close()
    return send_from_directory(directory, served_name, as_attachment=True)


@files_bp.route("/converted/<path:relpath>", methods=["GET"])
def download_converted(relpath: str):
    """Serve converted files (e.g., PDFs) relative to media/converted."""
    abs_path = os.path.join(MEDIA_ROOT, relpath)
    if not abs_path.startswith(MEDIA_ROOT):
        return jsonify({"error": "Invalid path"}), 400
    if not os.path.isfile(abs_path):
        return jsonify({"error": "File not found"}), 404
    return send_from_directory(os.path.dirname(abs_path), os.path.basename(abs_path), as_attachment=True)


@files_bp.route('/stream/<path:filename>')
def stream_file(filename: str):
    """Stream a media file via nginx X-Accel-Redirect after basic auth checks.

    The nginx config must define an internal alias for /internal_media/ that
    points to the media folder (for example: /opt/infoscreen/server/media/).
    """
    # Basic session-based auth: adapt to your project's auth logic if needed
    user_role = flask_session.get('role')
    if not user_role:
        return abort(403)

    # Normalize path to avoid directory traversal
    safe_path = os.path.normpath('/' + filename).lstrip('/')
    abs_path = os.path.join(MEDIA_ROOT, safe_path)
    if not os.path.isfile(abs_path):
        return abort(404)

    # Return X-Accel-Redirect header to let nginx serve the file efficiently
    internal_path = f'/internal_media/{safe_path}'
    resp = Response()
    resp.headers['X-Accel-Redirect'] = internal_path
    # Optional: set content-type if you want (nginx can detect it)
    return resp
