from datetime import date, datetime
from enum import Enum
from typing import Any

from pydantic import BaseModel, Field


class LoginType(str, Enum):
    phone_code = "phone_code"
    wechat = "wechat"


class UserRole(str, Enum):
    parent = "parent"
    coach = "coach"
    org_admin = "org_admin"
    platform_admin = "platform_admin"


class Gender(str, Enum):
    male = "male"
    female = "female"
    unknown = "unknown"


class VideoScene(str, Enum):
    front_posture = "front_posture"
    side_posture = "side_posture"
    squat = "squat"
    balance = "balance"
    gait = "gait"


class TaskType(str, Enum):
    posture_screening = "posture_screening"
    movement_scoring = "movement_scoring"
    reassessment = "reassessment"


class TaskStatus(str, Enum):
    CREATED = "CREATED"
    QUEUED = "QUEUED"
    PROCESSING = "PROCESSING"
    SUCCEEDED = "SUCCEEDED"
    FAILED = "FAILED"
    CANCELLED = "CANCELLED"


class RiskLevel(str, Enum):
    low = "low"
    medium = "medium"
    high = "high"
    review_required = "review_required"


class PlanStatus(str, Enum):
    draft = "draft"
    active = "active"
    completed = "completed"
    paused = "paused"


class LoginRequest(BaseModel):
    login_type: LoginType = Field(alias="loginType")
    credential: str
    code: str | None = None

    model_config = {"populate_by_name": True}


class User(BaseModel):
    id: int
    phone_masked: str = Field(alias="phoneMasked")
    role: UserRole

    model_config = {"populate_by_name": True}


class ChildCreateRequest(BaseModel):
    name: str
    birthday: date
    gender: Gender = Gender.unknown
    height: float | None = None
    weight: float | None = None
    contraindications: str | None = None


class ChildUpdateRequest(ChildCreateRequest):
    pass


class Child(BaseModel):
    id: int
    name: str
    birthday: date
    age: int
    height: float | None = None
    weight: float | None = None
    status: str = "active"


class UploadTokenRequest(BaseModel):
    child_id: int = Field(alias="childId")
    file_name: str = Field(alias="fileName")
    content_type: str = Field(alias="contentType")
    size: int

    model_config = {"populate_by_name": True}


class VideoCreateRequest(BaseModel):
    child_id: int = Field(alias="childId")
    object_key: str = Field(alias="objectKey")
    scene: VideoScene
    capture_hint: str | None = Field(default=None, alias="captureHint")

    model_config = {"populate_by_name": True}


class AnalysisTaskCreateRequest(BaseModel):
    child_id: int = Field(alias="childId")
    video_id: int = Field(alias="videoId")
    task_type: TaskType = Field(alias="taskType")

    model_config = {"populate_by_name": True}


class AnalysisTaskWebhook(BaseModel):
    task_id: int = Field(alias="taskId")
    status: TaskStatus
    progress: int | None = None
    error_code: str | None = Field(default=None, alias="errorCode")
    result: dict[str, Any] | None = None
    signature: str | None = None

    model_config = {"populate_by_name": True}


class TrainingPlanCreateRequest(BaseModel):
    child_id: int = Field(alias="childId")
    report_id: int | None = Field(default=None, alias="reportId")
    goal: str
    cycle_days: int = Field(alias="cycleDays", ge=7)
    exercise_ids: list[int] | None = Field(default=None, alias="exerciseIds")
    constraints: dict[str, Any] | None = None

    model_config = {"populate_by_name": True}


class TrainingRecordCreateRequest(BaseModel):
    exercise_id: int = Field(alias="exerciseId")
    completed: bool
    score: int | None = Field(default=None, ge=0, le=100)
    duration_seconds: int | None = Field(default=None, alias="durationSeconds")
    note: str | None = None
    media: list[str] | None = None

    model_config = {"populate_by_name": True}


class ReportMetric(BaseModel):
    name: str
    value: float
    level: str
    confidence: float


class ReportReviewRequest(BaseModel):
    action: str = Field(description="approve or reject")
    note: str | None = None
