<?php

require_once __DIR__ . '/../config/config.php';
require_once __DIR__ . '/../config/database.php';
require_once __DIR__ . '/../utilities/Logger.php';

/**
 * NotificationController handles webhook notifications for status changes
 */
class NotificationController {
    /**
     * Send webhook notification for status change
     * 
     * @param string $clientId API client ID
     * @param string $requestId Request ID
     * @param string $senderId Sender ID
     * @param string $oldStatus Old status
     * @param string $newStatus New status
     * @param string $rejectionReason Reason for rejection (if applicable)
     * @param string $approvedBy Who approved/rejected the request
     * @return bool Success status
     */
    public static function sendStatusChangeWebhook($clientId, $requestId, $senderId, $oldStatus, $newStatus, $rejectionReason = null, $approvedBy = null) {
        try {
            // Get webhook configuration for this client
            $webhookConfig = self::getWebhookConfig($clientId);
            
            if (!$webhookConfig) {
                // No webhook configured for this client
                return false;
            }
            
            if (!$webhookConfig['is_active']) {
                Logger::log(Logger::WARNING, "Inactive webhook configuration", ['client_id' => $clientId]);
                return false;
            }
            
            // Prepare payload
            $payload = [
                'event' => 'sender_id.status_changed',
                'timestamp' => date('c'),
                'data' => [
                    'request_id' => $requestId,
                    'sender_id' => $senderId,
                    'old_status' => $oldStatus,
                    'new_status' => $newStatus,
                    'rejection_reason' => $rejectionReason,
                    'approved_by' => $approvedBy
                ]
            ];
            
            // Send webhook notification
            return self::sendWebhook($webhookConfig['url'], $payload, $webhookConfig['secret'], $clientId);
        } catch (Exception $e) {
            Logger::log(Logger::ERROR, "Webhook notification error: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Get webhook configuration for a client
     * 
     * @param string $clientId API client ID
     * @return array|null Webhook configuration or null if not found
     */
    private static function getWebhookConfig($clientId) {
        try {
            $db = Database::getApiConnection();
            
            $stmt = $db->prepare("
                SELECT url, secret, is_active, failed_attempts 
                FROM webhook_configurations 
                WHERE client_id = ?
            ");
            
            $stmt->bind_param("s", $clientId);
            $stmt->execute();
            $result = $stmt->get_result();
            
            if ($result->num_rows == 0) {
                return null;
            }
            
            $config = $result->fetch_assoc();
            $stmt->close();
            
            return $config;
        } catch (Exception $e) {
            Logger::log(Logger::ERROR, "Get webhook config error: " . $e->getMessage());
            return null;
        }
    }
    
    /**
     * Send webhook notification
     * 
     * @param string $url Webhook URL
     * @param array $payload Webhook payload
     * @param string $secret Webhook secret for signing
     * @param string $clientId API client ID
     * @return bool Success status
     */
    private static function sendWebhook($url, $payload, $secret, $clientId) {
        try {
            // Convert payload to JSON
            $payloadJson = json_encode($payload);
            
            // Prepare headers
            $headers = [
                'Content-Type: application/json',
                'User-Agent: Deywuro-API/1.0',
                'X-Deywuro-Delivery-ID: ' . uniqid('dey_', true)
            ];
            
            // Add signature if secret is configured
            if (!empty($secret)) {
                $signature = hash_hmac('sha256', $payloadJson, $secret);
                $headers[] = 'X-Deywuro-Signature: ' . $signature;
            }
            
            // Initialize cURL session
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $payloadJson);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_TIMEOUT, API_TIMEOUT);
            
            // Execute request
            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);
            
            // Check response
            $success = ($httpCode >= 200 && $httpCode < 300);
            
            if (!$success) {
                // Update failed attempts
                self::updateFailedAttempts($clientId, true);
                
                Logger::log(Logger::WARNING, "Webhook delivery failed", [
                    'client_id' => $clientId,
                    'url' => $url,
                    'http_code' => $httpCode,
                    'response' => substr($response, 0, 200)
                ]);
                
                return false;
            }
            
            // Reset failed attempts on success
            self::updateFailedAttempts($clientId, false);
            
            Logger::log(Logger::INFO, "Webhook delivered successfully", [
                'client_id' => $clientId,
                'url' => $url
            ]);
            
            return true;
            
        } catch (Exception $e) {
            self::updateFailedAttempts($clientId, true);
            Logger::log(Logger::ERROR, "Webhook sending error: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Update failed attempts count for a webhook
     * 
     * @param string $clientId API client ID
     * @param bool $failed Whether the attempt failed
     * @return bool Success status
     */
    private static function updateFailedAttempts($clientId, $failed) {
        try {
            $db = Database::getApiConnection();
            
            if ($failed) {
                // Increment failed attempts
                $stmt = $db->prepare("
                    UPDATE webhook_configurations 
                    SET failed_attempts = failed_attempts + 1,
                        is_active = IF(failed_attempts >= ?, 0, is_active),
                        updated_at = NOW()
                    WHERE client_id = ?
                ");
                
                $maxRetries = WEBHOOK_MAX_RETRIES;
                $stmt->bind_param("is", $maxRetries, $clientId);
            } else {
                // Reset failed attempts
                $stmt = $db->prepare("
                    UPDATE webhook_configurations 
                    SET failed_attempts = 0,
                        updated_at = NOW()
                    WHERE client_id = ?
                ");
                
                $stmt->bind_param("s", $clientId);
            }
            
            $result = $stmt->execute();
            $stmt->close();
            
            return $result;
            
        } catch (Exception $e) {
            Logger::log(Logger::ERROR, "Update webhook attempts error: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Send SMS notification for status change
     * 
     * @param string $phoneNumber Recipient phone number
     * @param string $requestId Request ID
     * @param string $senderId Sender ID
     * @param string $newStatus New status
     * @param string $rejectionReason Reason for rejection (if applicable)
     * @return bool Success status
     */
    public static function sendStatusChangeSms($phoneNumber, $requestId, $senderId, $newStatus, $rejectionReason = null) {
        try {
            // Prepare message
            $message = "Your Sender ID request for '{$senderId}' (ID: {$requestId}) is now {$newStatus}.";
            
            if ($newStatus == 'REJECTED' && !empty($rejectionReason)) {
                $message .= " Reason: {$rejectionReason}";
            }
            
            if ($newStatus == 'APPROVED') {
                $message .= " You can now use this Sender ID for sending messages.";
            }
            
            // Send the SMS
            $url = SMS_API_URL;
            $params = [
                'username' => SMS_USERNAME,
                'password' => SMS_PASSWORD,
                'source' => SMS_SOURCE,
                'destination' => $phoneNumber,
                'message' => $message
            ];
            
            // Initialize cURL session
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url . '?' . http_build_query($params));
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_TIMEOUT, API_TIMEOUT);
            
            // Execute request
            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);
            
            if ($httpCode != 200) {
                Logger::log(Logger::WARNING, "SMS status notification failed", [
                    'phone' => $phoneNumber,
                    'http_code' => $httpCode,
                    'response' => $response
                ]);
                return false;
            }
            
            return true;
            
        } catch (Exception $e) {
            Logger::log(Logger::ERROR, "SMS notification error: " . $e->getMessage());
            return false;
        }
    }
} 