"""Pydantic schemas for dimension tables."""

from datetime import date
from decimal import Decimal
from enum import Enum

from pydantic import BaseModel, Field, HttpUrl


class PolicyLevel(str, Enum):
    """Government level for policy events."""

    FEDERAL = "federal"
    PROVINCIAL = "provincial"
    MUNICIPAL = "municipal"


class PolicyCategory(str, Enum):
    """Policy event category."""

    MONETARY = "monetary"
    TAX = "tax"
    REGULATORY = "regulatory"
    SUPPLY = "supply"
    ECONOMIC = "economic"


class ExpectedDirection(str, Enum):
    """Expected price impact direction."""

    BULLISH = "bullish"  # Expected to increase prices
    BEARISH = "bearish"  # Expected to decrease prices
    NEUTRAL = "neutral"  # Uncertain or mixed impact


class Confidence(str, Enum):
    """Confidence level in policy event data."""

    HIGH = "high"
    MEDIUM = "medium"
    LOW = "low"


class AreaType(str, Enum):
    """TRREB area type."""

    WEST = "West"
    CENTRAL = "Central"
    EAST = "East"
    NORTH = "North"


class TimeDimension(BaseModel):
    """Schema for time dimension record."""

    date_key: int = Field(description="Date key in YYYYMMDD format")
    full_date: date
    year: int = Field(ge=2000, le=2100)
    month: int = Field(ge=1, le=12)
    quarter: int = Field(ge=1, le=4)
    month_name: str = Field(max_length=20)
    is_month_start: bool = True


class TRREBDistrict(BaseModel):
    """Schema for TRREB district dimension."""

    district_code: str = Field(max_length=3, description="W01, C01, E01, etc.")
    district_name: str = Field(max_length=100)
    area_type: AreaType
    geometry_wkt: str | None = Field(default=None, description="WKT geometry string")


class CMHCZone(BaseModel):
    """Schema for CMHC zone dimension."""

    zone_code: str = Field(max_length=10)
    zone_name: str = Field(max_length=100)
    geometry_wkt: str | None = Field(default=None, description="WKT geometry string")


class Neighbourhood(BaseModel):
    """Schema for City of Toronto neighbourhood dimension.

    Note: No FK to fact tables in V1 - reference overlay only.
    """

    neighbourhood_id: int = Field(ge=1, le=200)
    name: str = Field(max_length=100)
    geometry_wkt: str | None = Field(default=None)
    population: int | None = Field(default=None, ge=0)
    land_area_sqkm: Decimal | None = Field(default=None, ge=0)
    pop_density_per_sqkm: Decimal | None = Field(default=None, ge=0)
    pct_bachelors_or_higher: Decimal | None = Field(default=None, ge=0, le=100)
    median_household_income: Decimal | None = Field(default=None, ge=0)
    pct_owner_occupied: Decimal | None = Field(default=None, ge=0, le=100)
    pct_renter_occupied: Decimal | None = Field(default=None, ge=0, le=100)
    census_year: int = Field(default=2021, description="Census year for SCD tracking")


class PolicyEvent(BaseModel):
    """Schema for policy event dimension.

    Used for time-series annotation. No causation claims.
    """

    event_date: date = Field(description="Date event was announced/occurred")
    effective_date: date | None = Field(
        default=None, description="Date policy took effect"
    )
    level: PolicyLevel
    category: PolicyCategory
    title: str = Field(max_length=200, description="Short event title for display")
    description: str | None = Field(
        default=None, description="Longer description for tooltip"
    )
    expected_direction: ExpectedDirection
    source_url: HttpUrl | None = Field(default=None)
    confidence: Confidence = Field(default=Confidence.MEDIUM)

    model_config = {"str_strip_whitespace": True}
