<?php

$authSecretsFile = __DIR__ . '/auth_secrets.php';
if (is_file($authSecretsFile)) {
    require_once $authSecretsFile;
}

if (!function_exists('sikompro_env')) {
    function sikompro_env($key, $default = '')
    {
        if (defined($key)) {
            $value = constant($key);
            return $value === '' ? $default : $value;
        }

        $value = getenv($key);
        return $value === false || $value === '' ? $default : $value;
    }
}

if (!function_exists('sikompro_normalize_phone')) {
    function sikompro_normalize_phone($value)
    {
        $phone = preg_replace('/[^0-9]/', '', (string) $value);
        if ($phone === '') {
            return '';
        }

        if (strpos($phone, '0') === 0) {
            $phone = '62' . substr($phone, 1);
        }

        if (strpos($phone, '62') !== 0) {
            $phone = '62' . ltrim($phone, '0');
        }

        return $phone;
    }
}

if (!function_exists('sikompro_random_numeric_code')) {
    function sikompro_random_numeric_code($length = 6)
    {
        $min = (int) pow(10, max(1, $length) - 1);
        $max = (int) pow(10, max(1, $length)) - 1;
        return (string) random_int($min, $max);
    }
}

if (!function_exists('sikompro_http_json_request')) {
    function sikompro_http_json_request($url, array $payload, array $headers = [], $method = 'POST')
    {
        if (!function_exists('curl_init')) {
            return ['ok' => false, 'message' => 'Ekstensi cURL belum aktif.'];
        }

        $ch = curl_init($url);
        $headerLines = array_merge(['Content-Type: application/json'], $headers);

        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_CUSTOMREQUEST => strtoupper($method),
            CURLOPT_POSTFIELDS => json_encode($payload),
            CURLOPT_HTTPHEADER => $headerLines,
            CURLOPT_TIMEOUT => 20,
        ]);

        $response = curl_exec($ch);
        $error = curl_error($ch);
        $status = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($response === false) {
            return ['ok' => false, 'message' => $error ?: 'Request HTTP gagal.'];
        }

        $decoded = json_decode($response, true);
        return [
            'ok' => $status >= 200 && $status < 300,
            'status' => $status,
            'message' => $decoded['message'] ?? $response,
            'raw' => $response,
            'data' => $decoded,
        ];
    }
}

if (!function_exists('sikompro_google_oauth_url')) {
    function sikompro_google_oauth_url($state, $redirectUri = null)
    {
        $clientId = sikompro_env('GOOGLE_CLIENT_ID');
        if ($clientId === '') {
            return '';
        }

        if ($redirectUri === null || $redirectUri === '') {
            $redirectUri = sikompro_env('GOOGLE_REDIRECT_URI');
        }

        if ($redirectUri === '') {
            $redirectUri = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http')
                . '://' . ($_SERVER['HTTP_HOST'] ?? 'localhost')
                . rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? '/middleware/login.php'), '/\\') . '/login.php';
        }

        $params = http_build_query([
            'client_id' => $clientId,
            'redirect_uri' => $redirectUri,
            'response_type' => 'code',
            'scope' => 'openid email profile',
            'access_type' => 'offline',
            'prompt' => 'consent',
            'state' => $state,
            'include_granted_scopes' => 'true',
        ]);

        return 'https://accounts.google.com/o/oauth2/v2/auth?' . $params;
    }
}

if (!function_exists('sikompro_google_exchange_code')) {
    function sikompro_google_exchange_code($code, $redirectUri = null)
    {
        $clientId = sikompro_env('GOOGLE_CLIENT_ID');
        $clientSecret = sikompro_env('GOOGLE_CLIENT_SECRET');
        if ($redirectUri === null || $redirectUri === '') {
            $redirectUri = sikompro_env('GOOGLE_REDIRECT_URI');
        }

        if ($clientId === '' || $clientSecret === '' || $code === '') {
            return ['ok' => false, 'message' => 'Konfigurasi Google belum lengkap.'];
        }

        if ($redirectUri === '') {
            return ['ok' => false, 'message' => 'Redirect URI Google belum diatur.'];
        }

        $tokenResponse = sikompro_http_json_request(
            'https://oauth2.googleapis.com/token',
            [
                'code' => $code,
                'client_id' => $clientId,
                'client_secret' => $clientSecret,
                'redirect_uri' => $redirectUri,
                'grant_type' => 'authorization_code',
            ]
        );

        if (empty($tokenResponse['ok']) || empty($tokenResponse['data']['access_token'])) {
            return [
                'ok' => false,
                'message' => $tokenResponse['message'] ?? 'Gagal menukar token Google.',
                'raw' => $tokenResponse,
            ];
        }

        $accessToken = $tokenResponse['data']['access_token'];
        if (!function_exists('curl_init')) {
            return ['ok' => false, 'message' => 'Ekstensi cURL belum aktif.'];
        }

        $ch = curl_init('https://openidconnect.googleapis.com/v1/userinfo');
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $accessToken],
            CURLOPT_TIMEOUT => 20,
        ]);

        $response = curl_exec($ch);
        $error = curl_error($ch);
        $status = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($response === false) {
            return ['ok' => false, 'message' => $error ?: 'Gagal mengambil profil Google.'];
        }

        $profile = json_decode($response, true);
        if ($status < 200 || $status >= 300 || empty($profile['sub'])) {
            return ['ok' => false, 'message' => 'Profil Google tidak valid.'];
        }

        return [
            'ok' => true,
            'profile' => $profile,
            'token' => $tokenResponse['data'],
        ];
    }
}

if (!function_exists('sikompro_store_login_otp')) {
    function sikompro_store_login_otp($identifier, $channel, $otp, array $meta = [])
    {
        if (session_status() !== PHP_SESSION_ACTIVE) {
            session_start();
        }

        $_SESSION['login_otp'] = [
            'identifier' => $identifier,
            'channel' => $channel,
            'otp' => $otp,
            'expires_at' => time() + 600,
            'meta' => $meta,
        ];
    }
}

if (!function_exists('sikompro_verify_login_otp')) {
    function sikompro_verify_login_otp($identifier, $otp)
    {
        if (session_status() !== PHP_SESSION_ACTIVE) {
            session_start();
        }

        $stored = $_SESSION['login_otp'] ?? null;
        if (!$stored || !is_array($stored)) {
            return ['ok' => false, 'message' => 'OTP belum dikirim.'];
        }

        if (($stored['identifier'] ?? '') !== $identifier) {
            return ['ok' => false, 'message' => 'Nomor/akun OTP tidak cocok.'];
        }

        if (($stored['expires_at'] ?? 0) < time()) {
            unset($_SESSION['login_otp']);
            return ['ok' => false, 'message' => 'OTP sudah kedaluwarsa.'];
        }

        if ((string) ($stored['otp'] ?? '') !== (string) $otp) {
            return ['ok' => false, 'message' => 'OTP salah.'];
        }

        return ['ok' => true, 'meta' => $stored['meta'] ?? []];
    }
}

if (!function_exists('sikompro_send_login_otp')) {
    function sikompro_send_login_otp($phone, $otp, $channel = 'phone')
    {
        $phone = sikompro_normalize_phone($phone);
        if ($phone === '') {
            return ['ok' => false, 'message' => 'Nomor HP tidak valid.'];
        }

        $message = "Kode login PT Alvindo: {$otp}. Berlaku 10 menit. Jangan bagikan ke siapa pun.";
        $channel = strtolower(trim((string) $channel));

        $sent = ['ok' => false, 'message' => 'Belum ada gateway aktif.'];

        if ($channel === 'whatsapp') {
            $endpoint = sikompro_env('WHATSAPP_LOGIN_WEBHOOK', sikompro_env('WHATSAPP_API_URL'));
            if ($endpoint !== '') {
                $headers = [];
                $token = sikompro_env('WHATSAPP_API_TOKEN');
                if ($token !== '') {
                    $headers[] = 'Authorization: Bearer ' . $token;
                }
                $sent = sikompro_http_json_request($endpoint, [
                    'phone' => $phone,
                    'message' => $message,
                    'otp' => $otp,
                    'type' => 'login_otp',
                ], $headers);
            }
        } else {
            $endpoint = sikompro_env('SMS_LOGIN_WEBHOOK', sikompro_env('PHONE_LOGIN_WEBHOOK'));
            if ($endpoint !== '') {
                $headers = [];
                $token = sikompro_env('SMS_API_TOKEN');
                if ($token !== '') {
                    $headers[] = 'Authorization: Bearer ' . $token;
                }
                $sent = sikompro_http_json_request($endpoint, [
                    'phone' => $phone,
                    'message' => $message,
                    'otp' => $otp,
                    'type' => 'login_otp',
                ], $headers);
            }
        }

        if (!empty($sent['ok'])) {
            return ['ok' => true, 'message' => 'OTP berhasil dikirim.'];
        }

        if (filter_var(sikompro_env('AUTH_SHOW_OTP_ON_SCREEN', '1'), FILTER_VALIDATE_BOOLEAN)) {
            return [
                'ok' => true,
                'message' => 'Gateway belum aktif, OTP ditampilkan untuk kebutuhan pengujian.',
                'demo' => $otp,
            ];
        }

        return ['ok' => false, 'message' => $sent['message'] ?? 'Gagal mengirim OTP.'];
    }
}

if (!function_exists('sikompro_auth_complete_login')) {
    function sikompro_auth_complete_login(array $user)
    {
        session_regenerate_id(true);
        $_SESSION['login'] = true;
        $_SESSION['user_id'] = $user['id'];
        $_SESSION['username'] = $user['username'];
        $_SESSION['role'] = strtolower(trim((string) $user['role']));
        $_SESSION['last_activity'] = time();
        $_SESSION['session_created_at'] = time();
        unset($_SESSION['login_otp']);
    }
}

if (!function_exists('sikompro_auth_find_user_by_google')) {
    function sikompro_auth_find_user_by_google($conn, $googleId, $email)
    {
        $googleIdSql = mysqli_real_escape_string($conn, (string) $googleId);
        $emailSql = mysqli_real_escape_string($conn, (string) $email);

        $sql = "
            SELECT *
            FROM users
            WHERE (google_id = '{$googleIdSql}' AND google_id IS NOT NULL AND google_id <> '')
               OR (email = '{$emailSql}' AND email IS NOT NULL AND email <> '')
            LIMIT 1
        ";

        $result = mysqli_query($conn, $sql);
        return $result ? mysqli_fetch_assoc($result) : null;
    }
}

if (!function_exists('sikompro_auth_find_user_by_phone')) {
    function sikompro_auth_find_user_by_phone($conn, $phone)
    {
        $phone = sikompro_normalize_phone($phone);
        if ($phone === '') {
            return null;
        }

        $phoneSql = mysqli_real_escape_string($conn, $phone);
        $result = mysqli_query($conn, "
            SELECT * FROM users
            WHERE REPLACE(REPLACE(REPLACE(COALESCE(no_hp, ''), ' ', ''), '-', ''), '+', '') = '{$phoneSql}'
            LIMIT 1
        ");

        return $result ? mysqli_fetch_assoc($result) : null;
    }
}
