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

class InvoiceStatus(str, enum.Enum):
    draft = 'draft'
    sent = 'sent'
    paid = 'paid'
    overdue = 'overdue'
    cancelled = 'cancelled'

class Invoice(Base):
    __tablename__ = 'invoices'
    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    invoice_number = Column(String(50), unique=True, nullable=False, index=True)
    booking_id = Column(Integer, ForeignKey('bookings.id'), nullable=False, index=True)
    user_id = Column(Integer, ForeignKey('users.id'), nullable=False, index=True)
    issue_date = Column(DateTime, default=datetime.utcnow, nullable=False)
    due_date = Column(DateTime, nullable=False)
    paid_date = Column(DateTime, nullable=True)
    subtotal = Column(Numeric(10, 2), nullable=False, default=0.0)
    tax_rate = Column(Numeric(5, 2), nullable=False, default=0.0)
    tax_amount = Column(Numeric(10, 2), nullable=False, default=0.0)
    discount_amount = Column(Numeric(10, 2), nullable=False, default=0.0)
    total_amount = Column(Numeric(10, 2), nullable=False)
    amount_paid = Column(Numeric(10, 2), nullable=False, default=0.0)
    balance_due = Column(Numeric(10, 2), nullable=False)
    status = Column(Enum(InvoiceStatus), nullable=False, default=InvoiceStatus.draft)
    is_proforma = Column(Boolean, nullable=False, default=False)
    company_name = Column(String(200), nullable=True)
    company_address = Column(Text, nullable=True)
    company_phone = Column(String(50), nullable=True)
    company_email = Column(String(100), nullable=True)
    company_tax_id = Column(String(100), nullable=True)
    company_logo_url = Column(String(500), nullable=True)
    customer_name = Column(String(200), nullable=False)
    customer_email = Column(String(100), nullable=False)
    customer_address = Column(Text, nullable=True)
    customer_phone = Column(String(50), nullable=True)
    customer_tax_id = Column(String(100), nullable=True)
    notes = Column(Text, nullable=True)
    terms_and_conditions = Column(Text, nullable=True)
    payment_instructions = Column(Text, nullable=True)
    created_by_id = Column(Integer, ForeignKey('users.id'), nullable=True)
    updated_by_id = Column(Integer, ForeignKey('users.id'), 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='invoices')
    user = relationship('User', foreign_keys=[user_id], backref='invoices')
    created_by = relationship('User', foreign_keys=[created_by_id])
    updated_by = relationship('User', foreign_keys=[updated_by_id])
    items = relationship('InvoiceItem', back_populates='invoice', cascade='all, delete-orphan')
    
    # Index for invoice status and date queries
    __table_args__ = (
        Index('idx_invoice_status', 'status'),
        Index('idx_invoice_user_status', 'user_id', 'status'),
        Index('idx_invoice_due_date', 'due_date'),
    )

class InvoiceItem(Base):
    __tablename__ = 'invoice_items'
    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    invoice_id = Column(Integer, ForeignKey('invoices.id'), nullable=False)
    description = Column(String(500), nullable=False)
    quantity = Column(Numeric(10, 2), nullable=False, default=1.0)
    unit_price = Column(Numeric(10, 2), nullable=False)
    tax_rate = Column(Numeric(5, 2), nullable=False, default=0.0)
    discount_amount = Column(Numeric(10, 2), nullable=False, default=0.0)
    line_total = Column(Numeric(10, 2), nullable=False)
    room_id = Column(Integer, ForeignKey('rooms.id'), nullable=True)
    service_id = Column(Integer, ForeignKey('services.id'), nullable=True)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    invoice = relationship('Invoice', back_populates='items')
    room = relationship('Room')
    service = relationship('Service')