<?php
// Integraciones - Acciones backend (Voiso settings y click-to-call)
if (session_status() === PHP_SESSION_NONE) { session_start(); }
if (!defined('BASE_PATH')) { define('BASE_PATH', dirname(dirname(__DIR__))); }
require_once BASE_PATH . '/database/config.php';
require_once BASE_PATH . '/database/connection.php';
require_once BASE_PATH . '/api/shared/ApiLoader.php';

header('Content-Type: application/json; charset=utf-8');

function isLoggedIn() { return isset($_SESSION['user_id']) && !empty($_SESSION['user_id']); }
if (!isLoggedIn()) { http_response_code(401); echo json_encode(['success' => false, 'message' => 'No autenticado']); exit; }

$db = getDB();
$pdo = $db->getConnection();
$current_user_id = (int)($_SESSION['user_id'] ?? 0);

function userHasPermissionByName($pdo, $permName, $userId) {
    if (empty($userId)) return false;
    $stmt = $pdo->prepare("SELECT 1 FROM role_permissions rp INNER JOIN permissions p ON rp.permission_id = p.id INNER JOIN user_roles ur ON rp.role_id = ur.role_id WHERE ur.user_id = ? AND p.name = ? LIMIT 1");
    $stmt->execute([$userId, $permName]);
    return (bool)$stmt->fetchColumn();
}

$action = $_GET['action'] ?? '';

function saveSettings($pdo, $current_user_id) {
    $input = json_decode(file_get_contents('php://input'), true);
    $integration = $input['integration'] ?? '';
    $settings = $input['settings'] ?? [];
    
    if ($integration === 'voiso') {
        if (!userHasPermissionByName($pdo, 'voiso.configure', $current_user_id)) {
            http_response_code(403);
            return ['success' => false, 'message' => 'No tienes permiso para configurar Voiso'];
        }
        
        try {
            $voisoClient = ApiLoader::getVoisoClient($pdo);
            $result = $voisoClient->saveConfiguration(
                $settings['api_base_url'] ?? '',
                $settings['api_token'] ?? '',
                $settings['default_caller_id'] ?? '',
                $settings['default_agent_id'] ?? ''
            );
            
            if ($result) {
                return ['success' => true, 'message' => 'Configuración de Voiso guardada'];
            } else {
                return ['success' => false, 'message' => 'Error guardando configuración de Voiso'];
            }
        } catch (Exception $e) {
            return ['success' => false, 'message' => 'Error guardando configuración: ' . $e->getMessage()];
        }
    } elseif ($integration === 'big4pay') {
        // Permitir configurar Big4pay si el usuario tiene big4pay.configure o payments.configure
        $canConfigureBig4pay = userHasPermissionByName($pdo, 'big4pay.configure', $current_user_id)
            || userHasPermissionByName($pdo, 'payments.configure', $current_user_id);
        if (!$canConfigureBig4pay) {
            http_response_code(403);
            return ['success' => false, 'message' => 'No tienes permiso para configurar Big4pay'];
        }
        
        try {
            $big4payClient = ApiLoader::getBig4payClient($pdo);
            $username = $settings['username'] ?? '';
            $passwordInput = $settings['password'] ?? '';
            $currency = $settings['currency'] ?? null;
            $ipnUrl = $settings['ipn_url'] ?? null;
            $successUrl = $settings['success_url'] ?? null;
            $cancelUrl = $settings['cancel_url'] ?? null;

            // Si el password viene como '******', conservar el actual
            if ($passwordInput === '******') {
                $passwordInput = $big4payClient->getPassword();
            }

            $extra = [ 'ipn_url' => $ipnUrl, 'success_url' => $successUrl, 'cancel_url' => $cancelUrl ];
            $result = $big4payClient->saveConfiguration($username, $passwordInput, $currency, $extra);
            
            if ($result) {
                return ['success' => true, 'message' => 'Configuración de Big4pay guardada'];
            } else {
                return ['success' => false, 'message' => 'Error guardando configuración de Big4pay'];
            }
        } catch (Exception $e) {
            return ['success' => false, 'message' => 'Error guardando configuración: ' . $e->getMessage()];
        }
    } elseif ($integration === 'key2pay') {
        $canConfigure = userHasPermissionByName($pdo, 'key2pay.configure', $current_user_id) || userHasPermissionByName($pdo, 'payments.configure', $current_user_id);
        if (!$canConfigure) { http_response_code(403); return ['success'=>false,'message'=>'No tienes permiso para configurar Key2Pay']; }
        try {
            $client = ApiLoader::getIntegrationClient('key2pay', $pdo);
            $api_base_url = $settings['api_base_url'] ?? '';
            $username = $settings['username'] ?? '';
            $passwordInput = $settings['password'] ?? '';
            $currency = $settings['currency'] ?? null;
            if ($passwordInput === '******' || $passwordInput === '') {
                // Conservar contraseña actual
                $cfg = $client->getConfiguration();
                $passwordInput = $cfg['username'] ? null : ''; // si no hay usuario, requerirá password luego
            }
            $result = $client->saveConfiguration($api_base_url, $username, $passwordInput ?? '', $currency, []);
            return ['success'=>$result, 'message'=>$result ? 'Configuración de Key2Pay guardada' : 'Error guardando configuración de Key2Pay'];
        } catch (Exception $e) { return ['success'=>false,'message'=>'Error guardando configuración: '.$e->getMessage()]; }
    } else {
        return ['success' => false, 'message' => 'Integración inválida'];
    }
}

function getBig4payConfig($pdo) {
    $big4payClient = ApiLoader::getBig4payClient($pdo);
    return $big4payClient->getConfiguration();
}

function testBig4payIntegration($pdo) {
    try {
        $big4payClient = ApiLoader::getBig4payClient($pdo);
        
        if (!$big4payClient->isConfigured()) {
            return ['success' => false, 'message' => 'Big4pay no está configurado correctamente'];
        }
        
        // Realizar un test de conexión usando el cliente API
        $result = $big4payClient->createAccessToken(1, 'MXN', true);
        
        if ($result['success']) {
            return [
                'success' => true,
                'message' => $result['message'] ?? 'Conexión exitosa con Big4pay',
                'status' => $result['status'] ?? null,
                'token' => $result['token'] ?? null
            ];
        } else {
            return [
                'success' => false, 
                'message' => $result['message'] ?? 'Error en autenticación Big4pay',
                'status' => $result['status'] ?? null,
                'error_code' => $result['error_code'] ?? null
            ];
        }
        
    } catch (Exception $e) {
        // Propagar el mensaje real del error para facilitar el ajuste
        return [
            'success' => false,
            'message' => $e->getMessage(),
        ];
    }
}

function createBig4payAccessToken($pdo) {
    try {
        $big4payClient = ApiLoader::getBig4payClient($pdo);
        
        if (!$big4payClient->isConfigured()) {
            return ['success' => false, 'message' => 'Big4pay no está configurado correctamente'];
        }
        
        // Obtener parámetros de la solicitud
        $amount = $_POST['amount'] ?? 100;
        $currency = $_POST['currency'] ?? 'MXN';
        
        $result = $big4payClient->createAccessToken($amount, $currency);
        
        return $result;
        
    } catch (Exception $e) {
        return ['success' => false, 'message' => 'Error interno: ' . $e->getMessage()];
    }
}

function getVoisoConfig($pdo) {
    $voisoClient = ApiLoader::getVoisoClient($pdo);
    return $voisoClient->getConfiguration();
}

function testVoisoIntegration($pdo) {
    try {
        $voisoClient = ApiLoader::getVoisoClient($pdo);
        
        if (!$voisoClient->isConfigured()) {
            http_response_code(400);
            return ['success' => false, 'message' => 'Voiso no está configurado: faltan Base URL y/o Token'];
        }
        
        $result = $voisoClient->testConnection();
        
        if ($result['success']) {
            return $result;
        } else {
            // Establecer código de respuesta HTTP apropiado
            if (isset($result['status'])) {
                http_response_code($result['status']);
            } else {
                http_response_code(502);
            }
            return $result;
        }
        
    } catch (Exception $e) {
        http_response_code(500);
        return ['success' => false, 'message' => 'Error interno: ' . $e->getMessage()];
    }
}

function clickToCall($pdo, $current_user_id) {
    if (!userHasPermissionByName($pdo, 'voiso.click_to_call', $current_user_id)) {
        http_response_code(403);
        return ['success' => false, 'message' => 'No tienes permiso para realizar llamadas'];
    }
    
    try {
        $input = json_decode(file_get_contents('php://input'), true);
        $entity = $input['entity'] ?? ''; // 'lead' | 'client'
        $id = (int)($input['id'] ?? 0);
        if (!$entity || !$id) { 
            return ['success' => false, 'message' => 'Parámetros inválidos']; 
        }

        // Obtener teléfono REAL desde BD (no usar el valor mostrado en UI)
        if ($entity === 'lead') {
            $stmt = $pdo->prepare("SELECT phone, first_name, last_name FROM leads WHERE id = ? LIMIT 1");
        } else {
            $stmt = $pdo->prepare("SELECT phone, first_name, last_name FROM clients WHERE id = ? LIMIT 1");
        }
        $stmt->execute([$id]);
        $row = $stmt->fetch();
        if (!$row || empty($row['phone'])) { 
            return ['success' => false, 'message' => 'Teléfono no disponible']; 
        }
        $phone = preg_replace('/\D+/', '', (string)$row['phone']);

        // Usar el cliente API de Voiso
        $voisoClient = ApiLoader::getVoisoClient($pdo);
        
        if (!$voisoClient->isConfigured()) {
            return ['success' => false, 'message' => 'Voiso no está configurado'];
        }

        // Preparar datos del contexto
        $context = [
            'entity' => $entity, 
            'id' => $id, 
            'name' => trim(($row['first_name'] ?? '') . ' ' . ($row['last_name'] ?? ''))
        ];

        // Realizar la llamada usando el cliente API
        $result = $voisoClient->makeCall($phone, $context);
        
        return $result;
        
    } catch (Exception $e) {
        return ['success' => false, 'message' => 'Error interno: ' . $e->getMessage()];
    }
}

try {
    switch ($action) {
        case 'save_settings':
            echo json_encode(saveSettings($pdo, $current_user_id));
            break;
        case 'voiso_click_to_call':
            echo json_encode(clickToCall($pdo, $current_user_id));
            break;
        case 'test_voiso':
            echo json_encode(testVoisoIntegration($pdo));
            break;
        case 'test_big4pay':
            // Permitir probar integración si tiene big4pay.test o payments.configure
            if (!userHasPermissionByName($pdo, 'big4pay.test', $current_user_id)
                && !userHasPermissionByName($pdo, 'payments.configure', $current_user_id)) {
                echo json_encode(['success' => false, 'message' => 'Sin permisos para probar Big4pay']);
                exit;
            }
            echo json_encode(testBig4payIntegration($pdo));
            break;
        case 'test_key2pay':
            if (!userHasPermissionByName($pdo, 'key2pay.test', $current_user_id)
                && !userHasPermissionByName($pdo, 'payments.configure', $current_user_id)) {
                echo json_encode(['success'=>false,'message'=>'Sin permisos para probar Key2Pay']);
                exit;
            }
            try {
                $client = ApiLoader::getIntegrationClient('key2pay', $pdo);
                echo json_encode($client->createAccessToken());
            } catch (Exception $e) { echo json_encode(['success'=>false,'message'=>$e->getMessage()]); }
            break;
        case 'create_key2pay_token':
            try { $client = ApiLoader::getIntegrationClient('key2pay', $pdo); echo json_encode($client->createAccessToken()); } catch (Exception $e) { echo json_encode(['success'=>false,'message'=>$e->getMessage()]); }
            break;
        case 'test_key2pay_payment':
            if (!userHasPermissionByName($pdo, 'key2pay.test', $current_user_id)
                && !userHasPermissionByName($pdo, 'payments.configure', $current_user_id)) {
                echo json_encode(['success'=>false,'message'=>'Sin permisos para realizar pagos de prueba']);
                exit;
            }
            try {
                $client = ApiLoader::getIntegrationClient('key2pay', $pdo);
                $config = $client->getConfiguration();
                $scheme = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http';
                $origin = $scheme . '://' . ($_SERVER['HTTP_HOST'] ?? 'localhost');
                $rootPath = rtrim(dirname(dirname(dirname($_SERVER['SCRIPT_NAME']))), '/');
                $ipnUrl = $config['ipn_url'] ?? ($origin . $rootPath . '/api/payment_method/key2pay/ipn.php');
                $successUrl = $config['success_url'] ?? ($origin . $rootPath . '/modules/client_portal/payment_success.php');
                $cancelUrl = $config['cancel_url'] ?? ($origin . $rootPath . '/modules/client_portal/payment_cancel.php');
                $res = $client->createPayment([
                    'amount' => 200,
                    'currency' => ($config['currency'] ?? 'USD'),
                    'description' => 'Pago de prueba',
                    'ipn_url' => $ipnUrl,
                    'success_url' => $successUrl,
                    'cancel_url' => $cancelUrl,
                    'customer' => [ 'first_name'=>'John','last_name'=>'Doe','email'=>'john@example.com','mobile'=>'123456789' ]
                ]);
                echo json_encode($res);
            } catch (Exception $e) { echo json_encode(['success'=>false,'message'=>$e->getMessage()]); }
            break;
        case 'test_key2pay_checkout':
            if (!userHasPermissionByName($pdo, 'key2pay.test', $current_user_id)
                && !userHasPermissionByName($pdo, 'payments.configure', $current_user_id)) {
                echo json_encode(['success'=>false,'message'=>'Sin permisos para iniciar checkout']);
                exit;
            }
            try {
                $client = ApiLoader::getIntegrationClient('key2pay', $pdo);
                $config = $client->getConfiguration();
                // Fallback a https del dominio del token si existe, si no usar placeholders
                $ipn = $config['ipn_url'] ?: 'https://goldendragonexchange.com/api/key2pay/ipn';
                $ret = $config['success_url'] ?: 'https://goldendragonexchange.com/portal/payment_success';
                $can = $config['cancel_url'] ?: 'https://goldendragonexchange.com/portal/payment_cancel';
                $orderId = method_exists($client,'generateIdentifier') ? $client->generateIdentifier() : ('ORD_' . time());
                $res = $client->createCheckoutPage([
                    'currency' => 'USD',
                    'amount' => 1550,
                    'language' => 'ES',
                    'orderId' => $orderId,
                    'description' => 'Depósito de prueba',
                    'notificationUrl' => $ipn,
                    'returnUrl' => $ret,
                    'cancelUrl' => $can,
                    'customer' => [ 'first_name'=>'Cliente','last_name'=>'Demo','email'=>'demo@example.com' ]
                ]);
                // Extraer checkout url si existe
                $checkout = $res['json']['checkoutUrl'] ?? $res['json']['url'] ?? null;
                $res['checkout_url'] = $checkout;
                echo json_encode($res);
            } catch (Exception $e) { echo json_encode(['success'=>false,'message'=>$e->getMessage()]); }
            break;
        
        case 'test_big4pay_payment':
            // Permitir pago de prueba si tiene big4pay.test o payments.configure
            if (!userHasPermissionByName($pdo, 'big4pay.test', $current_user_id)
                && !userHasPermissionByName($pdo, 'payments.configure', $current_user_id)) {
                echo json_encode(['success' => false, 'message' => 'Sin permisos para realizar pagos de prueba']);
                exit;
            }
            // Flujo: crear token, guardarlo y ejecutar initiate con parámetros solicitados
            $big4payClient = ApiLoader::getBig4payClient($pdo);
            if (!$big4payClient->isConfigured()) {
                echo json_encode(['success' => false, 'message' => 'Big4pay no está configurado correctamente']);
                exit;
            }
            $raw = $big4payClient->createAccessTokenRaw();
            if (!$raw['success']) { echo json_encode($raw); exit; }
            $token = $raw['authorization'] ?? ($raw['json']['access_token'] ?? null);
            if ($token) { $big4payClient->saveAccessToken($token); }
            $config = $big4payClient->getConfiguration();
            $currency = $config['currency'] ?? 'MXN';
            $identifier = $big4payClient->generateIdentifier();
            // Usar URLs configuradas; si faltan, construir absolutas como fallback
            $ipnUrl = $config['ipn_url'] ?? null;
            $successUrl = $config['success_url'] ?? null;
            $cancelUrl = $config['cancel_url'] ?? null;
            if (!$ipnUrl || !$successUrl || !$cancelUrl) {
                $scheme = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http';
                $origin = $scheme . '://' . ($_SERVER['HTTP_HOST'] ?? 'localhost');
                $rootPath = rtrim(dirname(dirname(dirname($_SERVER['SCRIPT_NAME']))), '/');
                $ipnUrl = $ipnUrl ?: ($origin . $rootPath . '/api/payment_method/big4pay/ipn.php');
                $successUrl = $successUrl ?: ($origin . $rootPath . '/modules/client_portal/big4pay_success.php');
                $cancelUrl = $cancelUrl ?: ($origin . $rootPath . '/modules/client_portal/big4pay_cancel.php');
            }
            $params = [
                'access_token' => $token,
                'identifier' => $identifier,
                'currency' => $currency,
                'amount' => 200,
                'details' => 'deposit transactions',
                'ipn_url' => $ipnUrl,
                'success_url' => $successUrl,
                'cancel_url' => $cancelUrl,
                'site_name' => 'IAttrade',
                'site_logo' => 'http://yoursite.com/logo.png',
                'checkout_theme' => 'light',
                'customer' => [
                    'first_name' => 'John',
                    'last_name' => 'Doe',
                    'email' => 'joan@gmail.com',
                    'mobile' => '12345789'
                ]
            ];
            $res = $big4payClient->initiatePayment($params);
            $res['identifier'] = $identifier;
            $res['access_token'] = $token;
            echo json_encode($res);
            break;
        case 'create_big4pay_token':
            echo json_encode(createBig4payAccessToken($pdo));
            break;
        case 'get_big4pay_password':
            // Devuelve la contraseña sólo si tiene permisos de configuración
            if (!userHasPermissionByName($pdo, 'big4pay.configure', $current_user_id)
                && !userHasPermissionByName($pdo, 'payments.configure', $current_user_id)) {
                http_response_code(403);
                echo json_encode(['success' => false, 'message' => 'Sin permisos para revelar contraseña']);
                break;
            }
            $client = ApiLoader::getBig4payClient($pdo);
            echo json_encode(['success' => true, 'password' => $client->getPassword()]);
            break;
        default:
            http_response_code(400);
            echo json_encode(['success' => false, 'message' => 'Acción inválida']);
    }
} catch (Exception $e) {
    http_response_code(500);
    echo json_encode(['success' => false, 'message' => 'Error interno: ' . $e->getMessage()]);
}
