from sqlalchemy import Column, Integer, String, DateTime, Numeric, Boolean, Text, Enum
from sqlalchemy.orm import relationship
from datetime import datetime
import enum
from ..config.database import Base

class DiscountType(str, enum.Enum):
    percentage = 'percentage'
    fixed_amount = 'fixed_amount'

class Promotion(Base):
    __tablename__ = 'promotions'
    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    code = Column(String(50), unique=True, nullable=False, index=True)
    name = Column(String(100), nullable=False)
    description = Column(Text, nullable=True)
    discount_type = Column(Enum(DiscountType), nullable=False)
    discount_value = Column(Numeric(10, 2), nullable=False)
    min_booking_amount = Column(Numeric(10, 2), nullable=True)
    max_discount_amount = Column(Numeric(10, 2), nullable=True)
    start_date = Column(DateTime, nullable=False)
    end_date = Column(DateTime, nullable=False)
    usage_limit = Column(Integer, nullable=True)
    used_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)

    def is_valid(self):
        from datetime import datetime
        now = datetime.utcnow()
        if not self.is_active:
            return False
        if now < self.start_date or now > self.end_date:
            return False
        if self.usage_limit is not None and self.used_count >= self.usage_limit:
            return False
        return True

    def calculate_discount(self, booking_amount):
        if not self.is_valid():
            return 0.0
        if self.min_booking_amount and booking_amount < float(self.min_booking_amount):
            return 0.0
        discount = 0.0
        if self.discount_type == DiscountType.percentage:
            discount = float(booking_amount) * float(self.discount_value) / 100.0
        elif self.discount_type == DiscountType.fixed_amount:
            discount = float(self.discount_value)
        if self.max_discount_amount and discount > float(self.max_discount_amount):
            discount = float(self.max_discount_amount)
        return discount