"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.loadConfig = loadConfig;
exports.saveConfig = saveConfig;
exports.clearConfig = clearConfig;
exports.getConfig = getConfig;
exports.listAccountSessions = listAccountSessions;
exports.getCurrentAccountSession = getCurrentAccountSession;
exports.findAccountSession = findAccountSession;
exports.listAccountSessionsForUsername = listAccountSessionsForUsername;
exports.saveAccountSession = saveAccountSession;
exports.migrateLegacySession = migrateLegacySession;
exports.setCurrentAccount = setCurrentAccount;
exports.removeAccountSession = removeAccountSession;
const fs_1 = require("fs");
const path_1 = require("path");
const os_1 = __importDefault(require("os"));
const CONFIG_VERSION = 2;
function getConfigPath() {
    const custom = process.env.PLAYDROP_CONFIG_PATH;
    if (custom)
        return custom;
    return (0, path_1.join)(os_1.default.homedir(), '.playdrop', 'config.json');
}
function normalizeKey(value) {
    return value.trim();
}
function clonePersistedConfig(cfg) {
    return JSON.parse(JSON.stringify(cfg));
}
function buildDerivedConfig(cfg) {
    const next = clonePersistedConfig(cfg);
    const current = getCurrentAccountSession(next);
    if (current) {
        next.currentUsername = current.username;
        next.env = current.env;
        next.token = current.token;
    }
    return next;
}
function readRawConfig() {
    const file = getConfigPath();
    try {
        const data = (0, fs_1.readFileSync)(file, 'utf8');
        const parsed = JSON.parse(data);
        return parsed && typeof parsed === 'object' ? parsed : {};
    }
    catch {
        return {};
    }
}
function stripDerivedFields(cfg) {
    const next = {
        version: typeof cfg.version === 'number' ? cfg.version : undefined,
        currentAccount: cfg.currentAccount ?? undefined,
        accounts: cfg.accounts ? clonePersistedConfig({ accounts: cfg.accounts }).accounts : undefined,
    };
    if (!next.accounts || Object.keys(next.accounts).length === 0) {
        if (typeof cfg.token === 'string' && cfg.token.trim().length > 0) {
            next.token = cfg.token.trim();
        }
        if (typeof cfg.env === 'string' && cfg.env.trim().length > 0) {
            next.env = cfg.env.trim();
        }
    }
    return next;
}
function loadConfig() {
    return buildDerivedConfig(readRawConfig());
}
function saveConfig(cfg) {
    const file = getConfigPath();
    (0, fs_1.mkdirSync)((0, path_1.dirname)(file), { recursive: true });
    (0, fs_1.writeFileSync)(file, JSON.stringify(stripDerivedFields(cfg), null, 2));
}
function clearConfig() {
    const file = getConfigPath();
    if ((0, fs_1.existsSync)(file))
        (0, fs_1.rmSync)(file);
}
function getConfig() {
    return { path: getConfigPath() };
}
function listAccountSessions(cfg = loadConfig()) {
    const accounts = cfg.accounts ?? {};
    const sessions = [];
    for (const [username, envMap] of Object.entries(accounts)) {
        for (const [env, session] of Object.entries(envMap ?? {})) {
            if (!session || typeof session.token !== 'string' || session.token.trim().length === 0) {
                continue;
            }
            sessions.push({
                username,
                env,
                token: session.token,
                updatedAt: typeof session.updatedAt === 'string' ? session.updatedAt : '',
            });
        }
    }
    sessions.sort((left, right) => {
        if (left.username === right.username) {
            return left.env.localeCompare(right.env);
        }
        return left.username.localeCompare(right.username);
    });
    return sessions;
}
function getCurrentAccountSession(cfg = loadConfig()) {
    const current = cfg.currentAccount;
    if (!current) {
        return null;
    }
    return findAccountSession(current.username, current.env, cfg);
}
function findAccountSession(username, env, cfg = loadConfig()) {
    const normalizedUsername = normalizeKey(username);
    if (!normalizedUsername) {
        return null;
    }
    const envMap = cfg.accounts?.[normalizedUsername];
    if (!envMap) {
        return null;
    }
    if (typeof env === 'string' && env.trim().length > 0) {
        const session = envMap[env.trim()];
        if (!session?.token) {
            return null;
        }
        return {
            username: normalizedUsername,
            env: env.trim(),
            token: session.token,
            updatedAt: typeof session.updatedAt === 'string' ? session.updatedAt : '',
        };
    }
    const envs = Object.keys(envMap);
    if (envs.length === 1) {
        const selectedEnv = envs[0];
        const session = envMap[selectedEnv];
        if (!session?.token) {
            return null;
        }
        return {
            username: normalizedUsername,
            env: selectedEnv,
            token: session.token,
            updatedAt: typeof session.updatedAt === 'string' ? session.updatedAt : '',
        };
    }
    return null;
}
function listAccountSessionsForUsername(username, cfg = loadConfig()) {
    const normalizedUsername = normalizeKey(username);
    if (!normalizedUsername) {
        return [];
    }
    return listAccountSessions(cfg).filter((session) => session.username === normalizedUsername);
}
function saveAccountSession(input) {
    const cfg = loadConfig();
    const username = normalizeKey(input.username);
    const env = normalizeKey(input.env);
    const token = input.token.trim();
    if (!username || !env || !token) {
        throw new Error('invalid_account_session');
    }
    const next = {
        version: CONFIG_VERSION,
        currentAccount: { username, env },
        accounts: {
            ...(cfg.accounts ?? {}),
            [username]: {
                ...(cfg.accounts?.[username] ?? {}),
                [env]: {
                    token,
                    updatedAt: input.updatedAt ?? new Date().toISOString(),
                },
            },
        },
    };
    saveConfig(next);
    return loadConfig();
}
function migrateLegacySession(input) {
    return saveAccountSession(input);
}
function setCurrentAccount(input) {
    const cfg = loadConfig();
    const username = normalizeKey(input.username);
    const env = typeof input.env === 'string' ? normalizeKey(input.env) : '';
    const session = findAccountSession(username, env || undefined, cfg);
    if (!session) {
        throw new Error(env ? 'account_session_not_found' : 'account_not_found');
    }
    const next = {
        version: CONFIG_VERSION,
        currentAccount: { username: session.username, env: session.env },
        accounts: cfg.accounts ?? {},
    };
    saveConfig(next);
    return loadConfig();
}
// eslint-disable-next-line complexity
function removeAccountSession(input = {}) {
    const cfg = loadConfig();
    const current = getCurrentAccountSession(cfg);
    const username = normalizeKey(input.username ?? current?.username ?? '');
    const env = normalizeKey(input.env ?? current?.env ?? '');
    if (!username) {
        return cfg;
    }
    const accounts = clonePersistedConfig({ accounts: cfg.accounts ?? {} }).accounts ?? {};
    if (!accounts[username]) {
        return cfg;
    }
    if (env) {
        delete accounts[username][env];
    }
    else {
        delete accounts[username];
    }
    if (accounts[username] && Object.keys(accounts[username]).length === 0) {
        delete accounts[username];
    }
    const remainingSessions = listAccountSessions({ accounts });
    const nextCurrent = remainingSessions[0]
        ? { username: remainingSessions[0].username, env: remainingSessions[0].env }
        : null;
    const next = {
        version: CONFIG_VERSION,
        currentAccount: nextCurrent,
        accounts,
    };
    if (!nextCurrent && typeof cfg.token === 'string' && typeof cfg.env === 'string' && (!cfg.accounts || Object.keys(cfg.accounts).length === 0)) {
        clearConfig();
        return {};
    }
    saveConfig(next);
    return loadConfig();
}
