"""
Webhook Model - Client webhook configurations and delivery logs
"""
from datetime import datetime
import secrets
import enum
from sqlalchemy import Column, Integer, String, Boolean, DateTime, Text, JSON, ForeignKey, Enum as SQLEnum
from sqlalchemy.orm import relationship

from app.models.base import Base, TimestampMixin, SoftDeleteMixin


class WebhookEventType(enum.Enum):
    """Webhook event types"""
    # Conversation events
    CONVERSATION_STARTED = "conversation.started"
    CONVERSATION_ENDED = "conversation.ended"
    MESSAGE_RECEIVED = "message.received"
    MESSAGE_SENT = "message.sent"

    # Billing events
    INVOICE_CREATED = "invoice.created"
    INVOICE_PAID = "invoice.paid"
    INVOICE_OVERDUE = "invoice.overdue"
    PAYMENT_RECEIVED = "payment.received"
    PAYMENT_FAILED = "payment.failed"

    # Subscription events
    SUBSCRIPTION_CREATED = "subscription.created"
    SUBSCRIPTION_RENEWED = "subscription.renewed"
    SUBSCRIPTION_CANCELLED = "subscription.cancelled"
    SUBSCRIPTION_EXPIRED = "subscription.expired"

    # Usage events
    USAGE_LIMIT_WARNING = "usage.limit_warning"
    USAGE_LIMIT_REACHED = "usage.limit_reached"

    # API events
    API_KEY_CREATED = "api_key.created"
    API_KEY_REVOKED = "api_key.revoked"


class WebhookDeliveryStatus(enum.Enum):
    """Webhook delivery status"""
    PENDING = "pending"
    DELIVERED = "delivered"
    FAILED = "failed"
    RETRYING = "retrying"


class ClientWebhook(Base, TimestampMixin, SoftDeleteMixin):
    """
    Client Webhook Configuration
    Stores webhook endpoints registered by clients
    """
    __tablename__ = "client_webhooks"

    id = Column(Integer, primary_key=True, index=True)
    client_id = Column(Integer, ForeignKey("clients.id"), nullable=False)

    # Webhook Details
    name = Column(String(100), nullable=False)
    description = Column(Text, nullable=True)
    url = Column(String(500), nullable=False)

    # Security
    secret_key = Column(String(64), nullable=False, index=True)

    # Configuration
    is_active = Column(Boolean, default=True)
    events = Column(JSON, nullable=False)  # List of WebhookEventType values

    # Headers to include
    custom_headers = Column(JSON, nullable=True)

    # Retry configuration
    max_retries = Column(Integer, default=3)
    retry_delay_seconds = Column(Integer, default=60)
    timeout_seconds = Column(Integer, default=30)

    # Stats
    total_deliveries = Column(Integer, default=0)
    successful_deliveries = Column(Integer, default=0)
    failed_deliveries = Column(Integer, default=0)
    last_delivery_at = Column(DateTime, nullable=True)
    last_success_at = Column(DateTime, nullable=True)
    last_failure_at = Column(DateTime, nullable=True)

    # Relationships
    client = relationship("Client", back_populates="webhooks")
    delivery_logs = relationship("WebhookDeliveryLog", back_populates="webhook", cascade="all, delete-orphan")

    @staticmethod
    def generate_secret():
        """Generate a webhook secret for signature verification"""
        return f"whsec_{secrets.token_hex(24)}"

    def __repr__(self):
        return f"<ClientWebhook(id={self.id}, name='{self.name}', url='{self.url}')>"


class WebhookDeliveryLog(Base, TimestampMixin):
    """
    Webhook Delivery Log
    Tracks all webhook delivery attempts
    """
    __tablename__ = "webhook_delivery_logs"

    id = Column(Integer, primary_key=True, index=True)
    webhook_id = Column(Integer, ForeignKey("client_webhooks.id"), nullable=False)

    # Event Details
    event_type = Column(String(50), nullable=False)
    event_id = Column(String(64), nullable=False, index=True)  # Unique event identifier
    payload = Column(JSON, nullable=False)

    # Delivery Status
    status = Column(SQLEnum(WebhookDeliveryStatus), default=WebhookDeliveryStatus.PENDING)
    attempt_count = Column(Integer, default=0)
    max_attempts = Column(Integer, default=3)

    # Response Details
    response_status_code = Column(Integer, nullable=True)
    response_body = Column(Text, nullable=True)
    response_time_ms = Column(Integer, nullable=True)

    # Error Details
    error_message = Column(Text, nullable=True)

    # Timing
    delivered_at = Column(DateTime, nullable=True)
    next_retry_at = Column(DateTime, nullable=True)

    # Relationships
    webhook = relationship("ClientWebhook", back_populates="delivery_logs")

    def __repr__(self):
        return f"<WebhookDeliveryLog(id={self.id}, event_type='{self.event_type}', status='{self.status}')>"
