"""
SMTP API Service - Main Application
Production deployment for https://easy-orders.co.uk
"""
from fastapi import FastAPI, Depends, HTTPException, status, Header
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from sqlalchemy.orm import Session
from datetime import timedelta
from typing import List, Optional
import uvicorn

from config import get_settings
from database import create_tables, get_db, User, ApiKey
from schemas import (
    UserCreate, UserLogin, UserResponse, Token, UserProfile,
    ApiKeyCreate, ApiKeyResponse, ApiKeyInfo,
    SMTPConfigCreate, SMTPConfigUpdate, SMTPConfigResponse,
    EmailSend, EmailSendWithApiKey, EmailResponse,
    EmailLogResponse, DashboardStats
)
from auth import (
    authenticate_user, create_access_token, get_password_hash,
    get_current_active_user, get_user_from_api_key
)
from api_key_service import (
    create_api_key, get_user_api_keys, get_api_key_by_id,
    revoke_api_key, delete_api_key, reactivate_api_key, get_api_key_stats, validate_api_key
)
from email_service import EmailService

settings = get_settings()

# Create FastAPI app
app = FastAPI(
    title=settings.APP_NAME,
    description="SMTP API Service - Send emails via REST API using your SMTP credentials",
    version=settings.APP_VERSION,
    docs_url="/docs",
    redoc_url="/redoc",
    openapi_url="/openapi.json"
)

# CORS middleware - configured for easy-orders.co.uk
app.add_middleware(
    CORSMiddleware,
    allow_origins=[
        "https://easy-orders.co.uk",
        "https://www.easy-orders.co.uk",
        "http://localhost:5173",
        "http://localhost:3000"
    ],
    allow_credentials=True,
    allow_methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
    allow_headers=["*"],
    expose_headers=["*"]
)

# Startup event
@app.on_event("startup")
async def startup_event():
    create_tables()
    print(f"🚀 {settings.APP_NAME} v{settings.APP_VERSION} started!")
    print(f"🌐 Domain: https://easy-orders.co.uk")

# ========== Health Check ==========
@app.get("/", tags=["Health"])
async def root():
    return {
        "name": settings.APP_NAME,
        "version": settings.APP_VERSION,
        "status": "running",
        "domain": "easy-orders.co.uk",
        "docs_url": "/docs",
        "api_base": "/api/v1"
    }

@app.get("/health", tags=["Health"])
async def health_check():
    return {
        "status": "healthy",
        "domain": "easy-orders.co.uk",
        "timestamp": str(__import__('datetime').datetime.utcnow())
    }

# ========== Authentication Routes ==========
@app.post("/api/v1/auth/register", response_model=UserResponse, tags=["Authentication"])
async def register(user_data: UserCreate, db: Session = Depends(get_db)):
    """Register a new user account"""
    existing_user = db.query(User).filter(
        (User.email == user_data.email) | (User.username == user_data.username)
    ).first()
    
    if existing_user:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="User with this email or username already exists"
        )
    
    hashed_password = get_password_hash(user_data.password)
    db_user = User(
        email=user_data.email,
        username=user_data.username,
        hashed_password=hashed_password,
        full_name=user_data.full_name,
        is_active=True
    )
    
    db.add(db_user)
    db.commit()
    db.refresh(db_user)
    return db_user

@app.post("/api/v1/auth/login", response_model=Token, tags=["Authentication"])
async def login(credentials: UserLogin, db: Session = Depends(get_db)):
    """Login and get access token"""
    user = authenticate_user(db, credentials.username, credentials.password)
    
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    access_token = create_access_token(data={"sub": user.username})
    
    return {
        "access_token": access_token,
        "token_type": "bearer",
        "expires_in": settings.ACCESS_TOKEN_EXPIRE_MINUTES * 60
    }

@app.get("/api/v1/auth/me", response_model=UserProfile, tags=["Authentication"])
async def get_me(current_user: User = Depends(get_current_active_user), db: Session = Depends(get_db)):
    """Get current user profile"""
    return {
        "id": current_user.id,
        "email": current_user.email,
        "username": current_user.username,
        "full_name": current_user.full_name,
        "is_active": current_user.is_active,
        "created_at": current_user.created_at,
        "api_keys_count": len(current_user.api_keys),
        "emails_sent": len(current_user.email_logs)
    }

# ========== API Key Routes ==========
@app.post("/api/v1/api-keys", response_model=ApiKeyResponse, tags=["API Keys"])
async def create_new_api_key(
    key_data: ApiKeyCreate,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """Create a new API key"""
    api_key = create_api_key(db, current_user.id, key_data.name)
    return api_key

@app.get("/api/v1/api-keys", response_model=List[ApiKeyInfo], tags=["API Keys"])
async def list_api_keys(
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """List all API keys for the current user"""
    return get_user_api_keys(db, current_user.id)

@app.delete("/api/v1/api-keys/{key_id}", tags=["API Keys"])
async def delete_api_key_endpoint(
    key_id: int,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """Delete an API key"""
    success = delete_api_key(db, key_id, current_user.id)
    if not success:
        raise HTTPException(status_code=404, detail="API key not found")
    return {"message": "API key deleted successfully"}

@app.post("/api/v1/api-keys/{key_id}/revoke", tags=["API Keys"])
async def revoke_api_key_endpoint(
    key_id: int,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """Revoke (deactivate) an API key"""
    success = revoke_api_key(db, key_id, current_user.id)
    if not success:
        raise HTTPException(status_code=404, detail="API key not found")
    return {"message": "API key revoked successfully"}

@app.post("/api/v1/api-keys/{key_id}/reactivate", tags=["API Keys"])
async def reactivate_api_key_endpoint(
    key_id: int,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """Reactivate a revoked API key"""
    success = reactivate_api_key(db, key_id, current_user.id)
    if not success:
        raise HTTPException(status_code=404, detail="API key not found")
    return {"message": "API key reactivated successfully"}

# ========== SMTP Configuration Routes ==========
@app.post("/api/v1/smtp-configs", response_model=SMTPConfigResponse, tags=["SMTP Configuration"])
async def create_smtp_config(
    config_data: SMTPConfigCreate,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """Create a new SMTP configuration"""
    email_service = EmailService(db)
    config = email_service.create_smtp_config(current_user.id, config_data.dict())
    return config

@app.get("/api/v1/smtp-configs", response_model=List[SMTPConfigResponse], tags=["SMTP Configuration"])
async def list_smtp_configs(
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """List all SMTP configurations"""
    email_service = EmailService(db)
    return email_service.get_all_user_smtp_configs(current_user.id)

@app.put("/api/v1/smtp-configs/{config_id}", response_model=SMTPConfigResponse, tags=["SMTP Configuration"])
async def update_smtp_config(
    config_id: int,
    config_data: SMTPConfigUpdate,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """Update an SMTP configuration"""
    email_service = EmailService(db)
    config = email_service.update_smtp_config(config_id, current_user.id, config_data.dict(exclude_unset=True))
    if not config:
        raise HTTPException(status_code=404, detail="SMTP configuration not found")
    return config

@app.delete("/api/v1/smtp-configs/{config_id}", tags=["SMTP Configuration"])
async def delete_smtp_config(
    config_id: int,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """Delete an SMTP configuration"""
    email_service = EmailService(db)
    success = email_service.delete_smtp_config(config_id, current_user.id)
    if not success:
        raise HTTPException(status_code=404, detail="SMTP configuration not found")
    return {"message": "SMTP configuration deleted successfully"}

# ========== Email Routes ==========
@app.post("/api/v1/emails/send", response_model=EmailResponse, tags=["Email"])
async def send_email(
    email_data: EmailSend,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """Send an email using your configured SMTP"""
    email_service = EmailService(db)
    return email_service.send_email(current_user.id, email_data)

@app.get("/api/v1/emails/logs", response_model=List[EmailLogResponse], tags=["Email"])
async def get_email_logs(
    limit: int = 50,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """Get email sending logs"""
    email_service = EmailService(db)
    return email_service.get_email_logs(current_user.id, limit)

# ========== Public API Routes (API Key Authentication) ==========
@app.post("/api/v1/public/send-email", response_model=EmailResponse, tags=["Public API"])
async def public_send_email(
    email_data: EmailSendWithApiKey,
    db: Session = Depends(get_db)
):
    """
    Send email using API Key authentication.
    
    This endpoint is designed for external applications to send emails
    using their API key. Include your API key in the X-API-Key header.
    """
    api_key_record = validate_api_key(db, email_data.api_key)
    if not api_key_record:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid or inactive API key"
        )
    
    email_service = EmailService(db)
    return email_service.send_email_with_api_key(
        api_key_record,
        email_data.dict(exclude={'api_key'})
    )

@app.post("/api/v1/public/send-email/header", response_model=EmailResponse, tags=["Public API"])
async def public_send_email_header(
    email_data: EmailSend,
    x_api_key: str = Header(..., description="Your API Key"),
    db: Session = Depends(get_db)
):
    """
    Send email using API Key in header.
    
    Include your API key in the X-API-Key header.
    """
    api_key_record = validate_api_key(db, x_api_key)
    if not api_key_record:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid or inactive API key"
        )
    
    email_service = EmailService(db)
    return email_service.send_email_with_api_key(
        api_key_record,
        email_data.dict()
    )

# ========== Dashboard Routes ==========
@app.get("/api/v1/dashboard/stats", response_model=DashboardStats, tags=["Dashboard"])
async def get_dashboard_stats(
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """Get dashboard statistics"""
    email_service = EmailService(db)
    email_stats = email_service.get_email_stats(current_user.id)
    api_stats = get_api_key_stats(db, current_user.id)
    
    recent_emails = email_service.get_email_logs(current_user.id, limit=10)
    
    return {
        "total_emails_sent": email_stats["total_sent"],
        "emails_sent_today": email_stats["today_sent"],
        "active_api_keys": api_stats["active_keys"],
        "smtp_configs": len(current_user.smtp_configs),
        "recent_emails": recent_emails,
        "api_usage": []
    }

# Run the application
if __name__ == "__main__":
    uvicorn.run(
        "main:app",
        host="0.0.0.0",
        port=8000,
        reload=False,
        workers=4,
        log_level="info"
    )
