from __future__ import annotations

from datetime import date

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

from ...core.logger import AppLogger
from ...core.permissions import PERMISSION_ATTENDANCE_REALTIME_SYNC, PERMISSION_ATTENDANCE_REALTIME_VIEW
from ...database.orm import UserORM
from ...integrations.dingtalk import DingTalkError
from ...services import OperationLogService, RealtimeAttendanceService
from ..dependencies import get_operation_log_service, get_realtime_attendance_service, require_permission
from ..request_meta import operation_request_meta
from ..schemas.realtime_attendance import RealtimeAttendanceResponse, RealtimeAttendanceSyncRequest

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


@router.get("/today", response_model=RealtimeAttendanceResponse)
def get_today_attendance(
    http_request: Request,
    attendance_date: date = Query(alias="date"),
    current_user: UserORM = Depends(require_permission(PERMISSION_ATTENDANCE_REALTIME_VIEW)),
    service: RealtimeAttendanceService = Depends(get_realtime_attendance_service),
    operation_logs: OperationLogService = Depends(get_operation_log_service),
) -> RealtimeAttendanceResponse:
    """查看某一天的实时考勤看板，通常用于今日打卡状态。"""
    response = service.get_today(attendance_date)
    operation_logs.record(
        actor=current_user,
        module="attendance",
        action="attendance.realtime.view",
        target_type="attendance_date",
        target_id=attendance_date.isoformat(),
        status="success",
        detail=f"查看实时考勤 attendance_date={attendance_date} employee_count={response.summary.employee_total}",
        **operation_request_meta(http_request),
    )
    return RealtimeAttendanceResponse(**response.to_dict())


@router.post("/sync", response_model=RealtimeAttendanceResponse)
async def sync_realtime_attendance(
    http_request: Request,
    request: RealtimeAttendanceSyncRequest,
    current_user: UserORM = Depends(require_permission(PERMISSION_ATTENDANCE_REALTIME_SYNC)),
    service: RealtimeAttendanceService = Depends(get_realtime_attendance_service),
    operation_logs: OperationLogService = Depends(get_operation_log_service),
) -> RealtimeAttendanceResponse:
    """按员工档案中的钉钉 userId 自动同步本月至今打卡，并刷新今日看板。"""
    try:
        response = await service.sync_today(
            attendance_date=request.attendance_date,
            created_by=current_user.username,
            include_salary_preview=request.include_salary_preview,
        )
    except ValueError as exc:
        operation_logs.record(
            actor=current_user,
            module="attendance",
            action="attendance.realtime.sync",
            target_type="attendance_sync_job",
            target_id="",
            status="failed",
            detail=f"实时考勤同步失败 attendance_date={request.attendance_date} reason={exc}",
            **operation_request_meta(http_request),
        )
        logger.error("实时考勤同步参数错误 attendance_date=%s reason=%s", request.attendance_date, exc)
        raise HTTPException(status_code=400, detail=str(exc)) from exc
    except DingTalkError as exc:
        operation_logs.record(
            actor=current_user,
            module="attendance",
            action="attendance.realtime.sync",
            target_type="attendance_sync_job",
            target_id="",
            status="failed",
            detail=f"实时考勤钉钉调用失败 attendance_date={request.attendance_date} reason={exc}",
            **operation_request_meta(http_request),
        )
        logger.error("实时考勤钉钉调用失败 attendance_date=%s reason=%s", request.attendance_date, exc)
        raise HTTPException(status_code=502, detail=str(exc)) from exc

    operation_logs.record(
        actor=current_user,
        module="attendance",
        action="attendance.realtime.sync",
        target_type="attendance_sync_job",
        target_id=response.sync_job_id or "",
        status="success",
        detail=f"实时考勤同步成功 attendance_date={request.attendance_date} employee_count={response.summary.employee_total}",
        **operation_request_meta(http_request),
    )
    return RealtimeAttendanceResponse(**response.to_dict())
