from fastapi import FastAPI, Request, UploadFile, File, APIRouter
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
import uvicorn
import requests
import os
from pathlib import Path
import uuid

app = FastAPI(title="Video Analysis UI")

# Setup directories
BASE_DIR = Path(__file__).resolve().parent.parent
RESULTS_DIR = BASE_DIR / "results"
RESULTS_DIR.mkdir(exist_ok=True)

# Define the subpath prefix
PREFIX = "/analyze"

# Create a router to handle all /analyze requests
router = APIRouter(prefix=PREFIX)

# Worker URL (Docker service name)
WORKER_URL = os.getenv("WORKER_URL", "<http://worker:8000/process>")

HTML_CONTENT = f"""
<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Skate Ollie Analyse</title>
    <style>
        :root {{
            --bg: #121212;
            --surface: #1e1e1e;
            --primary: #bb86fc;
            --text: #e0e0e0;
        }}
        body {{
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: var(--bg);
            color: var(--text);
            margin: 0;
            display: flex;
            flex-direction: column;
            align-items: center;
            min-height: 100vh;
        }}
        .container {{
            width: 90%;
            max-width: 900px;
            margin-top: 40px;
        }}
        h1 {{ color: var(--primary); text-align: center; }}
        .upload-card {{
            background: var(--surface);
            padding: 30px;
            border-radius: 12px;
            box-shadow: 0 4px 20px rgba(0,0,0,0.5);
            text-align: center;
            margin-bottom: 30px;
        }}
        input[type="file"] {{ margin: 20px 0; }}
        button {{
            background-color: var(--primary);
            color: #000;
            border: none;
            padding: 12px 24px;
            border-radius: 6px;
            font-weight: bold;
            cursor: pointer;
            transition: opacity 0.2s;
        }}
        button:disabled {{ opacity: 0.5; cursor: not-allowed; }}
        #status {{ margin-top: 20px; font-style: italic; }}
        .result-container {{
            display: none;
            width: 100%;
        }}
        video {{
            width: 100%;
            border-radius: 12px;
            box-shadow: 0 8px 30px rgba(0,0,0,0.6);
        }}
        .loading-spinner {{
            border: 4px solid rgba(255, 255, 255, 0.1);
            border-left-color: var(--primary);
            border-radius: 50%;
            width: 30px;
            height: 30px;
            animation: spin 1s linear infinite;
            display: none;
            margin: 20px auto;
        }}
        @keyframes spin {{ to {{ transform: rotate(360deg); }} }}
    </style>
</head>
<body>
    <div class="container">
        <h1>Skate Ollie Analyse</h1>
        
        <div class="upload-card">
            <p>Wähle ein Video deines Ollies aus zur Analyse.</p>
            <input type="file" id="videoInput" accept="video/*">
            <br>
            <button id="uploadBtn">Analyse starten</button>
            <div class="loading-spinner" id="spinner"></div>
            <p id="status"></p>
        </div>

        <div class="result-container" id="resultContainer">
            <h2>Deine Analyse:</h2>
            <video id="videoPlayer" controls autoplay loop playsinline>
                <source id="videoSource" src="" type="video/mp4">
                Ihr Browser unterstützt das Video-Tag nicht.
            </video>
        </div>
    </div>

    <script>
        const uploadBtn = document.getElementById('uploadBtn');
        const videoInput = document.getElementById('videoInput');
        const status = document.getElementById('status');
        const spinner = document.getElementById('spinner');
        const resultContainer = document.getElementById('resultContainer');
        const videoPlayer = document.getElementById('videoPlayer');
        const videoSource = document.getElementById('videoSource');

        uploadBtn.addEventListener('click', async () => {{
            const file = videoInput.files[0];
            if (!file) {{
                alert('Bitte wähle ein Video aus.');
                return;
            }}

            const formData = new FormData();
            formData.append('file', file);

            // UI Update
            uploadBtn.disabled = true;
            spinner.style.display = 'block';
            status.innerText = 'Verarbeitung läuft... Das kann bis zu 1 Minute dauern.';
            resultContainer.style.display = 'none';

            try {{
                const response = await fetch('{PREFIX}/upload', {{
                    method: 'POST',
                    body: formData
                }});

                const data = await response.json();

                if (response.ok) {{
                    status.innerText = 'Fertig!';
                    videoSource.src = data.video_url + '?t=' + Date.now();
                    videoPlayer.load();
                    resultContainer.style.display = 'block';
                }} else {{
                    status.innerText = 'Fehler: ' + (data.error || 'Unbekannt');
                }}
            }} catch (err) {{
                status.innerText = 'Verbindungsfehler: ' + err.message;
            }} finally {{
                uploadBtn.disabled = false;
                spinner.style.display = 'none';
            }}
        }});
    </script>
</body>
</html>
"""

@router.get("/", response_class=HTMLResponse)
async def index():
    return HTML_CONTENT

@router.post("/upload")
async def upload_video(file: UploadFile = File(...)):
    job_id = str(uuid.uuid4())
    
    # Forward to Worker
    try:
        files = {"file": (file.filename, file.file, file.content_type)}
        worker_response = requests.post(
            WORKER_URL, 
            files=files,
            timeout=300 # 5 minutes max
        )
    except Exception as e:
        return JSONResponse(status_code=500, content={"error": f"Worker unreachable: {str(e)}"})

    if worker_response.status_code != 200:
        return JSONResponse(
            status_code=500,
            content={"error": "Worker failed", "details": worker_response.text},
        )

    # Save result
    output_path = RESULTS_DIR / f"{job_id}.mp4"
    output_path.write_bytes(worker_response.content)

    return {
        "job_id": job_id,
        "video_url": f"{PREFIX}/results/{job_id}.mp4"
    }

# Mount results for static access 
app.mount(f"{PREFIX}/results", StaticFiles(directory=str(RESULTS_DIR)), name="results")

# Include the router
app.include_router(router)

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8080)