import uuid
from datetime import datetime, timezone
from decimal import Decimal
from sqlalchemy import DateTime, ForeignKey, Numeric, String, Text, UniqueConstraint
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column
from app.db.base import Base
class Sale(Base):
 __tablename__='sales';__table_args__=(UniqueConstraint('business_id','receipt_number',name='uq_sale_business_receipt'),)
 id:Mapped[uuid.UUID]=mapped_column(UUID(as_uuid=True),primary_key=True,default=uuid.uuid4);business_id:Mapped[uuid.UUID]=mapped_column(UUID(as_uuid=True),ForeignKey('businesses.id',ondelete='CASCADE'),nullable=False,index=True);branch_id:Mapped[uuid.UUID]=mapped_column(UUID(as_uuid=True),ForeignKey('branches.id',ondelete='RESTRICT'),nullable=False,index=True);customer_id:Mapped[uuid.UUID|None]=mapped_column(UUID(as_uuid=True),ForeignKey('customers.id',ondelete='RESTRICT'));receipt_number:Mapped[str]=mapped_column(String(100),nullable=False);sale_datetime:Mapped[datetime]=mapped_column(DateTime(timezone=True),default=lambda:datetime.now(timezone.utc),nullable=False);lifecycle_status:Mapped[str]=mapped_column(String(20),default='COMPLETED',nullable=False);payment_status:Mapped[str]=mapped_column(String(20),nullable=False);subtotal:Mapped[Decimal]=mapped_column(Numeric(14,2),nullable=False);discount:Mapped[Decimal]=mapped_column(Numeric(14,2),nullable=False);tax:Mapped[Decimal]=mapped_column(Numeric(14,2),nullable=False);total:Mapped[Decimal]=mapped_column(Numeric(14,2),nullable=False);amount_paid:Mapped[Decimal]=mapped_column(Numeric(14,2),nullable=False);balance:Mapped[Decimal]=mapped_column(Numeric(14,2),nullable=False);notes:Mapped[str|None]=mapped_column(Text);created_by:Mapped[uuid.UUID]=mapped_column(UUID(as_uuid=True),ForeignKey('users.id',ondelete='RESTRICT'),nullable=False);created_at:Mapped[datetime]=mapped_column(DateTime(timezone=True),default=lambda:datetime.now(timezone.utc),nullable=False);updated_at:Mapped[datetime]=mapped_column(DateTime(timezone=True),default=lambda:datetime.now(timezone.utc),onupdate=lambda:datetime.now(timezone.utc),nullable=False)
class SaleItem(Base):
 __tablename__='sale_items'
 id:Mapped[uuid.UUID]=mapped_column(UUID(as_uuid=True),primary_key=True,default=uuid.uuid4);sale_id:Mapped[uuid.UUID]=mapped_column(UUID(as_uuid=True),ForeignKey('sales.id',ondelete='RESTRICT'),nullable=False,index=True);product_id:Mapped[uuid.UUID]=mapped_column(UUID(as_uuid=True),ForeignKey('products.id',ondelete='RESTRICT'),nullable=False);variant_id:Mapped[uuid.UUID|None]=mapped_column(UUID(as_uuid=True),ForeignKey('product_variants.id',ondelete='RESTRICT'));unit_id:Mapped[uuid.UUID|None]=mapped_column(UUID(as_uuid=True),ForeignKey('units.id',ondelete='RESTRICT'));quantity:Mapped[Decimal]=mapped_column(Numeric(14,4),nullable=False);quantity_in_base:Mapped[Decimal]=mapped_column(Numeric(14,4),nullable=False);unit_price:Mapped[Decimal]=mapped_column(Numeric(14,2),nullable=False);discount:Mapped[Decimal]=mapped_column(Numeric(14,2),nullable=False);line_total:Mapped[Decimal]=mapped_column(Numeric(14,2),nullable=False)
class SalePayment(Base):
 __tablename__='sale_payments'
 id:Mapped[uuid.UUID]=mapped_column(UUID(as_uuid=True),primary_key=True,default=uuid.uuid4);business_id:Mapped[uuid.UUID]=mapped_column(UUID(as_uuid=True),ForeignKey('businesses.id',ondelete='CASCADE'),nullable=False,index=True);sale_id:Mapped[uuid.UUID]=mapped_column(UUID(as_uuid=True),ForeignKey('sales.id',ondelete='RESTRICT'),nullable=False,index=True);amount:Mapped[Decimal]=mapped_column(Numeric(14,2),nullable=False);payment_method:Mapped[str]=mapped_column(String(20),nullable=False);reference:Mapped[str|None]=mapped_column(String(150));recorded_by:Mapped[uuid.UUID]=mapped_column(UUID(as_uuid=True),ForeignKey('users.id',ondelete='RESTRICT'),nullable=False);paid_at:Mapped[datetime]=mapped_column(DateTime(timezone=True),default=lambda:datetime.now(timezone.utc),nullable=False)
class SaleIdempotency(Base):
 __tablename__='sale_idempotency';__table_args__=(UniqueConstraint('business_id','user_id','idempotency_key',name='uq_sale_idempotency'),)
 id:Mapped[uuid.UUID]=mapped_column(UUID(as_uuid=True),primary_key=True,default=uuid.uuid4);business_id:Mapped[uuid.UUID]=mapped_column(UUID(as_uuid=True),ForeignKey('businesses.id',ondelete='CASCADE'),nullable=False);user_id:Mapped[uuid.UUID]=mapped_column(UUID(as_uuid=True),ForeignKey('users.id',ondelete='CASCADE'),nullable=False);idempotency_key:Mapped[str]=mapped_column(String(255),nullable=False);sale_id:Mapped[uuid.UUID]=mapped_column(UUID(as_uuid=True),ForeignKey('sales.id',ondelete='RESTRICT'),nullable=False)
