"""Flow proposal model.

Generated by the Knowledge Flywheel after AI sessions resolve.
Represents a proposed new flow or enhancement awaiting human review.
"""
import uuid
from datetime import datetime, timezone
from typing import Optional, Any, TYPE_CHECKING

from sqlalchemy import String, Text, DateTime, ForeignKey, Integer, Float, CheckConstraint
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.dialects.postgresql import UUID, JSONB

from app.core.database import Base

if TYPE_CHECKING:
    from app.models.user import User
    from app.models.team import Team
    from app.models.account import Account
    from app.models.tree import Tree
    from app.models.ai_session import AISession


class FlowProposal(Base):
    """A proposed new flow or enhancement generated from an AI session.

    proposal_type:
    - new_flow: No similar flow exists. Full flow definition proposed.
    - enhancement: Similar flow exists but session discovered new branch/edge case.
    - branch_addition: A single new branch to add to an existing flow.
    - auto_reinforced: Session matched existing flow exactly (tracking only).

    status:
    - pending: Awaiting review
    - approved: Reviewed and published to knowledge base
    - modified: Reviewer edited before publishing
    - rejected: Reviewer decided not to publish (bad quality)
    - dismissed: Parked for later — not wrong, just not actionable now.
    - auto_reinforced: Session matched existing flow exactly (no review needed)
    """
    __tablename__ = "flow_proposals"
    __table_args__ = (
        CheckConstraint(
            "proposal_type IN ('new_flow', 'enhancement', 'branch_addition', 'auto_reinforced')",
            name="ck_flow_proposals_type",
        ),
        CheckConstraint(
            "status IN ('pending', 'approved', 'modified', 'rejected', 'dismissed', 'auto_reinforced')",
            name="ck_flow_proposals_status",
        ),
    )

    id: Mapped[uuid.UUID] = mapped_column(
        UUID(as_uuid=True), primary_key=True, default=uuid.uuid4
    )
    account_id: Mapped[uuid.UUID] = mapped_column(
        UUID(as_uuid=True),
        ForeignKey("accounts.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
    )
    team_id: Mapped[Optional[uuid.UUID]] = mapped_column(
        UUID(as_uuid=True),
        ForeignKey("teams.id", ondelete="SET NULL"),
        nullable=True,
        index=True,
    )
    source_session_id: Mapped[uuid.UUID] = mapped_column(
        UUID(as_uuid=True),
        ForeignKey("ai_sessions.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
    )

    # ── Proposal details ──
    proposal_type: Mapped[str] = mapped_column(
        String(30), nullable=False,
    )
    target_flow_id: Mapped[Optional[uuid.UUID]] = mapped_column(
        UUID(as_uuid=True),
        ForeignKey("trees.id", ondelete="SET NULL"),
        nullable=True,
        comment="For enhancements: which existing flow to modify",
    )
    title: Mapped[str] = mapped_column(
        String(255), nullable=False,
        comment="Human-readable title for the proposed flow",
    )
    description: Mapped[Optional[str]] = mapped_column(
        Text, nullable=True,
        comment="AI-generated description of what this flow covers",
    )
    proposed_flow_data: Mapped[dict[str, Any]] = mapped_column(
        JSONB, nullable=False,
        comment="Complete flow/tree_structure definition (nodes, edges, conditions)",
    )
    proposed_diff: Mapped[Optional[dict[str, Any]]] = mapped_column(
        JSONB, nullable=True,
        comment="For enhancements: what changed vs existing flow",
    )

    # ── Scoring ──
    confidence_score: Mapped[float] = mapped_column(
        Float, nullable=False, default=0.0,
        comment="How confident the system is in this proposal (0.0-1.0)",
    )
    supporting_session_count: Mapped[int] = mapped_column(
        Integer, nullable=False, default=1,
        comment="Number of sessions with similar resolution paths",
    )
    supporting_session_ids: Mapped[list] = mapped_column(
        JSONB, nullable=False, default=list,
        comment="Array of session IDs that support this proposal",
    )
    problem_domain: Mapped[Optional[str]] = mapped_column(
        String(100), nullable=True,
    )

    # ── Review ──
    status: Mapped[str] = mapped_column(
        String(30), nullable=False, default="pending", index=True,
    )
    reviewed_by: Mapped[Optional[uuid.UUID]] = mapped_column(
        UUID(as_uuid=True),
        ForeignKey("users.id", ondelete="SET NULL"),
        nullable=True,
    )
    reviewer_notes: Mapped[Optional[str]] = mapped_column(
        Text, nullable=True,
    )
    published_flow_id: Mapped[Optional[uuid.UUID]] = mapped_column(
        UUID(as_uuid=True),
        ForeignKey("trees.id", ondelete="SET NULL"),
        nullable=True,
        comment="The flow that was created/updated when this proposal was approved",
    )

    # ── Timestamps ──
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)
    )
    reviewed_at: Mapped[Optional[datetime]] = mapped_column(
        DateTime(timezone=True), nullable=True,
    )

    # ── Relationships ──
    account: Mapped["Account"] = relationship("Account")
    team: Mapped[Optional["Team"]] = relationship("Team")
    source_session: Mapped["AISession"] = relationship("AISession")
    target_flow: Mapped[Optional["Tree"]] = relationship("Tree", foreign_keys=[target_flow_id])
    published_flow: Mapped[Optional["Tree"]] = relationship("Tree", foreign_keys=[published_flow_id])
    reviewer: Mapped[Optional["User"]] = relationship("User")
