from __future__ import annotations

from datetime import datetime

from sqlalchemy import BigInteger, Index, Integer, String, Text, UniqueConstraint, func
from sqlalchemy.orm import Mapped, mapped_column

from supply_infra.db.base import Base


class DemandGradePlan(Base):
    """统筹规划 Agent 产出的单日全量分级计划。"""

    __tablename__ = "demand_grade_plan"
    __table_args__ = (Index("idx_demand_grade_plan_biz_dt", "biz_dt"),)

    id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
    plan_id: Mapped[str] = mapped_column(String(36), nullable=False, unique=True)
    biz_dt: Mapped[str] = mapped_column(String(8), nullable=False)
    status: Mapped[str] = mapped_column(String(32), nullable=False, default="planned")
    total_hanging_nodes: Mapped[int] = mapped_column(Integer, nullable=False)
    group_count: Mapped[int] = mapped_column(Integer, nullable=False)
    coverage_complete: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    plan_json: Mapped[str] = mapped_column(Text, nullable=False)
    create_time: Mapped[datetime] = mapped_column(nullable=False, server_default=func.now())
    update_time: Mapped[datetime] = mapped_column(nullable=False, server_default=func.now(), onupdate=func.now())


class DemandGradePlanGroup(Base):
    """日计划中的节点组任务，由并发分级 worker 领取执行。"""

    __tablename__ = "demand_grade_plan_group"
    __table_args__ = (
        UniqueConstraint("plan_id", "group_no", name="uk_demand_grade_plan_group"),
        Index("idx_demand_grade_plan_group_claim", "plan_id", "status", "group_no"),
        Index("idx_demand_grade_plan_group_biz_dt", "biz_dt"),
    )

    id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
    plan_id: Mapped[str] = mapped_column(String(36), nullable=False)
    biz_dt: Mapped[str] = mapped_column(String(8), nullable=False)
    group_no: Mapped[int] = mapped_column(Integer, nullable=False)
    group_key: Mapped[str] = mapped_column(String(128), nullable=False)
    category_ids: Mapped[str] = mapped_column(Text, nullable=False)
    planning_reason: Mapped[str] = mapped_column(Text, nullable=False)
    shared_traits: Mapped[str] = mapped_column(Text, nullable=False)
    status: Mapped[str] = mapped_column(String(32), nullable=False, default="pending")
    attempts: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    error_message: Mapped[str | None] = mapped_column(Text, nullable=True)
    started_at: Mapped[datetime | None] = mapped_column(nullable=True)
    finished_at: Mapped[datetime | None] = mapped_column(nullable=True)
    create_time: Mapped[datetime] = mapped_column(nullable=False, server_default=func.now())
    update_time: Mapped[datetime] = mapped_column(nullable=False, server_default=func.now(), onupdate=func.now())


class DemandGradePlanGroupItem(Base):
    """计划组内待执行分级的具体需求池记录。"""

    __tablename__ = "demand_grade_plan_group_item"
    __table_args__ = (
        UniqueConstraint("group_id", "pool_id", name="uk_demand_grade_plan_group_item"),
        Index("idx_demand_grade_plan_group_item_group_status", "group_id", "status", "sort_order"),
        Index("idx_demand_grade_plan_group_item_biz_dt", "biz_dt"),
    )

    id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
    group_id: Mapped[int] = mapped_column(BigInteger, nullable=False)
    biz_dt: Mapped[str] = mapped_column(String(8), nullable=False)
    pool_id: Mapped[int] = mapped_column(BigInteger, nullable=False)
    demand_name: Mapped[str] = mapped_column(String(512), nullable=False)
    sort_order: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    status: Mapped[str] = mapped_column(String(32), nullable=False, default="pending")
    error_message: Mapped[str | None] = mapped_column(Text, nullable=True)
    finished_at: Mapped[datetime | None] = mapped_column(nullable=True)
    create_time: Mapped[datetime] = mapped_column(nullable=False, server_default=func.now())
    update_time: Mapped[datetime] = mapped_column(nullable=False, server_default=func.now(), onupdate=func.now())
