<?php
// Prevent direct access
if (count(get_included_files()) === 1) {
    http_response_code(403);
    exit('Forbidden');
}

require_once __DIR__ . '/platform_settings.php';

class TwilioService {
    /**
     * Envía un mensaje saliente por la API REST de Twilio (WhatsApp o SMS).
     * From = número oficial de Supraide. Para WhatsApp fuera de la ventana de 24h
     * el body debe corresponder a una plantilla aprobada por Meta.
     * @return array{ok:bool, sid?:string, error?:string}
     */
    public static function sendMessage(string $to, string $body, string $channel = 'whatsapp'): array {
        $sid = getenv('TWILIO_ACCOUNT_SID');
        $token = getenv('TWILIO_AUTH_TOKEN');
        $num = PlatformSettings::supraideNumber(); // solo dígitos
        if (empty($sid) || empty($token) || $num === '') {
            return ['ok' => false, 'error' => 'Falta TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN o el número de Supraide.'];
        }
        $pref = $channel === 'whatsapp' ? 'whatsapp:+' : '+';
        $from = $pref . $num;
        $toDigits = preg_replace('/\D+/', '', $to);
        $toAddr = $pref . $toDigits;

        $ch = curl_init("https://api.twilio.com/2010-04-01/Accounts/$sid/Messages.json");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(['From' => $from, 'To' => $toAddr, 'Body' => $body]));
        curl_setopt($ch, CURLOPT_USERPWD, "$sid:$token");
        curl_setopt($ch, CURLOPT_TIMEOUT, 20);
        $resp = curl_exec($ch);
        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $err = curl_error($ch);

        if ($resp === false) {
            return ['ok' => false, 'error' => 'cURL: ' . $err];
        }
        $data = json_decode($resp, true);
        if ($code >= 200 && $code < 300) {
            return ['ok' => true, 'sid' => $data['sid'] ?? null];
        }
        return ['ok' => false, 'error' => ($data['message'] ?? ('HTTP ' . $code))];
    }

    public static function validateSignature(string $authToken, string $signature, string $url, array $params): bool {
        ksort($params);
        $data = $url;
        foreach ($params as $key => $value) {
            $data .= $key . $value;
        }
        $computed = base64_encode(hash_hmac('sha1', $data, $authToken, true));
        return hash_equals($computed, $signature);
    }

    public static function validateRequest(): bool {
        $validationEnabled = filter_var(getenv('TWILIO_VALIDATION_ENABLED') ?: 'true', FILTER_VALIDATE_BOOLEAN);
        if (!$validationEnabled) {
            error_log("Twilio signature validation bypassed (TWILIO_VALIDATION_ENABLED=false)");
            return true;
        }

        $authToken = getenv('TWILIO_AUTH_TOKEN');
        if (empty($authToken)) {
            error_log("Twilio signature validation failed: TWILIO_AUTH_TOKEN is not configured.");
            return false;
        }

        $signature = $_SERVER['HTTP_X_TWILIO_SIGNATURE'] ?? '';
        if (empty($signature)) {
            error_log("Twilio signature validation failed: Missing X-Twilio-Signature header.");
            return false;
        }

        // Reconstruct the URL, accounting for proxy and Cloud Run load balancer
        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || 
                    (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') 
                    ? 'https' : 'http';
        
        $host = $_SERVER['HTTP_HOST'];
        $uri = $_SERVER['REQUEST_URI'];
        $url = $protocol . '://' . $host . $uri;

        $params = $_POST;

        $isValid = self::validateSignature($authToken, $signature, $url, $params);
        if (!$isValid) {
            error_log("Twilio signature validation failed. Reconstructed URL: $url");
        }
        return $isValid;
    }
}
