import os
import uuid
import tempfile
from flask import Flask, request, jsonify, send_file
from flask_cors import CORS
from werkzeug.utils import secure_filename
from pymongo import MongoClient
from datetime import datetime
from bson.objectid import ObjectId
import json
from dotenv import load_dotenv
from processing import process_video

# Load environment variables
load_dotenv()

app = Flask(__name__)
CORS(app)

# MongoDB configuration
MONGO_URI = os.getenv('MONGO_URI', 'mongodb+srv://human:kY5ORJCzW0unboME@cluster0.8cnqn.mongodb.net/VIDEO-AI')
client = MongoClient(MONGO_URI)
db = client.get_database()
documents_collection = db.documents

# Configure upload folder
UPLOAD_FOLDER = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'uploads')
DOCUMENT_FOLDER = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'documents')
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
os.makedirs(DOCUMENT_FOLDER, exist_ok=True)

# Allowed file extensions
ALLOWED_EXTENSIONS = {'mp4'}

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/api/upload', methods=['POST'])
def upload_file():
    if 'file' not in request.files:
        return jsonify({'error': 'No file part'}), 400
    
    file = request.files['file']
    
    if file.filename == '':
        return jsonify({'error': 'No selected file'}), 400
    
    if not allowed_file(file.filename):
        return jsonify({'error': 'File type not allowed'}), 400
    
    # Generate a unique filename
    filename = secure_filename(file.filename)
    unique_filename = f"{uuid.uuid4()}_{filename}"
    file_path = os.path.join(UPLOAD_FOLDER, unique_filename)
    
    # Save the file
    file.save(file_path)
    
    # Create document record in database
    document_id = documents_collection.insert_one({
        'original_filename': filename,
        'stored_filename': unique_filename,
        'upload_date': datetime.now(),
        'status': 'uploaded',
        'file_path': file_path
    }).inserted_id
    
    # Return the document ID to the client
    return jsonify({
        'message': 'File uploaded successfully',
        'document_id': str(document_id)
    }), 201

@app.route('/api/process/<document_id>', methods=['POST'])
def process_document(document_id):
    # Find the document in MongoDB
    document = documents_collection.find_one({'_id': ObjectId(document_id)})
    
    if not document:
        return jsonify({'error': 'Document not found'}), 404
    
    # Update status
    documents_collection.update_one(
        {'_id': ObjectId(document_id)},
        {'$set': {'status': 'processing'}}
    )
    
    try:
        # Process the video
        result = process_video(document['file_path'])
        
        # Update document with generated files
        documents_collection.update_one(
            {'_id': ObjectId(document_id)},
            {'$set': {
                'status': 'completed',
                'transcription_path': result['transcription_path'],
                'summary_path': result['summary_path'],
                'summary_clean_path': result['summary_clean_path'],
                'verbale_path': result['verbale_path'],
                'docx_path': result['docx_path'],
                'docx_verbale_path': result['docx_verbale_path'],
                'completion_date': datetime.now()
            }}
        )
        
        return jsonify({
            'message': 'Document processed successfully',
            'document_id': document_id
        }), 200
    except Exception as e:
        # Update status to failed
        documents_collection.update_one(
            {'_id': ObjectId(document_id)},
            {'$set': {
                'status': 'failed',
                'error': str(e)
            }}
        )
        
        return jsonify({
            'error': f'Processing failed: {str(e)}'
        }), 500

@app.route('/api/documents', methods=['GET'])
def get_documents():
    documents = list(documents_collection.find({}, {
        'original_filename': 1,
        'upload_date': 1,
        'status': 1,
        'completion_date': 1
    }))
    
    # Convert ObjectId to string
    for doc in documents:
        doc['_id'] = str(doc['_id'])
        if 'upload_date' in doc:
            doc['upload_date'] = doc['upload_date'].isoformat()
        if 'completion_date' in doc:
            doc['completion_date'] = doc['completion_date'].isoformat()
    
    return jsonify(documents), 200

@app.route('/api/documents/<document_id>', methods=['GET'])
def get_document(document_id):
    document = documents_collection.find_one({'_id': ObjectId(document_id)})
    
    if not document:
        return jsonify({'error': 'Document not found'}), 404
    
    # Convert ObjectId to string
    document['_id'] = str(document['_id'])
    if 'upload_date' in document:
        document['upload_date'] = document['upload_date'].isoformat()
    if 'completion_date' in document:
        document['completion_date'] = document['completion_date'].isoformat()
    
    return jsonify(document), 200

@app.route('/api/download/<document_id>/<file_type>', methods=['GET'])
def download_file(document_id, file_type):
    document = documents_collection.find_one({'_id': ObjectId(document_id)})
    
    if not document:
        return jsonify({'error': 'Document not found'}), 404
    
    file_type_mapping = {
        'docx': 'docx_path',
        'verbale_docx': 'docx_verbale_path',
        'summary': 'summary_path',
        'summary_clean': 'summary_clean_path',
        'verbale': 'verbale_path',
        'transcription': 'transcription_path'
    }
    
    if file_type not in file_type_mapping:
        return jsonify({'error': 'Invalid file type'}), 400
    
    file_path_key = file_type_mapping[file_type]
    
    if file_path_key not in document or not document[file_path_key]:
        return jsonify({'error': f'{file_type} not available for this document'}), 404
    
    file_path = document[file_path_key]
    
    try:
        return send_file(file_path, as_attachment=True)
    except Exception as e:
        return jsonify({'error': f'Error downloading file: {str(e)}'}), 500

if __name__ == '__main__':
    app.run(debug=True, port=5000)