"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.deleteBrand = exports.updateBrand = exports.createBrand = exports.getBrandBySlug = exports.getBrandById = exports.listBrands = 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 brandSerializers_js_1 = require("./brandSerializers.js");
const insertMedia = async (tx, ownerTypeId, mediaItems, uploadedByStaffId) => {
    if (!mediaItems?.length)
        return;
    await tx.insert(schema_js_1.mediaAssets).values(mediaItems.map((m) => ({
        ownerType: "brand",
        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, "brand"), (0, drizzle_orm_1.eq)(schema_js_1.mediaAssets.ownerId, ownerTypeId)));
    if (mediaItems?.length) {
        await insertMedia(tx, ownerTypeId, mediaItems, uploadedByStaffId);
    }
};
const fetchBrandMedia = async (brandId) => {
    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, "brand"), (0, drizzle_orm_1.eq)(schema_js_1.mediaAssets.ownerId, brandId)))
        .orderBy((0, drizzle_orm_1.asc)(schema_js_1.mediaAssets.sortOrder));
};
const fetchProductCount = async (brandId) => {
    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.brandId, brandId));
    return result[0]?.count || 0;
};
const listBrands = async (query) => {
    const { q, page, perPage, includeInactive } = query;
    const conditions = [];
    if (!includeInactive) {
        conditions.push((0, drizzle_orm_1.eq)(schema_js_1.brands.isActive, true));
    }
    if (q) {
        conditions.push((0, drizzle_orm_1.like)(schema_js_1.brands.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.brands)
            .where(whereClause)
            .orderBy((0, drizzle_orm_1.asc)(schema_js_1.brands.name))
            .limit(perPage)
            .offset((page - 1) * perPage),
        index_js_1.db
            .select({ count: (0, drizzle_orm_1.count)() })
            .from(schema_js_1.brands)
            .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([
            fetchBrandMedia(row.id),
            fetchProductCount(row.id),
        ]);
        return (0, brandSerializers_js_1.toBrandListItem)(row, mediaRows, productCount);
    }));
    return { items, total, page, perPage, totalPages };
};
exports.listBrands = listBrands;
const getBrandById = async (id) => {
    const rows = await index_js_1.db
        .select()
        .from(schema_js_1.brands)
        .where((0, drizzle_orm_1.eq)(schema_js_1.brands.id, id))
        .limit(1);
    const row = rows[0];
    if (!row)
        return null;
    const [mediaRows, productCount] = await Promise.all([
        fetchBrandMedia(row.id),
        fetchProductCount(row.id),
    ]);
    return (0, brandSerializers_js_1.toBrandListItem)(row, mediaRows, productCount);
};
exports.getBrandById = getBrandById;
const getBrandBySlug = async (slug) => {
    const rows = await index_js_1.db
        .select()
        .from(schema_js_1.brands)
        .where((0, drizzle_orm_1.eq)(schema_js_1.brands.slug, slug))
        .limit(1);
    const row = rows[0];
    if (!row)
        return null;
    const [mediaRows, productCount] = await Promise.all([
        fetchBrandMedia(row.id),
        fetchProductCount(row.id),
    ]);
    return (0, brandSerializers_js_1.toBrandListItem)(row, mediaRows, productCount);
};
exports.getBrandBySlug = getBrandBySlug;
const createBrand = async (input, staffId) => {
    const finalSlug = input.slug ?? (0, brandSerializers_js_1.slugifyBrand)(input.name);
    await index_js_1.db.transaction(async (tx) => {
        await tx.insert(schema_js_1.brands).values({
            name: input.name,
            slug: finalSlug,
        });
        const created = await tx
            .select({ id: schema_js_1.brands.id })
            .from(schema_js_1.brands)
            .where((0, drizzle_orm_1.eq)(schema_js_1.brands.slug, finalSlug))
            .limit(1);
        if (created[0] && input.media?.length) {
            await insertMedia(tx, created[0].id, input.media, staffId);
        }
    });
    const result = await (0, exports.getBrandBySlug)(finalSlug);
    return result;
};
exports.createBrand = createBrand;
const updateBrand = async (id, input, staffId) => {
    const existing = await (0, exports.getBrandById)(id);
    if (!existing) {
        throw new Error("BRAND_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.brands)
            .set(updateData)
            .where((0, drizzle_orm_1.eq)(schema_js_1.brands.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.getBrandById)(id));
};
exports.updateBrand = updateBrand;
const deleteBrand = async (id) => {
    const existing = await (0, exports.getBrandById)(id);
    if (!existing) {
        throw new Error("BRAND_NOT_FOUND");
    }
    await index_js_1.db
        .update(schema_js_1.brands)
        .set({ isActive: false })
        .where((0, drizzle_orm_1.eq)(schema_js_1.brands.id, id));
};
exports.deleteBrand = deleteBrand;
//# sourceMappingURL=brandService.js.map