from flask import Flask, request, send_file, jsonify, render_template_string, send_from_directory
from flask_cors import CORS
import os
import cv2
import numpy as np
import json
import tempfile
from moviepy import VideoFileClip, ImageClip, CompositeVideoClip
import logging

app = Flask(__name__)
CORS(app)  # Enable CORS for all routes

# Configure logging
logging.basicConfig(level=logging.DEBUG)

# Load green area coordinates
with open('green_areas.json', 'r') as f:
    GREEN_AREAS = json.load(f)

UPLOAD_FOLDER = 'uploads'
os.makedirs(UPLOAD_FOLDER, exist_ok=True)

# Route to serve the main HTML page
@app.route('/')
def index():
    # Read the HTML file and serve it
    with open('billboard_app.html', 'r', encoding='utf-8') as f:
        html_content = f.read()
    return html_content

# Route to serve static files (videos, JSON, etc.)
@app.route('/<path:filename>')
def serve_static(filename):
    return send_from_directory('.', filename)

@app.route('/process', methods=['POST'])
def process_video():
    template = request.form.get('template')
    if template not in GREEN_AREAS:
        return jsonify({'error': 'Invalid template'}), 400
    if 'media' not in request.files:
        return jsonify({'error': 'No media uploaded'}), 400
    media_file = request.files['media']
    media_path = os.path.join(UPLOAD_FOLDER, media_file.filename)
    media_file.save(media_path)

    # Process video
    template_path = template
    green_areas = GREEN_AREAS[template]
    output_path = os.path.join(tempfile.gettempdir(), 'output.mp4')

    # Use moviepy for compositing
    clip = VideoFileClip(template_path)
    if media_file.filename.lower().endswith(('.png', '.jpg', '.jpeg')):
        overlay = ImageClip(media_path).with_duration(clip.duration)
    else:
        overlay = VideoFileClip(media_path).resized((green_areas[0]['w'], green_areas[0]['h']))
        
        # Handle duration mismatch - use the shorter duration to avoid errors
        min_duration = min(overlay.duration, clip.duration)
        
        # Crop both videos to the minimum duration
        clip = clip.subclipped(0, min_duration)
        overlay = overlay.subclipped(0, min_duration)
        
        logging.info(f"Template duration: {VideoFileClip(template_path).duration:.2f}s")
        logging.info(f"Overlay duration: {VideoFileClip(media_path).duration:.2f}s") 
        logging.info(f"Using minimum duration: {min_duration:.2f}s")

    # Place overlay at green area coordinates (use first detected area)
    x, y, w, h = green_areas[0]['x'], green_areas[0]['y'], green_areas[0]['w'], green_areas[0]['h']
    overlay = overlay.with_position((x, y))
    final = CompositeVideoClip([clip, overlay])
    final.write_videofile(output_path, codec='libx264', audio_codec='aac')

    return send_file(output_path, as_attachment=True, download_name='billboard_result.mp4')

@app.errorhandler(Exception)
def handle_exception(e):
    import traceback
    print(traceback.format_exc())
    return jsonify({'error': str(e)}), 500

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80, debug=True)
