"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.deleteClientReview = exports.updateClientReview = exports.createClientReview = exports.getClientReviewById = exports.listClientReviews = exports.getActiveClientReviews = 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 clientReviewSerializers_js_1 = require("./clientReviewSerializers.js");
const insertMedia = async (tx, ownerTypeId, mediaItems, uploadedByStaffId) => {
    if (!mediaItems?.length)
        return;
    await tx.insert(schema_js_1.mediaAssets).values(mediaItems.map((m) => ({
        ownerType: "review",
        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, "review"), (0, drizzle_orm_1.eq)(schema_js_1.mediaAssets.ownerId, ownerTypeId)));
    if (mediaItems?.length) {
        await insertMedia(tx, ownerTypeId, mediaItems, uploadedByStaffId);
    }
};
const fetchReviewMedia = async (reviewId) => {
    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, "review"), (0, drizzle_orm_1.eq)(schema_js_1.mediaAssets.ownerId, reviewId)))
        .orderBy((0, drizzle_orm_1.asc)(schema_js_1.mediaAssets.sortOrder));
};
const getActiveClientReviews = async () => {
    const rows = await index_js_1.db
        .select()
        .from(schema_js_1.clientReviews)
        .where((0, drizzle_orm_1.eq)(schema_js_1.clientReviews.isActive, true))
        .orderBy((0, drizzle_orm_1.asc)(schema_js_1.clientReviews.sortOrder), (0, drizzle_orm_1.desc)(schema_js_1.clientReviews.createdAt));
    const items = await Promise.all(rows.map(async (row) => {
        const mediaRows = await fetchReviewMedia(row.id);
        return (0, clientReviewSerializers_js_1.toClientReviewListItem)(row, mediaRows);
    }));
    return items;
};
exports.getActiveClientReviews = getActiveClientReviews;
const listClientReviews = async (query) => {
    const { q, page, perPage, includeInactive } = query;
    const conditions = [];
    if (!includeInactive) {
        conditions.push((0, drizzle_orm_1.eq)(schema_js_1.clientReviews.isActive, true));
    }
    if (q) {
        conditions.push((0, drizzle_orm_1.like)(schema_js_1.clientReviews.clientName, `%${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.clientReviews)
            .where(whereClause)
            .orderBy((0, drizzle_orm_1.asc)(schema_js_1.clientReviews.sortOrder), (0, drizzle_orm_1.desc)(schema_js_1.clientReviews.createdAt))
            .limit(perPage)
            .offset((page - 1) * perPage),
        index_js_1.db
            .select({ count: (0, drizzle_orm_1.count)() })
            .from(schema_js_1.clientReviews)
            .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 = await fetchReviewMedia(row.id);
        return (0, clientReviewSerializers_js_1.toClientReviewListItem)(row, mediaRows);
    }));
    return { items, total, page, perPage, totalPages };
};
exports.listClientReviews = listClientReviews;
const getClientReviewById = async (id) => {
    const rows = await index_js_1.db
        .select()
        .from(schema_js_1.clientReviews)
        .where((0, drizzle_orm_1.eq)(schema_js_1.clientReviews.id, id))
        .limit(1);
    const row = rows[0];
    if (!row)
        return null;
    const mediaRows = await fetchReviewMedia(row.id);
    return (0, clientReviewSerializers_js_1.toClientReviewListItem)(row, mediaRows);
};
exports.getClientReviewById = getClientReviewById;
const createClientReview = async (input, staffId) => {
    const result = await index_js_1.db.transaction(async (tx) => {
        await tx.insert(schema_js_1.clientReviews).values({
            clientName: input.clientName,
            reviewText: input.reviewText,
            postUrl: input.postUrl ?? null,
            starRating: input.starRating ?? 5,
            sortOrder: input.sortOrder ?? 0,
        });
        const inserted = await tx
            .select({ id: schema_js_1.clientReviews.id })
            .from(schema_js_1.clientReviews)
            .orderBy((0, drizzle_orm_1.desc)(schema_js_1.clientReviews.id))
            .limit(1);
        const createdId = inserted[0]?.id;
        if (!createdId)
            throw new Error("CLIENT_REVIEW_CREATE_FAILED");
        if (input.media?.length) {
            await insertMedia(tx, createdId, input.media, staffId);
        }
        return createdId;
    });
    return (await (0, exports.getClientReviewById)(result));
};
exports.createClientReview = createClientReview;
const updateClientReview = async (id, input, staffId) => {
    const existing = await (0, exports.getClientReviewById)(id);
    if (!existing) {
        throw new Error("CLIENT_REVIEW_NOT_FOUND");
    }
    const updateData = {};
    if (input.clientName !== undefined)
        updateData.clientName = input.clientName;
    if (input.reviewText !== undefined)
        updateData.reviewText = input.reviewText;
    if (input.postUrl !== undefined)
        updateData.postUrl = input.postUrl;
    if (input.starRating !== undefined)
        updateData.starRating = input.starRating;
    if (input.sortOrder !== undefined)
        updateData.sortOrder = input.sortOrder;
    if (input.isActive !== undefined)
        updateData.isActive = input.isActive;
    if (Object.keys(updateData).length > 0) {
        await index_js_1.db
            .update(schema_js_1.clientReviews)
            .set(updateData)
            .where((0, drizzle_orm_1.eq)(schema_js_1.clientReviews.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.getClientReviewById)(id));
};
exports.updateClientReview = updateClientReview;
const deleteClientReview = async (id) => {
    const existing = await (0, exports.getClientReviewById)(id);
    if (!existing) {
        throw new Error("CLIENT_REVIEW_NOT_FOUND");
    }
    await index_js_1.db
        .update(schema_js_1.clientReviews)
        .set({ isActive: false })
        .where((0, drizzle_orm_1.eq)(schema_js_1.clientReviews.id, id));
};
exports.deleteClientReview = deleteClientReview;
//# sourceMappingURL=clientReviewService.js.map