"""
采购确认和抵扣相关的Pydantic模式定义
"""

from datetime import datetime
from typing import Optional, List, Dict, Any
from decimal import Decimal
from pydantic import BaseModel, Field, validator


# ============= FIFO和采购确认相关模式 =============

class ProcurementConfirmationCreate(BaseModel):
    """创建采购确认请求"""
    purchase_list_id: int = Field(..., description="采购清单ID")
    product_key: str = Field(..., description="产品键")
    confirmed_quantity: int = Field(..., gt=0, description="确认采购数量")
    unit_cost: Optional[Decimal] = Field(None, ge=0, description="采购单价")
    supplier: Optional[str] = Field(None, max_length=255, description="供应商")
    expected_arrival: Optional[datetime] = Field(None, description="预计到货时间")
    notes: Optional[str] = Field(None, description="备注")


class ProcurementConfirmationUpdate(BaseModel):
    """更新采购确认请求"""
    confirmed_quantity: Optional[int] = Field(None, gt=0, description="确认采购数量")
    unit_cost: Optional[Decimal] = Field(None, ge=0, description="采购单价")
    supplier: Optional[str] = Field(None, max_length=255, description="供应商")
    expected_arrival: Optional[datetime] = Field(None, description="预计到货时间")
    actual_arrival: Optional[datetime] = Field(None, description="实际到货时间")
    status: Optional[str] = Field(None, description="状态")
    notes: Optional[str] = Field(None, description="备注")


class ProcurementConfirmationResponse(BaseModel):
    """采购确认响应"""
    id: int
    purchase_list_id: int
    product_key: str
    confirmed_quantity: int
    unit_cost: Optional[Decimal]
    total_cost: Optional[Decimal]
    supplier: Optional[str]
    confirmed_at: datetime
    expected_arrival: Optional[datetime]
    actual_arrival: Optional[datetime]
    status: str
    remaining_quantity: int
    notes: Optional[str]
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True


class FIFOMatchResponse(BaseModel):
    """FIFO匹配响应"""
    id: int
    normalized_order_id: int
    procurement_confirmation_id: int
    product_key: str
    matched_quantity: int
    unit_cost: Optional[Decimal]
    match_score: Decimal
    order_date: datetime
    procurement_date: datetime
    matched_at: datetime
    match_type: str
    status: str
    notes: Optional[str]

    class Config:
        from_attributes = True


class FIFOReprocessRequest(BaseModel):
    """FIFO重新处理请求"""
    product_key: str = Field(..., description="产品键")
    force_reprocess: bool = Field(False, description="是否强制重新处理")


class ProcurementSummaryResponse(BaseModel):
    """采购摘要响应"""
    product_key: str
    total_confirmed: int
    total_matched: int
    remaining_procurement: int
    unmatched_orders: int
    match_rate: float


# ============= 退款检测相关模式 =============

class RefundDetectionResponse(BaseModel):
    """退款检测响应"""
    id: int
    original_order_id: int
    refund_order_id: Optional[int]
    product_key: str
    detection_method: str
    confidence_score: Decimal
    refund_amount: Optional[Decimal]
    refund_quantity: Optional[int]
    refund_reason: Optional[str]
    original_order_date: datetime
    refund_order_date: Optional[datetime]
    detected_at: datetime
    status: str
    is_verified: bool
    notes: Optional[str]

    class Config:
        from_attributes = True


class RefundVerificationRequest(BaseModel):
    """退款验证请求"""
    is_verified: bool = Field(..., description="是否确认为退款")
    notes: Optional[str] = Field(None, description="验证备注")


class RefundDetectionBatchRequest(BaseModel):
    """批量退款检测请求"""
    limit: int = Field(1000, ge=1, le=10000, description="处理订单数量限制")
    force_reprocess: bool = Field(False, description="是否强制重新处理")


class RefundSummaryResponse(BaseModel):
    """退款检测摘要响应"""
    period_days: int
    total_detected: int
    status_breakdown: Dict[str, int]
    method_breakdown: Dict[str, int]
    average_confidence: float
    total_refund_amount: float


# ============= 抵扣关系相关模式 =============

class OffsetCalculationResponse(BaseModel):
    """抵扣计算响应"""
    original_cost: Decimal
    adjusted_cost: Decimal
    cost_impact: Decimal
    offset_quantity: int
    offset_amount: Decimal
    method: str
    confidence: float


class OffsetProposalResponse(BaseModel):
    """抵扣建议响应"""
    refund_detection_id: int
    fifo_match_id: int
    product_key: str
    offset_type: str
    calculation: OffsetCalculationResponse
    reason: str
    priority: int


class OffsetRelationshipCreate(BaseModel):
    """创建抵扣关系请求"""
    refund_detection_id: int = Field(..., description="退款检测ID")
    fifo_match_id: int = Field(..., description="FIFO匹配ID")
    offset_quantity: int = Field(..., gt=0, description="抵扣数量")
    offset_amount: Optional[Decimal] = Field(None, ge=0, description="抵扣金额")
    offset_type: str = Field("refund", description="抵扣类型")
    notes: Optional[str] = Field(None, description="备注")
    auto_approve: bool = Field(False, description="是否自动审批")


class OffsetRelationshipResponse(BaseModel):
    """抵扣关系响应"""
    id: int
    refund_detection_id: int
    fifo_match_id: int
    product_key: str
    offset_quantity: int
    offset_amount: Optional[Decimal]
    original_cost: Optional[Decimal]
    adjusted_cost: Optional[Decimal]
    cost_impact: Optional[Decimal]
    offset_date: datetime
    offset_type: str
    status: str
    approval_status: str
    approved_by: Optional[str]
    approved_at: Optional[datetime]
    approval_notes: Optional[str]
    notes: Optional[str]

    class Config:
        from_attributes = True


class OffsetApprovalRequest(BaseModel):
    """抵扣审批请求"""
    approved_by: str = Field(..., description="审批人")
    approval_notes: Optional[str] = Field(None, description="审批备注")


class OffsetRejectionRequest(BaseModel):
    """抵扣拒绝请求"""
    rejected_by: str = Field(..., description="拒绝人")
    rejection_reason: str = Field(..., description="拒绝原因")


class OffsetBatchProcessRequest(BaseModel):
    """批量抵扣处理请求"""
    limit: int = Field(100, ge=1, le=1000, description="处理数量限制")
    auto_approve_threshold: float = Field(0.8, ge=0.0, le=1.0, description="自动审批置信度阈值")


class OffsetSummaryResponse(BaseModel):
    """抵扣摘要响应"""
    period_days: int
    total_offsets: int
    status_breakdown: Dict[str, int]
    type_breakdown: Dict[str, int]
    total_offset_amount: float
    pending_approvals: int


# ============= 手工备注相关模式 =============

class ManualNoteCreate(BaseModel):
    """创建手工备注请求"""
    note_type: str = Field(..., description="备注类型")
    title: str = Field(..., max_length=255, description="标题")
    content: str = Field(..., description="内容")
    created_by: str = Field(..., description="创建人")
    priority: str = Field("normal", description="优先级")
    tags: Optional[List[str]] = Field(None, description="标签列表")
    category: Optional[str] = Field(None, description="分类")
    assigned_to: Optional[str] = Field(None, description="分配给")
    due_date: Optional[datetime] = Field(None, description="截止日期")
    
    # 关联对象
    offset_relationship_id: Optional[int] = Field(None, description="抵扣关系ID")
    fifo_match_id: Optional[int] = Field(None, description="FIFO匹配ID")
    procurement_confirmation_id: Optional[int] = Field(None, description="采购确认ID")
    refund_detection_id: Optional[int] = Field(None, description="退款检测ID")
    
    is_pinned: bool = Field(False, description="是否置顶")


class ManualNoteUpdate(BaseModel):
    """更新手工备注请求"""
    title: Optional[str] = Field(None, max_length=255, description="标题")
    content: Optional[str] = Field(None, description="内容")
    priority: Optional[str] = Field(None, description="优先级")
    tags: Optional[List[str]] = Field(None, description="标签列表")
    category: Optional[str] = Field(None, description="分类")
    assigned_to: Optional[str] = Field(None, description="分配给")
    due_date: Optional[datetime] = Field(None, description="截止日期")
    status: Optional[str] = Field(None, description="状态")
    is_pinned: Optional[bool] = Field(None, description="是否置顶")


class ManualNoteResponse(BaseModel):
    """手工备注响应"""
    id: int
    note_type: str
    title: str
    content: str
    priority: str
    tags: List[str]
    category: Optional[str]
    status: str
    is_pinned: bool
    created_by: str
    assigned_to: Optional[str]
    due_date: Optional[datetime]
    resolved_at: Optional[datetime]
    created_at: datetime
    updated_at: datetime
    
    # 关联信息
    offset_relationship_id: Optional[int]
    fifo_match_id: Optional[int]
    procurement_confirmation_id: Optional[int]
    refund_detection_id: Optional[int]

    class Config:
        from_attributes = True


class ManualNoteFilter(BaseModel):
    """备注过滤条件"""
    note_type: Optional[str] = None
    priority: Optional[str] = None
    status: Optional[str] = None
    created_by: Optional[str] = None
    assigned_to: Optional[str] = None
    tags: Optional[List[str]] = None
    category: Optional[str] = None
    date_from: Optional[datetime] = None
    date_to: Optional[datetime] = None
    is_pinned: Optional[bool] = None
    has_due_date: Optional[bool] = None


class ManualNoteListRequest(BaseModel):
    """备注列表请求"""
    filters: Optional[ManualNoteFilter] = None
    page: int = Field(1, ge=1, description="页码")
    page_size: int = Field(50, ge=1, le=200, description="页面大小")
    order_by: str = Field("created_at", description="排序字段")
    order_desc: bool = Field(True, description="是否降序")


class ManualNoteSummaryResponse(BaseModel):
    """备注摘要响应"""
    total_active: int
    total_resolved: int
    overdue_count: int
    due_today_count: int
    priority_breakdown: Dict[str, int]
    type_breakdown: Dict[str, int]


class ManualNoteBulkUpdateRequest(BaseModel):
    """批量更新备注请求"""
    note_ids: List[int] = Field(..., min_items=1, description="备注ID列表")
    new_status: str = Field(..., description="新状态")


# ============= 通用响应模式 =============

class PaginatedResponse(BaseModel):
    """分页响应基类"""
    items: List[Any]
    total: int
    page: int
    page_size: int
    total_pages: int

    @validator('total_pages', pre=True, always=True)
    def calculate_total_pages(cls, v, values):
        total = values.get('total', 0)
        page_size = values.get('page_size', 1)
        return (total + page_size - 1) // page_size if page_size > 0 else 0


class OperationResult(BaseModel):
    """操作结果"""
    success: bool
    message: str
    data: Optional[Dict[str, Any]] = None


class BatchOperationResult(BaseModel):
    """批量操作结果"""
    total_processed: int
    successful_count: int
    failed_count: int
    errors: List[str] = []
    results: Optional[List[Any]] = None