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

class GroupBookingStatus(str, enum.Enum):
    draft = 'draft'
    pending = 'pending'
    confirmed = 'confirmed'
    partially_confirmed = 'partially_confirmed'
    checked_in = 'checked_in'
    checked_out = 'checked_out'
    cancelled = 'cancelled'

class PaymentOption(str, enum.Enum):
    coordinator_pays_all = 'coordinator_pays_all'
    individual_payments = 'individual_payments'
    split_payment = 'split_payment'

class GroupBooking(Base):
    __tablename__ = 'group_bookings'
    
    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    group_booking_number = Column(String(50), unique=True, nullable=False, index=True)
    
    # Coordinator information
    coordinator_id = Column(Integer, ForeignKey('users.id'), nullable=False)
    coordinator_name = Column(String(100), nullable=False)
    coordinator_email = Column(String(100), nullable=False)
    coordinator_phone = Column(String(20), nullable=True)
    
    # Group details
    group_name = Column(String(200), nullable=True)
    group_type = Column(String(50), nullable=True)  # corporate, wedding, conference, etc.
    total_rooms = Column(Integer, nullable=False, default=0)
    total_guests = Column(Integer, nullable=False, default=0)
    
    # Dates
    check_in_date = Column(DateTime, nullable=False)
    check_out_date = Column(DateTime, nullable=False)
    
    # Pricing
    base_rate_per_room = Column(Numeric(10, 2), nullable=False)
    group_discount_percentage = Column(Numeric(5, 2), nullable=True, default=0)
    group_discount_amount = Column(Numeric(10, 2), nullable=True, default=0)
    original_total_price = Column(Numeric(10, 2), nullable=False)
    discount_amount = Column(Numeric(10, 2), nullable=True, default=0)
    total_price = Column(Numeric(10, 2), nullable=False)
    
    # Payment
    payment_option = Column(Enum(PaymentOption), nullable=False, default=PaymentOption.coordinator_pays_all)
    deposit_required = Column(Boolean, nullable=False, default=False)
    deposit_percentage = Column(Integer, nullable=True)
    deposit_amount = Column(Numeric(10, 2), nullable=True)
    amount_paid = Column(Numeric(10, 2), nullable=False, default=0)
    balance_due = Column(Numeric(10, 2), nullable=False)
    
    # Status and policies
    status = Column(Enum(GroupBookingStatus), nullable=False, default=GroupBookingStatus.draft)
    cancellation_policy = Column(Text, nullable=True)
    cancellation_deadline = Column(DateTime, nullable=True)
    cancellation_penalty_percentage = Column(Numeric(5, 2), nullable=True, default=0)
    
    # Additional information
    special_requests = Column(Text, nullable=True)
    notes = Column(Text, nullable=True)
    contract_terms = Column(Text, nullable=True)
    
    # Metadata
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
    confirmed_at = Column(DateTime, nullable=True)
    cancelled_at = Column(DateTime, nullable=True)
    
    # Relationships
    coordinator = relationship('User', foreign_keys=[coordinator_id])
    room_blocks = relationship('GroupRoomBlock', back_populates='group_booking', cascade='all, delete-orphan')
    members = relationship('GroupBookingMember', back_populates='group_booking', cascade='all, delete-orphan')
    individual_bookings = relationship('Booking', back_populates='group_booking', cascade='all, delete-orphan')
    payments = relationship('GroupPayment', back_populates='group_booking', cascade='all, delete-orphan')

class GroupRoomBlock(Base):
    __tablename__ = 'group_room_blocks'
    
    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    group_booking_id = Column(Integer, ForeignKey('group_bookings.id'), nullable=False)
    room_type_id = Column(Integer, ForeignKey('room_types.id'), nullable=False)
    
    # Blocking details
    rooms_blocked = Column(Integer, nullable=False, default=0)
    rooms_confirmed = Column(Integer, nullable=False, default=0)
    rooms_available = Column(Integer, nullable=False, default=0)
    
    # Pricing
    rate_per_room = Column(Numeric(10, 2), nullable=False)
    total_block_price = Column(Numeric(10, 2), nullable=False)
    
    # Status
    is_active = Column(Boolean, nullable=False, default=True)
    block_released_at = Column(DateTime, nullable=True)
    
    # Metadata
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
    
    # Relationships
    group_booking = relationship('GroupBooking', back_populates='room_blocks')
    room_type = relationship('RoomType')

class GroupBookingMember(Base):
    __tablename__ = 'group_booking_members'
    
    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    group_booking_id = Column(Integer, ForeignKey('group_bookings.id'), nullable=False)
    
    # Guest information
    full_name = Column(String(100), nullable=False)
    email = Column(String(100), nullable=True)
    phone = Column(String(20), nullable=True)
    user_id = Column(Integer, ForeignKey('users.id'), nullable=True)  # If member is a registered user
    
    # Room assignment
    room_block_id = Column(Integer, ForeignKey('group_room_blocks.id'), nullable=True)
    assigned_room_id = Column(Integer, ForeignKey('rooms.id'), nullable=True)
    individual_booking_id = Column(Integer, ForeignKey('bookings.id'), nullable=True)
    
    # Guest preferences
    special_requests = Column(Text, nullable=True)
    preferences = Column(JSON, nullable=True)  # Store preferences as JSON
    
    # Payment (if individual payment option)
    individual_amount = Column(Numeric(10, 2), nullable=True)
    individual_paid = Column(Numeric(10, 2), nullable=True, default=0)
    individual_balance = Column(Numeric(10, 2), nullable=True, default=0)
    
    # Status
    is_checked_in = Column(Boolean, nullable=False, default=False)
    checked_in_at = Column(DateTime, nullable=True)
    is_checked_out = Column(Boolean, nullable=False, default=False)
    checked_out_at = Column(DateTime, nullable=True)
    
    # Metadata
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
    
    # Relationships
    group_booking = relationship('GroupBooking', back_populates='members')
    user = relationship('User', foreign_keys=[user_id])
    room_block = relationship('GroupRoomBlock')
    assigned_room = relationship('Room', foreign_keys=[assigned_room_id])
    individual_booking = relationship('Booking', foreign_keys=[individual_booking_id])

class GroupPayment(Base):
    __tablename__ = 'group_payments'
    
    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    group_booking_id = Column(Integer, ForeignKey('group_bookings.id'), nullable=False)
    
    # Payment details
    amount = Column(Numeric(10, 2), nullable=False)
    payment_method = Column(String(50), nullable=False)  # Using same PaymentMethod enum values
    payment_type = Column(String(50), nullable=False, default='deposit')  # deposit, full, remaining
    payment_status = Column(String(50), nullable=False, default='pending')  # pending, completed, failed, refunded
    
    # Transaction details
    transaction_id = Column(String(100), nullable=True)
    payment_date = Column(DateTime, nullable=True)
    notes = Column(Text, nullable=True)
    
    # Payer information (if individual payment)
    paid_by_member_id = Column(Integer, ForeignKey('group_booking_members.id'), nullable=True)
    paid_by_user_id = Column(Integer, ForeignKey('users.id'), nullable=True)
    
    # Metadata
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
    
    # Relationships
    group_booking = relationship('GroupBooking', back_populates='payments')
    paid_by_member = relationship('GroupBookingMember', foreign_keys=[paid_by_member_id])
    paid_by_user = relationship('User', foreign_keys=[paid_by_user_id])

