"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DashboardComponentService = void 0;
const api_locale_1 = require("@hed-hog/api-locale");
const api_pagination_1 = require("@hed-hog/api-pagination");
const api_prisma_1 = require("@hed-hog/api-prisma");
const common_1 = require("@nestjs/common");
const fs_1 = require("fs");
const path_1 = require("path");
let DashboardComponentService = class DashboardComponentService {
    constructor(prismaService, paginationService) {
        this.prismaService = prismaService;
        this.paginationService = paginationService;
    }
    async getAllComponents(paginationParams) {
        const fields = ['slug', 'library_slug'];
        const OR = this.prismaService.createInsensitiveSearch(fields, paginationParams);
        if (paginationParams.search) {
            OR.push({
                dashboard_component_locale: {
                    some: {
                        name: {
                            contains: paginationParams.search,
                            mode: 'insensitive',
                        },
                    },
                },
            });
        }
        return this.paginationService.paginate(this.prismaService.dashboard_component, paginationParams, {
            include: {
                dashboard_component_locale: {
                    include: {
                        locale: true,
                    },
                },
                dashboard_component_role: {
                    include: {
                        role: {
                            include: {
                                role_locale: {
                                    include: {
                                        locale: true,
                                    },
                                },
                            },
                        },
                    },
                },
            },
            where: {
                OR,
            },
            orderBy: {
                created_at: 'desc',
            },
        }, 'dashboardComponent');
    }
    async getAllComponentsByUserRole(paginationParams, userId) {
        var _a, _b;
        const userRoles = await this.prismaService.role_user.findMany({
            where: { user_id: userId },
            select: { role_id: true },
        });
        const userRoleIds = userRoles.map((ur) => ur.role_id);
        if (userRoleIds.length === 0) {
            const emptyResult = await this.paginationService.paginate(this.prismaService.dashboard_component, paginationParams, {
                include: {
                    dashboard_component_locale: {
                        include: {
                            locale: true,
                        },
                    },
                    dashboard_component_role: {
                        include: {
                            role: {
                                include: {
                                    role_locale: {
                                        include: {
                                            locale: true,
                                        },
                                    },
                                },
                            },
                        },
                    },
                },
                where: {
                    id: -1,
                },
                orderBy: {
                    created_at: 'desc',
                },
            }, 'dashboardComponent');
            return Object.assign(Object.assign({}, emptyResult), { modules: [] });
        }
        const requestedLibrarySlug = (_a = paginationParams.librarySlug) === null || _a === void 0 ? void 0 : _a.trim();
        const excludedComponents = ((_b = paginationParams.exclude) !== null && _b !== void 0 ? _b : '')
            .split(',')
            .map((value) => value.trim())
            .filter(Boolean)
            .map((value) => {
            const slugParts = value.split('.').filter(Boolean);
            const baseSlug = slugParts[slugParts.length - 1] || value;
            const librarySlug = slugParts.length > 1 ? slugParts[0] : undefined;
            return Object.assign({ slug: baseSlug }, (librarySlug ? { library_slug: librarySlug } : {}));
        });
        const fields = ['slug', 'library_slug'];
        const OR = this.prismaService.createInsensitiveSearch(fields, paginationParams);
        if (paginationParams.search) {
            OR.push({
                dashboard_component_locale: {
                    some: {
                        name: {
                            contains: paginationParams.search,
                            mode: 'insensitive',
                        },
                    },
                },
            });
        }
        const baseFilters = [
            {
                dashboard_component_role: {
                    some: {
                        role_id: {
                            in: userRoleIds,
                        },
                    },
                },
            },
            ...(OR.length > 0 ? [{ OR }] : []),
            ...(excludedComponents.length > 0
                ? [
                    {
                        NOT: {
                            OR: excludedComponents,
                        },
                    },
                ]
                : []),
        ];
        const [paginatedResult, modules] = await Promise.all([
            this.paginationService.paginate(this.prismaService.dashboard_component, paginationParams, {
                include: {
                    dashboard_component_locale: {
                        include: {
                            locale: true,
                        },
                    },
                    dashboard_component_role: {
                        include: {
                            role: {
                                include: {
                                    role_locale: {
                                        include: {
                                            locale: true,
                                        },
                                    },
                                },
                            },
                        },
                    },
                },
                where: {
                    AND: [
                        ...baseFilters,
                        ...(requestedLibrarySlug
                            ? [{ library_slug: requestedLibrarySlug }]
                            : []),
                    ],
                },
                orderBy: {
                    created_at: 'desc',
                },
            }, 'dashboardComponent'),
            this.prismaService.dashboard_component.findMany({
                where: {
                    AND: baseFilters,
                },
                select: {
                    library_slug: true,
                },
                distinct: ['library_slug'],
                orderBy: {
                    library_slug: 'asc',
                },
            }),
        ]);
        return Object.assign(Object.assign({}, paginatedResult), { modules: modules
                .map((component) => component.library_slug)
                .filter((value) => Boolean(value)) });
    }
    async getComponent(id, locale, userId) {
        if (userId) {
            const userRoles = await this.prismaService.role_user.findMany({
                where: { user_id: userId },
                select: { role_id: true },
            });
            const userRoleIds = userRoles.map((ur) => ur.role_id);
            const component = await this.prismaService.dashboard_component.findFirst({
                where: {
                    id,
                    dashboard_component_role: {
                        some: {
                            role_id: {
                                in: userRoleIds,
                            },
                        },
                    },
                },
                include: {
                    dashboard_component_locale: {
                        include: {
                            locale: true,
                        },
                    },
                },
            });
            if (!component) {
                throw new common_1.NotFoundException((0, api_locale_1.getLocaleText)('dashboardComponentNotFound', locale, 'Dashboard component not found'));
            }
            return component;
        }
        const component = await this.prismaService.dashboard_component.findUnique({
            where: { id },
            include: {
                dashboard_component_locale: {
                    include: {
                        locale: true,
                    },
                },
                dashboard_component_role: {
                    include: {
                        role: {
                            include: {
                                role_locale: {
                                    include: {
                                        locale: true,
                                    },
                                },
                            },
                        },
                    },
                },
            },
        });
        if (!component) {
            throw new common_1.NotFoundException((0, api_locale_1.getLocaleText)('dashboardComponentNotFound', locale, 'Dashboard component not found'));
        }
        return component;
    }
    async createComponent(data, locale) {
        var _a;
        const normalized = this.normalizeComponentIdentity(data.slug, data.library_slug);
        const component = await this.prismaService.dashboard_component.create({
            data: {
                slug: normalized.slug,
                library_slug: normalized.library_slug,
                min_width: data.min_width,
                max_width: data.max_width,
                min_height: data.min_height,
                max_height: data.max_height,
                width: data.width,
                height: data.height,
                is_resizable: (_a = data.is_resizable) !== null && _a !== void 0 ? _a : true,
            },
        });
        if (data.locale) {
            for (const [localeCode, localeData] of Object.entries(data.locale)) {
                const localeRecord = await this.prismaService.locale.findFirst({
                    where: { code: localeCode },
                });
                if (localeRecord) {
                    await this.prismaService.dashboard_component_locale.create({
                        data: {
                            dashboard_component_id: component.id,
                            locale_id: localeRecord.id,
                            name: localeData.name,
                            description: localeData.description || '',
                        },
                    });
                }
            }
        }
        return this.getComponent(component.id, locale);
    }
    async updateComponent(id, data, locale) {
        const normalized = data.slug
            ? this.normalizeComponentIdentity(data.slug, data.library_slug)
            : {
                slug: undefined,
                library_slug: data.library_slug,
            };
        await this.prismaService.dashboard_component.update({
            where: { id },
            data: {
                slug: normalized.slug,
                library_slug: normalized.library_slug,
                min_width: data.min_width,
                max_width: data.max_width,
                min_height: data.min_height,
                max_height: data.max_height,
                width: data.width,
                height: data.height,
                is_resizable: data.is_resizable,
            },
        });
        if (data.locale) {
            await this.prismaService.dashboard_component_locale.deleteMany({
                where: { dashboard_component_id: id },
            });
            for (const [localeCode, localeData] of Object.entries(data.locale)) {
                const localeRecord = await this.prismaService.locale.findFirst({
                    where: { code: localeCode },
                });
                if (localeRecord) {
                    await this.prismaService.dashboard_component_locale.create({
                        data: {
                            dashboard_component_id: id,
                            locale_id: localeRecord.id,
                            name: localeData.name,
                            description: localeData.description || '',
                        },
                    });
                }
            }
        }
        return this.getComponent(id, locale);
    }
    async deleteComponent(id, locale) {
        const component = await this.prismaService.dashboard_component.findUnique({
            where: { id },
        });
        if (!component) {
            throw new common_1.NotFoundException((0, api_locale_1.getLocaleText)('dashboardComponentNotFound', locale, 'Dashboard component not found'));
        }
        return this.prismaService.dashboard_component.delete({
            where: { id },
        });
    }
    normalizeComponentIdentity(slug, librarySlug) {
        const slugParts = slug.split('.').filter(Boolean);
        const baseSlug = slugParts.length > 0 ? slugParts[slugParts.length - 1] : slug;
        const resolvedLibrarySlug = librarySlug || (slugParts.length > 1 ? slugParts[0] : 'core');
        return {
            slug: baseSlug,
            library_slug: resolvedLibrarySlug,
        };
    }
    buildWidgetAssetSlug(slug, librarySlug) {
        const normalized = this.normalizeComponentIdentity(slug, librarySlug);
        return normalized.slug;
    }
    resolvePreviewDirectory() {
        const cwd = process.cwd();
        const candidates = [
            (0, path_1.resolve)(cwd, 'libraries/core/hedhog/frontend/public/dashboard-previews'),
            (0, path_1.resolve)(cwd, '../libraries/core/hedhog/frontend/public/dashboard-previews'),
            (0, path_1.resolve)(cwd, '../../libraries/core/hedhog/frontend/public/dashboard-previews'),
        ];
        for (const candidate of candidates) {
            const parentDirectory = (0, path_1.resolve)(candidate, '..');
            if ((0, fs_1.existsSync)(parentDirectory)) {
                return candidate;
            }
        }
        return candidates[0];
    }
    async savePreview(id, file, locale) {
        var _a;
        const isDevelopment = process.env.NODE_ENV !== 'production';
        if (!isDevelopment) {
            throw new common_1.ForbiddenException((0, api_locale_1.getLocaleText)('dashboardPreviewOnlyInDevelopment', locale, 'Preview capture is only available in development environment'));
        }
        if (!file || !file.buffer) {
            throw new common_1.BadRequestException((0, api_locale_1.getLocaleText)('dashboardPreviewFileRequired', locale, 'Preview image file is required'));
        }
        if (!((_a = file.mimetype) === null || _a === void 0 ? void 0 : _a.startsWith('image/'))) {
            throw new common_1.BadRequestException((0, api_locale_1.getLocaleText)('dashboardPreviewInvalidFileType', locale, 'Preview file must be an image'));
        }
        const component = await this.prismaService.dashboard_component.findUnique({
            where: { id },
            select: {
                id: true,
                slug: true,
                library_slug: true,
            },
        });
        if (!component) {
            throw new common_1.NotFoundException((0, api_locale_1.getLocaleText)('dashboardComponentNotFound', locale, 'Dashboard component not found'));
        }
        const previewDirectory = this.resolvePreviewDirectory();
        await fs_1.promises.mkdir(previewDirectory, { recursive: true });
        const assetSlug = this.buildWidgetAssetSlug(component.slug, component.library_slug);
        const fileName = `${assetSlug}.png`;
        const outputPath = (0, path_1.join)(previewDirectory, fileName);
        await fs_1.promises.writeFile(outputPath, file.buffer);
        return {
            success: true,
            componentId: component.id,
            slug: component.slug,
            library_slug: component.library_slug,
            fileName,
            relativeUrl: `/libraries/${component.library_slug}/dashboard-previews/${fileName}`,
        };
    }
};
exports.DashboardComponentService = DashboardComponentService;
exports.DashboardComponentService = DashboardComponentService = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, common_1.Inject)((0, common_1.forwardRef)(() => api_prisma_1.PrismaService))),
    __param(1, (0, common_1.Inject)((0, common_1.forwardRef)(() => api_pagination_1.PaginationService))),
    __metadata("design:paramtypes", [api_prisma_1.PrismaService,
        api_pagination_1.PaginationService])
], DashboardComponentService);
//# sourceMappingURL=dashboard-component.service.js.map