"""
Expense schemas for API requests and responses.
"""
from typing import Optional, List
from pydantic import BaseModel, Field
from datetime import date, datetime

from app.models.expense import ExpenseCategory, ExpenseStatus


class ExpenseAttachmentResponse(BaseModel):
    """Schema for expense attachment response."""
    id: int
    file_name: str
    file_path: str
    file_size: int
    mime_type: str
    uploaded_by_id: Optional[int] = None
    created_at: datetime

    class Config:
        from_attributes = True


class ExpenseBase(BaseModel):
    """Base expense schema."""
    description: str = Field(..., min_length=1, max_length=500)
    department_code: str = Field(..., min_length=1, max_length=50)
    category: ExpenseCategory
    amount_ht: float = Field(..., gt=0)
    tax_rate: float = Field(default=18.0, ge=0, le=100)
    expense_date: date
    due_date: Optional[date] = None
    supplier_name: Optional[str] = Field(None, max_length=200)
    supplier_reference: Optional[str] = Field(None, max_length=100)
    notes: Optional[str] = None


class ExpenseCreate(ExpenseBase):
    """Schema for creating an expense."""
    establishment_id: int


class ExpenseUpdate(BaseModel):
    """Schema for updating an expense."""
    description: Optional[str] = Field(None, min_length=1, max_length=500)
    department_code: Optional[str] = Field(None, min_length=1, max_length=50)
    category: Optional[ExpenseCategory] = None
    amount_ht: Optional[float] = Field(None, gt=0)
    tax_rate: Optional[float] = Field(None, ge=0, le=100)
    expense_date: Optional[date] = None
    due_date: Optional[date] = None
    supplier_name: Optional[str] = Field(None, max_length=200)
    supplier_reference: Optional[str] = Field(None, max_length=100)
    notes: Optional[str] = None


class ExpenseResponse(ExpenseBase):
    """Schema for expense response."""
    id: int
    reference: str
    establishment_id: int
    tax_amount: float
    amount_ttc: float
    currency: str
    status: ExpenseStatus
    paid_date: Optional[date] = None
    submitted_at: Optional[datetime] = None
    submitted_by_id: Optional[int] = None
    approved_at: Optional[datetime] = None
    approved_by_id: Optional[int] = None
    rejection_reason: Optional[str] = None
    attachments: List[ExpenseAttachmentResponse] = []
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True


class ExpenseListResponse(BaseModel):
    """Schema for list of expenses with pagination info."""
    items: List[ExpenseResponse]
    total: int
    page: int
    page_size: int


# Workflow action schemas
class ExpenseReject(BaseModel):
    """Schema for rejecting an expense."""
    reason: str = Field(..., min_length=1, max_length=500)


class ExpenseMarkPaid(BaseModel):
    """Schema for marking an expense as paid."""
    paid_date: date


# Statistics schemas
class ExpenseStatistics(BaseModel):
    """Statistics for expense dashboard."""
    total_expenses: float
    total_pending: float
    total_approved: float
    total_paid: float
    by_category: dict
    by_department: dict
    by_status: dict
    monthly_trend: List[dict]


class ExpenseByDepartment(BaseModel):
    """Expense grouped by department for budget comparison."""
    department_code: str
    total_amount: float
    expense_count: int
    categories: dict
