from fastapi import APIRouter, Depends, Query, status
from sqlalchemy.orm import Session
from typing import Optional
from utils.utils import get_db
from . import handler
from .schema import (
    JobtypeCreate,
    JobtypeUpdate,
    JobtypeResponse,
    JobstatusCreate,
    JobstatusUpdate,
    JobstatusResponse,
    JobpriorityCreate,
    JobpriorityUpdate,
    JobpriorityResponse,
    TagCreate,
    TagUpdate,
    TagResponse,
    PaginatedResponse,
)

router = APIRouter(prefix="/job-configuration", tags=["Job Configuration"])


@router.post(
    "/job-types",
    response_model=JobtypeResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Job Type",
    description="Creates a new job type configuration. Returns 409 if a job type with the same name already exists.",
)
def create_jobtype_route(data: JobtypeCreate, db: Session = Depends(get_db)):
    return handler.create_jobtype(db, data)


@router.get(
    "/job-types/{entity_id}",
    response_model=JobtypeResponse,
    summary="Get Job Type",
    description="Retrieves a single job type by ID. Returns 404 if the job type does not exist.",
)
def get_jobtype_route(entity_id: str, db: Session = Depends(get_db)):
    return handler.get_jobtype_by_id(db, entity_id)


@router.get(
    "/job-types",
    response_model=PaginatedResponse[JobtypeResponse],
    summary="List Job Types",
    description="Returns a paginated list of job types. Supports filtering by active status and searching by name.",
)
def list_jobtypes_route(
    limit: int = Query(20, ge=1),
    offset: int = Query(0, ge=0),
    is_active: Optional[bool] = None,
    search: Optional[str] = None,
    db: Session = Depends(get_db),
):
    return handler.list_jobtypes(db, limit, offset, is_active, search)


@router.patch(
    "/job-types/{entity_id}",
    response_model=JobtypeResponse,
    summary="Update Job Type",
    description="Updates an existing job type. Returns 404 if the job type does not exist, 409 if the updated name conflicts with another job type.",
)
def update_jobtype_route(entity_id: str, data: JobtypeUpdate, db: Session = Depends(get_db)):
    return handler.update_jobtype(db, entity_id, data)


@router.delete(
    "/job-types/{entity_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Job Type",
    description="Deletes a job type. Returns 404 if the job type does not exist, 409 if the job type is referenced by existing jobs.",
)
def delete_jobtype_route(entity_id: str, db: Session = Depends(get_db)):
    return handler.delete_jobtype(db, entity_id)


@router.post(
    "/job-statuses",
    response_model=JobstatusResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Job Status",
    description="Creates a new job status configuration. Returns 409 if a job status with the same name already exists.",
)
def create_jobstatus_route(data: JobstatusCreate, db: Session = Depends(get_db)):
    return handler.create_jobstatus(db, data)


@router.get(
    "/job-statuses/{entity_id}",
    response_model=JobstatusResponse,
    summary="Get Job Status",
    description="Retrieves a single job status by ID. Returns 404 if the job status does not exist.",
)
def get_jobstatus_route(entity_id: str, db: Session = Depends(get_db)):
    return handler.get_jobstatus_by_id(db, entity_id)


@router.get(
    "/job-statuses",
    response_model=PaginatedResponse[JobstatusResponse],
    summary="List Job Statuses",
    description="Returns a paginated list of job statuses ordered by display_order. Supports filtering by active status and searching by name.",
)
def list_jobstatuses_route(
    limit: int = Query(20, ge=1),
    offset: int = Query(0, ge=0),
    is_active: Optional[bool] = None,
    search: Optional[str] = None,
    db: Session = Depends(get_db),
):
    return handler.list_jobstatuses(db, limit, offset, is_active, search)


@router.patch(
    "/job-statuses/{entity_id}",
    response_model=JobstatusResponse,
    summary="Update Job Status",
    description="Updates an existing job status. Returns 404 if the job status does not exist, 409 if the updated name conflicts with another job status.",
)
def update_jobstatus_route(entity_id: str, data: JobstatusUpdate, db: Session = Depends(get_db)):
    return handler.update_jobstatus(db, entity_id, data)


@router.delete(
    "/job-statuses/{entity_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Job Status",
    description="Deletes a job status. Returns 404 if the job status does not exist, 409 if the job status is referenced by existing jobs.",
)
def delete_jobstatus_route(entity_id: str, db: Session = Depends(get_db)):
    return handler.delete_jobstatus(db, entity_id)


@router.post(
    "/job-priorities",
    response_model=JobpriorityResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Job Priority",
    description="Creates a new job priority configuration. Returns 409 if a job priority with the same name already exists.",
)
def create_jobpriority_route(data: JobpriorityCreate, db: Session = Depends(get_db)):
    return handler.create_jobpriority(db, data)


@router.get(
    "/job-priorities/{entity_id}",
    response_model=JobpriorityResponse,
    summary="Get Job Priority",
    description="Retrieves a single job priority by ID. Returns 404 if the job priority does not exist.",
)
def get_jobpriority_route(entity_id: str, db: Session = Depends(get_db)):
    return handler.get_jobpriority_by_id(db, entity_id)


@router.get(
    "/job-priorities",
    response_model=PaginatedResponse[JobpriorityResponse],
    summary="List Job Priorities",
    description="Returns a paginated list of job priorities ordered by level. Supports filtering by active status and searching by name.",
)
def list_jobpriorities_route(
    limit: int = Query(20, ge=1),
    offset: int = Query(0, ge=0),
    is_active: Optional[bool] = None,
    search: Optional[str] = None,
    db: Session = Depends(get_db),
):
    return handler.list_jobpriorities(db, limit, offset, is_active, search)


@router.patch(
    "/job-priorities/{entity_id}",
    response_model=JobpriorityResponse,
    summary="Update Job Priority",
    description="Updates an existing job priority. Returns 404 if the job priority does not exist, 409 if the updated name conflicts with another job priority.",
)
def update_jobpriority_route(entity_id: str, data: JobpriorityUpdate, db: Session = Depends(get_db)):
    return handler.update_jobpriority(db, entity_id, data)


@router.delete(
    "/job-priorities/{entity_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Job Priority",
    description="Deletes a job priority. Returns 404 if the job priority does not exist, 409 if the job priority is referenced by existing jobs.",
)
def delete_jobpriority_route(entity_id: str, db: Session = Depends(get_db)):
    return handler.delete_jobpriority(db, entity_id)


@router.post(
    "/tags",
    response_model=TagResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Tag",
    description="Creates a new tag for categorizing jobs. Returns 409 if a tag with the same name already exists.",
)
def create_tag_route(data: TagCreate, db: Session = Depends(get_db)):
    return handler.create_tag(db, data)


@router.get(
    "/tags/{entity_id}",
    response_model=TagResponse,
    summary="Get Tag",
    description="Retrieves a single tag by ID. Returns 404 if the tag does not exist.",
)
def get_tag_route(entity_id: str, db: Session = Depends(get_db)):
    return handler.get_tag_by_id(db, entity_id)


@router.get(
    "/tags",
    response_model=PaginatedResponse[TagResponse],
    summary="List Tags",
    description="Returns a paginated list of tags ordered by usage count descending. Supports searching by name.",
)
def list_tags_route(
    limit: int = Query(20, ge=1),
    offset: int = Query(0, ge=0),
    search: Optional[str] = None,
    db: Session = Depends(get_db),
):
    return handler.list_tags(db, limit, offset, search)


@router.patch(
    "/tags/{entity_id}",
    response_model=TagResponse,
    summary="Update Tag",
    description="Updates an existing tag. Returns 404 if the tag does not exist, 409 if the updated name conflicts with another tag.",
)
def update_tag_route(entity_id: str, data: TagUpdate, db: Session = Depends(get_db)):
    return handler.update_tag(db, entity_id, data)


@router.delete(
    "/tags/{entity_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Tag",
    description="Deletes a tag. Returns 404 if the tag does not exist, 409 if the tag is referenced by existing job tags.",
)
def delete_tag_route(entity_id: str, db: Session = Depends(get_db)):
    return handler.delete_tag(db, entity_id)