from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session, joinedload

from app.database import get_db
from app.models.user import User
from app.models.job import Job, JobApplication
from app.schemas import JobCreate, JobApplicationCreate
from app.services.auth import require_user
from app.services.notifications import create_notification

router = APIRouter(prefix="/api/jobs", tags=["jobs"])


@router.post("")
def create_job(data: JobCreate, user: User = Depends(require_user), db: Session = Depends(get_db)):
    job = Job(posted_by_id=user.id, **data.model_dump())
    db.add(job)
    db.commit()
    db.refresh(job)
    return {"id": job.id, "title": job.title}


@router.get("")
def list_jobs(
    q: str = Query(""),
    field_id: int | None = Query(None),
    job_type: str | None = Query(None),
    location: str | None = Query(None),
    sort: str = Query("newest"),
    page: int = Query(1, ge=1),
    per_page: int = Query(20, ge=1, le=100),
    db: Session = Depends(get_db),
):
    query = db.query(Job).options(joinedload(Job.posted_by), joinedload(Job.field)).filter(Job.is_active == True)
    if q:
        query = query.filter(Job.title.ilike(f"%{q}%") | Job.description.ilike(f"%{q}%"))
    if field_id:
        query = query.filter(Job.field_id == field_id)
    if job_type:
        query = query.filter(Job.job_type == job_type)
    if location:
        query = query.filter(Job.location.ilike(f"%{location}%"))

    if sort == "oldest":
        query = query.order_by(Job.created_at.asc())
    else:
        query = query.order_by(Job.created_at.desc())

    total = query.count()
    jobs = query.offset((page - 1) * per_page).limit(per_page).all()
    return {
        "total": total, "page": page, "per_page": per_page,
        "results": [
            {
                "id": j.id, "title": j.title, "institution": j.institution,
                "location": j.location, "job_type": j.job_type,
                "salary_range": j.salary_range, "deadline": str(j.deadline) if j.deadline else None,
                "created_at": str(j.created_at),
                "posted_by": {"id": j.posted_by.id, "full_name": j.posted_by.full_name, "is_verified": j.posted_by.is_verified},
                "field": {"id": j.field.id, "name": j.field.name, "color": j.field.color} if j.field else None,
            }
            for j in jobs
        ],
    }


@router.get("/{job_id}")
def get_job(job_id: int, db: Session = Depends(get_db)):
    job = db.query(Job).options(joinedload(Job.posted_by), joinedload(Job.field)).filter(Job.id == job_id).first()
    if not job:
        raise HTTPException(status_code=404, detail="Job not found")
    return {
        "id": job.id, "title": job.title, "description": job.description,
        "institution": job.institution, "location": job.location,
        "job_type": job.job_type, "salary_range": job.salary_range,
        "application_url": job.application_url, "deadline": str(job.deadline) if job.deadline else None,
        "created_at": str(job.created_at),
        "posted_by": {
            "id": job.posted_by.id, "full_name": job.posted_by.full_name,
            "is_verified": job.posted_by.is_verified,
            "affiliation": {"designation": job.posted_by.primary_affiliation.designation, "institution": job.posted_by.primary_affiliation.institution} if job.posted_by.primary_affiliation else None,
        },
        "field": {"id": job.field.id, "name": job.field.name, "color": job.field.color} if job.field else None,
    }


@router.post("/{job_id}/apply")
def apply_to_job(job_id: int, data: JobApplicationCreate, user: User = Depends(require_user), db: Session = Depends(get_db)):
    job = db.query(Job).filter(Job.id == job_id).first()
    if not job:
        raise HTTPException(status_code=404, detail="Job not found")
    existing = db.query(JobApplication).filter(JobApplication.job_id == job_id, JobApplication.applicant_id == user.id).first()
    if existing:
        raise HTTPException(status_code=400, detail="Already applied")
    app = JobApplication(job_id=job_id, applicant_id=user.id, cover_letter=data.cover_letter)
    db.add(app)
    db.commit()
    create_notification(db, job.posted_by_id, user.id, "job_application",
                        f"{user.full_name} applied to your job \"{job.title}\"",
                        f"/jobs/{job_id}")
    return {"message": "Application submitted"}


@router.delete("/{job_id}")
def delete_job(job_id: int, user: User = Depends(require_user), db: Session = Depends(get_db)):
    job = db.query(Job).filter(Job.id == job_id).first()
    if not job:
        raise HTTPException(status_code=404, detail="Job not found")
    if job.posted_by_id != user.id and not user.is_admin:
        raise HTTPException(status_code=403, detail="Not authorized")
    db.delete(job)
    db.commit()
    return {"message": "Deleted"}
