<?php
// Check if vendor/autoload exists
if (file_exists('vendor/autoload.php')) {
    require_once 'vendor/autoload.php';
}
require_once 'config.php';

// Enable error reporting for debugging
error_reporting(E_ALL);
ini_set('display_errors', 1);

/**
 * Twilio Consent Management System
 * Handles SMS consent requests, approvals, and denials for toll-free messaging
 */

class TwilioConsentManager {
    private $pdo;
    private $twilio;
    
    public function __construct() {
        $this->connectDatabase();
        $this->initializeTwilio();
    }
    
    private function connectDatabase() {
        try {
            $dsn = "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4";
            $options = [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                PDO::ATTR_EMULATE_PREPARES => false,
            ];
            $this->pdo = new PDO($dsn, DB_USER, DB_PASS, $options);
        } catch (PDOException $e) {
            throw new Exception("Database connection failed: " . $e->getMessage());
        }
    }
    
    private function initializeTwilio() {
        if (!class_exists('Twilio\Rest\Client')) {
            throw new Exception("Twilio SDK not found. Please run 'composer install'");
        }
        
        $this->twilio = new Twilio\Rest\Client(
            TWILIO_ACCOUNT_SID,
            TWILIO_AUTH_TOKEN
        );
    }
    
    /**
     * Create a new consent request
     */
    public function createConsentRequest($phoneNumber, $ipAddress = null, $userAgent = null) {
        // Validate phone number
        $phoneNumber = $this->validatePhoneNumber($phoneNumber);
        
        // Check if consent already exists
        $existing = $this->getConsentByPhone($phoneNumber);
        if ($existing && $existing['consent_status'] === 'approved') {
            return [
                'success' => false,
                'message' => 'Consent already approved for this number',
                'status' => $existing['consent_status']
            ];
        }
        
        // Generate unique consent token
        $consentToken = bin2hex(random_bytes(16));
        
        // Insert or update consent request
        $sql = "INSERT INTO consent_requests 
                (phone_number, consent_token, consent_status, ip_address, user_agent)
                VALUES (?, ?, 'pending', ?, ?)
                ON DUPLICATE KEY UPDATE 
                consent_token = VALUES(consent_token),
                consent_status = 'pending',
                request_date = CURRENT_TIMESTAMP,
                ip_address = VALUES(ip_address),
                user_agent = VALUES(user_agent)";
        
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute([$phoneNumber, $consentToken, $ipAddress, $userAgent]);
        
        // Send consent request SMS
        $this->sendConsentSMS($phoneNumber, $consentToken);
        
        return [
            'success' => true,
            'message' => 'Consent request sent successfully',
            'token' => $consentToken
        ];
    }
    
    /**
     * Send consent request SMS via Twilio
     */
    private function sendConsentSMS($phoneNumber, $consentToken) {
        try {
            $baseUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? "https" : "http") . "://" . ($_SERVER['HTTP_HOST'] ?? 'localhost');
            $scriptDir = dirname($_SERVER['PHP_SELF']);
            $pathPrefix = $scriptDir === '/' ? '' : rtrim($scriptDir, '/');
            $consentUrl = $baseUrl . $pathPrefix . "/consent_simple.php?token=" . urlencode($consentToken) . "&phone=" . urlencode($phoneNumber);
            
            $message = $this->twilio->messages->create(
                $phoneNumber,
                [
                    'from' => TWILIO_PHONE_NUMBER,
                    'body' => "Mark's Tech Solution: Please consent to receive SMS updates. Reply YES to approve or NO to deny. Or visit: " . $consentUrl
                ]
            );
            
            // Log the message
            $this->logMessage($phoneNumber, $message->sid, 'consent_request', $message->body, 'sent');
            
            return $message;
            
        } catch (Exception $e) {
            $this->logMessage($phoneNumber, null, 'consent_request', '', 'failed', $e->getMessage());
            throw new Exception("Failed to send SMS: " . $e->getMessage());
        }
    }
    
    /**
     * Handle consent response (from webhook or form)
     */
    public function handleConsentResponse($consentToken, $phoneNumber, $response, $ipAddress = null, $userAgent = null) {
        // Validate response
        $response = strtolower(trim($response));
        if (!in_array($response, ['yes', 'no', 'approve', 'deny', 'approved', 'denied'])) {
            return ['success' => false, 'message' => 'Invalid response'];
        }
        
        // Map responses to status
        $statusMap = [
            'yes' => 'approved',
            'approve' => 'approved',
            'approved' => 'approved',
            'no' => 'denied',
            'deny' => 'denied',
            'denied' => 'denied'
        ];
        
        $status = $statusMap[$response];
        
        // Update consent record
        $sql = "UPDATE consent_requests 
                SET consent_status = ?, response_date = CURRENT_TIMESTAMP
                WHERE consent_token = ? AND phone_number = ?";
        
        $stmt = $this->pdo->prepare($sql);
        $result = $stmt->execute([$status, $consentToken, $phoneNumber]);
        
        if (!$result || $stmt->rowCount() === 0) {
            return ['success' => false, 'message' => 'Consent request not found'];
        }
        
        // Get consent ID for logging
        $consentId = $this->getConsentId($consentToken);
        
        // Log response
        if ($status === 'denied') {
            $this->logRevocation($consentId, $phoneNumber, 'User denied consent via SMS/web', $ipAddress, $userAgent);
        }
        
        return [
            'success' => true,
            'message' => "Consent {$status} successfully",
            'status' => $status
        ];
    }
    
    /**
     * Get consent status by phone number
     */
    public function getConsentByPhone($phoneNumber) {
        $sql = "SELECT * FROM consent_requests WHERE phone_number = ? ORDER BY request_date DESC LIMIT 1";
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute([$phoneNumber]);
        return $stmt->fetch();
    }
    
    /**
     * Get consent by token
     */
    public function getConsentByToken($token) {
        $sql = "SELECT * FROM consent_requests WHERE consent_token = ?";
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute([$token]);
        return $stmt->fetch();
    }
    
    /**
     * Get consent ID
     */
    private function getConsentId($token) {
        $sql = "SELECT id FROM consent_requests WHERE consent_token = ?";
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute([$token]);
        $result = $stmt->fetch();
        return $result ? $result['id'] : null;
    }
    
    /**
     * Log message
     */
    private function logMessage($phoneNumber, $messageSid, $messageType, $content, $status, $error = null) {
        $sql = "INSERT INTO message_logs 
                (phone_number, message_sid, message_content, message_type, status, error_message)
                VALUES (?, ?, ?, ?, ?, ?)";
        
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute([$phoneNumber, $messageSid, $content, $messageType, $status, $error]);
    }
    
    /**
     * Log consent revocation
     */
    private function logRevocation($consentId, $phoneNumber, $reason, $ipAddress = null, $userAgent = null) {
        $sql = "INSERT INTO consent_revocations 
                (consent_id, phone_number, revocation_reason, ip_address, user_agent)
                VALUES (?, ?, ?, ?, ?)";
        
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute([$consentId, $phoneNumber, $reason, $ipAddress, $userAgent]);
    }
    
    /**
     * Validate phone number format
     */
    private function validatePhoneNumber($phoneNumber) {
        // Remove all non-numeric characters
        $phoneNumber = preg_replace('/[^0-9]/', '', $phoneNumber);
        
        // Add +1 if US number without country code
        if (strlen($phoneNumber) === 10) {
            $phoneNumber = '1' . $phoneNumber;
        }
        
        // Add + prefix
        if (strpos($phoneNumber, '+') !== 0) {
            $phoneNumber = '+' . $phoneNumber;
        }
        
        return $phoneNumber;
    }
    
    /**
     * Check if phone number has consent
     */
    public function hasConsent($phoneNumber) {
        $consent = $this->getConsentByPhone($phoneNumber);
        return $consent && $consent['consent_status'] === 'approved';
    }
}

// Handle incoming requests
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    header('Content-Type: application/json');
    
    try {
        $manager = new TwilioConsentManager();
        $action = $_POST['action'] ?? '';
        
        switch ($action) {
            case 'request_consent':
                $phoneNumber = $_POST['phone_number'] ?? '';
                $result = $manager->createConsentRequest($phoneNumber, $_SERVER['REMOTE_ADDR'], $_SERVER['HTTP_USER_AGENT']);
                echo json_encode($result);
                break;
                
            case 'handle_response':
                $token = $_POST['token'] ?? '';
                $phone = $_POST['phone'] ?? '';
                $response = $_POST['response'] ?? '';
                $result = $manager->handleConsentResponse($token, $phone, $response, $_SERVER['REMOTE_ADDR'], $_SERVER['HTTP_USER_AGENT']);
                echo json_encode($result);
                break;
                
            default:
                echo json_encode(['success' => false, 'message' => 'Invalid action']);
        }
        
    } catch (Exception $e) {
        http_response_code(500);
        echo json_encode(['success' => false, 'message' => $e->getMessage()]);
    }
} elseif ($_SERVER['REQUEST_METHOD'] === 'GET') {
    // Handle webhook responses from Twilio
    $token = $_GET['token'] ?? '';
    $phone = $_GET['phone'] ?? '';
    
    if ($token && $phone) {
        try {
            $manager = new TwilioConsentManager();
            $consent = $manager->getConsentByToken($token);
            
            if ($consent) {
                // Redirect to consent page
                header('Location: consent_page.php?token=' . urlencode($token) . '&phone=' . urlencode($phone));
                exit;
            } else {
                http_response_code(404);
                echo 'Consent request not found';
            }
        } catch (Exception $e) {
            http_response_code(500);
            echo 'Error: ' . $e->getMessage();
        }
    } else {
        http_response_code(400);
        echo 'Missing required parameters';
    }
}
?>