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

class SecurityEventType(str, enum.Enum):
    login_attempt = 'login_attempt'
    login_success = 'login_success'
    login_failure = 'login_failure'
    logout = 'logout'
    password_change = 'password_change'
    password_reset = 'password_reset'
    account_locked = 'account_locked'
    account_unlocked = 'account_unlocked'
    permission_denied = 'permission_denied'
    suspicious_activity = 'suspicious_activity'
    data_access = 'data_access'
    data_modification = 'data_modification'
    data_deletion = 'data_deletion'
    api_access = 'api_access'
    ip_blocked = 'ip_blocked'
    rate_limit_exceeded = 'rate_limit_exceeded'
    oauth_login = 'oauth_login'
    sso_login = 'sso_login'

class SecurityEventSeverity(str, enum.Enum):
    low = 'low'
    medium = 'medium'
    high = 'high'
    critical = 'critical'

class SecurityEvent(Base):
    __tablename__ = 'security_events'
    
    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    user_id = Column(Integer, ForeignKey('users.id'), nullable=True, index=True)
    event_type = Column(Enum(SecurityEventType), nullable=False, index=True)
    severity = Column(Enum(SecurityEventSeverity), nullable=False, default=SecurityEventSeverity.medium, index=True)
    
    # Request details
    ip_address = Column(String(45), nullable=True, index=True)
    user_agent = Column(String(500), nullable=True)
    request_path = Column(String(500), nullable=True)
    request_method = Column(String(10), nullable=True)
    request_id = Column(String(36), nullable=True, index=True)
    
    # Event details
    description = Column(Text, nullable=True)
    details = Column(JSON, nullable=True)
    extra_data = Column(JSON, nullable=True)  # Additional metadata (metadata is reserved by SQLAlchemy)
    
    # Status
    resolved = Column(Boolean, nullable=False, default=False)
    resolved_at = Column(DateTime, nullable=True)
    resolved_by = Column(Integer, ForeignKey('users.id'), nullable=True)
    resolution_notes = Column(Text, nullable=True)
    
    # Location (if available)
    country = Column(String(100), nullable=True)
    city = Column(String(100), nullable=True)
    latitude = Column(String(20), nullable=True)
    longitude = Column(String(20), nullable=True)
    
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False, index=True)
    
    # Relationships
    user = relationship('User', foreign_keys=[user_id])
    resolver = relationship('User', foreign_keys=[resolved_by])

class IPWhitelist(Base):
    __tablename__ = 'ip_whitelist'
    
    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    ip_address = Column(String(45), nullable=False, unique=True, index=True)
    description = Column(String(255), nullable=True)
    is_active = Column(Boolean, nullable=False, default=True)
    created_by = 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)
    
    # Relationships
    creator = relationship('User', foreign_keys=[created_by])

class IPBlacklist(Base):
    __tablename__ = 'ip_blacklist'
    
    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    ip_address = Column(String(45), nullable=False, unique=True, index=True)
    reason = Column(Text, nullable=True)
    is_active = Column(Boolean, nullable=False, default=True)
    blocked_until = Column(DateTime, nullable=True)  # Temporary block
    created_by = 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)
    
    # Relationships
    creator = relationship('User', foreign_keys=[created_by])

class OAuthProvider(Base):
    __tablename__ = 'oauth_providers'
    
    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    name = Column(String(50), nullable=False, unique=True)  # google, microsoft, github, etc.
    display_name = Column(String(100), nullable=False)
    client_id = Column(String(500), nullable=False)
    client_secret = Column(String(500), nullable=False)  # Should be encrypted
    authorization_url = Column(String(500), nullable=False)
    token_url = Column(String(500), nullable=False)
    userinfo_url = Column(String(500), nullable=False)
    scopes = Column(String(500), nullable=True)  # space-separated scopes
    is_active = Column(Boolean, nullable=False, default=True)
    is_sso_enabled = Column(Boolean, nullable=False, default=False)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)

class OAuthToken(Base):
    __tablename__ = 'oauth_tokens'
    
    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    user_id = Column(Integer, ForeignKey('users.id'), nullable=False, index=True)
    provider_id = Column(Integer, ForeignKey('oauth_providers.id'), nullable=False)
    provider_user_id = Column(String(255), nullable=False)  # User ID from OAuth provider
    access_token = Column(Text, nullable=False)  # Should be encrypted
    refresh_token = Column(Text, nullable=True)  # Should be encrypted
    token_type = Column(String(50), nullable=True, default='Bearer')
    expires_at = Column(DateTime, nullable=True)
    scopes = Column(String(500), nullable=True)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
    
    # Relationships
    user = relationship('User')
    provider = relationship('OAuthProvider')

