from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
import os
import sys
import subprocess
from pathlib import Path

# Initialize FastAPI app
app = FastAPI(root_path="/backend")

# CORS settings (important for frontend communication)
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # Update to specific domain in production
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Function to ensure model is downloaded
def ensure_model_exists():
    # Get the current directory
    current_dir = os.path.dirname(os.path.abspath(__file__))
    # Define model directory path relative to current directory
    model_dir = os.path.join(current_dir, "models", "grounding-dino")
    # Check if the model directory exists and contains required files
    model_files_exist = (
        os.path.exists(model_dir) and
        os.path.exists(os.path.join(model_dir, "config.json")) and
        os.path.exists(os.path.join(model_dir, "model.safetensors")) and 
        os.path.exists(os.path.join(model_dir, "preprocessor_config.json")) and
        os.path.exists(os.path.join(model_dir, "special_tokens_map.json")) and
        os.path.exists(os.path.join(model_dir, "tokenizer_config.json")) and
        os.path.exists(os.path.join(model_dir, "tokenizer.json")) and
        os.path.exists(os.path.join(model_dir, "vocab.txt")) 
    )
    
    if not model_files_exist:
        print(f"Model not found at {model_dir}. Downloading...")
        try:
            # Try to import the download_model module directly first
            sys.path.append(current_dir)
            try:
                from download_model import download_model
                if not download_model():
                    print("Failed to download model using import method.")
                    raise ImportError("Download failed")
            except ImportError:
                # Fall back to subprocess if import fails
                download_script = os.path.join(current_dir, "download_model.py")
                result = subprocess.run([sys.executable, download_script],
                                       capture_output=True, 
                                       text=True, 
                                       check=False)
                
                if result.returncode != 0:
                    print(f"Error downloading model:")
                    print(f"STDOUT: {result.stdout}")
                    print(f"STDERR: {result.stderr}")
                    raise RuntimeError("Failed to download model. Please check the error messages above.")
        
        except Exception as e:
            print(f"ERROR: {str(e)}")
            print("The application will continue, but image comparison features may not work.")
    
    # Set the environment variable for the app to use the model directory
    os.environ["MODEL_DIR"] = model_dir
    return model_dir

# Ensure model exists before starting the app
model_dir = ensure_model_exists()
print(f"Using model directory: {model_dir}")

# Create directories for images if they don't exist
os.makedirs("Input_Images", exist_ok=True)
os.makedirs("Output_Images", exist_ok=True)

# Serve your image folders
app.mount("/Input_Images", StaticFiles(directory="Input_Images"), name="input_images")
app.mount("/Output_Images", StaticFiles(directory="Output_Images"), name="output_images")

# Import routers after model initialization
from src.routers import auth
from src.routers import upload

# Include routers
app.include_router(auth.router, prefix="/api", tags=["auth"])
app.include_router(upload.router, prefix="/api", tags=["upload"])

# Entry point for running the app
if __name__ == "__main__":
    import uvicorn
    # Start the app with uvicorn
    uvicorn.run(app, host="127.0.0.1", port=8080)
