import uuid
from datetime import datetime
from sqlalchemy import Column, String, DateTime, ForeignKey, Numeric, Integer, Text, Enum as SqlEnum
from sqlalchemy.orm import relationship
from utils.utils import Base
from .schema import OrderStatus, PaymentMethod, PaymentStatus, ShipmentStatus


class Order(Base):
    __tablename__ = "orders"

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    order_number = Column(String(50), nullable=False, unique=True, index=True)
    buyer_id = Column(String(36), ForeignKey("users.id", ondelete="RESTRICT"), nullable=False, index=True)
    seller_id = Column(String(36), ForeignKey("users.id", ondelete="RESTRICT"), nullable=False, index=True)
    status = Column(SqlEnum(OrderStatus, name="order_status"), nullable=False, index=True)
    subtotal = Column(Numeric(12, 2), nullable=False)
    shipping_cost = Column(Numeric(12, 2), nullable=False)
    tax_amount = Column(Numeric(12, 2), nullable=False)
    platform_fee = Column(Numeric(12, 2), nullable=False)
    total_amount = Column(Numeric(12, 2), nullable=False)
    shipping_address_id = Column(String(36), ForeignKey("addresses.id", ondelete="RESTRICT"), nullable=False, index=True)
    billing_address_id = Column(String(36), ForeignKey("addresses.id", ondelete="RESTRICT"), nullable=False, index=True)
    notes = Column(Text, nullable=True)
    cancelled_at = Column(DateTime, nullable=True)
    cancellation_reason = Column(Text, nullable=True)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)

    buyer = relationship("User", foreign_keys=[buyer_id], back_populates="orders_as_buyer")
    seller = relationship("User", foreign_keys=[seller_id], back_populates="orders_as_seller")
    shipping_address = relationship("Address", foreign_keys=[shipping_address_id], back_populates="orders_as_shipping")
    billing_address = relationship("Address", foreign_keys=[billing_address_id], back_populates="orders_as_billing")
    order_items = relationship("Orderitem", back_populates="order", cascade="all, delete-orphan", passive_deletes=True)
    payment = relationship("Payment", back_populates="order", uselist=False, cascade="all, delete-orphan", passive_deletes=True)
    shipment = relationship("Shipment", back_populates="order", uselist=False, cascade="all, delete-orphan", passive_deletes=True)
    review = relationship("Review", back_populates="order", uselist=False)
    dispute = relationship("Dispute", back_populates="order", uselist=False)
    conversations = relationship("Conversation", back_populates="order")
    transactions = relationship("Transaction", back_populates="order")
    promotion_usages = relationship("Promotionusage", back_populates="order")


class Orderitem(Base):
    __tablename__ = "order_items"

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    order_id = Column(String(36), ForeignKey("orders.id", ondelete="CASCADE"), nullable=False, index=True)
    listing_id = Column(String(36), ForeignKey("listings.id", ondelete="RESTRICT"), nullable=False, index=True)
    card_id = Column(String(36), ForeignKey("cards.id", ondelete="RESTRICT"), nullable=False, index=True)
    quantity = Column(Integer, nullable=False)
    price = Column(Numeric(12, 2), nullable=False)
    condition = Column(String(50), nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)

    order = relationship("Order", back_populates="order_items")
    listing = relationship("Listing", back_populates="order_items")
    card = relationship("Card", back_populates="order_items")


class Payment(Base):
    __tablename__ = "payments"

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    order_id = Column(String(36), ForeignKey("orders.id", ondelete="CASCADE"), nullable=False, unique=True, index=True)
    payment_method = Column(SqlEnum(PaymentMethod, name="payment_method"), nullable=False)
    amount = Column(Numeric(12, 2), nullable=False)
    currency = Column(String(3), nullable=False)
    status = Column(SqlEnum(PaymentStatus, name="payment_status"), nullable=False, index=True)
    transaction_id = Column(String(255), nullable=True, index=True)
    payment_gateway = Column(String(50), nullable=True)
    payment_details = Column(Text, nullable=True)
    processed_at = Column(DateTime, nullable=True)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)

    order = relationship("Order", back_populates="payment")


class Shipment(Base):
    __tablename__ = "shipments"

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    order_id = Column(String(36), ForeignKey("orders.id", ondelete="CASCADE"), nullable=False, unique=True, index=True)
    carrier = Column(String(100), nullable=False)
    tracking_number = Column(String(255), nullable=True, index=True)
    shipping_method = Column(String(100), nullable=True)
    status = Column(SqlEnum(ShipmentStatus, name="shipment_status"), nullable=False, index=True)
    shipped_at = Column(DateTime, nullable=True)
    estimated_delivery_date = Column(DateTime, nullable=True)
    delivered_at = Column(DateTime, nullable=True)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)

    order = relationship("Order", back_populates="shipment")