"""Training Management APIs — Phase 9.6."""
from __future__ import annotations

from uuid import UUID

from fastapi import APIRouter, Depends, Query, status
from sqlalchemy.ext.asyncio import AsyncSession

from app.api.deps import get_db, get_pagination, require_tenant
from app.core.security import get_current_user
from app.schemas.training import (
    AssessmentCreate,
    AssessmentRead,
    BodyCompositionCreate,
    BodyCompositionRead,
    ExerciseCreate,
    ExerciseRead,
    ExerciseUpdate,
    MeasurementCreate,
    MeasurementRead,
    NutritionPlanCreate,
    NutritionPlanRead,
    PerformanceRecordCreate,
    PerformanceRecordRead,
    ProgressRecordCreate,
    ProgressRecordRead,
    TrainingGoalCreate,
    TrainingGoalRead,
    TrainingProgramCreate,
    TrainingProgramRead,
    TrainingProgramUpdate,
    WorkoutAssignmentCreate,
    WorkoutAssignmentRead,
    WorkoutPlanCreate,
    WorkoutPlanRead,
    WorkoutPlanUpdate,
)
from app.services.training import (
    AssessmentService,
    BodyCompositionService,
    ExerciseService,
    MeasurementService,
    NutritionPlanService,
    PerformanceRecordService,
    ProgressRecordService,
    TrainingGoalService,
    TrainingProgramService,
    WorkoutAssignmentService,
    WorkoutPlanService,
)
from shared.pagination import PaginationParams
from shared.security import CurrentUser

programs_router = APIRouter()
exercises_router = APIRouter()
workout_plans_router = APIRouter()
workout_assignments_router = APIRouter()
goals_router = APIRouter()
measurements_router = APIRouter()
progress_router = APIRouter()
nutrition_router = APIRouter()
assessments_router = APIRouter()
performance_router = APIRouter()
body_composition_router = APIRouter()


@programs_router.post("", response_model=TrainingProgramRead, status_code=status.HTTP_201_CREATED)
async def create_program(body: TrainingProgramCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user)):
    return await TrainingProgramService(db).create(tenant_id, body, actor=user)


@programs_router.get("", response_model=list[TrainingProgramRead])
async def list_programs(tenant_id: UUID = Depends(require_tenant), pagination: PaginationParams = Depends(get_pagination), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(get_current_user)):
    return await TrainingProgramService(db).list(tenant_id, offset=pagination.offset, limit=pagination.page_size)


@exercises_router.post("", response_model=ExerciseRead, status_code=status.HTTP_201_CREATED)
async def create_exercise(body: ExerciseCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user)):
    return await ExerciseService(db).create(tenant_id, body, actor=user)


@workout_plans_router.post("", response_model=WorkoutPlanRead, status_code=status.HTTP_201_CREATED)
async def create_workout_plan(body: WorkoutPlanCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user)):
    return await WorkoutPlanService(db).create(tenant_id, body, actor=user)


@workout_assignments_router.post("", response_model=WorkoutAssignmentRead, status_code=status.HTTP_201_CREATED)
async def assign_workout(body: WorkoutAssignmentCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user)):
    return await WorkoutAssignmentService(db).create(tenant_id, body, actor=user)


@goals_router.post("", response_model=TrainingGoalRead, status_code=status.HTTP_201_CREATED)
async def create_goal(body: TrainingGoalCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user)):
    return await TrainingGoalService(db).create(tenant_id, body, actor=user)


@measurements_router.post("", response_model=MeasurementRead, status_code=status.HTTP_201_CREATED)
async def create_measurement(body: MeasurementCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user)):
    return await MeasurementService(db).create(tenant_id, body, actor=user)


@progress_router.post("", response_model=ProgressRecordRead, status_code=status.HTTP_201_CREATED)
async def create_progress(body: ProgressRecordCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user)):
    return await ProgressRecordService(db).create(tenant_id, body, actor=user)


@nutrition_router.post("", response_model=NutritionPlanRead, status_code=status.HTTP_201_CREATED)
async def create_nutrition_plan(body: NutritionPlanCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user)):
    return await NutritionPlanService(db).create(tenant_id, body, actor=user)


@assessments_router.post("", response_model=AssessmentRead, status_code=status.HTTP_201_CREATED)
async def create_assessment(body: AssessmentCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user)):
    return await AssessmentService(db).create(tenant_id, body, actor=user)


@performance_router.post("", response_model=PerformanceRecordRead, status_code=status.HTTP_201_CREATED)
async def create_performance(body: PerformanceRecordCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user)):
    return await PerformanceRecordService(db).create(tenant_id, body, actor=user)


@body_composition_router.post("", response_model=BodyCompositionRead, status_code=status.HTTP_201_CREATED)
async def create_body_composition(body: BodyCompositionCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user)):
    return await BodyCompositionService(db).create(tenant_id, body, actor=user)
