from pydantic import BaseModel, Field

from app.schemas.common import NaiveDatetime, NaiveDatetimeOptional


class CreditAdjustRequest(BaseModel):
    amount: float = Field(..., ge=-9999999.99, le=9999999.99, multiple_of=0.01)
    description: str = Field(..., max_length=256)


class ModelConfigCreate(BaseModel):
    name: str = Field(..., max_length=64)
    provider: str = Field(..., max_length=32)
    api_base: str = Field(..., max_length=512)
    api_key: str = Field(..., max_length=256)
    model_name: str = Field(..., max_length=128)
    weight: int = Field(default=1, ge=0)
    max_tokens: int = Field(default=4096, ge=1)
    temperature: float = Field(default=0.7, ge=0, le=2)
    is_active: bool = True
    priority: int = 0


class ModelConfigOut(ModelConfigCreate):
    id: str
    created_at: NaiveDatetime

    model_config = {"from_attributes": True}


class SystemConfigUpdate(BaseModel):
    value: str | int | float


class SystemConfigOut(BaseModel):
    id: str
    key: str
    value: str
    description: str | None = None

    model_config = {"from_attributes": True}


class AdminUserOut(BaseModel):
    id: str
    username: str
    email: str | None = None
    phone: str | None = None
    credits: float
    is_active: bool
    is_admin: bool
    user_type: str = "frontend"
    frontend_user_kind: str = "external"
    created_at: NaiveDatetime
    last_login_at: NaiveDatetimeOptional = None
    allowed_menus: list | None = None

    model_config = {"from_attributes": True}


class CreateUserRequest(BaseModel):
    username: str | None = Field(None, max_length=64)
    password: str = Field(..., min_length=6, max_length=128)
    email: str | None = None
    phone: str | None = None
    credits: float = 0.0
    user_type: str = Field(default="frontend", pattern="^(frontend|admin)$")
    frontend_user_kind: str = Field(default="external", pattern="^(internal|external)$")
    allowed_menus: list | None = None


class UpdateFrontendUserKindRequest(BaseModel):
    frontend_user_kind: str = Field(..., pattern="^(internal|external)$")


class UpdateMenusRequest(BaseModel):
    allowed_menus: list | None = None


class ResetPasswordRequest(BaseModel):
    new_password: str = Field(..., min_length=6, max_length=128)


class OperationLogOut(BaseModel):
    id: str
    user_id: str
    username: str
    action: str
    method: str
    path: str
    detail: str | None = None
    ip: str | None = None
    created_at: NaiveDatetime

    model_config = {"from_attributes": True}


class AdminStatsOut(BaseModel):
    total_users: int
    total_projects: int
    total_generations: int
    total_records: int
    total_revenue: float
    credits_consumed_today: float
    today_alipay_revenue: float
    today_wechat_revenue: float
    last_period_users: int = 0
    last_period_projects: int = 0
    last_period_generations: int = 0
    last_period_records: int = 0
    last_period_revenue: float = 0.0
    last_period_credits_consumed: float = 0.0


class AdminCreditRecordSummaryOut(BaseModel):
    total_recharge: float = 0.0
    total_consume: float = 0.0
    total_refund: float = 0.0
    transaction_count: int = 0
    generation_count: int = 0
    generation_attempt_count: int = 0
    image_generation_count: int = 0
    video_generation_count: int = 0
    image_consume: float = 0.0
    video_consume: float = 0.0
    text_consume: float = 0.0
    analysis_consume: float = 0.0
    total_tokens: int = 0
    input_tokens: int = 0
    output_tokens: int = 0


class AdminCreditRecordOut(BaseModel):
    id: str
    user_id: str
    username: str | None = None
    phone: str | None = None
    email: str | None = None
    user_type: str | None = None
    user_type_label: str | None = None
    frontend_user_kind: str | None = None
    frontend_user_kind_label: str | None = None
    type: str
    record_type: str
    record_type_label: str | None = None
    amount: float
    balance_after: float
    description: str | None = None
    related_id: str | None = None
    biz_key: str | None = None
    refund_for_biz_key: str | None = None
    owner_type: str | None = None
    owner_id: str | None = None
    owner_deleted: bool = False
    owner_deleted_at: str | None = None
    attempt_no: int | None = None
    charge_kind: str | None = None
    charge_kind_label: str | None = None
    charge_action: str | None = None
    credit_subject: str | None = None
    credit_subject_label: str | None = None
    media_type: str | None = None
    media_type_label: str | None = None
    billing_scene: str | None = None
    billing_scene_label: str | None = None
    source_module: str | None = None
    source_module_label: str | None = None
    source_project_id: str | None = None
    source_step_id: str | None = None
    source_step_code: str | None = None
    source_step_code_label: str | None = None
    token_usage_id: str | None = None
    input_tokens: int = 0
    output_tokens: int = 0
    total_tokens: int = 0
    engine_type: str | None = None
    engine_id: str | None = None
    engine_name: str | None = None
    engine_provider: str | None = None
    engine_model_name: str | None = None
    created_at: str | None = None


class AdminCreditRecordListOut(BaseModel):
    items: list[AdminCreditRecordOut]
    total: int
    summary: AdminCreditRecordSummaryOut
