const { publicUser, requireAdmin } = require("./auth.cjs");
const { loadDb, saveDb, getSubscription, addUserLog } = require("./db.cjs");
const { sendJson } = require("./http-utils.cjs");
const { nowIso, addHours, passwordHash } = require("./security.cjs");
const { systemConfigDescriptions } = require("./config.cjs");

function isValidSubscription(subscription) {
    return subscription && new Date(subscription.expires_at).getTime() > Date.now();
}

function userRow(db, user) {
    const subscription = getSubscription(db, user.id);
    const owner = db.users.find(item => Number(item.id) === Number(user.owner_admin_id));
    const deviceCount = db.devices.filter(item => Number(item.user_id) === Number(user.id)).length || (user.device_fingerprint ? 1 : 0);

    return {
        ...publicUser(user),
        avatar: user.avatar || null,
        device_fingerprint: user.device_fingerprint || "",
        current_token: null,
        subscription_type: subscription.subscription_type,
        expires_at: subscription.expires_at,
        owner_admin_name: owner?.username || null,
        device_count: deviceCount,
    };
}

function configRows(db) {
    return Object.entries(db.systemConfigs).map(([config_key, config_value], index) => ({
        id: index + 1,
        config_key,
        config_value: String(config_value ?? ""),
        description: systemConfigDescriptions[config_key] || "",
        updated_at: nowIso(),
        updated_by: "local-admin",
    }));
}

function logRows(db, logs) {
    return logs
        .slice()
        .sort((left, right) => new Date(right.created_at) - new Date(left.created_at))
        .map(log => ({
            ...log,
            username: db.users.find(user => Number(user.id) === Number(log.user_id))?.username || null,
        }));
}

function generationStats(db, userId) {
    const logs = userId
        ? db.generationLogs.filter(log => Number(log.user_id) === Number(userId))
        : db.generationLogs;
    const stats = { script: 0, voice: 0, video: 0, subtitle: 0, total: logs.length };
    for (const log of logs) {
        if (Object.prototype.hasOwnProperty.call(stats, log.type)) stats[log.type] += 1;
    }
    return stats;
}

function updateUserRole(user, role, inviteCode) {
    user.role = role === "admin" ? "admin" : "user";
    user.is_super_admin = user.is_super_admin || 0;
    if (inviteCode !== undefined) user.invite_code = inviteCode || null;
    user.updated_at = nowIso();
}

async function handleAdminApi(req, res, pathname, body, requestUrl) {
    if (!pathname.startsWith("/api/admin")) return false;

    const db = loadDb();
    const admin = requireAdmin(db, req);
    if (!admin) {
        sendJson(res, 401, { success: false, message: "需要管理员登录" });
        return true;
    }

    if (req.method === "GET" && pathname === "/api/admin/stats") {
        const activeUsers = db.users.filter(user => user.status === "active").length;
        const adminCount = db.users.filter(user => user.role === "admin" || Number(user.is_super_admin) === 1).length;
        const validSubscriptions = db.subscriptions.filter(isValidSubscription).length;
        sendJson(res, 200, {
            success: true,
            stats: {
                total_users: db.users.length,
                active_users: activeUsers,
                admin_count: adminCount,
                valid_subscriptions: validSubscriptions,
                expired_subscriptions: db.subscriptions.length - validSubscriptions,
                total_devices: db.devices.length,
            },
        });
        return true;
    }

    if (req.method === "GET" && pathname === "/api/admin/users") {
        const search = String(requestUrl.searchParams.get("search") || "").trim().toLowerCase();
        const status = String(requestUrl.searchParams.get("status") || "").trim();
        const subscription = String(requestUrl.searchParams.get("subscription") || "").trim();

        let users = db.users;
        if (search) {
            users = users.filter(user =>
                String(user.username || "").toLowerCase().includes(search) ||
                String(user.email || "").toLowerCase().includes(search),
            );
        }
        if (status) users = users.filter(user => user.status === status);
        if (subscription === "valid") users = users.filter(user => isValidSubscription(getSubscription(db, user.id)));
        if (subscription === "expired") users = users.filter(user => !isValidSubscription(getSubscription(db, user.id)));

        saveDb(db);
        sendJson(res, 200, { success: true, users: users.map(user => userRow(db, user)) });
        return true;
    }

    if (req.method === "GET" && pathname === "/api/admin/admins") {
        const admins = db.users
            .filter(user => user.role === "admin" || Number(user.is_super_admin) === 1)
            .map(user => ({
                id: user.id,
                username: user.username,
                email: user.email,
                invite_code: user.invite_code || null,
                is_super_admin: Number(user.is_super_admin || 0),
                status: user.status,
                owned_user_count: db.users.filter(item => Number(item.owner_admin_id) === Number(user.id)).length,
            }));
        sendJson(res, 200, { success: true, admins });
        return true;
    }

    if (req.method === "POST" && pathname === "/api/admin/add-time") {
        const user = db.users.find(item => Number(item.id) === Number(body.user_id));
        if (!user) {
            sendJson(res, 200, { success: false, message: "用户不存在" });
            return true;
        }
        const subscription = getSubscription(db, user.id);
        const base = new Date(subscription.expires_at).getTime() > Date.now() ? new Date(subscription.expires_at) : new Date();
        subscription.expires_at = addHours(base, Number(body.hours || 0)).toISOString();
        subscription.updated_at = nowIso();
        addUserLog(db, user.id, "add_time", body.reason || `管理员增加 ${body.hours || 0} 小时`);
        saveDb(db);
        sendJson(res, 200, { success: true, subscription });
        return true;
    }

    if (req.method === "POST" && pathname === "/api/admin/user/status") {
        const user = db.users.find(item => Number(item.id) === Number(body.user_id));
        if (!user) {
            sendJson(res, 200, { success: false, message: "用户不存在" });
            return true;
        }
        user.status = body.status === "disabled" ? "disabled" : "active";
        user.updated_at = nowIso();
        addUserLog(db, user.id, "status", `管理员修改状态为 ${user.status}`);
        saveDb(db);
        sendJson(res, 200, { success: true, user: userRow(db, user) });
        return true;
    }

    if (req.method === "POST" && pathname === "/api/admin/device/unbind") {
        const user = db.users.find(item => Number(item.id) === Number(body.user_id));
        if (!user) {
            sendJson(res, 200, { success: false, message: "用户不存在" });
            return true;
        }
        user.device_fingerprint = "";
        user.last_login_device = null;
        db.devices = db.devices.filter(item => Number(item.user_id) !== Number(user.id));
        addUserLog(db, user.id, "device_unbind", "管理员解绑设备");
        saveDb(db);
        sendJson(res, 200, { success: true });
        return true;
    }

    if (req.method === "POST" && pathname === "/api/admin/user/reset-password") {
        const user = db.users.find(item => Number(item.id) === Number(body.user_id));
        if (!user || !body.new_password) {
            sendJson(res, 200, { success: false, message: "用户或新密码无效" });
            return true;
        }
        user.password = passwordHash(body.new_password);
        user.updated_at = nowIso();
        addUserLog(db, user.id, "reset_password", "管理员重置密码");
        saveDb(db);
        sendJson(res, 200, { success: true });
        return true;
    }

    if (req.method === "POST" && pathname === "/api/admin/create-admin") {
        const email = String(body.email || "").trim();
        const username = String(body.username || "").trim();
        const password = String(body.password || "");
        if (!email || !username || !password) {
            sendJson(res, 200, { success: false, message: "管理员账号信息不完整" });
            return true;
        }
        if (db.users.some(user => user.email === email || user.username === username)) {
            sendJson(res, 200, { success: false, message: "账号已存在" });
            return true;
        }
        const user = {
            id: db.nextUserId++,
            username,
            email,
            password: passwordHash(password),
            role: "admin",
            status: "active",
            points: 999999,
            is_super_admin: 0,
            owner_admin_id: admin.id,
            invite_code: body.invite_code || null,
            max_devices: 99,
            device_fingerprint: "",
            created_at: nowIso(),
            updated_at: nowIso(),
            last_login_at: null,
            last_login_device: null,
            current_token: "",
            cloud_digital_human_disabled: 0,
        };
        db.users.push(user);
        getSubscription(db, user.id);
        addUserLog(db, user.id, "create_admin", `由 ${admin.username} 创建管理员`);
        saveDb(db);
        sendJson(res, 200, { success: true, admin: userRow(db, user) });
        return true;
    }

    if (req.method === "POST" && pathname === "/api/admin/points/modify") {
        const user = db.users.find(item => Number(item.id) === Number(body.user_id));
        if (!user) {
            sendJson(res, 200, { success: false, message: "用户不存在" });
            return true;
        }
        user.points = Number(user.points || 0) + Number(body.points_change || 0);
        user.updated_at = nowIso();
        addUserLog(db, user.id, "points_modify", body.reason || `积分变更 ${body.points_change || 0}`);
        saveDb(db);
        sendJson(res, 200, { success: true, points: user.points });
        return true;
    }

    const userLogMatch = pathname.match(/^\/api\/admin\/logs\/user\/(\d+)$/);
    if (req.method === "GET" && userLogMatch) {
        const logs = db.userLogs.filter(log => Number(log.user_id) === Number(userLogMatch[1]));
        sendJson(res, 200, { success: true, logs: logRows(db, logs) });
        return true;
    }

    if (req.method === "GET" && pathname === "/api/admin/logs/all") {
        const limit = Number(requestUrl.searchParams.get("limit") || 100);
        sendJson(res, 200, { success: true, logs: logRows(db, db.userLogs).slice(0, limit), page: 1, limit });
        return true;
    }

    if (req.method === "POST" && pathname === "/api/admin/user/assign-owner") {
        const user = db.users.find(item => Number(item.id) === Number(body.user_id));
        if (!user) {
            sendJson(res, 200, { success: false, message: "用户不存在" });
            return true;
        }
        user.owner_admin_id = body.owner_admin_id ? Number(body.owner_admin_id) : null;
        user.updated_at = nowIso();
        addUserLog(db, user.id, "assign_owner", `管理员归属变更为 ${user.owner_admin_id || "无"}`);
        saveDb(db);
        sendJson(res, 200, { success: true, user: userRow(db, user) });
        return true;
    }

    if (req.method === "PUT" && pathname === "/api/admin/admin/invite-code") {
        const user = db.users.find(item => Number(item.id) === Number(body.admin_id));
        if (!user) {
            sendJson(res, 200, { success: false, message: "管理员不存在" });
            return true;
        }
        user.invite_code = body.invite_code || null;
        user.updated_at = nowIso();
        addUserLog(db, user.id, "invite_code", "管理员邀请码变更");
        saveDb(db);
        sendJson(res, 200, { success: true, admin: userRow(db, user) });
        return true;
    }

    if (req.method === "POST" && pathname === "/api/admin/user/role") {
        const user = db.users.find(item => Number(item.id) === Number(body.user_id));
        if (!user) {
            sendJson(res, 200, { success: false, message: "用户不存在" });
            return true;
        }
        updateUserRole(user, body.role, body.invite_code);
        addUserLog(db, user.id, "role", `角色变更为 ${user.role}`);
        saveDb(db);
        sendJson(res, 200, { success: true, user: userRow(db, user) });
        return true;
    }

    if (req.method === "GET" && pathname === "/api/admin/generation-stats") {
        sendJson(res, 200, {
            success: true,
            stats: generationStats(db, requestUrl.searchParams.get("userId")),
        });
        return true;
    }

    if (req.method === "GET" && pathname === "/api/admin/generation-logs") {
        const userId = requestUrl.searchParams.get("userId");
        const limit = Number(requestUrl.searchParams.get("limit") || 100);
        const logs = userId ? db.generationLogs.filter(log => Number(log.user_id) === Number(userId)) : db.generationLogs;
        const rows = logRows(db, logs).slice(0, limit);
        sendJson(res, 200, { success: true, logs: rows, total: logs.length });
        return true;
    }

    if (req.method === "GET" && pathname === "/api/admin/system/config") {
        sendJson(res, 200, { success: true, configs: configRows(db) });
        return true;
    }

    if (req.method === "PUT" && pathname === "/api/admin/system/config") {
        const updates = Array.isArray(body.configs)
            ? body.configs.reduce((acc, item) => ({ ...acc, [item.config_key]: item.config_value }), {})
            : body.configs || body;
        for (const [key, value] of Object.entries(updates || {})) {
            if (key in db.systemConfigs) db.systemConfigs[key] = String(value ?? "");
        }
        addUserLog(db, admin.id, "system_config", "管理员更新系统配置");
        saveDb(db);
        sendJson(res, 200, { success: true, configs: configRows(db) });
        return true;
    }

    if (req.method === "PUT" && pathname === "/api/admin/user/cloud-digital-human") {
        const user = db.users.find(item => Number(item.id) === Number(body.user_id));
        if (!user) {
            sendJson(res, 200, { success: false, message: "用户不存在" });
            return true;
        }
        user.cloud_digital_human_disabled = body.disabled ? 1 : 0;
        user.updated_at = nowIso();
        addUserLog(db, user.id, "cloud_digital_human", `云数字人状态 ${user.cloud_digital_human_disabled ? "禁用" : "启用"}`);
        saveDb(db);
        sendJson(res, 200, { success: true, user: userRow(db, user) });
        return true;
    }

    sendJson(res, 404, { success: false, message: `Admin endpoint not found: ${req.method} ${pathname}` });
    return true;
}

module.exports = {
    handleAdminApi,
};
