<?php
session_start();
if (!defined('BASE_PATH')) { define('BASE_PATH', dirname(dirname(dirname(__DIR__)))); }
require_once BASE_PATH . '/database/connection.php';
require_once BASE_PATH . '/api/shared/ApiLoader.php';

$db = Database::getInstance();
$pdo = $db->getConnection();
$client = ApiLoader::getIntegrationClient('key2pay', $pdo);
$action = $_GET['action'] ?? $_POST['action'] ?? '';

header('Content-Type: application/json');
if (!$client) { echo json_encode(['success'=>false,'message'=>'Key2Pay no configurado']); exit; }

$clientLogged = isset($_SESSION['client_id']) && !empty($_SESSION['client_id']);
$userLogged = isset($_SESSION['user_id']) && !empty($_SESSION['user_id']);
$privActions = ['create_key2pay_checkout','create_key2pay_payment','create_key2pay_payment_raw'];
if (in_array($action, $privActions, true) && (!$clientLogged && !$userLogged)) { http_response_code(401); echo json_encode(['success'=>false,'message'=>'No autorizado']); exit; }

try {
  if ($action === 'list_key2pay_methods') {
    $params = [];
    foreach (['channel','country','currency'] as $k) {
      if (isset($_GET[$k]) && $_GET[$k] !== '') { $params[$k] = $_GET[$k]; continue; }
      if (isset($_POST[$k]) && $_POST[$k] !== '') { $params[$k] = $_POST[$k]; }
    }
    $res = $client->getPaymentMethods($params);
    echo json_encode($res);
    exit;
  }
  if ($action === 'create_key2pay_checkout') {
    $currency = $_POST['currency'] ?? 'USD';
    $amountMinor = (int)($_POST['amount_minor'] ?? 0);
    $orderId = $_POST['order_id'] ?? ('ORD_' . time());
    $desc = $_POST['description'] ?? 'deposit';
    $lang = $_POST['language'] ?? 'EN';
    $clientId = isset($_POST['client_id']) ? (int)$_POST['client_id'] : null;
    $accountNumber = $_POST['account_number'] ?? null;

    $scheme = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http';
    $origin = $scheme . '://' . ($_SERVER['HTTP_HOST'] ?? 'localhost');
    $rootPath = rtrim(dirname(dirname(dirname($_SERVER['SCRIPT_NAME']))), '/');
    $ipnUrl = $origin . $rootPath . '/api/payment_method/key2pay/ipn.php';
    $returnUrl = $origin . $rootPath . '/modules/client_portal/payment_success.php';
    $cancelUrl = $origin . $rootPath . '/modules/client_portal/payment_cancel.php';

    $firstName = $_POST['first_name'] ?? ($_SESSION['first_name'] ?? null);
    $lastName = $_POST['last_name'] ?? ($_SESSION['last_name'] ?? null);
    $email = $_POST['email'] ?? ($_SESSION['email'] ?? null);
    $mobile = $_POST['mobile'] ?? $_POST['phone'] ?? ($_SESSION['mobile'] ?? null);
    if ((!$firstName || !$email) && $clientId) {
      try {
        $st = $pdo->prepare("SELECT first_name,last_name,email,phone FROM clients WHERE id=? LIMIT 1");
        $st->execute([$clientId]);
        if ($row = $st->fetch()) { $firstName = $firstName ?: ($row['first_name'] ?? 'Cliente'); $lastName = $lastName ?: ($row['last_name'] ?? ''); $email = $email ?: ($row['email'] ?? ''); $mobile = $mobile ?: ($row['phone'] ?? ''); }
      } catch (Throwable $__) {}
    }

    $res = $client->createCheckoutPage([
      'currency' => $currency,
      'amount' => $amountMinor,
      'language' => $lang,
      'orderId' => $orderId,
      'description' => $desc,
      'notificationUrl' => $ipnUrl,
      'returnUrl' => $returnUrl,
      'cancelUrl' => $cancelUrl,
      'customer' => [ 'FirstName'=>$firstName ?: 'Cliente', 'LastName'=>$lastName ?: 'CRM', 'Email'=>$email ?: 'demo@example.com', 'Mobile'=>$mobile ?: '' ],
      'client_id' => $clientId,
      'account_number' => $accountNumber
    ]);
    echo json_encode($res);
    exit;
  }
  if ($action === 'ensure_key2pay_token') {
    $cfg = $client->getConfiguration();
    $hasToken = !empty($cfg['access_token']);
    $res = [ 'success'=>true, 'configured'=>$cfg['configured'], 'api_base_url'=>$cfg['api_base_url'], 'has_token'=>$hasToken, 'token_masked'=>($hasToken ? (substr($cfg['access_token'],0,6).'***') : null) ];
    if (!$hasToken) {
      $tok = $client->createAccessToken();
      $res['token_created'] = (bool)$tok['success'];
      $res['status'] = $tok['status'] ?? null;
      $res['message'] = $tok['message'] ?? null;
    }
    echo json_encode($res);
    exit;
  }
  if ($action === 'create_key2pay_payment') {
    $currency = $_POST['currency'] ?? 'USD';
    $amount = (int)($_POST['amount'] ?? 0);
    $orderId = $_POST['order_id'] ?? ('ORD_' . time());
    $desc = $_POST['description'] ?? 'deposit';
    $lang = $_POST['language'] ?? 'EN';
    $clientId = isset($_POST['client_id']) ? (int)$_POST['client_id'] : null;
    $accountNumber = $_POST['account_number'] ?? null;
    $pmId = $_POST['paymentMethodId'] ?? '';
    $channel = strtoupper(trim($_POST['channel'] ?? 'ONLINE'));

    $scheme = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http';
    $origin = $scheme . '://' . ($_SERVER['HTTP_HOST'] ?? 'localhost');
    $rootPath = rtrim(dirname(dirname(dirname($_SERVER['SCRIPT_NAME']))), '/');
    $ipnUrl = $origin . $rootPath . '/api/payment_method/key2pay/ipn.php';
    $returnUrl = $origin . $rootPath . '/modules/client_portal/payment_success.php';
    $cancelUrl = $origin . $rootPath . '/modules/client_portal/payment_cancel.php';

    $firstName = $_POST['first_name'] ?? ($_SESSION['first_name'] ?? null);
    $lastName = $_POST['last_name'] ?? ($_SESSION['last_name'] ?? null);
    $email = $_SESSION['email'] ?? null;
    $mobile = $_SESSION['mobile'] ?? null;
    $countryIso = null;
    $getIp = function(){
      $keys = ['HTTP_CF_CONNECTING_IP','HTTP_X_FORWARDED_FOR','HTTP_X_REAL_IP','REMOTE_ADDR'];
      foreach ($keys as $k) { if (!empty($_SERVER[$k])) { $v = $_SERVER[$k]; if ($k==='HTTP_X_FORWARDED_FOR') { $parts = explode(',', $v); $v = trim($parts[0]); } return $v; } }
      return null;
    };
    $ipAddr = $getIp();
    if ($clientId) {
      try {
        $st = $pdo->prepare("SELECT first_name,last_name,email,phone FROM clients WHERE id=? LIMIT 1");
        $st->execute([$clientId]);
        if ($row=$st->fetch()) {
          $firstName = $row['first_name'] ?? $firstName ?? 'Cliente';
          $lastName = $row['last_name'] ?? $lastName ?? '';
          $email = $row['email'] ?? $email ?? '';
          $mobile = $row['phone'] ?? $mobile ?? '';
        }
        // Complementar con perfil extendido si existe
        $stp = $pdo->prepare("SELECT country, city, postcode, personal_id FROM client_profiles WHERE client_id=? LIMIT 1");
        $stp->execute([$clientId]);
        if ($prow = $stp->fetch()) {
          if (empty($countryIso) && !empty($prow['country'])) { $countryIso = strtoupper($prow['country']); }
          $city = $prow['city'] ?? null;
          $postcode = $prow['postcode'] ?? null;
          $personalId = $prow['personal_id'] ?? null;
        }
      } catch (Throwable $__) {}
    }
    if (!$countryIso) { $countryIso = ($currency === 'MXN' ? 'MX' : 'US'); }
    // Mantener formato original del teléfono (p.ej. E.164 con '+')
    if (isset($_POST['country']) && $_POST['country'] !== '') { $countryIso = strtoupper(trim($_POST['country'])); }

    if (stripos($ipnUrl, 'https://') !== 0) { $ipnUrl = null; }
    $payload = [
      'paymentMethodId' => $pmId,
      'channel' => $channel,
      'amount' => $amount,
      'currency' => $currency,
      'language' => $lang,
      'order_id' => $orderId,
      'description' => $desc,
      'notificationUrl' => $ipnUrl,
      'returnUrl' => $returnUrl,
      'cancelUrl' => $cancelUrl,
      'customer' => [ 'FirstName'=>$firstName ?: 'Cliente', 'LastName'=>$lastName ?: 'CRM', 'Email'=>$email ?: 'demo@example.com', 'Mobile'=>$mobile ?: '', 'phone'=>$mobile ?: '', 'Country'=>$countryIso, 'city'=>($city ?? ''), 'postcode'=>($postcode ?? ''), 'personalId'=>($personalId ?? ''), 'ip'=>$ipAddr ],
      'client_id' => $clientId,
      'account_number' => $accountNumber
    ];
    // Refrescar token antes de crear el pago
    $tokRes = $client->createAccessToken();
    $res = $client->createPayment($payload);
    $ok = isset($res['success']) ? (bool)$res['success'] : false;
    if ($ok) {
      echo json_encode([
        'success'=>true,
        'redirect_url'=>$res['redirect_url'] ?? null,
        'checkout_url'=>$res['checkout_url'] ?? null,
        'json'=>$res['json'] ?? null,
        'http_code'=>$res['http_code'] ?? null,
        'api_base_url'=>($client->getConfiguration()['api_base_url'] ?? null),
        'auth_used'=>($res['auth_used'] ?? null),
        'token_masked'=>((($client->getConfiguration()['access_token'] ?? null)) ? (substr($client->getConfiguration()['access_token'],0,6).'***') : null),
        'response_json'=>($res['json'] ?? null),
        'response_body'=>($res['body'] ?? null),
        'token_refreshed'=> (bool)($tokRes['success'] ?? false),
        'token_status'=> ($tokRes['status'] ?? null),
        'request_url'=>($res['request_url'] ?? null),
        'request_headers'=>($res['request_headers'] ?? null),
        'override_used'=>((isset($_POST['token_override']) && trim((string)$_POST['token_override'])!=='') ? true : false),
        'auth_header_prefix'=>($res['auth_header_prefix'] ?? null),
        'auth_token_preview'=>($res['auth_token_preview'] ?? null),
        'auth_token_len'=>($res['auth_token_len'] ?? null),
        'jwt_exp'=>($res['jwt_exp'] ?? null),
        'jwt_iss'=>($res['jwt_iss'] ?? null),
        'payload'=>[
          'paymentMethodId'=>$pmId,
          'channel'=>$channel,
          'amount'=>$amount,
          'currency'=>$currency,
          'language'=>$lang,
          'order_id'=>$orderId,
          'description'=>$desc,
          'customer'=>[ 'FirstName'=>$firstName ?: 'Cliente', 'LastName'=>$lastName ?: 'CRM', 'Email'=>($email ? substr($email,0,3).'***' : ''), 'Mobile'=>$mobile ?: '', 'phone'=>$mobile ?: '', 'Country'=>$countryIso, 'city'=>($city ?? ''), 'postcode'=>($postcode ?? ''), 'personalId'=>($personalId ?? ''), 'ip'=>$ipAddr ]
        ]
      ]);
    }
    else {
      $msg = $res['message'] ?? '';
      if (!$msg) { $j = $res['json'] ?? null; if (is_array($j)) { $msg = $j['message'] ?? ($j['error'] ?? ''); } }
      if (!$msg) { $body = $res['body'] ?? null; if (is_string($body)) { $msg = substr($body, 0, 200); } }
      echo json_encode([ 'success'=>false, 'http_code'=>($res['http_code'] ?? null), 'message'=>$msg ?: 'Checkout API error', 'api_base_url'=>($client->getConfiguration()['api_base_url'] ?? null), 'auth_used'=>($res['auth_used'] ?? null), 'token_masked'=>((($client->getConfiguration()['access_token'] ?? null)) ? (substr($client->getConfiguration()['access_token'],0,6).'***') : null), 'response_json'=>($res['json'] ?? null), 'response_body'=>($res['body'] ?? null), 'token_refreshed'=> (bool)($tokRes['success'] ?? false), 'token_status'=> ($tokRes['status'] ?? null), 'request_url'=>($res['request_url'] ?? null), 'request_headers'=>($res['request_headers'] ?? null), 'override_used'=>((isset($_POST['token_override']) && trim((string)$_POST['token_override'])!=='') ? true : false), 'auth_header_prefix'=>($res['auth_header_prefix'] ?? null), 'auth_token_preview'=>($res['auth_token_preview'] ?? null), 'auth_token_len'=>($res['auth_token_len'] ?? null), 'jwt_exp'=>($res['jwt_exp'] ?? null), 'jwt_iss'=>($res['jwt_iss'] ?? null), 'payload'=>[
        'paymentMethodId'=>$pmId,
        'channel'=>$channel,
        'amount'=>$amount,
        'currency'=>$currency,
        'language'=>$lang,
        'order_id'=>$orderId,
        'description'=>$desc,
        'customer'=>[ 'FirstName'=>$firstName ?: 'Cliente', 'LastName'=>$lastName ?: 'CRM', 'Email'=>($email ? substr($email,0,3).'***' : ''), 'Mobile'=>$mobile ?: '', 'phone'=>$mobile ?: '', 'Country'=>$countryIso, 'city'=>($city ?? ''), 'postcode'=>($postcode ?? ''), 'personalId'=>($personalId ?? ''), 'ip'=>$ipAddr ]
      ] ]);
    }
    exit;
  }
  if ($action === 'create_key2pay_payment_raw') {
    $currency = $_POST['currency'] ?? 'USD';
    $amount = (int)($_POST['amount'] ?? 0);
    $orderId = $_POST['orderId'] ?? $_POST['order_id'] ?? ('ORD_' . time());
    $lang = $_POST['language'] ?? 'ES';
    $pmId = $_POST['paymentMethodId'] ?? '';
    $channel = strtoupper(trim($_POST['channel'] ?? 'ONLINE'));
    $ipn = $_POST['notificationUrl'] ?? $_POST['notification_url'] ?? '';
    $clientId = isset($_POST['client_id']) ? (int)$_POST['client_id'] : null;
    $firstName = $_POST['first_name'] ?? $_POST['FirstName'] ?? '';
    $lastName = $_POST['last_name'] ?? $_POST['LastName'] ?? '';
    $email = $_POST['email'] ?? $_POST['Email'] ?? '';
    $phone = $_POST['phone'] ?? $_POST['Mobile'] ?? '';
    $country = strtoupper(trim($_POST['country'] ?? $_POST['Country'] ?? ''));
    $city = $_POST['city'] ?? '';
    $postcode = $_POST['postcode'] ?? '';
    $personalId = $_POST['personalId'] ?? $_POST['personal_id'] ?? '';
    $getIp = function(){ $keys = ['HTTP_CF_CONNECTING_IP','HTTP_X_FORWARDED_FOR','HTTP_X_REAL_IP','REMOTE_ADDR']; foreach($keys as $k){ if(!empty($_SERVER[$k])){ $v=$_SERVER[$k]; if($k==='HTTP_X_FORWARDED_FOR'){ $parts=explode(',', $v); $v=trim($parts[0]); } return $v; } } return null; };
    $ipAddr = $_POST['ip'] ?? $getIp();
    if ($clientId) {
      try {
        $st = $pdo->prepare("SELECT first_name,last_name,email,phone FROM clients WHERE id=? LIMIT 1");
        $st->execute([$clientId]);
        if ($row = $st->fetch()) {
          $firstName = $firstName ?: ($row['first_name'] ?? '');
          $lastName = $lastName ?: ($row['last_name'] ?? '');
          $email = $email ?: ($row['email'] ?? '');
          $phone = $phone ?: ($row['phone'] ?? '');
        }
        $stp = $pdo->prepare("SELECT country, city, postcode, personal_id FROM client_profiles WHERE client_id=? LIMIT 1");
        $stp->execute([$clientId]);
        if ($prow = $stp->fetch()) {
          $country = $country ?: strtoupper(trim($prow['country'] ?? ''));
          $city = $city ?: ($prow['city'] ?? '');
          $postcode = $postcode ?: ($prow['postcode'] ?? '');
          $personalId = $personalId ?: ($prow['personal_id'] ?? '');
        }
      } catch (Throwable $__) {}
    }
    if (!$country) { $country = ($currency === 'MXN' ? 'MX' : 'US'); }
    if (!$firstName) { $firstName = 'Cliente'; }
    if (!$lastName) { $lastName = 'CRM'; }
    $payload = [
      'paymentMethodId' => $pmId,
      'channel' => $channel,
      'currency' => $currency,
      'amount' => $amount,
      'language' => $lang,
      'orderId' => $orderId,
      'description' => 'deposit',
      'notificationUrl' => (stripos($ipn,'https://')===0 ? $ipn : null),
      'customer' => [
        'country' => $country,
        'firstName' => $firstName,
        'lastName' => $lastName,
        'city' => $city,
        'email' => $email,
        'phone' => $phone,
        'postcode' => $postcode,
        'personalId' => $personalId,
        'ip' => $ipAddr
      ]
    ];
    $res = $client->createPaymentRaw($payload, true);
    $debug = (isset($_POST['debug']) && $_POST['debug']) || (isset($_GET['debug']) && $_GET['debug']);
    $ok = isset($res['success']) ? (bool)$res['success'] : false;
    // Persistir intento en payment_attempts para garantizar que se registre
    try {
      $pdo->exec("CREATE TABLE IF NOT EXISTS payment_attempts (
        id INT AUTO_INCREMENT PRIMARY KEY,
        client_id INT NULL,
        account_number VARCHAR(64) NULL,
        method VARCHAR(64) NOT NULL,
        identifier VARCHAR(64) NOT NULL,
        amount DECIMAL(18,6) NOT NULL,
        currency VARCHAR(8) NOT NULL,
        status VARCHAR(32) NOT NULL,
        payment_method VARCHAR(64) NULL,
        channel VARCHAR(32) NULL,
        external_transaction_id VARCHAR(128) NULL,
        source VARCHAR(32) NOT NULL,
        redirect_url VARCHAR(255) NULL,
        checkout_url VARCHAR(255) NULL,
        message TEXT NULL,
        raw_json JSON NULL,
        created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
        updated_at DATETIME NULL,
        UNIQUE KEY uniq_identifier (identifier)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
      $j = is_array($res) ? ($res['json'] ?? []) : [];
      if (!is_array($j) && isset($res['body']) && is_string($res['body'])) { $j = json_decode($res['body'], true) ?: []; }
      $identifier = $j['orderId'] ?? $payload['orderId'] ?? null;
      $checkoutUrl = $j['paymentPageUrl'] ?? $j['paymentFormUrl'] ?? ($res['checkout_url'] ?? null);
      $pmLabel = $j['payment_method'] ?? ($j['paymentMethod'] ?? null);
      if (is_array($j['paymentMethod'] ?? null)) { $pmLabel = ($j['paymentMethod']['name'] ?? ($j['paymentMethod']['label'] ?? $pmLabel)); }
      if (is_array($j['payment'] ?? null)) { $pmLabel = $pmLabel ?: ($j['payment']['method_label'] ?? ($j['payment']['method'] ?? $pmLabel)); }
      $channelOut = $j['channel'] ?? ($j['category'] ?? ($j['payment']['channel'] ?? null));
      if (is_array($j['paymentMethod'] ?? null)) { $channelOut = $channelOut ?: ($j['paymentMethod']['channel'] ?? null); }
      if ($channelOut && !in_array(strtolower($channelOut), ['online','cash'])) { $channelOut = strtolower($channelOut)==='cash'?'cash':'online'; }
      if ($identifier) {
        $sel = $pdo->prepare("SELECT id FROM payment_attempts WHERE identifier = ? LIMIT 1");
        $sel->execute([$identifier]);
        $row = $sel->fetch(PDO::FETCH_ASSOC);
        if ($row) {
          $upd = $pdo->prepare("UPDATE payment_attempts SET client_id=?, account_number=?, method=?, amount=?, currency=?, status=?, payment_method=?, channel=?, source='key2pay', checkout_url=?, raw_json=?, updated_at=NOW() WHERE id=?");
          $upd->execute([$clientId, null, 'key2pay', ($amount/100.0), $currency, ($ok? 'created':'error'), $pmLabel, $channelOut, $checkoutUrl, json_encode($res), (int)$row['id']]);
        } else {
          $ins = $pdo->prepare("INSERT INTO payment_attempts (client_id, account_number, method, identifier, amount, currency, status, payment_method, channel, source, checkout_url, raw_json) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)");
          $ins->execute([$clientId, null, 'key2pay', $identifier, ($amount/100.0), $currency, ($ok? 'created':'error'), $pmLabel, $channelOut, 'key2pay', $checkoutUrl, json_encode($res)]);
        }
      }
    } catch (Throwable $__) {}
    if ($ok) {
      $out = [ 'success'=>true, 'redirect_url'=>($res['redirect_url'] ?? null), 'checkout_url'=>($res['checkout_url'] ?? null) ];
      if ($debug) { $out['payload'] = $payload; $out['response_body'] = ($res['body'] ?? null); $out['response_json'] = ($res['json'] ?? null); $out['request_url'] = ($res['request_url'] ?? null); }
      echo json_encode($out);
    } else {
      $msg = $res['message'] ?? '';
      if (!$msg) { $j = $res['json'] ?? null; if (is_array($j)) { $msg = $j['message'] ?? ($j['error'] ?? ''); } }
      if (!$msg) { $body = $res['body'] ?? null; if (is_string($body)) { $msg = substr($body, 0, 200); } }
      $out = [ 'success'=>false, 'http_code'=>($res['http_code'] ?? null), 'message'=>$msg ?: 'Checkout API error' ];
      if ($debug) { $out['payload'] = $payload; $out['response_body'] = ($res['body'] ?? null); $out['response_json'] = ($res['json'] ?? null); $out['request_url'] = ($res['request_url'] ?? null); }
      echo json_encode($out);
    }
    exit;
  }
  echo json_encode(['success'=>false,'message'=>'Acción inválida']);
} catch (Throwable $e) {
  echo json_encode(['success'=>false,'message'=>'Error: '.$e->getMessage()]);
}
