from __future__ import annotations

import enum

from sqlalchemy import CheckConstraint, ForeignKey, Index, Integer, String, text
from sqlalchemy.orm import Mapped, mapped_column, relationship

from src.db.base import Base


class Form4ProjectLevelEnum(str, enum.Enum):
    PROGRAM = "program"
    PROJECT = "project"


class Form4Project(Base):
    __tablename__ = "form4_project"
    __table_args__ = (
        CheckConstraint(
            "level IN ('program', 'project')", name="chk_form4_project_level"
        ),
        CheckConstraint(
            "(level = 'program' AND parent_id IS NULL) OR (level = 'project')",
            name="chk_form4_project_parent",
        ),
        CheckConstraint(
            "(level = 'program') = (section_code IS NOT NULL)",
            name="chk_form4_project_section_code",
        ),
        Index(
            "ix_form4_project_section_code",
            "section_code",
            postgresql_where=text("level = 'program'"),
        ),
        Index("ix_v3_form4_project_parent", "parent_id"),
        Index("ix_v3_form4_project_form", "form_id"),
        {"schema": "v3"},
    )

    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str] = mapped_column(String)
    level: Mapped[Form4ProjectLevelEnum] = mapped_column(String)  # type: ignore
    section_code: Mapped[str | None] = mapped_column(String)
    parent_id: Mapped[int | None] = mapped_column(
        Integer, ForeignKey("v3.form4_project.id")
    )
    form_id: Mapped[int] = mapped_column(
        Integer, ForeignKey("v3.budget_form.id")
    )

    # parent = relationship("Form4Project", remote_side="Form4Project.id", back_populates="children")
    # children: Mapped[list["Form4Project"]] = relationship("Form4Project", back_populates="parent")  # type: ignore
    # budget_form = relationship("BudgetForm")
    # budget_lines: Mapped[list["BudgetLine"]] = relationship("BudgetLine", back_populates="form4_project")  # type: ignore
