from sqlalchemy import Column, String, DateTime, Numeric, Date, Boolean, Integer, ForeignKey, Text, Enum as SqlEnum
from sqlalchemy.orm import relationship
from datetime import datetime
from utils.utils import Base
import uuid

class Payment(Base):
    __tablename__ = "payments"
    
    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    booking_id = Column(String(36), ForeignKey("bookings.id", ondelete="RESTRICT"), nullable=False, index=True)
    payment_method = Column(String(50), nullable=False)
    transaction_id = Column(String(255), nullable=True)
    amount = Column(Numeric(12, 2), nullable=False)
    currency = Column(String(3), nullable=False)
    payment_status = Column(String(50), nullable=False)
    payment_date = Column(DateTime, nullable=True)
    payment_gateway = Column(String(100), nullable=True)
    gateway_response = Column(Text, nullable=True)
    notes = 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)
    
    booking = relationship("Booking", back_populates="payments")

class Invoice(Base):
    __tablename__ = "invoices"
    
    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    booking_id = Column(String(36), ForeignKey("bookings.id", ondelete="RESTRICT"), nullable=False, index=True)
    invoice_number = Column(String(50), nullable=False, unique=True, index=True)
    invoice_date = Column(Date, nullable=False)
    due_date = Column(Date, nullable=True)
    subtotal = Column(Numeric(12, 2), nullable=False)
    tax_amount = Column(Numeric(12, 2), nullable=False)
    discount_amount = Column(Numeric(12, 2), nullable=False)
    total_amount = Column(Numeric(12, 2), nullable=False)
    notes = Column(Text, nullable=True)
    terms = Column(Text, nullable=True)
    invoice_status = 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)
    
    booking = relationship("Booking", back_populates="invoice")
    invoice_line_items = relationship("Invoicelineitem", back_populates="invoice", cascade="all, delete-orphan", passive_deletes=True)

class Invoicelineitem(Base):
    __tablename__ = "invoice_line_items"
    
    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    invoice_id = Column(String(36), ForeignKey("invoices.id", ondelete="CASCADE"), nullable=False, index=True)
    description = Column(String(255), nullable=False)
    quantity = Column(Integer, nullable=False)
    unit_price = Column(Numeric(12, 2), nullable=False)
    total_price = Column(Numeric(12, 2), nullable=False)
    item_order = Column(Integer, nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
    
    invoice = relationship("Invoice", back_populates="invoice_line_items")

class Discount(Base):
    __tablename__ = "discounts"
    
    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    code = Column(String(50), nullable=False, unique=True, index=True)
    name = Column(String(255), nullable=False)
    description = Column(Text, nullable=True)
    discount_type = Column(String(50), nullable=False)
    discount_value = Column(Numeric(12, 2), nullable=False)
    min_booking_amount = Column(Numeric(12, 2), nullable=True)
    max_discount_amount = Column(Numeric(12, 2), nullable=True)
    min_travelers = Column(Integer, nullable=True)
    applicable_tour_package_id = Column(String(36), ForeignKey("tour_packages.id", ondelete="SET NULL"), nullable=True, index=True)
    valid_from = Column(Date, nullable=False)
    valid_to = Column(Date, nullable=False)
    usage_limit = Column(Integer, nullable=True)
    usage_count = Column(Integer, nullable=False, default=0)
    is_active = Column(Boolean, nullable=False, default=True)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
    
    applicable_tour_package = relationship("Tourpackage", back_populates="discounts")
    bookings = relationship("Booking", back_populates="discount")