"""Main FastAPI application factory and initialization."""

from fastapi import FastAPI, APIRouter, HTTPException, Depends, status, UploadFile, File
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from fastapi.responses import FileResponse
from starlette.middleware.cors import CORSMiddleware
from motor.motor_asyncio import AsyncIOMotorClient
import os
import logging
from pathlib import Path
import bcrypt
import jwt
import shutil

from .models import (
    UserCreate, User, Question, QuestionUpdate, AnswerKey,
    SubmissionCreate, Submission, AdminLogin, ApprovalData
)
from .config import get_settings

# Logging setup
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

# Settings
settings = get_settings()

# MongoDB client (will be initialized in create_app)
db = None
client = None

# Security
security = HTTPBearer()

# Image storage directory
IMAGE_DIR = Path(os.getcwd()) / 'question_images'
IMAGE_DIR.mkdir(exist_ok=True)


def create_jwt_token(data: dict):
    """Create JWT token."""
    return jwt.encode(data, settings.JWT_SECRET, algorithm=settings.JWT_ALGORITHM)


def verify_jwt_token(token: str):
    """Verify JWT token."""
    try:
        payload = jwt.decode(token, settings.JWT_SECRET, algorithms=[settings.JWT_ALGORITHM])
        return payload
    except jwt.PyJWTError:
        return None


async def get_current_admin(credentials: HTTPAuthorizationCredentials = Depends(security)):
    """Get current admin from token."""
    token = credentials.credentials
    payload = verify_jwt_token(token)
    if not payload or payload.get('role') != 'admin':
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid credentials")
    return payload


def create_app() -> FastAPI:
    """Create and configure FastAPI application."""
    global db, client
    
    app = FastAPI(
        title="CPM Assessment API",
        description="Coloured Progressive Matrices Assessment System",
        version="1.0.0"
    )
    
    api_router = APIRouter(prefix="/api")
    
    # MongoDB connection
    client = AsyncIOMotorClient(settings.MONGO_URL)
    db = client[settings.DB_NAME]
    
    # ============= ROUTES =============
    
    @api_router.get("/")
    async def root():
        return {"message": "CPM Assessment API", "version": "1.0.0"}
    
    # User Registration
    @api_router.post("/user/register", response_model=User)
    async def register_user(user_data: UserCreate):
        user = User(**user_data.model_dump())
        doc = user.model_dump()
        doc['created_at'] = doc['created_at'].isoformat()
        await db.users.insert_one(doc)
        return user
    
    # Get All Questions
    @api_router.get("/questions")
    async def get_questions():
        questions = await db.questions.find({}, {"_id": 0}).to_list(100)
        return questions

    app.include_router(api_router)
    return app
