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 (
    DepartmentCreate,
    DepartmentUpdate,
    DepartmentResponse,
    PaginatedDepartmentResponse,
    TeamCreate,
    TeamUpdate,
    TeamResponse,
    PaginatedTeamResponse,
    TeamDetailResponse,
    UserteamCreate,
    UserteamUpdate,
    UserteamResponse,
    PaginatedUserteamResponse,
)

router = APIRouter(prefix="/organization", tags=["Organization"])


# Department routes
@router.post(
    "/departments",
    response_model=DepartmentResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Department",
    description="Creates a new department record. Returns 409 if a department with the same name already exists.",
)
def create_department_route(data: DepartmentCreate, db: Session = Depends(get_db)):
    return handler.create_department(db, data)


@router.get(
    "/departments/{entity_id}",
    response_model=DepartmentResponse,
    summary="Get Department By ID",
    description="Retrieves a single department by its unique identifier. Returns 404 if not found.",
)
def get_department_route(entity_id: str, db: Session = Depends(get_db)):
    return handler.get_department_by_id(db, entity_id)


@router.get(
    "/departments",
    response_model=PaginatedDepartmentResponse,
    summary="List Departments",
    description="Returns a paginated list of departments. Supports optional search by name.",
)
def list_departments_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_departments(db, limit, offset, search)


@router.put(
    "/departments/{entity_id}",
    response_model=DepartmentResponse,
    summary="Update Department",
    description="Updates an existing department. Only provided fields are modified. Returns 404 if department not found, 409 if new name conflicts.",
)
def update_department_route(entity_id: str, data: DepartmentUpdate, db: Session = Depends(get_db)):
    return handler.update_department(db, entity_id, data)


@router.delete(
    "/departments/{entity_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Department",
    description="Deletes a department. Returns 404 if not found, 409 if department has associated users or jobs.",
)
def delete_department_route(entity_id: str, db: Session = Depends(get_db)):
    return handler.delete_department(db, entity_id)


# Team routes
@router.post(
    "/teams",
    response_model=TeamResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Team",
    description="Creates a new team within a department. Returns 400 if department does not exist.",
)
def create_team_route(data: TeamCreate, db: Session = Depends(get_db)):
    return handler.create_team(db, data)


@router.get(
    "/teams/{entity_id}",
    response_model=TeamResponse,
    summary="Get Team By ID",
    description="Retrieves a single team by its unique identifier. Returns 404 if not found.",
)
def get_team_route(entity_id: str, db: Session = Depends(get_db)):
    return handler.get_team_by_id(db, entity_id)


@router.get(
    "/teams",
    response_model=PaginatedTeamResponse,
    summary="List Teams",
    description="Returns a paginated list of teams. Supports optional filters for department and search by name.",
)
def list_teams_route(
    limit: int = Query(20, ge=1),
    offset: int = Query(0, ge=0),
    department_id: Optional[str] = None,
    search: Optional[str] = None,
    db: Session = Depends(get_db),
):
    return handler.list_teams(db, limit, offset, department_id, search)


@router.put(
    "/teams/{entity_id}",
    response_model=TeamResponse,
    summary="Update Team",
    description="Updates an existing team. Only provided fields are modified. Returns 404 if team not found, 400 if department does not exist.",
)
def update_team_route(entity_id: str, data: TeamUpdate, db: Session = Depends(get_db)):
    return handler.update_team(db, entity_id, data)


@router.delete(
    "/teams/{entity_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Team",
    description="Deletes a team. Returns 404 if not found, 409 if team has active jobs or user assignments.",
)
def delete_team_route(entity_id: str, db: Session = Depends(get_db)):
    return handler.delete_team(db, entity_id)


@router.get(
    "/teams/{entity_id}/details",
    response_model=TeamDetailResponse,
    summary="Get Team Details",
    description="Retrieves detailed team information including department and all user assignments with user details. Returns 404 if team not found.",
)
def get_team_details_route(entity_id: str, db: Session = Depends(get_db)):
    return handler.get_team_details(db, entity_id)


# Userteam routes
@router.post(
    "/user-teams",
    response_model=UserteamResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Assign User To Team",
    description="Creates a user-team assignment. Returns 400 if user or team does not exist, 409 if assignment already exists.",
)
def create_userteam_route(data: UserteamCreate, db: Session = Depends(get_db)):
    return handler.create_userteam(db, data)


@router.get(
    "/user-teams/{entity_id}",
    response_model=UserteamResponse,
    summary="Get User Team Assignment By ID",
    description="Retrieves a single user-team assignment by its unique identifier. Returns 404 if not found.",
)
def get_userteam_route(entity_id: str, db: Session = Depends(get_db)):
    return handler.get_userteam_by_id(db, entity_id)


@router.get(
    "/user-teams",
    response_model=PaginatedUserteamResponse,
    summary="List User Team Assignments",
    description="Returns a paginated list of user-team assignments. Supports optional filters for user_id and team_id.",
)
def list_userteams_route(
    limit: int = Query(20, ge=1),
    offset: int = Query(0, ge=0),
    user_id: Optional[str] = None,
    team_id: Optional[str] = None,
    db: Session = Depends(get_db),
):
    return handler.list_userteams(db, limit, offset, user_id, team_id)


@router.put(
    "/user-teams/{entity_id}",
    response_model=UserteamResponse,
    summary="Update User Team Assignment",
    description="Updates an existing user-team assignment. Only provided fields are modified. Returns 404 if assignment not found, 400 if user or team does not exist.",
)
def update_userteam_route(entity_id: str, data: UserteamUpdate, db: Session = Depends(get_db)):
    return handler.update_userteam(db, entity_id, data)


@router.delete(
    "/user-teams/{entity_id}",
    status_code=status.HTTP_200_OK,
    summary="Remove User From Team",
    description="Deletes a user-team assignment. Returns 404 if assignment not found.",
)
def delete_userteam_route(entity_id: str, db: Session = Depends(get_db)):
    return handler.delete_userteam(db, entity_id)