"""
Configuration for authentication system
"""

from typing import Optional
from pydantic import BaseModel, Field, field_validator


class AuthConfig(BaseModel):
    """
    Configuration for authentication system
    
    Attributes:
        database_url: SQLAlchemy database URL
        secret_key: Secret key for JWT signing (HS256)
        algorithm: JWT algorithm ("HS256" or "RS256")
        access_token_expire_minutes: Access token expiration (default: 15 minutes)
        refresh_token_expire_days: Refresh token expiration (default: 30 days)
        verification_token_expire_hours: Email verification token expiration (default: 24 hours)
        reset_token_expire_hours: Password reset token expiration (default: 1 hour)
        private_key_path: Path to RSA private key for RS256 (optional)
        public_key_path: Path to RSA public key for RS256 (optional)
    """
    
    database_url: str = Field(..., description="SQLAlchemy database URL")
    secret_key: str = Field(..., min_length=32, description="Secret key for JWT (HS256)")
    algorithm: str = Field(default="HS256", description="JWT algorithm")
    
    # Token expiration times
    access_token_expire_minutes: int = Field(default=15, ge=1, le=1440)
    refresh_token_expire_days: int = Field(default=30, ge=1, le=365)
    verification_token_expire_hours: int = Field(default=24, ge=1, le=168)
    reset_token_expire_hours: int = Field(default=1, ge=1, le=24)
    
    # RSA keys for RS256 (optional)
    private_key_path: Optional[str] = Field(default=None, description="Path to RSA private key")
    public_key_path: Optional[str] = Field(default=None, description="Path to RSA public key")
    
    @field_validator("algorithm")
    @classmethod
    def validate_algorithm(cls, v: str) -> str:
        """Validate JWT algorithm"""
        if v.upper() not in ["HS256", "RS256"]:
            raise ValueError("Algorithm must be 'HS256' or 'RS256'")
        return v.upper()
    
    @field_validator("secret_key")
    @classmethod
    def validate_secret_key(cls, v: str) -> str:
        """Ensure secret key is sufficiently long"""
        if len(v) < 32:
            raise ValueError("Secret key must be at least 32 characters")
        return v
    
    def get_private_key(self) -> bytes:
        """Load RSA private key for RS256"""
        if self.algorithm == "RS256":
            if not self.private_key_path:
                raise ValueError("private_key_path required for RS256")
            with open(self.private_key_path, "rb") as f:
                return f.read()
        return self.secret_key.encode()
    
    def get_public_key(self) -> bytes:
        """Load RSA public key for RS256"""
        if self.algorithm == "RS256":
            if not self.public_key_path:
                raise ValueError("public_key_path required for RS256")
            with open(self.public_key_path, "rb") as f:
                return f.read()
        return self.secret_key.encode()

    model_config = {"frozen": True}  # Make config immutable
