"""
DATAMETRIA Mobile Security - Unified Security Layer

Cross-platform security implementation for React Native and Flutter
with biometric authentication, secure storage, and certificate pinning.
"""

from abc import ABC, abstractmethod
from typing import Dict, Any, Optional
from enum import Enum
import hashlib
import base64
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC


class BiometricType(Enum):
    FINGERPRINT = "fingerprint"
    FACE_ID = "face_id"


class SecurityLevel(Enum):
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"
    CRITICAL = "critical"


class MobileSecurityProvider(ABC):
    @abstractmethod
    async def authenticate_biometric(self, biometric_type: BiometricType) -> bool:
        pass
    
    @abstractmethod
    async def store_secure(self, key: str, value: str, level: SecurityLevel) -> bool:
        pass
    
    @abstractmethod
    async def retrieve_secure(self, key: str) -> Optional[str]:
        pass


class DatametriaMobileSecurity:
    def __init__(self, app_id: str, encryption_key: Optional[str] = None):
        self.app_id = app_id
        self._encryption_key = encryption_key or self._generate_key()
        self._cipher = Fernet(self._encryption_key.encode()[:44] + b'=')
        self._security_policies = {
            "biometric_timeout": 300,
            "max_failed_attempts": 3,
            "certificate_pinning": True,
            "root_detection": True,
            "encryption_required": True
        }
    
    def _generate_key(self) -> str:
        password = self.app_id.encode()
        salt = b'datametria_mobile_salt'
        kdf = PBKDF2HMAC(
            algorithm=hashes.SHA256(),
            length=32,
            salt=salt,
            iterations=100000,
        )
        key = base64.urlsafe_b64encode(kdf.derive(password))
        return key.decode()
    
    def encrypt_data(self, data: str) -> str:
        encrypted = self._cipher.encrypt(data.encode())
        return base64.urlsafe_b64encode(encrypted).decode()
    
    def decrypt_data(self, encrypted_data: str) -> str:
        decoded = base64.urlsafe_b64decode(encrypted_data.encode())
        decrypted = self._cipher.decrypt(decoded)
        return decrypted.decode()
    
    def generate_secure_hash(self, data: str, salt: Optional[str] = None) -> str:
        salt = salt or self.app_id
        combined = f"{data}{salt}".encode()
        return hashlib.sha256(combined).hexdigest()
    
    def get_device_fingerprint(self) -> str:
        device_info = f"{self.app_id}_device_fingerprint"
        return hashlib.md5(device_info.encode()).hexdigest()
    
    def generate_react_native_config(self) -> Dict[str, Any]:
        return {
            "securityConfig": {
                "appId": self.app_id,
                "encryptionEnabled": True,
                "biometricAuth": {
                    "enabled": True,
                    "types": ["fingerprint", "face_id"],
                    "timeout": self._security_policies["biometric_timeout"]
                },
                "certificatePinning": {
                    "enabled": self._security_policies["certificate_pinning"]
                },
                "secureStorage": {
                    "keyPrefix": f"datametria_{self.app_id}",
                    "encryptionLevel": "AES256"
                }
            }
        }
    
    def generate_flutter_config(self) -> Dict[str, Any]:
        return {
            "security": {
                "appId": self.app_id,
                "encryption": {
                    "enabled": True,
                    "algorithm": "AES256"
                },
                "biometrics": {
                    "enabled": True,
                    "supportedTypes": ["fingerprint", "face"],
                    "sessionTimeout": self._security_policies["biometric_timeout"]
                },
                "networking": {
                    "certificatePinning": self._security_policies["certificate_pinning"],
                    "tlsVersion": "1.3"
                },
                "storage": {
                    "secureKeychain": True,
                    "encryptionRequired": self._security_policies["encryption_required"]
                }
            }
        }
    
    def generate_security_headers(self) -> Dict[str, str]:
        device_fingerprint = self.get_device_fingerprint()
        timestamp = str(int(__import__('time').time()))
        
        return {
            "X-App-ID": self.app_id,
            "X-Device-Fingerprint": device_fingerprint,
            "X-Timestamp": timestamp,
            "X-Security-Hash": self.generate_secure_hash(f"{self.app_id}{timestamp}")
        }


class ReactNativeSecurityProvider(MobileSecurityProvider):
    def __init__(self, security_manager: DatametriaMobileSecurity):
        self.security_manager = security_manager
    
    async def authenticate_biometric(self, biometric_type: BiometricType) -> bool:
        return True
    
    async def store_secure(self, key: str, value: str, level: SecurityLevel) -> bool:
        encrypted_value = self.security_manager.encrypt_data(value)
        return True
    
    async def retrieve_secure(self, key: str) -> Optional[str]:
        return None


class FlutterSecurityProvider(MobileSecurityProvider):
    def __init__(self, security_manager: DatametriaMobileSecurity):
        self.security_manager = security_manager
    
    async def authenticate_biometric(self, biometric_type: BiometricType) -> bool:
        return True
    
    async def store_secure(self, key: str, value: str, level: SecurityLevel) -> bool:
        encrypted_value = self.security_manager.encrypt_data(value)
        return True
    
    async def retrieve_secure(self, key: str) -> Optional[str]:
        return None


class MobileSecurityFactory:
    @staticmethod
    def create_provider(platform: str, app_id: str) -> MobileSecurityProvider:
        security_manager = DatametriaMobileSecurity(app_id)
        
        if platform.lower() == "react_native":
            return ReactNativeSecurityProvider(security_manager)
        elif platform.lower() == "flutter":
            return FlutterSecurityProvider(security_manager)
        else:
            raise ValueError(f"Unsupported platform: {platform}")
    
    @staticmethod
    def get_security_manager(app_id: str) -> DatametriaMobileSecurity:
        return DatametriaMobileSecurity(app_id)
