from flask import Flask, render_template, request, redirect, url_for, send_from_directory, flash
from pytube import YouTube
import os
import re # Für das Bereinigen von Dateinamen

app = Flask(__name__)
app.secret_key = 'dein_super_geheimer_schlüssel' # Wichtig für Flash-Nachrichten

DOWNLOAD_FOLDER = 'downloads'
if not os.path.exists(DOWNLOAD_FOLDER):
    os.makedirs(DOWNLOAD_FOLDER)

def sanitize_filename(filename):
    """Entfernt ungültige Zeichen aus Dateinamen."""
    return re.sub(r'[\\/*?:"<>|]', "", filename)

@app.route('/')
def index():
    try:
        # Liste nur .mp4 Dateien auf
        downloaded_files = [f for f in os.listdir(DOWNLOAD_FOLDER) if f.endswith('.mp4')]
    except FileNotFoundError:
        downloaded_files = []
    return render_template('index.html', files=downloaded_files)

@app.route('/download', methods=['POST'])
def download_video():
    video_url = request.form.get('youtube_url')
    if not video_url:
        flash('Bitte gib eine YouTube URL ein.', 'error')
        return redirect(url_for('index'))

    try:
        yt = YouTube(video_url)
        
        # Wähle den Stream mit der höchsten Auflösung, der progressiv ist (Audio+Video) und mp4 ist
        stream = yt.streams.filter(progressive=True, file_extension='mp4')\
            .order_by('resolution')\
            .desc()\
            .first()

        if not stream:
            flash(f'Kein passender MP4 Stream für {yt.title} gefunden.', 'error')
            return redirect(url_for('index'))
            
        # Bereinige den Titel für den Dateinamen
        filename = sanitize_filename(yt.title) + ".mp4"
        filepath = os.path.join(DOWNLOAD_FOLDER, filename)

        # Überprüfen, ob die Datei bereits existiert
        if os.path.exists(filepath):
            flash(f'Video "{yt.title}" wurde bereits heruntergeladen.', 'info')
            return redirect(url_for('index'))

        flash(f'Starte Download für: {yt.title}...', 'info')
        # Wichtig: Um Flask nicht zu blockieren, könnte man hier Threading/Async verwenden,
        # aber für ein "einfaches" Skript ist dies der direkteste Weg.
        # Bei langen Downloads kann der Browser einen Timeout anzeigen, obwohl der Download im Hintergrund läuft.
        stream.download(output_path=DOWNLOAD_FOLDER, filename=filename)
        flash(f'Video "{yt.title}" erfolgreich heruntergeladen!', 'success')

    except Exception as e:
        import traceback
        print("---------- ERROR DETAILS ----------")
        print(f"Error type: {type(e)}")
        print(f"Error message: {str(e)}")
        print("Traceback:")
        traceback.print_exc() # Gibt den kompletten Traceback auf der Konsole aus
        print("---------------------------------")
        flash(f'Ein Fehler ist aufgetreten: {str(e)}', 'error')
    
    return redirect(url_for('index'))
    
    return redirect(url_for('index'))

@app.route('/play/<filename>')
def play_video(filename):
    # send_from_directory ermöglicht das direkte Abspielen/Herunterladen der Datei
    return send_from_directory(DOWNLOAD_FOLDER, filename, as_attachment=False) # as_attachment=False versucht, es im Browser abzuspielen

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5555) # host='0.0.0.0' macht es im lokalen Netzwerk erreichbar