# services/pos/app/models/pos_webhook.py
"""
POS Webhook Log Model
Tracks webhook events from POS systems
"""

from sqlalchemy import Column, String, DateTime, Boolean, Integer, Text, JSON, Index
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.sql import func
import uuid

from shared.database.base import Base


class POSWebhookLog(Base):
    """
    Log of webhook events received from POS systems
    """
    __tablename__ = "pos_webhook_logs"
    
    # Primary identifiers
    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, index=True)
    tenant_id = Column(UUID(as_uuid=True), nullable=True, index=True)  # May be null until parsed
    
    # POS Provider Information
    pos_system = Column(String(50), nullable=False, index=True)  # square, toast, lightspeed
    webhook_type = Column(String(100), nullable=False, index=True)  # payment.created, order.updated, etc.
    
    # Request Information
    method = Column(String(10), nullable=False)  # POST, PUT, etc.
    url_path = Column(String(500), nullable=False)
    query_params = Column(JSON, nullable=True)
    headers = Column(JSON, nullable=True)
    
    # Payload
    raw_payload = Column(Text, nullable=False)  # Raw webhook payload
    payload_size = Column(Integer, nullable=False, default=0)
    content_type = Column(String(100), nullable=True)
    
    # Security
    signature = Column(String(500), nullable=True)  # Webhook signature for verification
    is_signature_valid = Column(Boolean, nullable=True)  # null = not checked, true/false = verified
    source_ip = Column(String(45), nullable=True)  # IPv4 or IPv6
    
    # Processing Status
    status = Column(String(50), nullable=False, default="received", index=True)  # received, processing, processed, failed
    processing_started_at = Column(DateTime(timezone=True), nullable=True)
    processing_completed_at = Column(DateTime(timezone=True), nullable=True)
    processing_duration_ms = Column(Integer, nullable=True)
    
    # Error Handling
    error_message = Column(Text, nullable=True)
    error_code = Column(String(50), nullable=True)
    retry_count = Column(Integer, default=0, nullable=False)
    max_retries = Column(Integer, default=3, nullable=False)
    
    # Response Information
    response_status_code = Column(Integer, nullable=True)
    response_body = Column(Text, nullable=True)
    response_sent_at = Column(DateTime(timezone=True), nullable=True)
    
    # Event Metadata
    event_id = Column(String(255), nullable=True, index=True)  # POS system's event ID
    event_timestamp = Column(DateTime(timezone=True), nullable=True)  # When event occurred in POS
    sequence_number = Column(Integer, nullable=True)  # For ordered events
    
    # Business Data References
    transaction_id = Column(String(255), nullable=True, index=True)  # Referenced transaction
    order_id = Column(String(255), nullable=True, index=True)  # Referenced order
    customer_id = Column(String(255), nullable=True)  # Referenced customer
    
    # Internal References
    created_transaction_id = Column(UUID(as_uuid=True), nullable=True)  # Created POSTransaction record
    updated_transaction_id = Column(UUID(as_uuid=True), nullable=True)  # Updated POSTransaction record
    
    # Duplicate Detection
    is_duplicate = Column(Boolean, default=False, nullable=False, index=True)
    duplicate_of = Column(UUID(as_uuid=True), nullable=True)
    
    # Processing Priority
    priority = Column(String(20), default="normal", nullable=False)  # low, normal, high, urgent
    
    # Debugging Information
    user_agent = Column(String(500), nullable=True)
    forwarded_for = Column(String(200), nullable=True)  # X-Forwarded-For header
    request_id = Column(String(100), nullable=True)  # For request tracing
    
    # Timestamps
    received_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False, index=True)
    created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
    updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)
    
    # Indexes for performance
    __table_args__ = (
        Index('idx_webhook_pos_system_type', 'pos_system', 'webhook_type'),
        Index('idx_webhook_status', 'status'),
        Index('idx_webhook_event_id', 'event_id'),
        Index('idx_webhook_received_at', 'received_at'),
        Index('idx_webhook_tenant_received', 'tenant_id', 'received_at'),
        Index('idx_webhook_transaction_id', 'transaction_id'),
        Index('idx_webhook_order_id', 'order_id'),
        Index('idx_webhook_duplicate', 'is_duplicate'),
        Index('idx_webhook_priority', 'priority'),
        Index('idx_webhook_retry', 'retry_count'),
        Index('idx_webhook_signature_valid', 'is_signature_valid'),
    )
    
    def __repr__(self):
        return f"<POSWebhookLog(id={self.id}, pos_system='{self.pos_system}', type='{self.webhook_type}', status='{self.status}')>"