from __future__ import annotations
import uuid
from datetime import datetime
from typing import Optional, Dict, Any
from sqlmodel import SQLModel, Field, Column
from sqlalchemy import JSON, DateTime

# --- Core routing tables ---


class RoutingRule(SQLModel, table=True):
    __tablename__ = "routing_rules"
    __table_args__ = {"extend_existing": True}
    id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
    tenant_id: Optional[str] = Field(default=None, index=True)
    priority: int = Field(index=True, description="Lower number = higher priority")
    condition: Dict[str, Any] = Field(
        sa_column=Column(JSON), description="Condition JSON (DSL)"
    )
    action: Dict[str, Any] = Field(
        sa_column=Column(JSON), description="Action JSON (DSL)"
    )
    enabled: bool = Field(default=True)
    updated_at: datetime = Field(
        default_factory=datetime.utcnow, sa_column=Column(DateTime(timezone=False))
    )


class RoutingPool(SQLModel, table=True):
    __tablename__ = "routing_pools"
    __table_args__ = {"extend_existing": True}
    id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
    tenant_id: Optional[str] = Field(default=None, index=True)
    name: str = Field(index=True)
    algorithm: str = Field(default="fair_rr", description="fair_rr|weighted_rr|random")
    daily_cap: Optional[int] = None
    timezone: Optional[str] = None
    enabled: bool = Field(default=True)
    updated_at: datetime = Field(
        default_factory=datetime.utcnow, sa_column=Column(DateTime(timezone=False))
    )


class PoolMember(SQLModel, table=True):
    __tablename__ = "pool_members"
    __table_args__ = {"extend_existing": True}
    id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
    pool_id: uuid.UUID = Field(foreign_key="routing_pools.id", index=True)
    user_id: str = Field(index=True)
    weight: float = Field(default=1.0)
    daily_cap: Optional[int] = None
    work_hours: Optional[Dict[str, Any]] = Field(default=None, sa_column=Column(JSON))
    ooo_from: Optional[datetime] = Field(
        default=None, sa_column=Column(DateTime(timezone=False))
    )
    ooo_to: Optional[datetime] = Field(
        default=None, sa_column=Column(DateTime(timezone=False))
    )
    enabled: bool = Field(default=True)
    updated_at: datetime = Field(
        default_factory=datetime.utcnow, sa_column=Column(DateTime(timezone=False))
    )


class PoolState(SQLModel, table=True):
    __tablename__ = "pool_state"
    __table_args__ = {"extend_existing": True}
    pool_id: uuid.UUID = Field(foreign_key="routing_pools.id", primary_key=True)
    last_user_id: Optional[str] = Field(default=None)
    assigned_today: Dict[str, int] = Field(default_factory=dict, sa_column=Column(JSON))
    date_key: str = Field(
        default_factory=lambda: datetime.utcnow().strftime("%Y-%m-%d"), index=True
    )
    updated_at: datetime = Field(
        default_factory=datetime.utcnow, sa_column=Column(DateTime(timezone=False))
    )


class RoutingDecision(SQLModel, table=True):
    __tablename__ = "routing_decisions"
    __table_args__ = {"extend_existing": True}
    id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
    tenant_id: Optional[str] = Field(default=None, index=True)
    lead_id: str = Field(index=True)
    decision: str = Field(description="assign_owner|assign_pool|hold")
    owner_id: Optional[str] = None
    pool_id: Optional[uuid.UUID] = Field(default=None, foreign_key="routing_pools.id")
    reason: Optional[str] = None
    rule_id: Optional[uuid.UUID] = Field(default=None, foreign_key="routing_rules.id")
    run_id: Optional[str] = Field(
        default=None, index=True, description="Batch/run correlation id"
    )
    created_at: datetime = Field(
        default_factory=datetime.utcnow, sa_column=Column(DateTime(timezone=False))
    )
    context: Optional[Dict[str, Any]] = Field(default=None, sa_column=Column(JSON))


class IdempotencyKey(SQLModel, table=True):
    __tablename__ = "idempotency_keys"
    __table_args__ = {"extend_existing": True}
    key: str = Field(primary_key=True)
    scope: str = Field(index=True)
    status: str = Field(default="created", description="created|applied|error")
    decision_id: Optional[uuid.UUID] = Field(
        default=None, foreign_key="routing_decisions.id"
    )
    expires_at: Optional[datetime] = Field(
        default=None, sa_column=Column(DateTime(timezone=False))
    )
