<?php
// ============================================================
// MERILLEDGE INVEST — API ROUTER
// Works WITHOUT .htaccess on any shared cPanel host.
// ============================================================

// ── 1. Buffer ALL output so stray PHP warnings never corrupt JSON ──
ob_start();

// ── 2. Suppress warnings from printing to output ──────────────
error_reporting(E_ALL);
ini_set('display_errors', '0');   // never print errors to output
ini_set('log_errors', '1');       // log them to PHP error log instead

// ── 3. CORS — absolute first thing sent to browser ────────────
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With, Accept");
header("Access-Control-Max-Age: 86400");
header("Content-Type: application/json; charset=UTF-8");

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    ob_end_clean();
    http_response_code(204);
    exit();
}

// ── 4. Bootstrap ───────────────────────────────────────────────
require_once __DIR__ . '/../config/config.php';
require_once __DIR__ . '/../config/database.php';

// ── 5. Route detection — ?route=/auth/login (no .htaccess needed) ──
if (!empty($_GET['route'])) {
    $uri = '/' . ltrim($_GET['route'], '/');
} else {
    $rawUri    = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
    $scriptDir = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/');
    if ($scriptDir && $scriptDir !== '/' && strpos($rawUri, $scriptDir) === 0) {
        $rawUri = substr($rawUri, strlen($scriptDir));
    }
    $rawUri = preg_replace('#^/index\.php#', '', $rawUri);
    $uri    = '/' . ltrim($rawUri, '/');
}
if ($uri !== '/') $uri = rtrim($uri, '/');

$method = $_SERVER['REQUEST_METHOD'];
$input  = json_decode(file_get_contents('php://input'), true) ?? [];

// ── 6. Helpers ─────────────────────────────────────────────────
function route(string $pattern, string $file): bool {
    global $uri;
    $regex = '#^' . preg_replace('/\{[^}]+\}/', '([^/]+)', $pattern) . '$#';
    if (preg_match($regex, $uri)) {
        require __DIR__ . '/endpoints/' . $file;
        return true;
    }
    return false;
}

function getBearerToken(): ?string {
    // Standard header
    $auth = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
    if (!$auth && isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
        $auth = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
    }
    // Some cPanel setups strip it — check apache_request_headers()
    if (!$auth && function_exists('apache_request_headers')) {
        $h    = apache_request_headers();
        $auth = $h['Authorization'] ?? $h['authorization'] ?? '';
    }
    if (preg_match('/Bearer\s+(.+)$/i', $auth, $m)) return trim($m[1]);
    return null;
}

function verifyJWT(string $token): ?array {
    $parts = explode('.', $token);
    if (count($parts) !== 3) return null;
    [$header, $payload, $signature] = $parts;
    $expected = rtrim(strtr(base64_encode(hash_hmac('sha256', "$header.$payload", JWT_SECRET, true)), '+/', '-_'), '=');
    if (!hash_equals($expected, $signature)) return null;
    $data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
    if (!$data || (isset($data['exp']) && $data['exp'] < time())) return null;
    return $data;
}

function createJWT(array $payload): string {
    $header  = rtrim(strtr(base64_encode(json_encode(['alg'=>'HS256','typ'=>'JWT'])), '+/', '-_'), '=');
    $payload['exp'] = time() + SESSION_LIFETIME;
    $payload['iat'] = time();
    $p   = rtrim(strtr(base64_encode(json_encode($payload)), '+/', '-_'), '=');
    $sig = rtrim(strtr(base64_encode(hash_hmac('sha256', "$header.$p", JWT_SECRET, true)), '+/', '-_'), '=');
    return "$header.$p.$sig";
}

function requireAuth(): array {
    $token = getBearerToken();
    if (!$token) {
        http_response_code(401);
        die(json_encode(['success'=>false,'message'=>'Unauthorized. Please log in.']));
    }
    $data = verifyJWT($token);
    if (!$data) {
        http_response_code(401);
        die(json_encode(['success'=>false,'message'=>'Session expired. Please log in again.']));
    }
    $db   = Database::getInstance();
    $user = $db->fetch("SELECT id,status FROM users WHERE id=? LIMIT 1", [$data['user_id']]);
    if (!$user || $user['status'] === 'banned') {
        http_response_code(403);
        die(json_encode(['success'=>false,'message'=>'Account access denied.']));
    }
    return $data;
}

function requireAdmin(): array {
    $token = getBearerToken();
    if (!$token) {
        http_response_code(401);
        die(json_encode(['success'=>false,'message'=>'Unauthorized']));
    }
    $data = verifyJWT($token);
    if (!$data || !isset($data['admin_id'])) {
        http_response_code(401);
        die(json_encode(['success'=>false,'message'=>'Admin access required']));
    }
    return $data;
}

function success($data = [], string $message = 'Success'): void {
    // Discard any stray output (PHP notices etc.) accumulated so far
    ob_end_clean();
    echo json_encode(['success'=>true,'message'=>$message,'data'=>$data]);
    exit();
}

function error(string $message, int $code = 400): void {
    ob_end_clean();
    http_response_code($code);
    echo json_encode(['success'=>false,'message'=>$message]);
    exit();
}

function sanitize($val): string {
    return htmlspecialchars(trim((string)$val), ENT_QUOTES, 'UTF-8');
}

// ── 7. Dispatch ────────────────────────────────────────────────
// Auth
if (route('/auth/register',             'auth.php')) exit();
if (route('/auth/login',                'auth.php')) exit();
if (route('/auth/logout',               'auth.php')) exit();
if (route('/auth/forgot-password',      'auth.php')) exit();
if (route('/auth/reset-password',       'auth.php')) exit();
if (route('/auth/verify-email/{t}',     'auth.php')) exit();
if (route('/auth/me',                   'auth.php')) exit();

// User
if (route('/user/dashboard',            'user.php')) exit();
if (route('/user/profile',              'user.php')) exit();
if (route('/user/profile/update',       'user.php')) exit();
if (route('/user/change-password',      'user.php')) exit();
if (route('/user/referrals',            'user.php')) exit();
if (route('/user/transactions',         'user.php')) exit();

// Investments
if (route('/invest/plans',              'invest.php')) exit();
if (route('/invest/create',             'invest.php')) exit();
if (route('/invest/history',            'invest.php')) exit();

// Deposits
if (route('/deposit/methods',           'deposit.php')) exit();
if (route('/deposit/submit',            'deposit.php')) exit();
if (route('/deposit/history',           'deposit.php')) exit();

// Withdrawals
if (route('/withdraw/submit',           'withdraw.php')) exit();
if (route('/withdraw/history',          'withdraw.php')) exit();

// Support
if (route('/support/tickets',           'support.php')) exit();
if (route('/support/ticket/create',     'support.php')) exit();
if (route('/support/ticket/{id}/reply', 'support.php')) exit();
if (route('/support/ticket/{id}',       'support.php')) exit();

// Trade
if (route('/trade/prices',    'trade.php')) exit();
if (route('/trade/positions', 'trade.php')) exit();
if (route('/trade/open',      'trade.php')) exit();
if (route('/trade/close',     'trade.php')) exit();
if (route('/trade/tick',      'trade.php')) exit();

// KYC
if (route('/kyc/submit',                'kyc.php')) exit();
if (route('/kyc/status',                'kyc.php')) exit();

// Admin auth
if (route('/admin/auth/login',          'admin_auth.php')) exit();

// Admin
if (route('/admin/dashboard',                   'admin.php')) exit();
if (route('/admin/users',                        'admin.php')) exit();
if (route('/admin/user/{id}',                    'admin.php')) exit();
if (route('/admin/deposits',                     'admin.php')) exit();
if (route('/admin/deposit/{id}/action',          'admin.php')) exit();
if (route('/admin/withdrawals',                  'admin.php')) exit();
if (route('/admin/withdrawal/{id}/action',       'admin.php')) exit();
if (route('/admin/investments',                  'admin.php')) exit();
if (route('/admin/plans',                        'admin.php')) exit();
if (route('/admin/wallets',                      'admin.php')) exit();
if (route('/admin/kyc',                          'admin.php')) exit();
if (route('/admin/kyc/{id}/action',              'admin.php')) exit();
if (route('/admin/tickets',                      'admin.php')) exit();
if (route('/admin/ticket/{id}',                  'admin.php')) exit();
if (route('/admin/settings',                     'admin.php')) exit();
if (route('/admin/cron/process-investments',     'admin.php')) exit();

// 404 — clean any buffered output before responding
ob_end_clean();
http_response_code(404);
echo json_encode(['success'=>false,'message'=>"Route not found: $uri"]);
