/**
 * API 大锅饭 - Key 管理模块
 * 使用内存缓存 + 写锁 + 定期持久化，解决并发安全问题
 */

import { promises as fs } from 'fs';
import logger from '../../utils/logger.js';
import { existsSync, readFileSync, writeFileSync } from 'fs';
import path from 'path';
import crypto from 'crypto';

// 配置常量
const KEYS_STORE_FILE = path.join(process.cwd(), 'configs', 'api-potluck-keys.json');
const KEY_PREFIX = 'maki_';

// 默认配置（会被 user-data-manager 的配置覆盖）
const DEFAULT_CONFIG = {
    defaultDailyLimit: 500,
    persistInterval: 5000
};

// 配置获取函数（由外部注入）
let configGetter = null;

/**
 * 设置配置获取函数
 * @param {Function} getter - 返回配置对象的函数
 */
export function setConfigGetter(getter) {
    configGetter = getter;
}

/**
 * 获取当前配置
 */
function getConfig() {
    if (configGetter) {
        return configGetter();
    }
    return DEFAULT_CONFIG;
}

// 内存缓存
let keyStore = null;
let isDirty = false;
let isWriting = false;
let persistTimer = null;
let currentPersistInterval = DEFAULT_CONFIG.persistInterval;

/**
 * 初始化：从文件加载数据到内存
 */
function ensureLoaded() {
    if (keyStore !== null) return;
    try {
        if (existsSync(KEYS_STORE_FILE)) {
            const content = readFileSync(KEYS_STORE_FILE, 'utf8');
            keyStore = JSON.parse(content);
            // 兼容历史数据：为旧 Key 添加 bonusRemaining 字段
            let needsMigration = false;
            for (const keyData of Object.values(keyStore.keys)) {
                if (keyData.bonusRemaining === undefined) {
                    keyData.bonusRemaining = 0;
                    needsMigration = true;
                }
            }
            if (needsMigration) {
                logger.info('[API Potluck] Migrated legacy keys: added bonusRemaining field');
                markDirty();
            }
        } else {
            keyStore = { keys: {} };
            syncWriteToFile();
        }
    } catch (error) {
        logger.error('[API Potluck] Failed to load key store:', error.message);
        keyStore = { keys: {} };
    }
    
    // 获取配置的持久化间隔
    const config = getConfig();
    currentPersistInterval = config.persistInterval || DEFAULT_CONFIG.persistInterval;
    
    // 启动定期持久化
    if (!persistTimer) {
        persistTimer = setInterval(persistIfDirty, currentPersistInterval);
        // 进程退出时保存
        process.on('beforeExit', () => persistIfDirty());
        process.on('SIGINT', () => { persistIfDirty(); process.exit(0); });
        process.on('SIGTERM', () => { persistIfDirty(); process.exit(0); });
    }
}

/**
 * 同步写入文件（仅初始化时使用）
 */
function syncWriteToFile() {
    try {
        const dir = path.dirname(KEYS_STORE_FILE);
        if (!existsSync(dir)) {
            require('fs').mkdirSync(dir, { recursive: true });
        }
        writeFileSync(KEYS_STORE_FILE, JSON.stringify(keyStore, null, 2), 'utf8');
    } catch (error) {
        logger.error('[API Potluck] Sync write failed:', error.message);
    }
}

/**
 * 异步持久化（带写锁）
 */
async function persistIfDirty() {
    if (!isDirty || isWriting || keyStore === null) return;
    isWriting = true;
    try {
        const dir = path.dirname(KEYS_STORE_FILE);
        if (!existsSync(dir)) {
            await fs.mkdir(dir, { recursive: true });
        }
        // 写入临时文件再重命名，防止写入中断导致文件损坏
        const tempFile = KEYS_STORE_FILE + '.tmp';
        await fs.writeFile(tempFile, JSON.stringify(keyStore, null, 2), 'utf8');
        await fs.rename(tempFile, KEYS_STORE_FILE);
        isDirty = false;
    } catch (error) {
        logger.error('[API Potluck] Persist failed:', error.message);
    } finally {
        isWriting = false;
    }
}

/**
 * 标记数据已修改
 */
function markDirty() {
    isDirty = true;
}

/**
 * 生成随机 API Key（确保不重复）
 */
function generateApiKey() {
    ensureLoaded();
    let apiKey;
    let attempts = 0;
    const maxAttempts = 10;
    
    do {
        apiKey = `${KEY_PREFIX}${crypto.randomBytes(16).toString('hex')}`;
        attempts++;
        if (attempts >= maxAttempts) {
            throw new Error('Failed to generate unique API key after multiple attempts');
        }
    } while (keyStore.keys[apiKey]);
    
    return apiKey;
}

/**
 * 获取今天的日期字符串 (YYYY-MM-DD)
 */
function getTodayDateString() {
    const now = new Date();
    return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
}

/**
 * 检查并重置过期的每日计数
 */
function checkAndResetDailyCount(keyData) {
    const today = getTodayDateString();
    if (keyData.lastResetDate !== today) {
        keyData.todayUsage = 0;
        keyData.lastResetDate = today;
    }
    return keyData;
}

/**
 * 创建新的 API Key
 * @param {string} name - Key 名称
 * @param {number} [dailyLimit] - 每日限额，不传则使用配置的默认值
 */
export async function createKey(name = '', dailyLimit = null) {
    ensureLoaded();
    const config = getConfig();
    const actualDailyLimit = dailyLimit ?? config.defaultDailyLimit ?? DEFAULT_CONFIG.defaultDailyLimit;
    
    const apiKey = generateApiKey();
    const now = new Date().toISOString();
    const today = getTodayDateString();

    const keyData = {
        id: apiKey,
        name: name || `Key-${Object.keys(keyStore.keys).length + 1}`,
        createdAt: now,
        dailyLimit: actualDailyLimit,
        todayUsage: 0,
        totalUsage: 0,
        lastResetDate: today,
        lastUsedAt: null,
        enabled: true,
        bonusRemaining: 0           // 剩余资源包总次数（由同步检查更新）
    };

    keyStore.keys[apiKey] = keyData;
    markDirty();
    await persistIfDirty(); // 创建操作立即持久化

    logger.info(`[API Potluck] Created key: ${apiKey.substring(0, 12)}...`);
    return keyData;
}

/**
 * 获取所有 Key 列表
 */
export async function listKeys() {
    ensureLoaded();
    const keys = [];
    for (const [keyId, keyData] of Object.entries(keyStore.keys)) {
        const updated = checkAndResetDailyCount({ ...keyData });
        keys.push({
            ...updated,
            maskedKey: `${keyId.substring(0, 12)}...${keyId.substring(keyId.length - 4)}`
        });
    }
    return keys;
}

/**
 * 获取单个 Key 详情
 */
export async function getKey(keyId) {
    ensureLoaded();
    const keyData = keyStore.keys[keyId];
    if (!keyData) return null;
    return checkAndResetDailyCount({ ...keyData });
}

/**
 * 删除 Key
 */
export async function deleteKey(keyId) {
    ensureLoaded();
    if (!keyStore.keys[keyId]) return false;
    delete keyStore.keys[keyId];
    markDirty();
    await persistIfDirty(); // 删除操作立即持久化
    logger.info(`[API Potluck] Deleted key: ${keyId.substring(0, 12)}...`);
    return true;
}

/**
 * 更新 Key 的每日限额
 */
export async function updateKeyLimit(keyId, newLimit) {
    ensureLoaded();
    if (!keyStore.keys[keyId]) return null;
    keyStore.keys[keyId].dailyLimit = newLimit;
    markDirty();
    return keyStore.keys[keyId];
}

/**
 * 重置 Key 的当天调用次数
 */
export async function resetKeyUsage(keyId) {
    ensureLoaded();
    if (!keyStore.keys[keyId]) return null;
    keyStore.keys[keyId].todayUsage = 0;
    keyStore.keys[keyId].lastResetDate = getTodayDateString();
    markDirty();
    return keyStore.keys[keyId];
}

/**
 * 切换 Key 的启用/禁用状态
 */
export async function toggleKey(keyId) {
    ensureLoaded();
    if (!keyStore.keys[keyId]) return null;
    keyStore.keys[keyId].enabled = !keyStore.keys[keyId].enabled;
    markDirty();
    return keyStore.keys[keyId];
}

/**
 * 更新 Key 名称
 */
export async function updateKeyName(keyId, newName) {
    ensureLoaded();
    if (!keyStore.keys[keyId]) return null;
    keyStore.keys[keyId].name = newName;
    markDirty();
    return keyStore.keys[keyId];
}

/**
 * 重新生成 API Key（保留原有数据，更换 Key ID）
 * @param {string} oldKeyId - 原 Key ID
 * @returns {Promise<{oldKey: string, newKey: string, keyData: Object}|null>}
 */
export async function regenerateKey(oldKeyId) {
    ensureLoaded();
    const oldKeyData = keyStore.keys[oldKeyId];
    if (!oldKeyData) return null;
    
    // 生成新的唯一 Key
    const newKeyId = generateApiKey();
    
    // 复制数据到新 Key
    const newKeyData = {
        ...oldKeyData,
        id: newKeyId,
        regeneratedAt: new Date().toISOString(),
        regeneratedFrom: oldKeyId.substring(0, 12) + '...'
    };
    
    // 删除旧 Key，添加新 Key
    delete keyStore.keys[oldKeyId];
    keyStore.keys[newKeyId] = newKeyData;
    
    markDirty();
    await persistIfDirty(); // 立即持久化
    
    logger.info(`[API Potluck] Regenerated key: ${oldKeyId.substring(0, 12)}... -> ${newKeyId.substring(0, 12)}...`);
    
    return {
        oldKey: oldKeyId,
        newKey: newKeyId,
        keyData: newKeyData
    };
}

/**
 * 验证 API Key 是否有效且有配额（每日限额 + 资源包）
 */
export async function validateKey(apiKey) {
    ensureLoaded();
    if (!apiKey || !apiKey.startsWith(KEY_PREFIX)) {
        return { valid: false, reason: 'invalid_format' };
    }
    const keyData = keyStore.keys[apiKey];
    if (!keyData) return { valid: false, reason: 'not_found' };
    if (!keyData.enabled) return { valid: false, reason: 'disabled' };

    // 直接在内存中检查和重置
    checkAndResetDailyCount(keyData);
    
    // 检查每日限额
    if (keyData.todayUsage < keyData.dailyLimit) {
        return { valid: true, keyData, useBonus: false };
    }
    
    // 每日限额用尽，检查资源包
    const bonusRemaining = keyData.bonusRemaining || 0;
    if (bonusRemaining > 0) {
        return { valid: true, keyData, useBonus: true, bonusRemaining };
    }
    
    return { valid: false, reason: 'quota_exceeded', keyData };
}

/**
 * 增加 Key 的使用次数（原子操作，直接修改内存）
 * 优先消耗每日限额，用尽后消耗资源包
 * @param {string} apiKey - API Key
 * @param {Function} [onBonusUsed] - 资源包消耗回调，用于更新 data 中的 usedCount
 */
export async function incrementUsage(apiKey, onBonusUsed = null) {
    ensureLoaded();
    const keyData = keyStore.keys[apiKey];
    if (!keyData) return null;

    checkAndResetDailyCount(keyData);
    
    let usedBonus = false;
    
    // 优先消耗每日限额
    if (keyData.todayUsage < keyData.dailyLimit) {
        keyData.todayUsage += 1;
    } else {
        // 每日限额用尽，消耗资源包
        const bonusRemaining = keyData.bonusRemaining || 0;
        
        if (bonusRemaining > 0) {
            keyData.bonusRemaining = bonusRemaining - 1;
            usedBonus = true;
            
            // 触发回调更新 data 中的 usedCount
            if (onBonusUsed) {
                await onBonusUsed(apiKey);
            }
        } else {
            // 无可用配额
            return null;
        }
    }
    
    keyData.totalUsage += 1;
    keyData.lastUsedAt = new Date().toISOString();
    markDirty();
    
    return {
        ...keyData,
        usedBonus
    };
}

/**
 * 获取统计信息
 */
export async function getStats() {
    ensureLoaded();
    const keys = Object.values(keyStore.keys);
    let enabledKeys = 0, todayTotalUsage = 0, totalUsage = 0;

    for (const key of keys) {
        checkAndResetDailyCount(key);
        if (key.enabled) enabledKeys++;
        todayTotalUsage += key.todayUsage;
        totalUsage += key.totalUsage;
    }

    return {
        totalKeys: keys.length,
        enabledKeys,
        disabledKeys: keys.length - enabledKeys,
        todayTotalUsage,
        totalUsage
    };
}

// ============ 凭证资源包管理 ============

/**
 * 更新 Key 的剩余资源包次数（由同步检查调用）
 * @param {string} keyId - Key ID
 * @param {number} bonusRemaining - 剩余资源包总次数
 * @returns {Promise<boolean>}
 */
export async function updateBonusRemaining(keyId, bonusRemaining) {
    ensureLoaded();
    const keyData = keyStore.keys[keyId];
    if (!keyData) return false;
    
    keyData.bonusRemaining = Math.max(0, bonusRemaining);
    markDirty();
    return true;
}

/**
 * 获取 Key 的资源包信息
 * @param {string} keyId - Key ID
 * @param {Function} getConfigFn - 获取配置的函数（从 user-data-manager 传入）
 * @returns {Promise<Object|null>}
 */
export async function getBonusInfo(keyId, getConfigFn = null) {
    ensureLoaded();
    const keyData = keyStore.keys[keyId];
    if (!keyData) return null;
    
    // 从 user-data-manager 获取配置
    const config = getConfigFn ? getConfigFn() : { bonusPerCredential: 300, bonusValidityDays: 30 };
    
    return {
        bonusRemaining: keyData.bonusRemaining || 0,
        bonusPerCredential: config.bonusPerCredential,
        validityDays: config.bonusValidityDays
    };
}

/**
 * 批量更新所有 Key 的每日限额
 * @param {number} newLimit - 新的每日限额
 * @returns {Promise<{total: number, updated: number}>}
 */
export async function applyDailyLimitToAllKeys(newLimit) {
    ensureLoaded();
    const keys = Object.values(keyStore.keys);
    let updated = 0;
    
    for (const keyData of keys) {
        if (keyData.dailyLimit !== newLimit) {
            keyData.dailyLimit = newLimit;
            updated++;
        }
    }
    
    if (updated > 0) {
        markDirty();
        await persistIfDirty();
    }
    
    logger.info(`[API Potluck] Applied daily limit ${newLimit} to ${updated}/${keys.length} keys`);
    return { total: keys.length, updated };
}

/**
 * 获取所有 Key ID 列表
 * @returns {string[]}
 */
export function getAllKeyIds() {
    ensureLoaded();
    return Object.keys(keyStore.keys);
}

// 导出常量
export { KEY_PREFIX };
