# FILE: src/apps/sales/models/contract.py
from __future__ import annotations

from datetime import datetime
from typing import TYPE_CHECKING, List, Optional
from uuid import UUID

from sqlalchemy import ForeignKey, String, Text, UniqueConstraint
from sqlalchemy import DateTime
from sqlalchemy.dialects.postgresql import UUID as PG_UUID
from sqlalchemy.orm import Mapped, mapped_column, relationship

from src.database.base import TenantModel

if TYPE_CHECKING:
    from src.apps.sales.models.contract_line_item import ContractLineItem
    from src.apps.billing.models.invoice import Invoice


class Contract(TenantModel):
    __tablename__ = "contracts"

    __table_args__ = (
        UniqueConstraint("tenant_id", "contract_number", name="uq_contracts_tenant_number"),
    )

    # Override tenant_id with explicit FK
    tenant_id: Mapped[UUID] = mapped_column(
        PG_UUID(as_uuid=True),
        ForeignKey("accounts.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
    )

    opportunity_id: Mapped[Optional[UUID]] = mapped_column(
        PG_UUID(as_uuid=True),
        ForeignKey("opportunities.id", ondelete="SET NULL"),
        nullable=True,
        index=True,
    )
    purchaser_id: Mapped[Optional[UUID]] = mapped_column(
        PG_UUID(as_uuid=True),
        ForeignKey("family_contacts.id", ondelete="SET NULL"),
        nullable=True,
        index=True,
    )
    plot_id: Mapped[Optional[UUID]] = mapped_column(
        PG_UUID(as_uuid=True),
        ForeignKey("plots.id", ondelete="SET NULL"),
        nullable=True,
        index=True,
    )

    contract_number: Mapped[str] = mapped_column(String(50), nullable=False)
    status: Mapped[str] = mapped_column(String(50), nullable=False, default="draft")
    purchaser_signature_b64: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
    witness_name: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
    signed_at: Mapped[Optional[datetime]] = mapped_column(
        DateTime(timezone=True), nullable=True
    )
    pdf_s3_key: Mapped[Optional[str]] = mapped_column(Text, nullable=True)

    # Relationships
    line_items: Mapped[List["ContractLineItem"]] = relationship(
        "ContractLineItem", back_populates="contract"
    )
    invoices: Mapped[List["Invoice"]] = relationship(
        "Invoice", back_populates="contract"
    )
