<?php
/* ===============================
   API CONFIG EDIT HANDLER
=============================== */

session_start();
include_once '../config/connect.php';
require_once '../config/whatsapp.php';
require_once __DIR__ . '/../../api/v1/NEXUSGGR.php';
require_once __DIR__ . '/../../api/v1/SGX.php';

function redirect_settings(?string $query = null): void
{
    $location = '../Settings';
    if ($query !== null && $query !== '') {
        $location .= '?' . ltrim($query, '?&');
    }

    header('Location: ' . $location);
    exit;
}

function set_nexus_sync_flash(array $flash): void
{
    $_SESSION['nexus_sync_flash'] = $flash;
}

function format_nexus_sync_flash(string $type, string $message, array $payload = []): void
{
    set_nexus_sync_flash(array_merge([
        'type' => $type,
        'message' => $message,
    ], $payload));
}

function set_sgx_sync_flash(array $flash): void
{
    $_SESSION['sgx_sync_flash'] = $flash;
}

function format_sgx_sync_flash(string $type, string $message, array $payload = []): void
{
    set_sgx_sync_flash(array_merge([
        'type' => $type,
        'message' => $message,
    ], $payload));
}

function get_nexus_sync_message($response): string
{
    if (!is_array($response)) {
        return 'Response provider tidak valid.';
    }

    foreach (['msg', 'message', 'error'] as $key) {
        if (isset($response[$key]) && trim((string)$response[$key]) !== '') {
            return trim((string)$response[$key]);
        }
    }

    return 'Provider tidak mengirimkan pesan.';
}

function is_nexus_sync_already_exists($response): bool
{
    if (!is_array($response)) {
        return false;
    }

    $message = strtoupper(get_nexus_sync_message($response));
    if ($message === '') {
        return false;
    }

    $hasUserKeyword = preg_match('/\b(USER|USERNAME|MEMBER)\b/', $message) === 1;
    $hasExistsKeyword = preg_match('/\b(ALREADY|EXIST|EXISTS|EXISTED|DUPLICATE|REGISTERED|TAKEN)\b/', $message) === 1;

    return $hasUserKeyword && $hasExistsKeyword;
}

function get_sgx_sync_message($response): string
{
    if (!is_array($response)) {
        return 'Response provider tidak valid.';
    }

    foreach (['message', 'msg', 'error'] as $key) {
        if (isset($response[$key]) && trim((string)$response[$key]) !== '') {
            return trim((string)$response[$key]);
        }
    }

    return 'Provider tidak mengirimkan pesan.';
}

function is_sgx_sync_already_exists($response): bool
{
    if (!is_array($response)) {
        return false;
    }

    $message = strtoupper(get_sgx_sync_message($response));
    if ($message === '') {
        return false;
    }

    $hasUserKeyword = preg_match('/\b(USER|USERNAME|MEMBER)\b/', $message) === 1;
    $hasExistsKeyword = preg_match('/\b(ALREADY|EXIST|EXISTS|EXISTED|DUPLICATE|REGISTERED|TAKEN)\b/', $message) === 1;

    return $hasUserKeyword && $hasExistsKeyword;
}

function sync_all_local_accounts_to_nexus(mysqli $call): array
{
    @set_time_limit(0);

    $memberQuery = mysqli_query(
        $call,
        "SELECT extUser, intUser
         FROM tb_user
         ORDER BY created DESC"
    );

    if (!$memberQuery) {
        throw new Exception('Gagal membaca data member lokal: ' . mysqli_error($call));
    }

    $nexus = new fiver($call);
    $previewLimit = 20;
    $preview = [];
    $totalLocalUsers = 0;
    $processedUsers = 0;
    $successCount = 0;
    $existedCount = 0;
    $failedCount = 0;
    $skippedCount = 0;

    while ($member = mysqli_fetch_assoc($memberQuery)) {
        $totalLocalUsers++;

        $extUser = trim((string)($member['extUser'] ?? ''));
        $intUser = trim((string)($member['intUser'] ?? ''));

        if ($intUser === '') {
            $skippedCount++;

            if (count($preview) < $previewLimit) {
                $preview[] = [
                    'extUser' => $extUser,
                    'intUser' => $intUser,
                    'status' => 'Dilewati',
                    'status_type' => 'warning',
                    'message' => 'User API lokal kosong, tidak bisa didaftarkan.',
                ];
            }

            continue;
        }

        $processedUsers++;

        try {
            $response = $nexus->create($intUser);

            if (is_array($response) && (int)($response['status'] ?? 0) === 1) {
                $successCount++;
                $statusLabel = 'Berhasil';
                $statusType = 'success';
                $message = 'User API berhasil dibuat di NexusGGR.';
            } elseif (is_nexus_sync_already_exists($response)) {
                $existedCount++;
                $statusLabel = 'Sudah Ada';
                $statusType = 'info';
                $message = get_nexus_sync_message($response);
            } else {
                $failedCount++;
                $statusLabel = 'Gagal';
                $statusType = 'danger';
                $message = get_nexus_sync_message($response);
            }
        } catch (Throwable $exception) {
            $failedCount++;
            $statusLabel = 'Gagal';
            $statusType = 'danger';
            $message = $exception->getMessage();
        }

        if (count($preview) < $previewLimit) {
            $preview[] = [
                'extUser' => $extUser,
                'intUser' => $intUser,
                'status' => $statusLabel,
                'status_type' => $statusType,
                'message' => $message,
            ];
        }
    }

    mysqli_free_result($memberQuery);

    return [
        'total_local_users' => $totalLocalUsers,
        'processed_users' => $processedUsers,
        'success_count' => $successCount,
        'existed_count' => $existedCount,
        'failed_count' => $failedCount,
        'skipped_count' => $skippedCount,
        'preview_limit' => $previewLimit,
        'preview' => $preview,
    ];
}

function sync_all_local_accounts_to_sgx(mysqli $call): array
{
    @set_time_limit(0);

    $memberQuery = mysqli_query(
        $call,
        "SELECT extUser, intUser
         FROM tb_user
         ORDER BY created DESC"
    );

    if (!$memberQuery) {
        throw new Exception('Gagal membaca data member lokal: ' . mysqli_error($call));
    }

    $sgx = new sgx($call);
    $previewLimit = 20;
    $preview = [];
    $totalLocalUsers = 0;
    $processedUsers = 0;
    $successCount = 0;
    $existedCount = 0;
    $failedCount = 0;
    $skippedCount = 0;

    while ($member = mysqli_fetch_assoc($memberQuery)) {
        $totalLocalUsers++;

        $extUser = trim((string)($member['extUser'] ?? ''));
        $intUser = trim((string)($member['intUser'] ?? ''));

        if ($intUser === '') {
            $skippedCount++;

            if (count($preview) < $previewLimit) {
                $preview[] = [
                    'extUser' => $extUser,
                    'intUser' => $intUser,
                    'status' => 'Dilewati',
                    'status_type' => 'warning',
                    'message' => 'User API lokal kosong, tidak bisa didaftarkan.',
                ];
            }

            continue;
        }

        $processedUsers++;

        try {
            $response = $sgx->create($intUser);

            if (is_array($response) && (int)($response['status'] ?? 0) === 200) {
                $successCount++;
                $statusLabel = 'Berhasil';
                $statusType = 'success';
                $message = 'User API berhasil dibuat di SGX.';
            } elseif (is_sgx_sync_already_exists($response)) {
                $existedCount++;
                $statusLabel = 'Sudah Ada';
                $statusType = 'info';
                $message = get_sgx_sync_message($response);
            } else {
                $failedCount++;
                $statusLabel = 'Gagal';
                $statusType = 'danger';
                $message = get_sgx_sync_message($response);
            }
        } catch (Throwable $exception) {
            $failedCount++;
            $statusLabel = 'Gagal';
            $statusType = 'danger';
            $message = $exception->getMessage();
        }

        if (count($preview) < $previewLimit) {
            $preview[] = [
                'extUser' => $extUser,
                'intUser' => $intUser,
                'status' => $statusLabel,
                'status_type' => $statusType,
                'message' => $message,
            ];
        }
    }

    mysqli_free_result($memberQuery);

    return [
        'total_local_users' => $totalLocalUsers,
        'processed_users' => $processedUsers,
        'success_count' => $successCount,
        'existed_count' => $existedCount,
        'failed_count' => $failedCount,
        'skipped_count' => $skippedCount,
        'preview_limit' => $previewLimit,
        'preview' => $preview,
    ];
}

/* ===============================
   AUTH CHECK (ADMIN ONLY)
=============================== */
if (!isset($_SESSION['admin'])) {
    http_response_code(403);
    exit('FORBIDDEN');
}

$currentAgentName = agent_public_name((array)$_SESSION['admin']);
$currentAgentLevel = trim((string)($_SESSION['admin']['agent_level'] ?? ($_SESSION['agent_level'] ?? '')));

if ($currentAgentName === '' || $currentAgentLevel !== 'admin') {
    http_response_code(403);
    exit('FORBIDDEN');
}

/* ===============================
   FORM SUBMIT CHECK
=============================== */
if (!isset($_POST['save_api_config'])) {
    header('Location: ../');
    exit;
}

$shouldSyncNexusUsers = isset($_POST['register_nexus_accounts']);
$shouldSyncSgxUsers = isset($_POST['register_sgx_accounts']);

/* ===============================
   REQUIRED FIELD CHECK
=============================== */
$required = [
    'nexusggr_api_url',
    'nexusggr_agent_name',
    'nexusggr_secret_key',
    'sgx_api_url',
    'sgx_agent_name',
    'sgx_secret_key'
];

foreach ($required as $field) {
    if (empty($_POST[$field])) {
        redirect_settings('msg=36');
    }
}

$whatsAppApiUrl = trim((string)($_POST['whatsapp_api_url'] ?? ''));
$whatsAppAdminNumber = trim((string)($_POST['whatsapp_admin_number'] ?? ''));
$whatsAppToken = trim((string)($_POST['whatsapp_secret_key'] ?? ''));
$whatsAppWebhookSecret = trim((string)($_POST['whatsapp_webhook_secret'] ?? ''));
$bayarvipApiUrl = trim((string)($_POST['bayarvip_api_url'] ?? ''));
$bayarvipMerchantCode = trim((string)($_POST['bayarvip_merchant_code'] ?? ''));
$bayarvipSecretKey = trim((string)($_POST['bayarvip_secret_key'] ?? ''));

$hasAnyLegacyField = $whatsAppApiUrl !== '' || $whatsAppToken !== '';
$hasLegacyConfig = $whatsAppToken !== '';
$normalizedAdminTargets = implode(', ', wa_parse_targets($whatsAppAdminNumber));
$requiresAdminTargets = $hasLegacyConfig;
$hasAnyBayarvipField = $bayarvipApiUrl !== '' || $bayarvipMerchantCode !== '' || $bayarvipSecretKey !== '';
$hasFullBayarvipConfig = $bayarvipApiUrl !== '' && $bayarvipMerchantCode !== '' && $bayarvipSecretKey !== '';

if ($hasAnyLegacyField && !$hasLegacyConfig) {
    redirect_settings('msg=52');
}

if ($requiresAdminTargets && $whatsAppAdminNumber === '') {
    redirect_settings('msg=55');
}

if ($requiresAdminTargets && $normalizedAdminTargets === '') {
    redirect_settings('msg=50');
}

if ($hasAnyBayarvipField && !$hasFullBayarvipConfig) {
    redirect_settings('msg=72');
}

/* ===============================
   PREPARE DATA
=============================== */
$data = [
    'NEXUSGGR' => [
        'api_url'    => $_POST['nexusggr_api_url'],
        'agent_code' => $_POST['nexusggr_agent_name'],
        'secret_key'=> $_POST['nexusggr_secret_key']
    ],
    'SGX' => [
        'api_url'    => $_POST['sgx_api_url'],
        'agent_code' => $_POST['sgx_agent_name'],
        'secret_key'=> $_POST['sgx_secret_key']
    ]
];

if ($normalizedAdminTargets !== '' || $hasAnyLegacyField) {
    $data['WHATSAPP'] = [
        'api_url' => $whatsAppApiUrl !== '' ? $whatsAppApiUrl : wa_default_api_url(),
        'agent_code' => $normalizedAdminTargets,
        'secret_key' => $whatsAppToken,
    ];
}

if ($hasFullBayarvipConfig) {
    $data['BAYARVIP'] = [
        'api_url' => $bayarvipApiUrl,
        'agent_code' => $bayarvipMerchantCode,
        'secret_key' => $bayarvipSecretKey,
    ];
}

$data['WHATSAPP_BOT'] = [
    'api_url' => '',
    'agent_code' => $whatsAppWebhookSecret,
    'secret_key' => '',
];

/* ===============================
   SAVE DATA (UPSERT)
=============================== */
foreach ($data as $apiName => $cfg) {

    $apiName   = mysqli_real_escape_string($call, $apiName);
    $apiUrl    = mysqli_real_escape_string($call, trim($cfg['api_url']));
    $agentCode = mysqli_real_escape_string($call, trim($cfg['agent_code']));
    $secretKey = mysqli_real_escape_string($call, trim($cfg['secret_key']));

    mysqli_query(
        $call,
        "INSERT INTO tb_api_config (api_name, api_url, agent_code, secret_key)
         VALUES ('$apiName', '$apiUrl', '$agentCode', '$secretKey')
         ON DUPLICATE KEY UPDATE
            api_url    = VALUES(api_url),
            agent_code = VALUES(agent_code),
            secret_key = VALUES(secret_key)"
    );

    if (mysqli_error($call)) {
        redirect_settings('msg=13');
    }
}

if ($normalizedAdminTargets === '' && !$hasAnyLegacyField) {
    mysqli_query($call, "DELETE FROM tb_api_config WHERE api_name = 'WHATSAPP'");
}

if (!$hasAnyBayarvipField) {
    mysqli_query($call, "DELETE FROM tb_api_config WHERE api_name = 'BAYARVIP'");
}

mysqli_query($call, "DELETE FROM tb_api_config WHERE api_name = 'WHATSAPP_BRIDGE'");

if ($whatsAppWebhookSecret === '') {
    mysqli_query($call, "DELETE FROM tb_api_config WHERE api_name = 'WHATSAPP_BOT'");
}

mysqli_query($call, "DELETE FROM tb_api_config WHERE api_name = 'OPENAI'");
mysqli_query($call, "DROP TABLE IF EXISTS tb_whatsapp_ai_session");
mysqli_query($call, "DROP TABLE IF EXISTS tb_whatsapp_ai_settings");

/* ===============================
   SUCCESS
=============================== */
if (!$shouldSyncNexusUsers && !$shouldSyncSgxUsers) {
    redirect_settings('msg=51');
}

if ($shouldSyncNexusUsers) {
    try {
        $syncSummary = sync_all_local_accounts_to_nexus($call);
        $totalLocalUsers = (int)($syncSummary['total_local_users'] ?? 0);
        $successCount = (int)($syncSummary['success_count'] ?? 0);
        $existedCount = (int)($syncSummary['existed_count'] ?? 0);
        $failedCount = (int)($syncSummary['failed_count'] ?? 0);
        $skippedCount = (int)($syncSummary['skipped_count'] ?? 0);

        if ($totalLocalUsers === 0) {
            format_nexus_sync_flash(
                'info',
                'Konfigurasi API berhasil disimpan. Tidak ada akun lokal yang perlu didaftarkan ke NexusGGR.',
                $syncSummary
            );
            redirect_settings();
        }

        if ($failedCount === 0 && $successCount > 0 && $existedCount === 0) {
            format_nexus_sync_flash(
                'success',
                'Konfigurasi API berhasil disimpan. Semua akun lokal berhasil didaftarkan ke NexusGGR.',
                $syncSummary
            );
            redirect_settings();
        }

        if ($failedCount === 0 && $existedCount > 0) {
            format_nexus_sync_flash(
                'success',
                'Konfigurasi API berhasil disimpan. Sinkronisasi akun lokal ke NexusGGR selesai, sebagian akun memang sudah terdaftar sebelumnya.',
                $syncSummary
            );
            redirect_settings();
        }

        if ($successCount > 0 || $existedCount > 0 || $skippedCount > 0) {
            format_nexus_sync_flash(
                'warning',
                'Konfigurasi API berhasil disimpan, tetapi sinkronisasi akun lokal ke NexusGGR selesai dengan sebagian hasil perlu dicek.',
                $syncSummary
            );
            redirect_settings();
        }

        format_nexus_sync_flash(
            'danger',
            'Konfigurasi API berhasil disimpan, tetapi seluruh pendaftaran akun lokal ke NexusGGR gagal diproses.',
            $syncSummary
        );
        redirect_settings();
    } catch (Throwable $exception) {
        format_nexus_sync_flash(
            'danger',
            'Konfigurasi API berhasil disimpan, tetapi sinkronisasi akun lokal ke NexusGGR gagal diproses: ' . $exception->getMessage()
        );
        redirect_settings();
    }
}

if ($shouldSyncSgxUsers) {
    try {
        $syncSummary = sync_all_local_accounts_to_sgx($call);
        $totalLocalUsers = (int)($syncSummary['total_local_users'] ?? 0);
        $successCount = (int)($syncSummary['success_count'] ?? 0);
        $existedCount = (int)($syncSummary['existed_count'] ?? 0);
        $failedCount = (int)($syncSummary['failed_count'] ?? 0);
        $skippedCount = (int)($syncSummary['skipped_count'] ?? 0);

        if ($totalLocalUsers === 0) {
            format_sgx_sync_flash(
                'info',
                'Konfigurasi API berhasil disimpan. Tidak ada akun lokal yang perlu didaftarkan ke SGX.',
                $syncSummary
            );
            redirect_settings();
        }

        if ($failedCount === 0 && $successCount > 0 && $existedCount === 0) {
            format_sgx_sync_flash(
                'success',
                'Konfigurasi API berhasil disimpan. Semua akun lokal berhasil didaftarkan ke SGX.',
                $syncSummary
            );
            redirect_settings();
        }

        if ($failedCount === 0 && $existedCount > 0) {
            format_sgx_sync_flash(
                'success',
                'Konfigurasi API berhasil disimpan. Sinkronisasi akun lokal ke SGX selesai, sebagian akun memang sudah terdaftar sebelumnya.',
                $syncSummary
            );
            redirect_settings();
        }

        if ($successCount > 0 || $existedCount > 0 || $skippedCount > 0) {
            format_sgx_sync_flash(
                'warning',
                'Konfigurasi API berhasil disimpan, tetapi sinkronisasi akun lokal ke SGX selesai dengan sebagian hasil perlu dicek.',
                $syncSummary
            );
            redirect_settings();
        }

        format_sgx_sync_flash(
            'danger',
            'Konfigurasi API berhasil disimpan, tetapi seluruh pendaftaran akun lokal ke SGX gagal diproses.',
            $syncSummary
        );
        redirect_settings();
    } catch (Throwable $exception) {
        format_sgx_sync_flash(
            'danger',
            'Konfigurasi API berhasil disimpan, tetapi sinkronisasi akun lokal ke SGX gagal diproses: ' . $exception->getMessage()
        );
        redirect_settings();
    }
}
