"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.initGoogleAuth = initGoogleAuth;
exports.getAuthUrl = getAuthUrl;
exports.processCallback = processCallback;
exports.isAuthenticated = isAuthenticated;
exports.getAccessToken = getAccessToken;
exports.logoutGoogle = logoutGoogle;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const paths_1 = require("../config/paths");
const CREDENTIALS_PATH = path_1.default.join((0, paths_1.getAppDir)(), 'google-credentials.json');
const FALLBACK_TOKEN_PATH = path_1.default.join((0, paths_1.getAppDir)(), 'google-tokens.json');
const SCOPES = [
    'https://www.googleapis.com/auth/gmail.readonly',
    'https://www.googleapis.com/auth/calendar.readonly',
    'https://www.googleapis.com/auth/documents.readonly',
    'https://www.googleapis.com/auth/spreadsheets',
    'https://www.googleapis.com/auth/forms.responses.readonly',
    'https://www.googleapis.com/auth/drive.file'
];
let credentials = null;
let accessToken = null;
let tokenExpiry = 0; // Unix timestamp in ms
async function initGoogleAuth() {
    if (!fs_1.default.existsSync(CREDENTIALS_PATH)) {
        console.log(`[Google Auth] No credentials found at ${CREDENTIALS_PATH}`);
        return false;
    }
    try {
        const content = fs_1.default.readFileSync(CREDENTIALS_PATH, 'utf8');
        const parsed = JSON.parse(content);
        credentials = parsed.web || parsed.installed;
        // Check if we already have a refresh token saved
        const refreshToken = await getRefreshToken();
        if (refreshToken) {
            console.log('[Google Auth] Refresh token found in secure storage.');
            return true;
        }
        return false;
    }
    catch (err) {
        console.error('[Google Auth] Error initializing:', err);
        return false;
    }
}
function getAuthUrl() {
    if (!credentials)
        return null;
    const params = new URLSearchParams({
        client_id: credentials.client_id,
        redirect_uri: credentials.redirect_uris[0],
        response_type: 'code',
        scope: SCOPES.join(' '),
        access_type: 'offline',
        prompt: 'consent'
    });
    return `https://accounts.google.com/o/oauth2/v2/auth?${params.toString()}`;
}
async function processCallback(code) {
    if (!credentials)
        return false;
    try {
        const res = await fetch('https://oauth2.googleapis.com/token', {
            method: 'POST',
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            body: new URLSearchParams({
                code,
                client_id: credentials.client_id,
                client_secret: credentials.client_secret,
                redirect_uri: credentials.redirect_uris[0],
                grant_type: 'authorization_code'
            }).toString()
        });
        const data = await res.json();
        if (!res.ok) {
            console.error('[Google Auth] Token exchange failed:', data);
            return false;
        }
        if (data.access_token) {
            accessToken = data.access_token;
            tokenExpiry = Date.now() + (data.expires_in * 1000);
        }
        if (data.refresh_token) {
            await saveRefreshToken(data.refresh_token);
        }
        return true;
    }
    catch (err) {
        console.error('[Google Auth] Error processing callback:', err);
        return false;
    }
}
async function isAuthenticated() {
    const rt = await getRefreshToken();
    return !!rt;
}
async function getAccessToken() {
    if (!credentials)
        return null;
    // If token is valid for at least 5 more minutes, use it
    if (accessToken && Date.now() < tokenExpiry - 300000) {
        return accessToken;
    }
    // Otherwise, refresh it
    const refreshToken = await getRefreshToken();
    if (!refreshToken)
        return null;
    try {
        const res = await fetch('https://oauth2.googleapis.com/token', {
            method: 'POST',
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            body: new URLSearchParams({
                refresh_token: refreshToken,
                client_id: credentials.client_id,
                client_secret: credentials.client_secret,
                grant_type: 'refresh_token'
            }).toString()
        });
        const data = await res.json();
        if (!res.ok) {
            console.error('[Google Auth] Failed to refresh token:', data);
            return null;
        }
        accessToken = data.access_token;
        tokenExpiry = Date.now() + (data.expires_in * 1000);
        return accessToken;
    }
    catch (err) {
        console.error('[Google Auth] Error refreshing token:', err);
        return null;
    }
}
async function logoutGoogle() {
    try {
        const { Entry } = require('@napi-rs/keyring');
        const entry = new Entry('nyxora', 'google_refresh_token');
        await entry.deletePassword();
    }
    catch (e) { }
    try {
        if (fs_1.default.existsSync(FALLBACK_TOKEN_PATH)) {
            fs_1.default.unlinkSync(FALLBACK_TOKEN_PATH);
        }
    }
    catch (e) { }
    accessToken = null;
    tokenExpiry = 0;
    console.log('[Google Auth] Successfully logged out.');
    return true;
}
// ---- Secure Storage for Refresh Token ----
async function saveRefreshToken(token) {
    try {
        const { Entry } = require('@napi-rs/keyring');
        const entry = new Entry('nyxora', 'google_refresh_token');
        await entry.setPassword(token);
        console.log('[Google Auth] Refresh token saved securely to OS Keyring.');
    }
    catch (error) {
        console.warn('[Google Auth] Keyring failed, falling back to local tokens.json');
        fs_1.default.writeFileSync(FALLBACK_TOKEN_PATH, JSON.stringify({ refresh_token: token }), { mode: 0o600 });
    }
}
async function getRefreshToken() {
    try {
        const { Entry } = require('@napi-rs/keyring');
        const entry = new Entry('nyxora', 'google_refresh_token');
        const password = await entry.getPassword();
        if (password)
            return password;
    }
    catch (error) {
        // Fallback to file
        if (fs_1.default.existsSync(FALLBACK_TOKEN_PATH)) {
            try {
                const content = fs_1.default.readFileSync(FALLBACK_TOKEN_PATH, 'utf8');
                const parsed = JSON.parse(content);
                if (parsed.refresh_token)
                    return parsed.refresh_token;
            }
            catch (e) {
                return null;
            }
        }
    }
    return null;
}
