"""Completed-transaction model (Trust System — Phase 1).

A :class:`CompletedTransaction` is the authoritative record that a sale actually
happened: which buyer received which listing, via which accepted offer, and when.
It is the trustworthy foundation later Trust-System phases build on (reviews,
ratings, reputation, badges, seller/buyer statistics) — those features reference
this table rather than inferring the counterparties from listing status.

Integrity is enforced at the database level: exactly **one** transaction per
sold listing and per accepted offer (unique constraints), with foreign keys to
the listing, offer and both users. The model is intentionally minimal and easy
to extend — new columns (e.g. a future ``review`` relationship) can be added
without reshaping the sale flow.
"""

from __future__ import annotations

from app.extensions import db
from app.models.base import BaseModel, BigIntegerType, utcnow
from app.models.mixins import PublicIdMixin, TimestampMixin


class CompletedTransaction(BaseModel, PublicIdMixin, TimestampMixin):
    """One finalised sale between a buyer and a seller."""

    __tablename__ = "completed_transactions"
    __table_args__ = (
        # One transaction per sold listing and per accepted offer.
        db.UniqueConstraint("listing_id", name="uq_completed_transactions_listing_id"),
        db.UniqueConstraint("offer_id", name="uq_completed_transactions_offer_id"),
        # Reputation / statistics queries filter by participant.
        db.Index("ix_completed_transactions_buyer_id", "buyer_id"),
        db.Index("ix_completed_transactions_seller_id", "seller_id"),
        db.Index("ix_completed_transactions_completed_at", "completed_at"),
    )

    listing_id = db.Column(BigIntegerType, db.ForeignKey("listings.id"), nullable=False)
    offer_id = db.Column(BigIntegerType, db.ForeignKey("offers.id"), nullable=False)
    buyer_id = db.Column(BigIntegerType, db.ForeignKey("users.id"), nullable=False)
    seller_id = db.Column(BigIntegerType, db.ForeignKey("users.id"), nullable=False)
    completed_at = db.Column(db.DateTime, nullable=False, default=utcnow)

    listing = db.relationship("Listing", foreign_keys=[listing_id])
    offer = db.relationship("Offer", foreign_keys=[offer_id])
    buyer = db.relationship("User", foreign_keys=[buyer_id])
    seller = db.relationship("User", foreign_keys=[seller_id])

    def __repr__(self) -> str:
        return f"<CompletedTransaction id={self.id} listing_id={self.listing_id} buyer_id={self.buyer_id}>"
