"""Gradio-Jupyter deployment template for Modal.

This template provides Gradio deployment with Jupyter Lab integration.
"""

TEMPLATE = '''# 🚀 Modal Deployment Script (Gradio + Jupyter Configuration)
# Generated by modal-for-noobs - https://github.com/arthrod/modal-for-noobs
# Deployment Mode: gradio-jupyter
# Features: Gradio app with Jupyter Lab, dashboard, and logging
# Timeout: {timeout_seconds}s | Scaledown: {scaledown_window}s

import modal
import sys
import os
import subprocess
import asyncio
from pathlib import Path
from datetime import datetime
from fastapi import FastAPI
from fastapi.responses import RedirectResponse
import gradio as gr
from gradio.routes import mount_gradio_app
from loguru import logger

# Import dashboard components
sys.path.append(str(Path(__file__).parent))
from dashboard import create_dashboard_interface, create_dashboard_api, dashboard_state, DeploymentInfo

# 🎯 Create Modal App
app = modal.App("{app_name}")

# 🐳 Container Image Configuration (Gradio + Jupyter)
{image_config}

# 📦 Original Application Code
{original_code}

# 🔧 Jupyter Configuration
JUPYTER_CONFIG = """
c.ServerApp.allow_origin = '*'
c.ServerApp.allow_remote_access = True
c.ServerApp.ip = '0.0.0.0'
c.ServerApp.port = 8888
c.ServerApp.token = ''
c.ServerApp.password = ''
c.ServerApp.disable_check_xsrf = True
c.ServerApp.allow_root = True
c.ServerApp.root_dir = '/workspace'
"""

async def start_jupyter_server():
    """Start Jupyter Lab server in the background."""
    # Create workspace directory
    workspace_dir = Path("/workspace")
    workspace_dir.mkdir(exist_ok=True)

    # Write Jupyter config
    jupyter_config_dir = Path.home() / ".jupyter"
    jupyter_config_dir.mkdir(exist_ok=True)

    config_path = jupyter_config_dir / "jupyter_lab_config.py"
    config_path.write_text(JUPYTER_CONFIG)

    # Create a sample notebook
    sample_notebook = workspace_dir / "welcome.ipynb"
    if not sample_notebook.exists():
        notebook_content = {{
            "cells": [
                {{
                    "cell_type": "markdown",
                    "metadata": {{}},
                    "source": [
                        "# Welcome to Modal Jupyter Lab\\n",
                        "\\n",
                        "This Jupyter Lab instance is running alongside your Gradio app on Modal.\\n",
                        "\\n",
                        "You can use this environment for:\\n",
                        "- Interactive data analysis\\n",
                        "- Testing and debugging\\n",
                        "- Exploring your deployment\\n",
                        "\\n",
                        "Your Gradio app is available at the root URL."
                    ]
                }},
                {{
                    "cell_type": "code",
                    "execution_count": null,
                    "metadata": {{}},
                    "outputs": [],
                    "source": [
                        "import sys\\n",
                        "print(f'Python {{sys.version}}')\\n",
                        "print(f'Working directory: {{os.getcwd()}}')\\n",
                        "\\n",
                        "# List installed packages\\n",
                        "!pip list | head -20"
                    ]
                }}
            ],
            "metadata": {{
                "kernelspec": {{
                    "display_name": "Python 3",
                    "language": "python",
                    "name": "python3"
                }}
            }},
            "nbformat": 4,
            "nbformat_minor": 5
        }}

        import json
        sample_notebook.write_text(json.dumps(notebook_content, indent=2))

    # Start Jupyter Lab
    logger.info("Starting Jupyter Lab server on port 8888")
    process = await asyncio.create_subprocess_exec(
        "jupyter", "lab",
        "--config", str(config_path),
        "--no-browser",
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE
    )

    # Give it time to start
    await asyncio.sleep(3)
    logger.info("Jupyter Lab server started")

    return process

# ⚡ Modal Function Configuration
@app.function(
    image=image,
    gpu="any",  # GPU support for notebooks
    min_containers=1,
    max_containers=1,
    timeout={timeout_seconds},
    scaledown_window={scaledown_window},
    memory=16384,  # 16GB RAM
)
@modal.concurrent(max_inputs=100)
@modal.asgi_app()
def deploy_gradio():
    """Deploy Gradio app with Jupyter Lab and dashboard on Modal."""

    # Initialize deployment info
    deployment_info = DeploymentInfo(
        app_name="{app_name}",
        deployment_mode="gradio-jupyter",
        deployment_time=datetime.now().isoformat(),
        modal_version=modal.__version__,
        python_version=f"{{sys.version_info.major}}.{{sys.version_info.minor}}.{{sys.version_info.micro}}",
        gpu_enabled=True,
        timeout_seconds={timeout_seconds},
        max_containers=1,
        environment={{
            **{{k: v for k, v in os.environ.items() if k.startswith("MODAL_")}},
            "JUPYTER_ENABLED": "true",
            "JUPYTER_PORT": "8888",
        }}
    )
    dashboard_state.set_deployment_info(deployment_info)

    logger.info("Starting Modal deployment in gradio-jupyter mode")

    # Start Jupyter Lab in the background
    asyncio.create_task(start_jupyter_server())

    # 🔍 Detect Gradio Interface
    demo = None
    interface_names = ['demo', 'app', 'interface', 'iface']

    for name in interface_names:
        if name in globals() and hasattr(globals()[name], 'launch'):
            demo = globals()[name]
            logger.info(f"Found Gradio interface: {{name}}")
            break

    if demo is None:
        for var_name, var_value in globals().items():
            if hasattr(var_value, 'queue') and hasattr(var_value, 'launch'):
                demo = var_value
                logger.info(f"Found Gradio interface through scanning: {{var_name}}")
                break

    if demo is None:
        logger.error("No Gradio interface found")
        raise ValueError("Could not find Gradio interface")

    # 🎨 Create Dashboard with Jupyter integration
    with gr.Blocks() as enhanced_dashboard:
        gr.Markdown("# 🚀 Modal Deployment Dashboard")
        gr.Markdown("Monitor and manage your Modal deployment with Jupyter Lab integration")

        with gr.Tabs():
            # Jupyter Tab (first for easy access)
            with gr.Tab("🪐 Jupyter Lab"):
                gr.Markdown("### Interactive Jupyter Lab Environment")
                gr.Markdown("Access Jupyter Lab for interactive computing and data analysis.")

                with gr.Row():
                    gr.Markdown("**Jupyter Lab is running on port 8888**")
                    jupyter_btn = gr.Button("🚀 Open Jupyter Lab", variant="primary", scale=2)

                gr.Markdown("""
                #### Features:
                - Full Jupyter Lab interface
                - Pre-installed data science packages
                - GPU support enabled
                - Persistent workspace at `/workspace`

                #### Usage:
                1. Click the button above to open Jupyter Lab in a new tab
                2. Create notebooks and run experiments
                3. Your work is preserved during the session
                """)

                # JavaScript to open Jupyter in new tab
                jupyter_btn.click(
                    None,
                    None,
                    None,
                    js="window.open('/jupyter', '_blank')"
                )

            # Original dashboard tabs
            dashboard_interface = create_dashboard_interface(demo)
            for tab in dashboard_interface.children:
                if hasattr(tab, 'children'):
                    for child in tab.children:
                        child.render()

        gr.Markdown("---")
        gr.Markdown("🚀 Powered by [Modal](https://modal.com) | 🪐 [Jupyter Lab](/jupyter) | Generated by [modal-for-noobs](https://github.com/arthrod/modal-for-noobs)")

    enhanced_dashboard.queue(max_size=20)

    # 🔗 FastAPI Setup with Jupyter proxy
    fastapi_app = FastAPI(
        title="{app_name} - Modal Dashboard (Gradio + Jupyter)",
        description="Gradio deployment with Jupyter Lab integration and monitoring",
        version="1.0.0",
        docs_url="/docs",
        redoc_url="/redoc"
    )

    # Add Jupyter proxy endpoint
    @fastapi_app.get("/jupyter")
    @fastapi_app.get("/jupyter/{{path:path}}")
    async def jupyter_proxy(path: str = ""):
        """Proxy requests to Jupyter Lab."""
        # Redirect to Jupyter Lab
        jupyter_url = f"http://localhost:8888/{{path}}"
        return RedirectResponse(url=jupyter_url)

    # Add dashboard API endpoints
    fastapi_app = create_dashboard_api(fastapi_app)

    logger.info("Dashboard with Jupyter integration configured successfully")

    # Mount Gradio app
    return mount_gradio_app(fastapi_app, enhanced_dashboard, path="/")

# Import dashboard module
import os
import base64

# Dashboard module content (base64 encoded to avoid quote conflicts)
dashboard_module_encoded = "{dashboard_module_b64}"
dashboard_module_code = base64.b64decode(dashboard_module_encoded).decode('utf-8')

# Write dashboard module
dashboard_path = Path(__file__).parent / "dashboard.py"
if not dashboard_path.exists():
    dashboard_path.write_text(dashboard_module_code)

if __name__ == "__main__":
    app.run()
'''
