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

class NotificationChannel(str, enum.Enum):
    email = 'email'
    sms = 'sms'
    push = 'push'
    whatsapp = 'whatsapp'
    in_app = 'in_app'

class NotificationStatus(str, enum.Enum):
    pending = 'pending'
    sent = 'sent'
    delivered = 'delivered'
    failed = 'failed'
    read = 'read'

class NotificationType(str, enum.Enum):
    booking_confirmation = 'booking_confirmation'
    payment_receipt = 'payment_receipt'
    pre_arrival_reminder = 'pre_arrival_reminder'
    check_in_reminder = 'check_in_reminder'
    check_out_reminder = 'check_out_reminder'
    marketing_campaign = 'marketing_campaign'
    loyalty_update = 'loyalty_update'
    shift_update = 'shift_update'
    system_alert = 'system_alert'
    custom = 'custom'

class Notification(Base):
    __tablename__ = 'notifications'
    
    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    user_id = Column(Integer, ForeignKey('users.id'), nullable=True)  # Nullable for system-wide notifications
    notification_type = Column(Enum(NotificationType), nullable=False)
    channel = Column(Enum(NotificationChannel), nullable=False)
    subject = Column(String(255), nullable=True)  # For email/push
    content = Column(Text, nullable=False)
    template_id = Column(Integer, ForeignKey('notification_templates.id'), nullable=True)
    status = Column(Enum(NotificationStatus), nullable=False, default=NotificationStatus.pending)
    priority = Column(String(20), nullable=False, default='normal')  # low, normal, high, urgent
    scheduled_at = Column(DateTime, nullable=True)  # For scheduled notifications
    sent_at = Column(DateTime, nullable=True)
    delivered_at = Column(DateTime, nullable=True)
    read_at = Column(DateTime, nullable=True)
    error_message = Column(Text, nullable=True)
    external_id = Column(String(255), nullable=True)  # ID from external service (e.g., Twilio, SendGrid)
    meta_data = Column(JSON, nullable=True)  # Additional data (recipient info, attachments, etc.)
    booking_id = Column(Integer, ForeignKey('bookings.id'), nullable=True)
    payment_id = Column(Integer, ForeignKey('payments.id'), nullable=True)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
    
    user = relationship('User')
    template = relationship('NotificationTemplate')
    booking = relationship('Booking')
    payment = relationship('Payment')
    delivery_logs = relationship('NotificationDeliveryLog', back_populates='notification', cascade='all, delete-orphan')

class NotificationTemplate(Base):
    __tablename__ = 'notification_templates'
    
    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    name = Column(String(255), nullable=False)
    notification_type = Column(Enum(NotificationType), nullable=False)
    channel = Column(Enum(NotificationChannel), nullable=False)
    subject = Column(String(255), nullable=True)
    content = Column(Text, nullable=False)
    variables = Column(JSON, nullable=True)  # Available template variables
    is_active = Column(Boolean, nullable=False, default=True)
    created_by = Column(Integer, ForeignKey('users.id'), nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
    
    creator = relationship('User', foreign_keys=[created_by])
    notifications = relationship('Notification', back_populates='template')

class NotificationPreference(Base):
    __tablename__ = 'notification_preferences'
    
    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    user_id = Column(Integer, ForeignKey('users.id'), nullable=False, unique=True)
    email_enabled = Column(Boolean, nullable=False, default=True)
    sms_enabled = Column(Boolean, nullable=False, default=True)
    push_enabled = Column(Boolean, nullable=False, default=True)
    whatsapp_enabled = Column(Boolean, nullable=False, default=False)
    in_app_enabled = Column(Boolean, nullable=False, default=True)
    # Per-type preferences
    booking_confirmation_email = Column(Boolean, nullable=False, default=True)
    booking_confirmation_sms = Column(Boolean, nullable=False, default=False)
    payment_receipt_email = Column(Boolean, nullable=False, default=True)
    payment_receipt_sms = Column(Boolean, nullable=False, default=False)
    pre_arrival_reminder_email = Column(Boolean, nullable=False, default=True)
    pre_arrival_reminder_sms = Column(Boolean, nullable=False, default=True)
    check_in_reminder_email = Column(Boolean, nullable=False, default=True)
    check_in_reminder_sms = Column(Boolean, nullable=False, default=True)
    check_out_reminder_email = Column(Boolean, nullable=False, default=True)
    check_out_reminder_sms = Column(Boolean, nullable=False, default=True)
    marketing_campaign_email = Column(Boolean, nullable=False, default=True)
    marketing_campaign_sms = Column(Boolean, nullable=False, default=False)
    loyalty_update_email = Column(Boolean, nullable=False, default=True)
    loyalty_update_sms = Column(Boolean, nullable=False, default=False)
    system_alert_email = Column(Boolean, nullable=False, default=True)
    system_alert_push = 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)
    
    user = relationship('User')

class NotificationDeliveryLog(Base):
    __tablename__ = 'notification_delivery_logs'
    
    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    notification_id = Column(Integer, ForeignKey('notifications.id'), nullable=False)
    channel = Column(Enum(NotificationChannel), nullable=False)
    status = Column(Enum(NotificationStatus), nullable=False)
    external_id = Column(String(255), nullable=True)
    error_message = Column(Text, nullable=True)
    response_data = Column(JSON, nullable=True)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    
    notification = relationship('Notification', back_populates='delivery_logs')

