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

require_once dirname(__DIR__) . '/services/twilio.php';
require_once dirname(__DIR__) . '/services/agent_service.php';

// (a) Validate request from Twilio
if (!TwilioService::validateRequest()) {
    http_response_code(403);
    echo "Forbidden: Signature validation failed";
    exit;
}

$from = $_POST['From'] ?? '';
$to = $_POST['To'] ?? '';
$body = $_POST['Body'] ?? '';

if (empty($from) || empty($to)) {
    http_response_code(400);
    echo "Bad Request: Missing From or To parameters";
    exit;
}

$db = DB::connect();

// (b) Resolve tenant by receiver number
$stmt = $db->prepare("SELECT * FROM tenants WHERE whatsapp_number = :whatsapp_number AND deleted_at IS NULL LIMIT 1");
$stmt->execute([':whatsapp_number' => $to]);
$tenant = $stmt->fetch();

if (!$tenant) {
    // Log the unmapped webhook for debugging
    $stmtLog = $db->prepare("INSERT INTO agent_logs (type, gemini_call, payload) VALUES ('unmapped_webhook', 0, :payload)");
    $stmtLog->execute([
        ':payload' => json_encode([
            'to' => $to,
            'from' => $from,
            'error' => "Tenant with whatsapp number $to not found"
        ])
    ]);
    http_response_code(404);
    echo "Not Found: Tenant not registered for this number";
    exit;
}

$tenant['_channel'] = 'whatsapp';
$tenant_id = (int) $tenant['id'];
$profileName = $_POST['ProfileName'] ?? 'Cliente';

// (c) Find or create contact scoped by tenant_id
$stmt = $db->prepare("SELECT * FROM contacts WHERE tenant_id = :tenant_id AND phone = :phone LIMIT 1");
$stmt->execute([':tenant_id' => $tenant_id, ':phone' => $from]);
$contact = $stmt->fetch();

if (!$contact) {
    $stmt = $db->prepare("INSERT INTO contacts (tenant_id, name, phone, channel) VALUES (:tenant_id, :name, :phone, 'whatsapp')");
    $stmt->execute([':tenant_id' => $tenant_id, ':name' => $profileName, ':phone' => $from]);
    $contactId = (int) $db->lastInsertId();
} else {
    $contactId = (int) $contact['id'];
    // Update name to ProfileName if it was still the default
    if ($contact['name'] === 'Cliente' && $profileName !== 'Cliente') {
        $stmtUpdate = $db->prepare("UPDATE contacts SET name = :name WHERE id = :id");
        $stmtUpdate->execute([':name' => $profileName, ':id' => $contactId]);
    }
}

// Find or create conversation, then persist the inbound message
$conversationId = AgentService::findOrCreateConversation($db, $tenant_id, $contactId, 'whatsapp');
AgentService::persistInbound($db, $tenant_id, $conversationId, $body, $_POST['MediaUrl0'] ?? null);
AgentService::refreshWindow($db, $conversationId);

// (d-f) Build context, call Gemini, persist reply + agent_log
try {
    $result = AgentService::handleMessage($db, $tenant, $conversationId, $contactId);

    // (g) Respond with TwiML
    header('Content-Type: text/xml');
    echo '<?xml version="1.0" encoding="UTF-8"?>';
    echo '<Response>';
    echo '<Message>' . htmlspecialchars($result['text'], ENT_XML1) . '</Message>';
    echo '</Response>';

} catch (Throwable $e) {
    error_log("Gemini generation failed: " . $e->getMessage());
    AgentService::logError($db, $tenant_id, 'whatsapp_error', $e);

    $fallbackMessage = "Estoy experimentando dificultades técnicas. Por favor, intenta de nuevo más tarde o contáctanos directamente.";

    header('Content-Type: text/xml');
    echo '<?xml version="1.0" encoding="UTF-8"?>';
    echo '<Response>';
    echo '<Message>' . htmlspecialchars($fallbackMessage, ENT_XML1) . '</Message>';
    echo '</Response>';
}
