from __future__ import annotations

from fastapi import APIRouter, Depends, HTTPException, Query, Request

from ...core.logger import AppLogger
from ...core.permissions import PERMISSION_ORGANIZATION_MANAGE, PERMISSION_ORGANIZATION_VIEW
from ...database.orm import UserORM
from ...services import OperationLogService, OrganizationService
from ..dependencies import get_operation_log_service, get_organization_service, require_permission
from ..request_meta import operation_request_meta
from ..schemas.organization import DepartmentRequest, DepartmentResponse, PositionRequest, PositionResponse

router = APIRouter(prefix="/api/organization", tags=["organization"])
logger = AppLogger.get_logger(__name__)


@router.get("/departments", response_model=list[DepartmentResponse])
def list_departments(
    http_request: Request,
    active_only: bool = Query(default=True, description="是否只查询启用部门"),
    keyword: str | None = Query(default=None, description="部门编码或名称关键字"),
    current_user: UserORM = Depends(require_permission(PERMISSION_ORGANIZATION_VIEW)),
    service: OrganizationService = Depends(get_organization_service),
    operation_logs: OperationLogService = Depends(get_operation_log_service),
) -> list[DepartmentResponse]:
    """查询部门列表。"""
    departments = service.list_departments(active_only=active_only, keyword=keyword)
    operation_logs.record(
        actor=current_user,
        module="system",
        action="organization.department.list",
        target_type="department",
        target_id="",
        status="success",
        detail=f"查询部门 count={len(departments)}",
        **operation_request_meta(http_request),
    )
    return [DepartmentResponse.from_orm_model(department) for department in departments]


@router.post("/departments", response_model=DepartmentResponse)
def create_department(
    http_request: Request,
    request: DepartmentRequest,
    current_user: UserORM = Depends(require_permission(PERMISSION_ORGANIZATION_MANAGE)),
    service: OrganizationService = Depends(get_organization_service),
    operation_logs: OperationLogService = Depends(get_operation_log_service),
) -> DepartmentResponse:
    """新增部门。"""
    try:
        department = service.create_department(**request.model_dump())
    except ValueError as exc:
        logger.error("新增部门失败 name=%s reason=%s", request.name, exc)
        raise HTTPException(status_code=400, detail=str(exc)) from exc
    operation_logs.record(
        actor=current_user,
        module="system",
        action="organization.department.create",
        target_type="department",
        target_id=str(department.id),
        status="success",
        detail=f"新增部门 name={department.name}",
        **operation_request_meta(http_request),
    )
    return DepartmentResponse.from_orm_model(department)


@router.put("/departments/{department_id}", response_model=DepartmentResponse)
def update_department(
    http_request: Request,
    department_id: int,
    request: DepartmentRequest,
    current_user: UserORM = Depends(require_permission(PERMISSION_ORGANIZATION_MANAGE)),
    service: OrganizationService = Depends(get_organization_service),
    operation_logs: OperationLogService = Depends(get_operation_log_service),
) -> DepartmentResponse:
    """更新部门。"""
    try:
        department = service.update_department(department_id, **request.model_dump())
    except ValueError as exc:
        logger.error("更新部门失败 department_id=%s reason=%s", department_id, exc)
        raise HTTPException(status_code=400, detail=str(exc)) from exc
    operation_logs.record(
        actor=current_user,
        module="system",
        action="organization.department.update",
        target_type="department",
        target_id=str(department.id),
        status="success",
        detail=f"更新部门 name={department.name}",
        **operation_request_meta(http_request),
    )
    return DepartmentResponse.from_orm_model(department)


@router.get("/positions", response_model=list[PositionResponse])
def list_positions(
    http_request: Request,
    department_id: int | None = Query(default=None, description="部门ID"),
    active_only: bool = Query(default=True, description="是否只查询启用岗位"),
    keyword: str | None = Query(default=None, description="岗位编码或名称关键字"),
    current_user: UserORM = Depends(require_permission(PERMISSION_ORGANIZATION_VIEW)),
    service: OrganizationService = Depends(get_organization_service),
    operation_logs: OperationLogService = Depends(get_operation_log_service),
) -> list[PositionResponse]:
    """查询岗位列表。"""
    try:
        positions = service.list_positions(department_id=department_id, active_only=active_only, keyword=keyword)
    except ValueError as exc:
        raise HTTPException(status_code=400, detail=str(exc)) from exc
    operation_logs.record(
        actor=current_user,
        module="system",
        action="organization.position.list",
        target_type="position",
        target_id=str(department_id or ""),
        status="success",
        detail=f"查询岗位 count={len(positions)}",
        **operation_request_meta(http_request),
    )
    return [PositionResponse.from_orm_model(position) for position in positions]


@router.post("/positions", response_model=PositionResponse)
def create_position(
    http_request: Request,
    request: PositionRequest,
    current_user: UserORM = Depends(require_permission(PERMISSION_ORGANIZATION_MANAGE)),
    service: OrganizationService = Depends(get_organization_service),
    operation_logs: OperationLogService = Depends(get_operation_log_service),
) -> PositionResponse:
    """新增岗位。"""
    try:
        position = service.create_position(**request.model_dump())
    except ValueError as exc:
        logger.error("新增岗位失败 name=%s reason=%s", request.name, exc)
        raise HTTPException(status_code=400, detail=str(exc)) from exc
    operation_logs.record(
        actor=current_user,
        module="system",
        action="organization.position.create",
        target_type="position",
        target_id=str(position.id),
        status="success",
        detail=f"新增岗位 name={position.name}",
        **operation_request_meta(http_request),
    )
    return PositionResponse.from_orm_model(position)


@router.put("/positions/{position_id}", response_model=PositionResponse)
def update_position(
    http_request: Request,
    position_id: int,
    request: PositionRequest,
    current_user: UserORM = Depends(require_permission(PERMISSION_ORGANIZATION_MANAGE)),
    service: OrganizationService = Depends(get_organization_service),
    operation_logs: OperationLogService = Depends(get_operation_log_service),
) -> PositionResponse:
    """更新岗位。"""
    try:
        position = service.update_position(position_id, **request.model_dump())
    except ValueError as exc:
        logger.error("更新岗位失败 position_id=%s reason=%s", position_id, exc)
        raise HTTPException(status_code=400, detail=str(exc)) from exc
    operation_logs.record(
        actor=current_user,
        module="system",
        action="organization.position.update",
        target_type="position",
        target_id=str(position.id),
        status="success",
        detail=f"更新岗位 name={position.name}",
        **operation_request_meta(http_request),
    )
    return PositionResponse.from_orm_model(position)
