from __future__ import annotations

from datetime import datetime
from typing import Literal

from pydantic import BaseModel, Field


class ExpenseApplicationMemoryConflict(BaseModel):
    scope_type: Literal["user", "department", "enterprise"]
    scope_label: str
    priority: int
    reason: Literal["same_priority_conflict", "lower_priority_overridden"]


class ExpenseApplicationMemoryApplication(BaseModel):
    memory_id: str
    field_key: str = "transport_mode"
    field_label: str = "出行方式"
    value: str
    source: str = "verified_user_history"
    status: str = "applied"
    evidence_count: int = 0
    approved_evidence_count: int = 0
    confidence: float = 0.0
    effective_confidence: float = 0.0
    expires_at: datetime | None = None
    scope_type: Literal["user", "department", "enterprise"] = "user"
    scope_id: str = ""
    scope_label: str = "个人偏好"
    priority: int = 100
    conflicts: list[ExpenseApplicationMemoryConflict] = Field(default_factory=list)
    can_revoke: bool = True
    message: str = "已按可信历史记忆预填常用出行方式，可继续修改。"


class ExpenseApplicationLearningReceipt(BaseModel):
    memory_id: str
    evidence_id: str
    field_key: str = "transport_mode"
    field_label: str = "出行方式"
    value: str
    status: str
    evidence_count: int = 0
    approved_evidence_count: int = 0
    activated: bool = False
    message: str


class ExpenseApplicationMemoryRead(BaseModel):
    id: str
    scene: str
    field_key: str
    value: str = ""
    status: str
    scope_type: Literal["user", "department", "enterprise"] = "user"
    scope_id: str = ""
    scope_label: str = "个人偏好"
    source: str = "verified_user_history"
    origin_type: Literal["learned", "admin_managed"] = "learned"
    generation: int = 1
    evidence_count: int = 0
    approved_evidence_count: int = 0
    confidence: float = 0.0
    activation_threshold: int = 3
    policy_version: str
    valid_from: datetime | None = None
    expires_at: datetime | None = None
    last_evidence_at: datetime | None = None
    activated_at: datetime | None = None
    suppressed_at: datetime | None = None
    revoked_at: datetime | None = None
    revoked_reason: str = ""
    managed_by: str = ""
    managed_at: datetime | None = None
    management_reason: str = ""
    superseded_by_id: str = ""
    can_revoke: bool = True
    created_at: datetime | None = None
    updated_at: datetime | None = None


class ExpenseApplicationMemoryListRead(BaseModel):
    items: list[ExpenseApplicationMemoryRead] = Field(default_factory=list)


class ExpenseApplicationMemoryRevokedRead(BaseModel):
    memory_id: str
    status: str = "revoked"
    revoked_at: datetime


class ExpenseApplicationOrganizationMemoryCreate(BaseModel):
    scope_type: Literal["department", "enterprise"]
    scope_id: str | None = Field(default=None, max_length=120)
    value: Literal["飞机", "火车", "轮船"]
    expires_in_days: int = Field(default=180, ge=30, le=365)
    reason: str = Field(min_length=1, max_length=255)
    request_id: str = Field(min_length=8, max_length=120)


class ExpenseApplicationOrganizationMemoryUpdate(BaseModel):
    value: Literal["飞机", "火车", "轮船"] | None = None
    expires_in_days: int | None = Field(default=None, ge=30, le=365)
    expected_generation: int = Field(ge=1)
    reason: str = Field(min_length=1, max_length=255)
    request_id: str = Field(min_length=8, max_length=120)


class ExpenseApplicationOrganizationMemoryRevoke(BaseModel):
    expected_generation: int = Field(ge=1)
    reason: str = Field(min_length=1, max_length=255)
    request_id: str = Field(min_length=8, max_length=120)
