const SalesRepository = require('../../repository/admin/SalesRepository.js');
const HttpException = require('../../utils/HttpException.js');
const { SearchFilter } = require('../../utils/SearchFilter.js');
const timeLocal = require('../../utils/TimeLocal.js');
const prisma = require('../../prisma/PrismaClient.js');
const { createLog, updateLog, deleteLog } = require('../../utils/LogActivity.js');
const { formatISOWithoutTimezone } = require('../../utils/FormatDate.js');

exports.getAllSalesService = async ({ page, limit, search, sortBy, orderBy }) => {
    const skip = (page - 1) * limit;

    const where = {
        ...SearchFilter(search, ['username', 'user_areas.province.name'], ['user_areas']),
        deletedAt: null
    };

    const [sales, total] = await Promise.all([
        SalesRepository.UserRepository.findAll({ skip, take: limit, where, orderBy: { [sortBy]: orderBy } }),
        SalesRepository.UserRepository.countAll(where)
    ]);

    const formatted = sales.map(v => ({
        ...v,
        createdAt: formatISOWithoutTimezone(v.createdAt),
        updatedAt: formatISOWithoutTimezone(v.updatedAt),
    }));

    return { sales: formatted, total };
};

exports.showSalesService = async (id) => {
    const sales = await SalesRepository.UserRepository.findById(id);
    if (!sales) {
        throw new HttpException("Data sales not found", 404);
    }
    
    return {
        ...sales,
        createdAt: formatISOWithoutTimezone(sales.createdAt),
        updatedAt: formatISOWithoutTimezone(sales.updatedAt),
    };
};

exports.storeSalesService = async (userData, req) => {
    // Validasi province_ids
    if (userData.province_ids && userData.province_ids.length > 0) {
        const validProvinces = await prisma.province.findMany({
            where: { id: { in: userData.province_ids } },
            select: { id: true },
        });

        const validProvinceIds = validProvinces.map(p => p.id);
        const invalidProvinceIds = userData.province_ids.filter(id => !validProvinceIds.includes(id));

        if (invalidProvinceIds.length > 0) {
            throw new HttpException(
                `Province ID not found: ${invalidProvinceIds.join(', ')}`,
                404
            );
        }
    }

    // Create user dan assign role
    const userId = await SalesRepository.KeycloakRepository.createUser(userData);
    await SalesRepository.KeycloakRepository.assignSalesRole(userId);
    const data = await SalesRepository.UserRepository.createUser(userId, userData);

    // Insert ke user_areas
    if (userData.province_ids && userData.province_ids.length > 0) {
        await SalesRepository.UserAreaRepository.createMany(userId, userData.province_ids);
    }

    await createLog(req, data);
};

exports.updateSalesService = async (userData, id, req) => {
    // const sales = await SalesRepository.UserRepository.findById(id);
    // if (!sales) throw new HttpException('Sales not found', 404);

    // await SalesRepository.KeycloakRepository.updateUser(id, userData);
    // const data = await SalesRepository.UserRepository.updateUser(id, userData);

    // if (userData.province_ids && userData.province_ids.length > 0) {
    //     await SalesRepository.UserAreaRepository.deleteByUserId(id);
    //     await SalesRepository.UserAreaRepository.createMany(id, userData.province_ids);
    // }

    // await updateLog(req, data);

    const sales = await SalesRepository.UserRepository.findById(id);
    if (!sales) throw new HttpException('Sales not found', 404);

    // Validasi province_ids
    if (userData.province_ids && userData.province_ids.length > 0) {
        const validProvinces = await prisma.province.findMany({
            where: { id: { in: userData.province_ids } },
            select: { id: true },
        });

        const validProvinceIds = validProvinces.map(p => p.id);
        const invalidProvinceIds = userData.province_ids.filter(id => !validProvinceIds.includes(id));

        if (invalidProvinceIds.length > 0) {
            throw new HttpException(
                `Province ID not found: ${invalidProvinceIds.join(', ')}`,
                404
            );
        }
    }

    // Update ke Keycloak
    await SalesRepository.KeycloakRepository.updateUser(id, userData);

    // Update ke DB lokal
    const data = await SalesRepository.UserRepository.updateUser(id, userData);

    // Update relasi user_areas
    if (userData.province_ids && userData.province_ids.length > 0) {
        await SalesRepository.UserAreaRepository.deleteByUserId(id);
        await SalesRepository.UserAreaRepository.createMany(id, userData.province_ids);
    }

    await updateLog(req, data);
};

exports.deleteSalesService = async (id, req) => {
    const sales = await SalesRepository.UserRepository.findById(id);
    if (!sales) {
        throw new HttpException('Sales not found', 404);
    }

    await SalesRepository.KeycloakRepository.deleteUser(id);
    const data = await SalesRepository.UserRepository.deleteUser(id, { deletedAt: timeLocal.now().toDate() });

    await prisma.userArea.updateMany({
        where: { user_id: id },
        data: {
            deletedAt: timeLocal.now().toDate()
        }
    });

    await deleteLog(req, data);
};