const axios = require('axios');
const qs = require('qs');
const bcrypt = require('bcrypt');
const prisma = require('../../src/prisma/PrismaClient.js');
const {
    KEYCLOAK_TOKEN_URL,
    KEYCLOAK_ADMIN_URL,
    KEYCLOAK_REALM,
    CLIENT_ID,
    CLIENT_SECRET,
} = require('../../config/keycloak.js');

// Ambil token admin Keycloak
const getAdminToken = async () => {
    const tokenParams = qs.stringify({
        grant_type: 'client_credentials',
        client_id: CLIENT_ID,
        client_secret: CLIENT_SECRET,
    });

    const { data } = await axios.post(KEYCLOAK_TOKEN_URL, tokenParams, {
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    });

    return data.access_token;
};

// Buat user di Keycloak
const createUserInKeycloak = async (user, token) => {
    const checkUser = await axios.get(
        `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users?username=${user.username}`,
        { headers: { Authorization: `Bearer ${token}` } }
    );

    if (checkUser.data.length > 0) {
        console.log(`⚠️  User ${user.username} found in Keycloak`);
        return checkUser.data[0].id;
    }

    await axios.post(
        `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users`,
        {
            username: user.username,
            email: user.email,
            firstName: user.firstname,
            lastName: user.lastname,
            enabled: true,
            credentials: [
                {
                    type: 'password',
                    value: user.password,
                    temporary: false,
                },
            ],
        },
        {
            headers: { Authorization: `Bearer ${token}` },
        }
    );

    const { data } = await axios.get(
        `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users?username=${user.username}`,
        {
            headers: { Authorization: `Bearer ${token}` },
        }
    );

    return data[0].id;
};

// Assign role ke user di Keycloak
const assignRole = async (userId, roleName, token) => {
    const { data: roles } = await axios.get(
        `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/roles`,
        {
            headers: { Authorization: `Bearer ${token}` },
        }
    );

    const role = roles.find((r) => r.name === roleName);
    if (!role) throw new Error(`Role "${roleName}" not found in Keycloak`);

    await axios.post(
        `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users/${userId}/role-mappings/realm`,
        [role],
        {
            headers: { Authorization: `Bearer ${token}` },
        }
    );
};

// Data user yang ingin dibuat
const users = [
    {
        username: 'admin1',
        email: 'admin1@gmail.com',
        password: 'password123',
        firstname: 'Admin',
        lastname: 'Satu',
        role: 'admin',
    },
    {
        username: 'sales1',
        email: 'sales1@gmail.com',
        password: 'password123',
        firstname: 'Sales',
        lastname: 'Satu',
        role: 'sales',
    },
    {
        username: 'sales2',
        email: 'sales2@gmail.com',
        password: 'password123',
        firstname: 'Sales',
        lastname: 'Dua',
        role: 'sales',
    },
];

// Fungsi utama yang bisa dipanggil dari seeder utama
const seedUsers = async () => {
    const token = await getAdminToken();

    for (const user of users) {
        const userId = await createUserInKeycloak(user, token);
        await assignRole(userId, user.role, token);

        const hashedPassword = await bcrypt.hash(user.password, 10);

        await prisma.user.upsert({
            where: { id: userId },
            update: {},
            create: {
                id: userId,
                username: user.username,
                email: user.email,
                firstname: user.firstname,
                lastname: user.lastname,
                password: hashedPassword,
                role: user.role,
            },
        });

        console.log(`✅ Success seed user ${user.role}: ${user.username}`);
    }
};

module.exports = { seedUsers };