import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
import fs from 'fs/promises';
import fsSync from 'fs';
import path from 'path';
import logger from '../../../utils/logger.js';
export class DeveloperService {
    constructor(configManager) {
        this.configManager = configManager;
    }
    async checkAuthStatus(userPayload) {
        const hasPassword = this.configManager.hasDeveloperPassword();
        const isAuthenticated = userPayload?.type === 'developer';
        return {
            hasPassword,
            isAuthenticated
        };
    }
    async setPassword(password) {
        if (!password || typeof password !== 'string') {
            throw new Error('密码不能为空');
        }
        if (password.length < 6) {
            throw new Error('密码长度至少需要6位');
        }
        if (this.configManager.hasDeveloperPassword()) {
            throw new Error('开发者密码已设置，请使用登录接口');
        }
        const salt = await bcrypt.genSalt(10);
        const passwordHash = await bcrypt.hash(password, salt);
        await this.configManager.setDeveloperPassword(passwordHash, salt);
        return this.generateToken();
    }
    async login(password) {
        if (!password || typeof password !== 'string') {
            throw new Error('密码不能为空');
        }
        if (!this.configManager.hasDeveloperPassword()) {
            throw new Error('请先设置开发者密码');
        }
        const developerConfig = this.configManager.getDeveloperConfig();
        if (!developerConfig) {
            throw new Error('开发者配置不存在');
        }
        const isValid = await bcrypt.compare(password, developerConfig.passwordHash);
        if (!isValid) {
            throw new Error('开发者密码错误');
        }
        return this.generateToken();
    }
    async executeProductionPackage() {
        logger.info('开始执行正式环境封装');
        const currentDir = process.cwd();
        let dataDir;
        if (currentDir.endsWith('server')) {
            dataDir = path.join(currentDir, 'data');
        }
        else {
            dataDir = path.join(currentDir, 'server', 'data');
        }
        logger.info(`数据目录路径: ${dataDir}`);
        try {
            await fs.access(dataDir);
        }
        catch (error) {
            throw new Error(`数据目录不存在: ${dataDir}`);
        }
        const items = await fs.readdir(dataDir, { withFileTypes: true });
        let deletedFiles = 0;
        let preservedDirs = 0;
        let preservedFiles = 0;
        for (const item of items) {
            const itemPath = path.join(dataDir, item.name);
            if (item.isDirectory()) {
                preservedDirs++;
                logger.info(`保留目录: ${item.name}`);
            }
            else if (item.isFile() && item.name !== 'instances.json') {
                try {
                    await fs.unlink(itemPath);
                    deletedFiles++;
                    logger.info(`删除文件: ${item.name}`);
                }
                catch (error) {
                    logger.error(`删除文件失败 ${item.name}:`, error);
                }
            }
            else if (item.name === 'instances.json') {
                preservedFiles++;
                logger.info(`保留文件: ${item.name}`);
            }
        }
        const result = {
            deletedFiles,
            preservedDirs,
            preservedFiles,
            dataDir
        };
        logger.info(`正式环境封装完成: 删除了${deletedFiles}个文件，保留了${preservedDirs}个目录，保留了${preservedFiles}个文件`);
        setTimeout(() => {
            logger.info('正式环境封装完成，程序退出');
            process.exit(0);
        }, 1000);
        return result;
    }
    getInstallGameJsonPath() {
        const baseDir = process.cwd();
        const possiblePaths = [
            path.join(baseDir, 'data', 'games', 'installgame.json'),
            path.join(baseDir, 'server', 'data', 'games', 'installgame.json'),
        ];
        for (const possiblePath of possiblePaths) {
            try {
                fsSync.accessSync(possiblePath, fsSync.constants.F_OK);
                return possiblePath;
            }
            catch {
            }
        }
        return possiblePaths[0];
    }
    async getGameConfigs() {
        try {
            const filePath = this.getInstallGameJsonPath();
            const content = await fs.readFile(filePath, 'utf-8');
            return JSON.parse(content);
        }
        catch (error) {
            if (error.code === 'ENOENT') {
                return {};
            }
            throw error;
        }
    }
    async saveGameConfigs(configs) {
        const filePath = this.getInstallGameJsonPath();
        const dir = path.dirname(filePath);
        try {
            await fs.access(dir);
        }
        catch {
            await fs.mkdir(dir, { recursive: true });
        }
        await fs.writeFile(filePath, JSON.stringify(configs, null, 2), 'utf-8');
        logger.info(`游戏配置已保存到: ${filePath}`);
    }
    async createGameConfig(config) {
        const configs = await this.getGameConfigs();
        if (configs[config.key]) {
            throw new Error(`游戏配置 "${config.key}" 已存在`);
        }
        if (!config.key || !config.game_nameCN || !config.appid) {
            throw new Error('游戏标识、中文名和App ID为必填字段');
        }
        const { key, ...configData } = config;
        configs[key] = configData;
        await this.saveGameConfigs(configs);
        logger.info(`创建游戏配置: ${config.key}`);
        return config;
    }
    async updateGameConfig(key, configData) {
        const configs = await this.getGameConfigs();
        if (!configs[key]) {
            throw new Error(`游戏配置 "${key}" 不存在`);
        }
        if (!configData.game_nameCN || !configData.appid) {
            throw new Error('中文名和App ID为必填字段');
        }
        configs[key] = configData;
        await this.saveGameConfigs(configs);
        logger.info(`更新游戏配置: ${key}`);
        return { key, ...configData };
    }
    async deleteGameConfig(key) {
        const configs = await this.getGameConfigs();
        if (!configs[key]) {
            throw new Error(`游戏配置 "${key}" 不存在`);
        }
        delete configs[key];
        await this.saveGameConfigs(configs);
        logger.info(`删除游戏配置: ${key}`);
    }
    generateToken() {
        const jwtSecret = this.configManager.getJWTSecret();
        const payload = {
            type: 'developer',
            timestamp: Date.now()
        };
        return jwt.sign(payload, jwtSecret, { expiresIn: '24h' });
    }
}
