"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.deleteFrameShape = exports.updateFrameShape = exports.createFrameShape = exports.getFrameShapeBySlug = exports.getFrameShapeById = exports.listFrameShapes = 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 frameShapeSerializers_js_1 = require("./frameShapeSerializers.js");
const insertMedia = async (tx, ownerTypeId, mediaItems, uploadedByStaffId) => {
    if (!mediaItems?.length)
        return;
    await tx.insert(schema_js_1.mediaAssets).values(mediaItems.map((m) => ({
        ownerType: "frame_shape",
        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, "frame_shape"), (0, drizzle_orm_1.eq)(schema_js_1.mediaAssets.ownerId, ownerTypeId)));
    if (mediaItems?.length) {
        await insertMedia(tx, ownerTypeId, mediaItems, uploadedByStaffId);
    }
};
const fetchFrameShapeMedia = async (frameShapeId) => {
    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, "frame_shape"), (0, drizzle_orm_1.eq)(schema_js_1.mediaAssets.ownerId, frameShapeId)))
        .orderBy((0, drizzle_orm_1.asc)(schema_js_1.mediaAssets.sortOrder));
};
const fetchProductCount = async (frameShapeId) => {
    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.frameShapeId, frameShapeId));
    return result[0]?.count || 0;
};
const listFrameShapes = async (query) => {
    const { q, page, perPage, includeInactive } = query;
    const conditions = [];
    if (!includeInactive) {
        conditions.push((0, drizzle_orm_1.eq)(schema_js_1.frameShapes.isActive, true));
    }
    if (q) {
        conditions.push((0, drizzle_orm_1.like)(schema_js_1.frameShapes.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.frameShapes)
            .where(whereClause)
            .orderBy((0, drizzle_orm_1.asc)(schema_js_1.frameShapes.name))
            .limit(perPage)
            .offset((page - 1) * perPage),
        index_js_1.db
            .select({ count: (0, drizzle_orm_1.count)() })
            .from(schema_js_1.frameShapes)
            .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([
            fetchFrameShapeMedia(row.id),
            fetchProductCount(row.id),
        ]);
        return (0, frameShapeSerializers_js_1.toFrameShapeListItem)(row, mediaRows, productCount);
    }));
    return { items, total, page, perPage, totalPages };
};
exports.listFrameShapes = listFrameShapes;
const getFrameShapeById = async (id) => {
    const rows = await index_js_1.db
        .select()
        .from(schema_js_1.frameShapes)
        .where((0, drizzle_orm_1.eq)(schema_js_1.frameShapes.id, id))
        .limit(1);
    const row = rows[0];
    if (!row)
        return null;
    const [mediaRows, productCount] = await Promise.all([
        fetchFrameShapeMedia(row.id),
        fetchProductCount(row.id),
    ]);
    return (0, frameShapeSerializers_js_1.toFrameShapeListItem)(row, mediaRows, productCount);
};
exports.getFrameShapeById = getFrameShapeById;
const getFrameShapeBySlug = async (slug) => {
    const rows = await index_js_1.db
        .select()
        .from(schema_js_1.frameShapes)
        .where((0, drizzle_orm_1.eq)(schema_js_1.frameShapes.slug, slug))
        .limit(1);
    const row = rows[0];
    if (!row)
        return null;
    const [mediaRows, productCount] = await Promise.all([
        fetchFrameShapeMedia(row.id),
        fetchProductCount(row.id),
    ]);
    return (0, frameShapeSerializers_js_1.toFrameShapeListItem)(row, mediaRows, productCount);
};
exports.getFrameShapeBySlug = getFrameShapeBySlug;
const createFrameShape = async (input, staffId) => {
    const finalSlug = input.slug ?? (0, frameShapeSerializers_js_1.slugifyFrameShape)(input.name);
    await index_js_1.db.transaction(async (tx) => {
        await tx.insert(schema_js_1.frameShapes).values({
            name: input.name,
            slug: finalSlug,
        });
        const created = await tx
            .select({ id: schema_js_1.frameShapes.id })
            .from(schema_js_1.frameShapes)
            .where((0, drizzle_orm_1.eq)(schema_js_1.frameShapes.slug, finalSlug))
            .limit(1);
        if (created[0] && input.media?.length) {
            await insertMedia(tx, created[0].id, input.media, staffId);
        }
    });
    const result = await (0, exports.getFrameShapeBySlug)(finalSlug);
    return result;
};
exports.createFrameShape = createFrameShape;
const updateFrameShape = async (id, input, staffId) => {
    const existing = await (0, exports.getFrameShapeById)(id);
    if (!existing) {
        throw new Error("FRAME_SHAPE_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.frameShapes)
            .set(updateData)
            .where((0, drizzle_orm_1.eq)(schema_js_1.frameShapes.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.getFrameShapeById)(id));
};
exports.updateFrameShape = updateFrameShape;
const deleteFrameShape = async (id) => {
    const existing = await (0, exports.getFrameShapeById)(id);
    if (!existing) {
        throw new Error("FRAME_SHAPE_NOT_FOUND");
    }
    await index_js_1.db
        .update(schema_js_1.frameShapes)
        .set({ isActive: false })
        .where((0, drizzle_orm_1.eq)(schema_js_1.frameShapes.id, id));
};
exports.deleteFrameShape = deleteFrameShape;
//# sourceMappingURL=frameShapeService.js.map