"""
Applications API routes
"""
from fastapi import APIRouter, Depends, HTTPException, status, Request
from typing import List
from pydantic import BaseModel
from sqlalchemy.orm import Session

from ...database import SessionLocal
from ...models import Application, ApplicationStatus, User, JobPosting, Resume
from ...config.settings import settings

router = APIRouter()

# Pydantic models for applications
class ApplicationCreate(BaseModel):
    job_posting_id: int
    resume_id: int
    cover_letter: str = None

class ApplicationUpdate(BaseModel):
    status: ApplicationStatus = None
    cover_letter: str = None

class ApplicationResponse(BaseModel):
    id: int
    user_id: int
    job_posting_id: int
    resume_id: int
    cover_letter: str
    status: str
    created_at: str

    class Config:
        from_attributes = True
        json_schema_extra = {
            "example": {
                "id": 1,
                "user_id": 1,
                "job_posting_id": 1,
                "resume_id": 1,
                "cover_letter": "I am excited to apply for this position...",
                "status": "submitted",
                "created_at": "2023-10-24T10:00:00Z"
            }
        }

@router.get("/", response_model=List[ApplicationResponse])
async def get_applications(skip: int = 0, limit: int = 100, db: Session = Depends(SessionLocal), request: Request = None):
    """Get all applications for the current tenant"""
    tenant_id = getattr(request.state, 'tenant_id', None)
    if not tenant_id and settings.MULTI_TENANT_ENABLED:
        raise HTTPException(status_code=400, detail="Tenant ID is required")
    
    # Get applications for jobs in the current tenant or applications by users in the current tenant
    applications = db.query(Application).join(JobPosting).filter(
        (JobPosting.tenant_id == tenant_id) | (Application.user_id.in_(
            db.query(User.id).filter(User.tenant_id == tenant_id)
        ))
    ).offset(skip).limit(limit).all()
    return applications

@router.get("/{application_id}", response_model=ApplicationResponse)
async def get_application(application_id: int, db: Session = Depends(SessionLocal), request: Request = None):
    """Get a specific application"""
    tenant_id = getattr(request.state, 'tenant_id', None)
    if not tenant_id and settings.MULTI_TENANT_ENABLED:
        raise HTTPException(status_code=400, detail="Tenant ID is required")
    
    application = db.query(Application).join(JobPosting).filter(
        Application.id == application_id,
        (JobPosting.tenant_id == tenant_id) | (Application.user_id.in_(
            db.query(User.id).filter(User.tenant_id == tenant_id)
        ))
    ).first()
    if not application:
        raise HTTPException(status_code=404, detail="Application not found")
    return application

@router.post("/", response_model=ApplicationResponse)
async def create_application(application: ApplicationCreate, db: Session = Depends(SessionLocal), request: Request = None, user_id: int = 1):  # In real app, get from auth context
    """Create a new job application"""
    tenant_id = getattr(request.state, 'tenant_id', None)
    if not tenant_id and settings.MULTI_TENANT_ENABLED:
        raise HTTPException(status_code=400, detail="Tenant ID is required")
    
    # Verify user exists and has permission to apply
    user = db.query(User).filter(
        User.id == user_id,
        User.tenant_id == tenant_id  # Make sure user belongs to current tenant
    ).first()
    if not user or user.role != "job_seeker":
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Only job seekers can apply for jobs"
        )
    
    # Verify job posting exists and is active and belongs to the same tenant
    job_posting = db.query(JobPosting).filter(
        JobPosting.id == application.job_posting_id,
        JobPosting.is_active == True,
        JobPosting.tenant_id == tenant_id  # Ensure job belongs to current tenant
    ).first()
    if not job_posting:
        raise HTTPException(status_code=404, detail="Job posting not found or inactive or not in your tenant")
    
    # Verify resume exists and belongs to user
    resume = db.query(Resume).filter(
        Resume.id == application.resume_id,
        Resume.user_id == user_id
    ).first()
    if not resume:
        raise HTTPException(status_code=404, detail="Resume not found")
    
    db_application = Application(
        user_id=user_id,
        job_posting_id=application.job_posting_id,
        resume_id=application.resume_id,
        cover_letter=application.cover_letter
    )
    db.add(db_application)
    db.commit()
    db.refresh(db_application)
    return db_application

@router.put("/{application_id}", response_model=ApplicationResponse)
async def update_application(application_id: int, app_update: ApplicationUpdate, db: Session = Depends(SessionLocal), request: Request = None):
    """Update an application"""
    tenant_id = getattr(request.state, 'tenant_id', None)
    if not tenant_id and settings.MULTI_TENANT_ENABLED:
        raise HTTPException(status_code=400, detail="Tenant ID is required")
    
    db_application = db.query(Application).join(JobPosting).filter(
        Application.id == application_id,
        (JobPosting.tenant_id == tenant_id) | (Application.user_id.in_(
            db.query(User.id).filter(User.tenant_id == tenant_id)
        ))
    ).first()
    if not db_application:
        raise HTTPException(status_code=404, detail="Application not found")
    
    # Update fields if provided
    if app_update.status is not None:
        db_application.status = app_update.status.value
    if app_update.cover_letter is not None:
        db_application.cover_letter = app_update.cover_letter
    
    db.commit()
    db.refresh(db_application)
    return db_application

@router.delete("/{application_id}")
async def delete_application(application_id: int, db: Session = Depends(SessionLocal), request: Request = None):
    """Delete an application"""
    tenant_id = getattr(request.state, 'tenant_id', None)
    if not tenant_id and settings.MULTI_TENANT_ENABLED:
        raise HTTPException(status_code=400, detail="Tenant ID is required")
    
    db_application = db.query(Application).join(JobPosting).filter(
        Application.id == application_id,
        (JobPosting.tenant_id == tenant_id) | (Application.user_id.in_(
            db.query(User.id).filter(User.tenant_id == tenant_id)
        ))
    ).first()
    if not db_application:
        raise HTTPException(status_code=404, detail="Application not found")
    
    db.delete(db_application)
    db.commit()
    return {"message": "Application deleted successfully"}