<?php
//Developer: core tech web designTechnology
//Whatsapp: +2349162671360
//Telegram: @jeditech


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

require_once __DIR__ . '/../../include/config.php';
require_once __DIR__ . '/../../include/otp_functions.php';
require_once __DIR__ . '/../../include/smspva_functions.php';


// Ensure no stray output breaks JSON
if (!function_exists('json_clean_response')) {
    function json_clean_response(array $data, int $code = 200): void {
        ob_clean();
        http_response_code($code);
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode($data);
        exit;
    }
}

// ── Input validation ─────────────────────────────────────────────────────────

if (empty($_GET['order_id'])) {
    json_clean_response(['status' => '500', 'message' => 'Invalid Order ID']);
}
if (empty($_GET['token'])) {
    json_clean_response(['status' => '500', 'message' => 'Token Blank']);
}

$token    = trim($_GET['token']);
$order_id = trim($_GET['order_id']);

// ── Auth ─────────────────────────────────────────────────────────────────────

$user_id = otp_verify_user($token, $pdo);
if ($user_id === false) {
    json_clean_response(['status' => '500', 'message' => 'Invalid session. Please login again.']);
}

// ── Fetch active order ────────────────────────────────────────────────────────

try {
    $stmt = $pdo->prepare(
        "SELECT * FROM active_number
          WHERE order_id = :oid
            AND user_id  = :uid
          LIMIT 1"
    );
    $stmt->execute([':oid' => $order_id, ':uid' => $user_id]);
    $active = $stmt->fetch(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
    json_clean_response(['status' => '500', 'message' => 'Database error.']);
}

if (!$active) {
    json_clean_response(['status' => '500', 'message' => 'Invalid Order ID.']);
}

// ── If already finalised (inactive), return cached result ────────────────────

if ($active['active_status'] !== '2') {
    if (!empty($active['sms_text']) && otp_is_valid_sms($active['sms_text'])) {
        json_clean_response([
            'status'  => '200',
            'message' => 'Code Received',
            'sms'     => $active['sms_text'],
        ]);
    }
    json_clean_response(['status' => '500', 'message' => 'Order already cancelled or expired.']);
}

// ── Return immediately if valid SMS already stored ────────────────────────────

if (!empty($active['sms_text']) && otp_is_valid_sms($active['sms_text'])) {
    try {
        $pdo->prepare("UPDATE active_number SET active_status='1' WHERE id=:id AND active_status='2'")
            ->execute([':id' => $active['id']]);
    } catch (PDOException $e) {}

    json_clean_response([
        'status'  => '200',
        'message' => 'Code Received',
        'sms'     => $active['sms_text'],
    ]);
}

// ── Local timeout check ───────────────────────────────────────────────────────
// smspva orders expire in 600s (10 min); smscodes in 1200s (20 min)

$buy_ts  = strtotime($active['buy_time']);
$timeout_secs = ($active['provider'] ?? 'smscodes') === 'smspva' ? 600 : 1200;
$left_ms = max(0, (($buy_ts + $timeout_secs) - time()) * 1000);

if ($left_ms <= 0) {
    // Refund user and close order
    try {
        $pdo->beginTransaction();
        $w = $pdo->prepare("SELECT main_balance FROM users WHERE id = :uid FOR UPDATE");
        $w->execute([':uid' => $user_id]);
        $wallet = $w->fetch(PDO::FETCH_ASSOC);
        $new_balance = (float)$wallet['main_balance'] + (float)$active['service_price'];
        $pdo->prepare("UPDATE users SET main_balance = :b WHERE id = :uid")
            ->execute([':b' => $new_balance, ':uid' => $user_id]);
        $pdo->prepare("UPDATE active_number SET active_status='1', status='3' WHERE id=:id AND active_status='2'")
            ->execute([':id' => $active['id']]);
        $pdo->commit();
    } catch (Exception $e) {
        if ($pdo->inTransaction()) $pdo->rollBack();
    }
    json_clean_response(['status' => '500', 'message' => 'Number Expired. Balance Refunded.']);
}

// ── Load API config ───────────────────────────────────────────────────────────

$server_data = otp_get_server($active['server_id'], $pdo);
if (!$server_data) {
    json_clean_response(['status' => '500', 'message' => 'Server configuration error.']);
}

$api_data = otp_get_api($server_data['api_id'], $pdo);
if (!$api_data) {
    json_clean_response(['status' => '500', 'message' => 'API configuration error.']);
}

$provider = $active['provider'] ?? ($api_data['api_type'] ?? 'smscodes');

// ══════════════════════════════════════════════════════════════════
// PROVIDER: smspva.com  (Server1)
// ══════════════════════════════════════════════════════════════════
if ($provider === 'smspva') {

    $sms_result = smspva_get_sms(
        $api_data['api_url'],
        $api_data['api_key'],
        (int)$active['number_id']   // smspva orderId stored in number_id
    );

    switch ($sms_result['status']) {

        case 'received':
            $sms_raw = $sms_result['sms'];
            
            // Safety: ensure sms_raw is a string (smspva can return arrays)
            if (is_array($sms_raw)) {
                $sms_raw = isset($sms_raw[0]) ? (string)$sms_raw[0] : (isset($sms_raw['text']) ? (string)$sms_raw['text'] : implode(' ', array_map('strval', $sms_raw)));
            }
            $sms_raw = trim((string)$sms_raw);

            if (!otp_is_valid_sms($sms_raw)) {
                json_clean_response([
                    'status'    => '300',
                    'message'   => 'Waiting for SMS.',
                    'left_time' => (string)$left_ms,
                ]);
            }

            try {
                $pdo->prepare(
                    "UPDATE active_number
                        SET sms_text = :sms, status = '1', active_status = '1'
                      WHERE id = :id AND active_status = '2'"
                )->execute([':sms' => $sms_raw, ':id' => $active['id']]);
            } catch (PDOException $e) { /* non-fatal */ }

            json_clean_response([
                'status'  => '200',
                'message' => 'Code Received',
                'sms'     => $sms_raw,
            ]);
            break;

        case 'expired':
        case 'error':
            // Refund user
            try {
                $pdo->beginTransaction();
                $w = $pdo->prepare("SELECT main_balance FROM users WHERE id = :uid FOR UPDATE");
                $w->execute([':uid' => $user_id]);
                $wallet = $w->fetch(PDO::FETCH_ASSOC);
                $new_balance = (float)$wallet['main_balance'] + (float)$active['service_price'];
                $pdo->prepare("UPDATE users SET main_balance = :b WHERE id = :uid")
                    ->execute([':b' => $new_balance, ':uid' => $user_id]);
                $pdo->prepare("UPDATE active_number SET active_status='1', status='3' WHERE id=:id AND active_status='2'")
                    ->execute([':id' => $active['id']]);
                $pdo->commit();
            } catch (Exception $e) {
                if ($pdo->inTransaction()) $pdo->rollBack();
            }

            json_clean_response([
                'status'  => '500',
                'message' => 'Number expired/cancelled. Balance Refunded.',
            ]);
            break;

        default: // 'waiting'
            json_clean_response([
                'status'    => '300',
                'message'   => 'Waiting for SMS.',
                'left_time' => (string)$left_ms,
            ]);
    }
}

// ══════════════════════════════════════════════════════════════════
// PROVIDER: smscodes.io  (Server2) — original logic preserved exactly
// ══════════════════════════════════════════════════════════════════

$sms_url = otp_build_url($api_data['api_url'], 'GetSMSCode', $api_data['api_key'], [
    'sid'    => $active['number_id'],
    'number' => $active['number'],
]);

$raw_response = otp_curl_get($sms_url, 20);
$api_response = json_decode($raw_response, true);

if (!is_array($api_response)) {
    json_clean_response([
        'status'    => '300',
        'message'   => 'Waiting for SMS.',
        'left_time' => (string)$left_ms,
    ]);
}

$provider_status = $api_response['Status'] ?? '';

if ($provider_status === 'Success' && !empty($api_response['SMS'])) {
    $sms_raw = (string)$api_response['SMS'];

    if (!otp_is_valid_sms($sms_raw)) {
        json_clean_response([
            'status'    => '300',
            'message'   => 'Waiting for SMS.',
            'left_time' => (string)$left_ms,
        ]);
    }

    try {
        $pdo->prepare(
            "UPDATE active_number SET sms_text = :sms, status = '1', active_status = '1'
              WHERE id = :id AND active_status = '2'"
        )->execute([':sms' => $sms_raw, ':id' => $active['id']]);
    } catch (PDOException $e) {}

    json_clean_response([
        'status'  => '200',
        'message' => 'Code Received',
        'sms'     => $sms_raw,
    ]);
}

if (in_array($provider_status, ['Expired', 'Cancelled', 'Error'], true)) {
    try {
        $pdo->beginTransaction();
        $w = $pdo->prepare("SELECT main_balance FROM users WHERE id = :uid FOR UPDATE");
        $w->execute([':uid' => $user_id]);
        $wallet = $w->fetch(PDO::FETCH_ASSOC);
        $new_balance = (float)$wallet['main_balance'] + (float)$active['service_price'];
        $pdo->prepare("UPDATE users SET main_balance = :b WHERE id = :uid")
            ->execute([':b' => $new_balance, ':uid' => $user_id]);
        $pdo->prepare("UPDATE active_number SET active_status='1', status='3' WHERE id=:id AND active_status='2'")
            ->execute([':id' => $active['id']]);
        $pdo->commit();
    } catch (Exception $e) {
        if ($pdo->inTransaction()) $pdo->rollBack();
    }

    $error_detail = $api_response['Error'] ?? $provider_status;
    json_clean_response([
        'status'  => '500',
        'message' => 'Number expired/cancelled. Balance Refunded.',
    ]);
}

json_clean_response([
    'status'    => '300',
    'message'   => 'Waiting for SMS.',
    'left_time' => (string)$left_ms,
]);