"""
API Key Management Models - Simplified & Scalable
"""
from sqlalchemy import Column, String, Boolean, DateTime, Integer, Text, func
from sqlalchemy.ext.declarative import declarative_base
from datetime import datetime
import secrets
import hashlib

Base = declarative_base()


class APIClient(Base):
    """
    API Client - Simple: ID, Name, API Key
    Future-ready for billing and external clients
    """
    __tablename__ = "api_clients"
    
    id = Column(Integer, primary_key=True, index=True)
    
    # Simple fields as per director's requirement
    client_id = Column(String(100), unique=True, index=True, nullable=False)
    client_name = Column(String(200), nullable=False)
    api_key = Column(String(256), unique=True, nullable=False)  # Hashed
    
    # Status
    is_active = Column(Boolean, default=True)
    
    # Usage tracking (for future billing)
    total_requests = Column(Integer, default=0)
    created_at = Column(DateTime, default=datetime.utcnow)
    last_used_at = Column(DateTime, nullable=True)
    
    # Future billing fields (optional, can be null for internal use)
    billing_email = Column(String(200), nullable=True)
    billing_plan = Column(String(50), default="internal")  # internal, basic, pro, enterprise
    monthly_request_limit = Column(Integer, nullable=True)  # null = unlimited 
    
    @staticmethod
    def generate_api_key(client_id: str) -> str:
        """
        Generate API key: myrx_{client_id}_{random}
        Example: myrx_myrx-web_Xy8kL2mN9pQ4rT6vW8zB1dF3hJ5l
        """
        random_part = secrets.token_urlsafe(32)
        full_key = f"myrx_{client_id}_{random_part}"
        return full_key
    
    @staticmethod
    def hash_key(api_key: str) -> str:
        """Hash API key for secure storage"""
        return hashlib.sha256(api_key.encode()).hexdigest()
    
    def verify_key(self, api_key: str) -> bool:
        """Verify if provided key matches stored hash"""
        return self.api_key == self.hash_key(api_key)
    
    def increment_usage(self):
        """Track usage for billing"""
        self.total_requests += 1
        self.last_used_at = datetime.utcnow()


class AllowedDomain(Base):
    """
    Dynamic CORS - Domains stored in DB, no code changes needed
    Auto-registers new domains on first API call
    """
    __tablename__ = "allowed_domains"
    
    id = Column(Integer, primary_key=True, index=True)
    
    # Domain info
    domain = Column(String(500), unique=True, index=True, nullable=False)
    client_id = Column(String(100), index=True, nullable=False)  # Which client uses this domain
    
    # Tracking
    is_active = Column(Boolean, default=True)
    auto_registered = Column(Boolean, default=False)  # True if auto-added on first request
    first_seen_at = Column(DateTime, default=datetime.utcnow)
    last_seen_at = Column(DateTime, default=datetime.utcnow)
    total_requests = Column(Integer, default=0)
    
    # Notes
    description = Column(Text, nullable=True)


class APIRequestLog(Base):
    """
    Request logs for analytics and billing
    Simplified for essential tracking
    """
    __tablename__ = "api_request_logs"
    
    id = Column(Integer, primary_key=True, index=True)
    
    # Request tracking
    request_id = Column(String(100), unique=True, index=True)
    client_id = Column(String(100), index=True)
    
    # Request info
    endpoint = Column(String(500))
    method = Column(String(10))
    origin = Column(String(500), index=True)  # For CORS tracking
    
    # Response
    status_code = Column(Integer)
    response_time_ms = Column(Integer)
    success = Column(Boolean, default=True)
    
    # Timestamp
    timestamp = Column(DateTime, default=datetime.utcnow, index=True)
    
    # For monthly billing calculations
    year_month = Column(String(7), index=True)  # Format: "2026-02" for easy grouping
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Auto-set year_month for billing
        if not self.year_month:
            self.year_month = datetime.utcnow().strftime("%Y-%m")
