<?php
/**
 * index.php — Main Controller / Router
 *
 * Handles authentication, session management, and routes to the
 * appropriate view (login page or dashboard).
 * Also exposes JSON API endpoints for the dashboard to read/write config.
 */

declare(strict_types=1);
session_start();

// ─────────────────────────────────────────────────────────────
// Configuration
// ─────────────────────────────────────────────────────────────

// Admin credentials (change these!)
define('ADMIN_USER', 'admin');
define('ADMIN_PASS', 'BankyBot2026');

// Config file paths
define('BOT_CONFIG_PATH', __DIR__ . '/wt_webhook/whatsapp-bot/bot.config.json');
define('OPTIONS_PATH',    __DIR__ . '/wt_webhook/whatsapp-bot/options.json');
define('LOG_PATH',        __DIR__ . '/wt_webhook/whatsapp-bot/storage/whatsapp_bot.log');

// ─────────────────────────────────────────────────────────────
// Helper functions
// ─────────────────────────────────────────────────────────────

function isAuthenticated(): bool
{
    return !empty($_SESSION['authenticated']);
}

function jsonResponse(array $data, int $code = 200): void
{
    http_response_code($code);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
    exit;
}

function readJsonFile(string $path): ?array
{
    if (!is_file($path)) {
        return null;
    }
    $contents = file_get_contents($path);
    if ($contents === false) {
        return null;
    }
    $decoded = json_decode($contents, true);
    return is_array($decoded) ? $decoded : null;
}

function writeJsonFile(string $path, array $data): bool
{
    $json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) . "\n";
    return file_put_contents($path, $json, LOCK_EX) !== false;
}

// ─────────────────────────────────────────────────────────────
// Request handling
// ─────────────────────────────────────────────────────────────

$method = strtoupper($_SERVER['REQUEST_METHOD'] ?? 'GET');

// Determine if this is an AJAX/API request
$isAjax = (
    !empty($_SERVER['HTTP_X_REQUESTED_WITH'])
    && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'
) || (
    isset($_SERVER['CONTENT_TYPE'])
    && stripos($_SERVER['CONTENT_TYPE'], 'application/json') !== false
);

// ─────────────────────────────────────────────────────────────
// POST handlers
// ─────────────────────────────────────────────────────────────

if ($method === 'POST') {

    // Parse JSON body for AJAX requests
    if ($isAjax) {
        $body = json_decode(file_get_contents('php://input'), true) ?? [];
    } else {
        $body = $_POST;
    }

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

    // ── Login ────────────────────────────────────────────────
    if ($action === 'login') {
        $username = trim($body['username'] ?? '');
        $password = $body['password'] ?? '';

        if ($username === ADMIN_USER && $password === ADMIN_PASS) {
            $_SESSION['authenticated'] = true;
            $_SESSION['user'] = $username;
            $_SESSION['login_time'] = time();

            if ($isAjax) {
                jsonResponse(['success' => true, 'redirect' => 'dashboard.php']);
            }
            header('Location: dashboard.php');
            exit;
        }

        if ($isAjax) {
            jsonResponse(['success' => false, 'error' => 'Invalid credentials'], 401);
        }
        // Re-show login with error
        $loginError = 'Invalid username or password';
        require __DIR__ . '/views/login.php';
        exit;
    }

    // ── Logout ───────────────────────────────────────────────
    if ($action === 'logout') {
        session_destroy();
        if ($isAjax) {
            jsonResponse(['success' => true]);
        }
        header('Location: /');
        exit;
    }

    // ── Protected API endpoints (require auth) ───────────────
    if (!isAuthenticated()) {
        if ($isAjax) {
            jsonResponse(['success' => false, 'error' => 'Not authenticated'], 401);
        }
        header('Location: /');
        exit;
    }

    // ── Get config ───────────────────────────────────────────
    if ($action === 'get_config') {
        $botConfig = readJsonFile(BOT_CONFIG_PATH) ?? [];
        $options   = readJsonFile(OPTIONS_PATH) ?? [];
        jsonResponse([
            'success'    => true,
            'bot_config' => $botConfig,
            'options'    => $options,
        ]);
    }

    // ── Save bot config ──────────────────────────────────────
    if ($action === 'save_bot_config') {
        $newConfig = $body['config'] ?? [];
        if (!is_array($newConfig) || empty($newConfig)) {
            jsonResponse(['success' => false, 'error' => 'Invalid config data'], 400);
        }

        // Read current config and merge to preserve any extra fields
        $current = readJsonFile(BOT_CONFIG_PATH) ?? [];
        $allowed = ['instance_id', 'access_token', 'api_base_url', 'webhook_secret', 'welcome_message', 'api_new_order'];
        foreach ($allowed as $key) {
            if (array_key_exists($key, $newConfig)) {
                $current[$key] = $newConfig[$key];
            }
        }

        if (writeJsonFile(BOT_CONFIG_PATH, $current)) {
            jsonResponse(['success' => true, 'message' => 'Bot config saved']);
        }
        jsonResponse(['success' => false, 'error' => 'Failed to write config file'], 500);
    }

    // ── Test API connection ───────────────────────────────────
    if ($action === 'test_api_connection') {
        $url = trim((string) ($body['url'] ?? ''));
        if ($url === '' || !preg_match('/^https?:\/\//i', $url)) {
            jsonResponse(['success' => false, 'error' => 'Invalid or empty URL'], 400);
        }

        if (!function_exists('curl_init')) {
            jsonResponse(['success' => false, 'error' => 'cURL extension is not available on this server']);
        }

        $port = (int) (parse_url($url, PHP_URL_PORT) ?: (str_starts_with($url, 'https') ? 443 : 80));

        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_POST            => true,
            CURLOPT_RETURNTRANSFER  => true,
            CURLOPT_TIMEOUT         => 10,
            CURLOPT_CONNECTTIMEOUT  => 5,
            CURLOPT_IPRESOLVE       => CURL_IPRESOLVE_V4,
            CURLOPT_HTTPHEADER      => ['Content-Type: application/json'],
            CURLOPT_POSTFIELDS      => '{"test":true}',
        ]);

        $response  = curl_exec($ch);
        $httpCode  = (int)   curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $curlErrno = (int)   curl_errno($ch);
        $curlError = (string) curl_error($ch);
        $totalMs   = (int)   round((float) curl_getinfo($ch, CURLINFO_TOTAL_TIME) * 1000);
        curl_close($ch);

        if ($response !== false) {
            jsonResponse([
                'success'   => true,
                'reachable' => true,
                'http_code' => $httpCode,
                'time_ms'   => $totalMs,
            ]);
        }

        $hint = '';
        if ($curlErrno === CURLE_COULDNT_CONNECT) {
            $hint = "The bot server cannot reach this endpoint. Common causes: "
                  . "(1) Your hosting provider blocks outbound connections to port {$port} — try exposing your API on port 80 or 443 via a reverse proxy (nginx/apache). "
                  . "(2) The API server's firewall blocks incoming connections from this server's IP. "
                  . "(3) If the API runs on the same machine as the bot, use 127.0.0.1 instead of the public IP.";
        } elseif ($curlErrno === CURLE_OPERATION_TIMEDOUT) {
            $hint = "Connection timed out — the endpoint is unreachable or too slow from this server.";
        }

        jsonResponse([
            'success'    => false,
            'reachable'  => false,
            'curl_errno' => $curlErrno,
            'curl_error' => $curlError,
            'hint'       => $hint,
        ]);
    }

    // ── Save options ─────────────────────────────────────────
    if ($action === 'save_options') {
        $newOptions = $body['options'] ?? [];
        if (!is_array($newOptions) || empty($newOptions)) {
            jsonResponse(['success' => false, 'error' => 'Invalid options data'], 400);
        }

        $current = readJsonFile(OPTIONS_PATH) ?? [];
        $allowed = ['networks', 'voucher_categories', 'transfer_data'];
        foreach ($allowed as $key) {
            if (array_key_exists($key, $newOptions)) {
                $current[$key] = $newOptions[$key];
            }
        }

        if (writeJsonFile(OPTIONS_PATH, $current)) {
            jsonResponse(['success' => true, 'message' => 'Options saved']);
        }
        jsonResponse(['success' => false, 'error' => 'Failed to write options file'], 500);
    }

    // ── Get logs ─────────────────────────────────────────────
    if ($action === 'get_logs') {
        $lines = [];
        $tailCount = (int) ($body['lines'] ?? 100);
        $tailCount = max(10, min($tailCount, 2000));

        if (is_file(LOG_PATH)) {
            $allLines = file(LOG_PATH, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
            if (is_array($allLines)) {
                $lines = array_slice($allLines, -$tailCount);
            }
        }

        jsonResponse([
            'success' => true,
            'lines'   => $lines,
            'total'   => count($lines),
            'size_kb' => is_file(LOG_PATH) ? round(filesize(LOG_PATH) / 1024, 1) : 0,
        ]);
    }

    // ── Clear logs ───────────────────────────────────────────
    if ($action === 'clear_logs') {
        if (is_file(LOG_PATH)) {
            file_put_contents(LOG_PATH, '');
        }
        jsonResponse(['success' => true, 'message' => 'Logs cleared']);
    }
}

// ─────────────────────────────────────────────────────────────
// GET handlers
// ─────────────────────────────────────────────────────────────

$requestUri = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH);
$page = basename($requestUri);

// Dashboard page — requires auth
if ($page === 'dashboard.php') {
    if (!isAuthenticated()) {
        header('Location: /');
        exit;
    }

    // Load config data for the dashboard view
    $botConfig = readJsonFile(BOT_CONFIG_PATH) ?? [];
    $options   = readJsonFile(OPTIONS_PATH) ?? [];
    require __DIR__ . '/dashboard.php';
    exit;
}

// Default — show login or redirect to dashboard
if (isAuthenticated()) {
    header('Location: dashboard.php');
    exit;
}

// Show login page
$loginError = '';
require __DIR__ . '/views/login.php';
