import logging
import os
import uuid
from flask import Flask, render_template, Response, request, session
from main import yoink, process, user_streams, stream_lock

app = Flask(__name__, static_folder="website/static", template_folder="website")
app.secret_key = os.urandom(24)  # Necessary for using sessions

# Configure logging
logging.basicConfig(
    filename='./logs/app.log',
    level=logging.DEBUG,
    format='%(asctime)s %(levelname)s: %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S'
)

def create_session():
    """
    Create a new session by generating a UUID and ensuring it does not collide 
    with an existing session in the user_streams global dictionary.
    
    Returns:
        str: A unique session ID.
    """
    session_id = str(uuid.uuid4())
    # Even though collisions are unlikely, we check for safety.
    try:
        if user_streams[session_id]:
            session_id = create_session()
    except KeyError:
        pass
    return session_id

@app.route('/')
def home():
    """
    Render the home page and initialize a session.
    
    Returns:
        Response: The rendered home page with a unique session id.
    """
    session_id = create_session()
    session['id'] = session_id
    logging.info(f"Home page accessed. Assigned initial session ID: {session_id}")
    return render_template('index.html', session_id=session_id)

@app.route('/process_url', methods=['POST'])
def process_url():
    """
    Accept a YouTube URL (from a form submission), initialize the session if necessary, 
    and trigger the transcript retrieval and AI processing.
    
    Returns:
        Response: Text response indicating start or error message.
    """
    session_id = session.get('id')
    if not session_id:
        session_id = create_session()
        session['id'] = session_id
        logging.info(f"No existing session. Created new session ID: {session_id}")
    url = request.form['url']
    logging.info(f"Received URL for processing from session {session_id}: {url}")
    success, msg, status_code = process(url, session_id)
    if success:
        logging.info(f"Processing started successfully for session {session_id}.")
        return Response("Processing started. Check /stream_output for updates.", content_type='text/plain', status=200)
    else:
        logging.error(f"Processing failed for session {session_id}: {msg}")
        return Response(msg, content_type='text/plain', status=status_code)

@app.route('/stream_output')
def stream_output():
    """
    Stream the AI processing output for the current session.
    
    Returns:
        Response: A streaming response with text/plain content.
    """
    session_id = session.get('id')
    if not session_id or session_id not in user_streams:
        logging.warning(f"Stream requested without a valid session ID: {session_id}")
        return Response("No active stream for this session.", content_type='text/plain', status=400)
    logging.info(f"Streaming output requested for session {session_id}.")
    return Response(yoink(session_id), content_type='text/plain', status=200)

if __name__ == '__main__':
    logging.info("Starting Flask application.")
    # Running with threaded=True to handle multiple requests concurrently.
    app.run(debug=True, threaded=True)