"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.deleteProductType = exports.updateProductType = exports.createProductType = exports.getProductTypeBySlug = exports.getProductTypeById = exports.listProductTypes = void 0;
const drizzle_orm_1 = require("drizzle-orm");
const index_js_1 = require("../db/index.js");
const schema_js_1 = require("../db/schema.js");
const productTypeSerializers_js_1 = require("./productTypeSerializers.js");
const insertMedia = async (tx, ownerTypeId, mediaItems, uploadedByStaffId) => {
    if (!mediaItems?.length)
        return;
    await tx.insert(schema_js_1.mediaAssets).values(mediaItems.map((m) => ({
        ownerType: "product_type",
        ownerId: ownerTypeId,
        url: m.url,
        storageKey: m.storageKey || null,
        fileName: m.fileName || null,
        mimeType: m.mimeType || null,
        sizeBytes: m.sizeBytes || null,
        altText: m.altText || null,
        sortOrder: m.sortOrder ?? 0,
        isPrimary: m.isPrimary ?? false,
        uploadedByStaffId,
    })));
};
const replaceMedia = async (tx, ownerTypeId, mediaItems, uploadedByStaffId) => {
    await tx
        .delete(schema_js_1.mediaAssets)
        .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_js_1.mediaAssets.ownerType, "product_type"), (0, drizzle_orm_1.eq)(schema_js_1.mediaAssets.ownerId, ownerTypeId)));
    if (mediaItems?.length) {
        await insertMedia(tx, ownerTypeId, mediaItems, uploadedByStaffId);
    }
};
const fetchProductTypeMedia = async (productTypeId) => {
    return index_js_1.db
        .select()
        .from(schema_js_1.mediaAssets)
        .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_js_1.mediaAssets.ownerType, "product_type"), (0, drizzle_orm_1.eq)(schema_js_1.mediaAssets.ownerId, productTypeId)))
        .orderBy((0, drizzle_orm_1.asc)(schema_js_1.mediaAssets.sortOrder));
};
const fetchProductCount = async (productTypeId) => {
    const result = await index_js_1.db
        .select({ count: (0, drizzle_orm_1.count)() })
        .from(schema_js_1.products)
        .where((0, drizzle_orm_1.eq)(schema_js_1.products.productTypeId, productTypeId));
    return result[0]?.count || 0;
};
const listProductTypes = async (query) => {
    const { q, page, perPage, includeInactive } = query;
    const conditions = [];
    if (!includeInactive) {
        conditions.push((0, drizzle_orm_1.eq)(schema_js_1.productTypes.isActive, true));
    }
    if (q) {
        conditions.push((0, drizzle_orm_1.like)(schema_js_1.productTypes.name, `%${q}%`));
    }
    const whereClause = conditions.length ? (0, drizzle_orm_1.and)(...conditions) : undefined;
    const [dataRows, countResult] = await Promise.all([
        index_js_1.db
            .select()
            .from(schema_js_1.productTypes)
            .where(whereClause)
            .orderBy((0, drizzle_orm_1.asc)(schema_js_1.productTypes.name))
            .limit(perPage)
            .offset((page - 1) * perPage),
        index_js_1.db
            .select({ count: (0, drizzle_orm_1.count)() })
            .from(schema_js_1.productTypes)
            .where(whereClause),
    ]);
    const total = countResult[0]?.count || 0;
    const totalPages = Math.ceil(total / perPage);
    const items = await Promise.all(dataRows.map(async (row) => {
        const [mediaRows, productCount] = await Promise.all([
            fetchProductTypeMedia(row.id),
            fetchProductCount(row.id),
        ]);
        return (0, productTypeSerializers_js_1.toProductTypeListItem)(row, mediaRows, productCount);
    }));
    return { items, total, page, perPage, totalPages };
};
exports.listProductTypes = listProductTypes;
const getProductTypeById = async (id) => {
    const rows = await index_js_1.db
        .select()
        .from(schema_js_1.productTypes)
        .where((0, drizzle_orm_1.eq)(schema_js_1.productTypes.id, id))
        .limit(1);
    const row = rows[0];
    if (!row)
        return null;
    const [mediaRows, productCount] = await Promise.all([
        fetchProductTypeMedia(row.id),
        fetchProductCount(row.id),
    ]);
    return (0, productTypeSerializers_js_1.toProductTypeListItem)(row, mediaRows, productCount);
};
exports.getProductTypeById = getProductTypeById;
const getProductTypeBySlug = async (slug) => {
    const rows = await index_js_1.db
        .select()
        .from(schema_js_1.productTypes)
        .where((0, drizzle_orm_1.eq)(schema_js_1.productTypes.slug, slug))
        .limit(1);
    const row = rows[0];
    if (!row)
        return null;
    const [mediaRows, productCount] = await Promise.all([
        fetchProductTypeMedia(row.id),
        fetchProductCount(row.id),
    ]);
    return (0, productTypeSerializers_js_1.toProductTypeListItem)(row, mediaRows, productCount);
};
exports.getProductTypeBySlug = getProductTypeBySlug;
const createProductType = async (input, staffId) => {
    const finalSlug = input.slug ?? (0, productTypeSerializers_js_1.slugifyProductType)(input.name);
    await index_js_1.db.transaction(async (tx) => {
        await tx.insert(schema_js_1.productTypes).values({
            name: input.name,
            slug: finalSlug,
        });
        const created = await tx
            .select({ id: schema_js_1.productTypes.id })
            .from(schema_js_1.productTypes)
            .where((0, drizzle_orm_1.eq)(schema_js_1.productTypes.slug, finalSlug))
            .limit(1);
        if (created[0] && input.media?.length) {
            await insertMedia(tx, created[0].id, input.media, staffId);
        }
    });
    const result = await (0, exports.getProductTypeBySlug)(finalSlug);
    return result;
};
exports.createProductType = createProductType;
const updateProductType = async (id, input, staffId) => {
    const existing = await (0, exports.getProductTypeById)(id);
    if (!existing) {
        throw new Error("PRODUCT_TYPE_NOT_FOUND");
    }
    const updateData = {};
    if (input.name !== undefined)
        updateData.name = input.name;
    if (input.slug !== undefined)
        updateData.slug = input.slug;
    if (input.isActive !== undefined)
        updateData.isActive = input.isActive;
    if (Object.keys(updateData).length > 0) {
        await index_js_1.db
            .update(schema_js_1.productTypes)
            .set(updateData)
            .where((0, drizzle_orm_1.eq)(schema_js_1.productTypes.id, id));
    }
    if (input.media !== undefined) {
        await index_js_1.db.transaction(async (tx) => {
            await replaceMedia(tx, id, input.media || [], staffId);
        });
    }
    return (await (0, exports.getProductTypeById)(id));
};
exports.updateProductType = updateProductType;
const deleteProductType = async (id) => {
    const existing = await (0, exports.getProductTypeById)(id);
    if (!existing) {
        throw new Error("PRODUCT_TYPE_NOT_FOUND");
    }
    await index_js_1.db
        .update(schema_js_1.productTypes)
        .set({ isActive: false })
        .where((0, drizzle_orm_1.eq)(schema_js_1.productTypes.id, id));
};
exports.deleteProductType = deleteProductType;
//# sourceMappingURL=productTypeService.js.map