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

from app.models.budget import BudgetPeriod, BudgetStatus, BudgetLineType


# Budget Line Schemas

class BudgetLineBase(BaseModel):
    """Base budget line schema."""
    line_type: BudgetLineType
    department_code: str = Field(..., max_length=50)
    category: Optional[str] = Field(None, max_length=100)
    amount: float = Field(..., ge=0)
    currency: str = Field("XOF", max_length=3)
    description: Optional[str] = None
    notes: Optional[str] = None


class BudgetLineCreate(BudgetLineBase):
    """Schema for creating a budget line."""
    pass


class BudgetLineUpdate(BaseModel):
    """Schema for updating a budget line."""
    line_type: Optional[BudgetLineType] = None
    department_code: Optional[str] = Field(None, max_length=50)
    category: Optional[str] = Field(None, max_length=100)
    amount: Optional[float] = Field(None, ge=0)
    currency: Optional[str] = Field(None, max_length=3)
    description: Optional[str] = None
    notes: Optional[str] = None


class BudgetLineResponse(BudgetLineBase):
    """Schema for budget line response."""
    id: int
    budget_id: int
    created_at: date
    updated_at: date

    class Config:
        from_attributes = True


# Budget Schemas

class BudgetBase(BaseModel):
    """Base budget schema."""
    name: str = Field(..., min_length=1, max_length=200)
    period_type: BudgetPeriod
    year: int = Field(..., ge=2000, le=2100)
    month: Optional[int] = Field(None, ge=1, le=12)
    quarter: Optional[int] = Field(None, ge=1, le=4)
    start_date: date
    end_date: date
    notes: Optional[str] = None


class BudgetCreate(BudgetBase):
    """Schema for creating a budget."""
    establishment_id: int
    lines: List[BudgetLineCreate] = []


class BudgetUpdate(BaseModel):
    """Schema for updating a budget."""
    name: Optional[str] = Field(None, min_length=1, max_length=200)
    status: Optional[BudgetStatus] = None
    notes: Optional[str] = None


class BudgetResponse(BudgetBase):
    """Schema for budget response."""
    id: int
    establishment_id: int
    status: BudgetStatus
    created_by_id: Optional[int] = None
    approved_by_id: Optional[int] = None
    approved_at: Optional[date] = None
    created_at: date
    updated_at: date
    lines: List[BudgetLineResponse] = []

    # Computed fields
    total_revenue: float
    total_expenses: float
    net_income: float

    class Config:
        from_attributes = True


# Variance Analysis Schemas

class VarianceAnalysisResponse(BaseModel):
    """Schema for variance analysis response."""
    id: int
    establishment_id: int
    budget_id: int
    analysis_date: date
    period_type: BudgetPeriod
    department_code: str
    budget_amount: float
    actual_amount: float
    variance_amount: float
    variance_percent: float
    prior_year_amount: Optional[float] = None
    yoy_variance: Optional[float] = None
    yoy_variance_percent: Optional[float] = None
    is_favorable: bool

    class Config:
        from_attributes = True


class BudgetComparisonResponse(BaseModel):
    """Schema for budget vs actual comparison report."""
    budget_id: int
    budget_name: str
    period_type: BudgetPeriod
    start_date: date
    end_date: date

    # Totals
    total_budget_revenue: float
    total_actual_revenue: float
    total_budget_expenses: float
    total_actual_expenses: float
    total_budget_net: float
    total_actual_net: float

    # Variances by department
    department_variances: List[VarianceAnalysisResponse]


class YearOverYearComparison(BaseModel):
    """Schema for year-over-year comparison."""
    current_year: int
    prior_year: int
    department_code: str
    current_amount: float
    prior_amount: float
    variance: float
    variance_percent: float
    is_favorable: bool


class BudgetSummary(BaseModel):
    """Schema for budget summary."""
    id: int
    name: str
    year: int
    month: Optional[int] = None
    quarter: Optional[int] = None
    period_type: BudgetPeriod
    status: BudgetStatus
    total_revenue: float
    total_expenses: float
    net_income: float
    start_date: date
    end_date: date

    class Config:
        from_attributes = True
