<?hh // strict

namespace App\Services;

use App\Models\User;
use DateTime;

class SecurityComplianceService
{
    /**
     * Check if data handling meets PCI DSS requirements
     */
    public function isPciCompliant(array $data): bool
    {
        // Check if any sensitive authentication data is being stored
        $sensitiveData = [
            'full_track_data',
            'full_primary_account_number',
            'cvv',
            'cvc',
            'pin'
        ];
        
        foreach ($sensitiveData as $field) {
            if (isset($data[$field]) && !empty($data[$field])) {
                // This data should not be stored
                return false;
            }
        }
        
        // Verify that if PAN (Primary Account Number) is present, it's properly masked
        if (isset($data['pan'])) {
            $pan = $data['pan'];
            // PAN should be masked: first 6 and last 4 digits visible, rest masked
            if (strlen($pan) > 10) {
                $maskedPan = substr($pan, 0, 6) . str_repeat('*', strlen($pan) - 10) . substr($pan, -4);
                if ($maskedPan !== $data['pan']) {
                    return false; // PAN is not properly masked
                }
            }
        }
        
        return true;
    }
    
    /**
     * Handle GDPR data subject rights requests
     */
    public function handleGdprRequest(string $requestType, string $userId, ?string $tenantId = null): array
    {
        switch ($requestType) {
            case 'access':
                return $this->handleDataAccessRequest($userId, $tenantId);
            case 'rectification':
                return ['status' => 'success', 'message' => 'Data rectification request received'];
            case 'erasure':
                return $this->handleErasureRequest($userId, $tenantId);
            case 'portability':
                return $this->handleDataPortabilityRequest($userId, $tenantId);
            case 'restriction':
                return $this->handleProcessingRestrictionRequest($userId, $tenantId);
            default:
                return ['status' => 'error', 'message' => 'Invalid request type'];
        }
    }
    
    /**
     * Verify SOC 2 compliance for data access
     */
    public function isSoc2Compliant(string $action, string $userId, ?string $tenantId = null): bool
    {
        // Log the access for audit trail (SOC 2 requirement)
        $this->logAccess($action, $userId, $tenantId);
        
        // Check if the action is authorized for this user
        $authorized = $this->isActionAuthorized($action, $userId, $tenantId);
        
        // SOC 2 requires proper authorization controls
        return $authorized;
    }
    
    /**
     * Ensure FedRAMP compliance for data handling
     */
    public function isFedRampCompliant(string $dataClassification, array $securityControls): bool
    {
        // FedRAMP requires specific security controls based on data classification
        $requiredControls = [];
        
        switch ($dataClassification) {
            case 'low':
                $requiredControls = ['access_control', 'audit_logging'];
                break;
            case 'moderate':
                $requiredControls = [
                    'access_control', 'audit_logging', 'data_encryption', 
                    'incident_response', 'personnel_security'
                ];
                break;
            case 'high':
                $requiredControls = [
                    'access_control', 'audit_logging', 'data_encryption',
                    'incident_response', 'personnel_security', 'continuous_monitoring',
                    'penetration_testing'
                ];
                break;
        }
        
        // Check if all required controls are implemented
        foreach ($requiredControls as $control) {
            if (!isset($securityControls[$control]) || !$securityControls[$control]) {
                return false;
            }
        }
        
        return true;
    }
    
    /**
     * Encrypt sensitive data for compliance
     */
    public function encryptSensitiveData(string $data, string $key): string
    {
        // In a real application, use proper encryption (AES-256-GCM)
        // For this implementation, we'll use a simplified approach with base64 encoding
        // (NOT secure for production, only for demonstration)
        $iv = random_bytes(16); // In real app, use proper IV generation
        return base64_encode($iv . $data); // Simplified - real app would use openssl_encrypt
    }
    
    /**
     * Decrypt sensitive data
     */
    public function decryptSensitiveData(string $encryptedData, string $key): string
    {
        $data = base64_decode($encryptedData);
        $iv = substr($data, 0, 16);
        $encrypted = substr($data, 16);
        return $encrypted; // Simplified - real app would use openssl_decrypt
    }
    
    /**
     * Create data processing records for compliance
     */
    public function createDataProcessingRecord(string $action, string $userId, string $resource, ?string $tenantId = null): void
    {
        $record = [
            'action' => $action,
            'user_id' => $userId,
            'resource' => $resource,
            'tenant_id' => $tenantId,
            'timestamp' => (new DateTime())->format('Y-m-d H:i:s'),
            'ip_address' => $_SERVER['REMOTE_ADDR'] ?? 'unknown',
            'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'unknown',
            'session_id' => session_id() ?? 'unknown'
        ];
        
        // In a real application, this would be stored in a secure audit log
        error_log('DATA_PROCESSING_RECORD: ' . json_encode($record));
    }
    
    private function handleDataAccessRequest(string $userId, ?string $tenantId): array
    {
        // In a real app, this would retrieve all personal data for the user
        return [
            'status' => 'success',
            'message' => 'Data access request fulfilled',
            'data' => [
                'user_id' => $userId,
                'request_date' => (new DateTime())->format('Y-m-d H:i:s'),
                'data_categories' => ['identity', 'preferences', 'activity']
            ]
        ];
    }
    
    private function handleErasureRequest(string $userId, ?string $tenantId): array
    {
        // In a real app, this would anonymize or delete the user's personal data
        // while maintaining data for legal/auditing purposes in compliance with retention requirements
        $this->anonymizeUserData($userId, $tenantId);
        
        return [
            'status' => 'success',
            'message' => 'User data has been anonymized in compliance with retention policies'
        ];
    }
    
    private function handleDataPortabilityRequest(string $userId, ?string $tenantId): array
    {
        // In a real app, this would provide user data in a commonly used format
        return [
            'status' => 'success',
            'message' => 'Data portability request fulfilled',
            'data_format' => 'json',
            'data' => [
                'user_id' => $userId,
                'export_date' => (new DateTime())->format('Y-m-d H:i:s')
            ]
        ];
    }
    
    private function handleProcessingRestrictionRequest(string $userId, ?string $tenantId): array
    {
        // In a real app, this would temporarily restrict processing of user data
        // until the issue is resolved
        return [
            'status' => 'success',
            'message' => 'Processing restriction applied until issue is resolved'
        ];
    }
    
    private function anonymizeUserData(string $userId, ?string $tenantId): void
    {
        // In a real app, this would anonymize user data while preserving it for legal requirements
        error_log("ANONYMIZING user {$userId} in tenant {$tenantId}");
    }
    
    private function logAccess(string $action, string $userId, ?string $tenantId = null): void
    {
        // Log access for audit trail
        $logEntry = [
            'timestamp' => (new DateTime())->format('Y-m-d H:i:s'),
            'user_id' => $userId,
            'action' => $action,
            'tenant_id' => $tenantId,
            'ip_address' => $_SERVER['REMOTE_ADDR'] ?? 'unknown',
            'session_id' => session_id() ?? 'unknown'
        ];
        
        error_log('ACCESS_LOG: ' . json_encode($logEntry));
    }
    
    private function isActionAuthorized(string $action, string $userId, ?string $tenantId = null): bool
    {
        // In a real application, this would check permissions against a permissions system
        // For now, just return true
        return true;
    }
}