/******/ (() => { // webpackBootstrap
/******/ 	"use strict";
/******/ 	var __webpack_modules__ = ([
/* 0 */,
/* 1 */
/***/ ((module) => {

module.exports = require("@nestjs/core");

/***/ }),
/* 2 */
/***/ ((module) => {

module.exports = require("@nestjs/common");

/***/ }),
/* 3 */
/***/ ((module) => {

module.exports = require("path");

/***/ }),
/* 4 */
/***/ ((module) => {

module.exports = require("fs");

/***/ }),
/* 5 */
/***/ ((module) => {

module.exports = require("cookie-parser");

/***/ }),
/* 6 */
/***/ ((module) => {

module.exports = require("express-session");

/***/ }),
/* 7 */
/***/ ((module) => {

module.exports = require("connect-redis");

/***/ }),
/* 8 */
/***/ ((module) => {

module.exports = require("ioredis");

/***/ }),
/* 9 */
/***/ ((module) => {

module.exports = require("jsonwebtoken");

/***/ }),
/* 10 */
/***/ ((module) => {

module.exports = require("compression");

/***/ }),
/* 11 */
/***/ ((module) => {

module.exports = require("helmet");

/***/ }),
/* 12 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.AppModule = void 0;
const common_1 = __webpack_require__(2);
const config_1 = __webpack_require__(13);
const serve_static_1 = __webpack_require__(14);
const path_1 = __webpack_require__(3);
const fs_1 = __webpack_require__(4);
const prisma_module_1 = __webpack_require__(15);
const redis_module_1 = __webpack_require__(18);
const storage_module_1 = __webpack_require__(21);
const queue_module_1 = __webpack_require__(29);
const health_module_1 = __webpack_require__(37);
const auth_module_1 = __webpack_require__(42);
const users_module_1 = __webpack_require__(68);
const content_module_1 = __webpack_require__(97);
const media_module_1 = __webpack_require__(123);
const themes_module_1 = __webpack_require__(128);
const plugins_module_1 = __webpack_require__(164);
const settings_module_1 = __webpack_require__(78);
const public_module_1 = __webpack_require__(170);
const security_module_1 = __webpack_require__(241);
const groups_module_1 = __webpack_require__(256);
const menus_module_1 = __webpack_require__(152);
const shop_module_1 = __webpack_require__(183);
const lms_module_1 = __webpack_require__(198);
const analytics_module_1 = __webpack_require__(266);
const seo_module_1 = __webpack_require__(269);
const messages_module_1 = __webpack_require__(272);
const email_module_1 = __webpack_require__(77);
const notifications_module_1 = __webpack_require__(224);
const backup_module_1 = __webpack_require__(276);
const recommendations_module_1 = __webpack_require__(218);
const marketplace_module_1 = __webpack_require__(223);
const updates_module_1 = __webpack_require__(280);
const video_module_1 = __webpack_require__(288);
const subscriptions_module_1 = __webpack_require__(156);
const adminDistPath = (0, path_1.join)(process.cwd(), 'admin', 'dist');
const adminDistExists = (0, fs_1.existsSync)((0, path_1.join)(adminDistPath, 'index.html'));
if (!adminDistExists) {
    const logger = new common_1.Logger('AppModule');
    logger.warn('⚠️ Admin panel not built! The /admin route will not work.');
    logger.warn('   Run: cd admin && npm install && npm run build');
}
const staticModules = adminDistExists
    ? [
        serve_static_1.ServeStaticModule.forRoot({
            rootPath: adminDistPath,
            serveRoot: '/admin',
            exclude: ['/api/{*path}', '/uploads/{*path}', '/health/{*path}'],
            serveStaticOptions: {
                fallthrough: true,
            },
        }),
    ]
    : [];
let AppModule = class AppModule {
};
exports.AppModule = AppModule;
exports.AppModule = AppModule = __decorate([
    (0, common_1.Module)({
        imports: [
            config_1.ConfigModule.forRoot({
                isGlobal: true,
                envFilePath: '.env',
                cache: true,
            }),
            ...staticModules,
            prisma_module_1.PrismaModule,
            redis_module_1.RedisModule,
            storage_module_1.StorageModule,
            queue_module_1.QueueModule.forRoot(),
            health_module_1.HealthModule,
            auth_module_1.AuthModule,
            users_module_1.UsersModule,
            content_module_1.ContentModule,
            media_module_1.MediaModule,
            themes_module_1.ThemesModule,
            plugins_module_1.PluginsModule,
            settings_module_1.SettingsModule,
            public_module_1.PublicModule,
            security_module_1.SecurityModule,
            groups_module_1.GroupsModule,
            menus_module_1.MenusModule,
            shop_module_1.ShopModule,
            lms_module_1.LmsModule,
            analytics_module_1.AnalyticsModule,
            seo_module_1.SeoModule,
            messages_module_1.MessagesModule,
            email_module_1.EmailModule,
            notifications_module_1.NotificationsModule,
            backup_module_1.BackupModule,
            recommendations_module_1.RecommendationsModule,
            marketplace_module_1.MarketplaceModule,
            updates_module_1.UpdatesModule,
            video_module_1.VideoModule,
            subscriptions_module_1.SubscriptionsModule,
        ],
    })
], AppModule);


/***/ }),
/* 13 */
/***/ ((module) => {

module.exports = require("@nestjs/config");

/***/ }),
/* 14 */
/***/ ((module) => {

module.exports = require("@nestjs/serve-static");

/***/ }),
/* 15 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PrismaModule = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let PrismaModule = class PrismaModule {
};
exports.PrismaModule = PrismaModule;
exports.PrismaModule = PrismaModule = __decorate([
    (0, common_1.Global)(),
    (0, common_1.Module)({
        providers: [prisma_service_1.PrismaService],
        exports: [prisma_service_1.PrismaService],
    })
], PrismaModule);


/***/ }),
/* 16 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 PrismaService_1;
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PrismaService = void 0;
const common_1 = __webpack_require__(2);
const client_1 = __webpack_require__(17);
const config_1 = __webpack_require__(13);
let PrismaService = PrismaService_1 = class PrismaService extends client_1.PrismaClient {
    constructor(config) {
        const isDev = process.env.NODE_ENV === 'development';
        const connectionLimit = parseInt(process.env.DATABASE_CONNECTION_LIMIT || '10', 10);
        const poolTimeout = parseInt(process.env.DATABASE_POOL_TIMEOUT || '10', 10);
        let datasourceUrl = process.env.DATABASE_URL;
        if (datasourceUrl && !datasourceUrl.includes('connection_limit')) {
            const separator = datasourceUrl.includes('?') ? '&' : '?';
            datasourceUrl = `${datasourceUrl}${separator}connection_limit=${connectionLimit}&pool_timeout=${poolTimeout}`;
        }
        super({
            log: isDev
                ? [
                    { level: 'query', emit: 'event' },
                    { level: 'error', emit: 'stdout' },
                    { level: 'warn', emit: 'stdout' },
                ]
                : [{ level: 'error', emit: 'stdout' }],
            datasourceUrl,
        });
        this.config = config;
        this.logger = new common_1.Logger(PrismaService_1.name);
        if (isDev) {
            this.$on('query', (e) => {
                if (e.duration > 100) {
                    this.logger.warn(`Slow query (${e.duration}ms): ${e.query}`);
                }
            });
        }
    }
    async onModuleInit() {
        try {
            await this.$connect();
            this.logger.log('✅ Database connected');
        }
        catch (error) {
            this.logger.error(`Failed to connect to database: ${error.message}`);
            throw error;
        }
    }
    async onModuleDestroy() {
        await this.$disconnect();
        this.logger.log('👋 Database disconnected');
    }
    async executeWithRetry(operation, maxRetries = 3, delay = 1000) {
        let lastError;
        for (let attempt = 1; attempt <= maxRetries; attempt++) {
            try {
                return await operation();
            }
            catch (error) {
                lastError = error;
                if (error.code === 'P2024' || error.code === 'P1001') {
                    this.logger.warn(`Database operation failed (attempt ${attempt}/${maxRetries}): ${error.message}`);
                    if (attempt < maxRetries) {
                        await new Promise((resolve) => setTimeout(resolve, delay * attempt));
                        continue;
                    }
                }
                throw error;
            }
        }
        throw lastError;
    }
    async paginate(model, args, page = 1, limit = 20) {
        const skip = (page - 1) * limit;
        const [data, total] = await Promise.all([
            model.findMany({
                ...args,
                skip,
                take: limit,
            }),
            model.count({ where: args.where }),
        ]);
        const totalPages = Math.ceil(total / limit);
        return {
            data,
            pagination: {
                page,
                limit,
                total,
                totalPages,
                hasNext: page < totalPages,
                hasPrev: page > 1,
            },
        };
    }
    async cleanDatabase() {
        if (process.env.NODE_ENV === 'production') {
            throw new Error('Cannot clean database in production');
        }
        const models = Reflect.ownKeys(this).filter((key) => typeof key === 'string' && key[0] !== '_' && key[0] !== '$');
        return Promise.all(models.map((modelKey) => {
            const model = this[modelKey];
            if (model && typeof model.deleteMany === 'function') {
                return model.deleteMany();
            }
        }));
    }
    async getMetrics() {
        try {
            const result = await this.$queryRaw `
        SELECT
          numbackends as active_connections,
          xact_commit as transactions_committed,
          xact_rollback as transactions_rolled_back,
          blks_read as blocks_read,
          blks_hit as blocks_hit,
          tup_returned as rows_returned,
          tup_fetched as rows_fetched,
          tup_inserted as rows_inserted,
          tup_updated as rows_updated,
          tup_deleted as rows_deleted
        FROM pg_stat_database
        WHERE datname = current_database()
      `;
            return result[0] || {};
        }
        catch {
            return {};
        }
    }
};
exports.PrismaService = PrismaService;
exports.PrismaService = PrismaService = PrismaService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof config_1.ConfigService !== "undefined" && config_1.ConfigService) === "function" ? _a : Object])
], PrismaService);


/***/ }),
/* 17 */
/***/ ((module) => {

module.exports = require("@prisma/client");

/***/ }),
/* 18 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.RedisModule = void 0;
const common_1 = __webpack_require__(2);
const config_1 = __webpack_require__(13);
const redis_service_1 = __webpack_require__(19);
const cache_service_1 = __webpack_require__(20);
const logger = new common_1.Logger('RedisModule');
let RedisModule = class RedisModule {
};
exports.RedisModule = RedisModule;
exports.RedisModule = RedisModule = __decorate([
    (0, common_1.Global)(),
    (0, common_1.Module)({
        imports: [config_1.ConfigModule],
        providers: [
            {
                provide: 'REDIS_OPTIONS',
                useFactory: (configService) => {
                    const host = configService.get('REDIS_HOST');
                    if (!host) {
                        return null;
                    }
                    logger.log(`🔴 Redis configured: ${host}:${configService.get('REDIS_PORT', 6379)}`);
                    return {
                        host,
                        port: configService.get('REDIS_PORT', 6379),
                        password: configService.get('REDIS_PASSWORD'),
                        db: configService.get('REDIS_DB', 0),
                        keyPrefix: configService.get('REDIS_PREFIX', 'wpnode:'),
                        maxRetriesPerRequest: null,
                        lazyConnect: true,
                        enableReadyCheck: true,
                    };
                },
                inject: [config_1.ConfigService],
            },
            redis_service_1.RedisService,
            cache_service_1.CacheService,
        ],
        exports: [redis_service_1.RedisService, cache_service_1.CacheService, 'REDIS_OPTIONS'],
    })
], RedisModule);


/***/ }),
/* 19 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var RedisService_1;
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.RedisService = void 0;
const common_1 = __webpack_require__(2);
const ioredis_1 = __webpack_require__(8);
let RedisService = RedisService_1 = class RedisService {
    constructor(options) {
        this.options = options;
        this.logger = new common_1.Logger(RedisService_1.name);
        this.client = null;
        this.isConnected = false;
        this.redisEnabled =
            !!(options?.host && options.host !== 'localhost' && options.host !== '127.0.0.1') ||
                !!process.env.REDIS_HOST;
    }
    async onModuleInit() {
        if (!this.redisEnabled || !this.options) {
            this.logger.log('⏭️ Redis not configured - caching disabled (set REDIS_HOST to enable)');
            return;
        }
        try {
            this.client = new ioredis_1.default({
                ...this.options,
                maxRetriesPerRequest: null,
                retryStrategy: (times) => {
                    if (times > 3) {
                        this.logger.warn('Redis connection failed after 3 attempts, giving up');
                        return null;
                    }
                    return Math.min(times * 200, 1000);
                },
                reconnectOnError: () => false,
            });
            this.client.on('connect', () => {
                this.isConnected = true;
                this.logger.log('✅ Redis connected');
            });
            this.client.on('error', (err) => {
                if (this.isConnected) {
                    this.logger.warn(`Redis connection error: ${err.message}`);
                }
                this.isConnected = false;
            });
            this.client.on('close', () => {
                this.isConnected = false;
            });
            await this.client.ping();
        }
        catch (error) {
            this.logger.warn(`Redis not available, caching disabled: ${error.message}`);
            if (this.client) {
                this.client.disconnect();
            }
            this.client = null;
        }
    }
    async onModuleDestroy() {
        if (this.client) {
            await this.client.quit();
            this.logger.log('👋 Redis disconnected');
        }
    }
    getClient() {
        return this.client;
    }
    isAvailable() {
        return this.isConnected && this.client !== null;
    }
    async get(key) {
        if (!this.isAvailable())
            return null;
        try {
            return await this.client.get(key);
        }
        catch {
            return null;
        }
    }
    async set(key, value, ttlSeconds) {
        if (!this.isAvailable())
            return false;
        try {
            if (ttlSeconds) {
                await this.client.setex(key, ttlSeconds, value);
            }
            else {
                await this.client.set(key, value);
            }
            return true;
        }
        catch {
            return false;
        }
    }
    async del(key) {
        if (!this.isAvailable())
            return false;
        try {
            await this.client.del(key);
            return true;
        }
        catch {
            return false;
        }
    }
    async delPattern(pattern) {
        if (!this.isAvailable())
            return 0;
        try {
            const keys = await this.client.keys(pattern);
            if (keys.length > 0) {
                return await this.client.del(...keys);
            }
            return 0;
        }
        catch {
            return 0;
        }
    }
    async incr(key) {
        if (!this.isAvailable())
            return 0;
        try {
            return await this.client.incr(key);
        }
        catch {
            return 0;
        }
    }
    async expire(key, seconds) {
        if (!this.isAvailable())
            return false;
        try {
            await this.client.expire(key, seconds);
            return true;
        }
        catch {
            return false;
        }
    }
    async ttl(key) {
        if (!this.isAvailable())
            return -1;
        try {
            return await this.client.ttl(key);
        }
        catch {
            return -1;
        }
    }
};
exports.RedisService = RedisService;
exports.RedisService = RedisService = RedisService_1 = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, common_1.Optional)()),
    __param(0, (0, common_1.Inject)('REDIS_OPTIONS')),
    __metadata("design:paramtypes", [Object])
], RedisService);


/***/ }),
/* 20 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 CacheService_1;
var _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CacheService = void 0;
const common_1 = __webpack_require__(2);
const config_1 = __webpack_require__(13);
const redis_service_1 = __webpack_require__(19);
let CacheService = CacheService_1 = class CacheService {
    constructor(redis, config) {
        this.redis = redis;
        this.config = config;
        this.logger = new common_1.Logger(CacheService_1.name);
        this.defaultTtl = this.config.get('CACHE_TTL', 300);
    }
    buildKey(key, prefix) {
        return prefix ? `${prefix}:${key}` : key;
    }
    async get(key, options) {
        if (!this.redis.isAvailable())
            return null;
        const fullKey = this.buildKey(key, options?.prefix);
        const value = await this.redis.get(fullKey);
        if (!value)
            return null;
        try {
            return JSON.parse(value);
        }
        catch {
            return null;
        }
    }
    async set(key, value, options) {
        if (!this.redis.isAvailable())
            return false;
        const fullKey = this.buildKey(key, options?.prefix);
        const ttl = options?.ttl ?? this.defaultTtl;
        try {
            const serialized = JSON.stringify(value);
            return await this.redis.set(fullKey, serialized, ttl);
        }
        catch {
            return false;
        }
    }
    async getOrSet(key, factory, options) {
        const cached = await this.get(key, options);
        if (cached !== null) {
            return cached;
        }
        const value = await factory();
        await this.set(key, value, options);
        return value;
    }
    async invalidate(key, prefix) {
        const fullKey = this.buildKey(key, prefix);
        return await this.redis.del(fullKey);
    }
    async invalidatePattern(pattern) {
        return await this.redis.delPattern(pattern);
    }
    async invalidateByTags(tags) {
        for (const tag of tags) {
            await this.invalidatePattern(`*${tag}*`);
        }
    }
};
exports.CacheService = CacheService;
exports.CacheService = CacheService = CacheService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof redis_service_1.RedisService !== "undefined" && redis_service_1.RedisService) === "function" ? _a : Object, typeof (_b = typeof config_1.ConfigService !== "undefined" && config_1.ConfigService) === "function" ? _b : Object])
], CacheService);


/***/ }),
/* 21 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.StorageModule = void 0;
const common_1 = __webpack_require__(2);
const config_1 = __webpack_require__(13);
const storage_service_1 = __webpack_require__(22);
const local_provider_1 = __webpack_require__(23);
const s3_provider_1 = __webpack_require__(26);
let StorageModule = class StorageModule {
};
exports.StorageModule = StorageModule;
exports.StorageModule = StorageModule = __decorate([
    (0, common_1.Global)(),
    (0, common_1.Module)({
        imports: [config_1.ConfigModule],
        providers: [
            {
                provide: 'STORAGE_CONFIG',
                useFactory: (configService) => ({
                    provider: configService.get('STORAGE_PROVIDER', 'local'),
                    local: {
                        uploadDir: configService.get('UPLOAD_DIR', './uploads'),
                        baseUrl: configService.get('STORAGE_LOCAL_URL', '/uploads'),
                    },
                    s3: {
                        bucket: configService.get('S3_BUCKET'),
                        region: configService.get('S3_REGION', 'us-east-1'),
                        endpoint: configService.get('S3_ENDPOINT'),
                        accessKeyId: configService.get('S3_ACCESS_KEY_ID'),
                        secretAccessKey: configService.get('S3_SECRET_ACCESS_KEY'),
                        publicUrl: configService.get('S3_PUBLIC_URL'),
                        forcePathStyle: configService.get('S3_FORCE_PATH_STYLE', false),
                    },
                }),
                inject: [config_1.ConfigService],
            },
            local_provider_1.LocalStorageProvider,
            s3_provider_1.S3StorageProvider,
            storage_service_1.StorageService,
        ],
        exports: [storage_service_1.StorageService, 'STORAGE_CONFIG'],
    })
], StorageModule);


/***/ }),
/* 22 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var StorageService_1;
var _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.StorageService = void 0;
const common_1 = __webpack_require__(2);
const local_provider_1 = __webpack_require__(23);
const s3_provider_1 = __webpack_require__(26);
let StorageService = StorageService_1 = class StorageService {
    constructor(config, local, s3) {
        this.config = config;
        this.local = local;
        this.s3 = s3;
        this.logger = new common_1.Logger(StorageService_1.name);
        this.provider = this.config.provider;
        this.logger.log(`📦 Storage provider: ${this.provider}`);
    }
    async upload(file, originalName, options) {
        if (this.provider === 's3' && this.s3.isConfigured()) {
            return this.s3.upload(file, originalName, options);
        }
        return this.local.upload(file, originalName, options);
    }
    async delete(path) {
        if (this.provider === 's3' && this.s3.isConfigured()) {
            return this.s3.delete(path);
        }
        return this.local.delete(path);
    }
    async exists(path) {
        if (this.provider === 's3' && this.s3.isConfigured()) {
            return this.s3.exists(path);
        }
        return this.local.exists(path);
    }
    getUrl(path) {
        if (this.provider === 's3' && this.s3.isConfigured()) {
            return this.s3.getUrl(path);
        }
        return this.local.getUrl(path);
    }
    async getPresignedUrl(path, options) {
        if (this.provider === 's3' && this.s3.isConfigured()) {
            return this.s3.getPresignedUrl(path, options);
        }
        return null;
    }
    isCloudStorage() {
        return this.provider === 's3' && this.s3.isConfigured();
    }
    getProviderName() {
        return this.provider;
    }
};
exports.StorageService = StorageService;
exports.StorageService = StorageService = StorageService_1 = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, common_1.Inject)('STORAGE_CONFIG')),
    __metadata("design:paramtypes", [Object, typeof (_a = typeof local_provider_1.LocalStorageProvider !== "undefined" && local_provider_1.LocalStorageProvider) === "function" ? _a : Object, typeof (_b = typeof s3_provider_1.S3StorageProvider !== "undefined" && s3_provider_1.S3StorageProvider) === "function" ? _b : Object])
], StorageService);


/***/ }),
/* 23 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var LocalStorageProvider_1;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.LocalStorageProvider = void 0;
const common_1 = __webpack_require__(2);
const fs = __webpack_require__(24);
const path = __webpack_require__(3);
const uuid_1 = __webpack_require__(25);
let LocalStorageProvider = LocalStorageProvider_1 = class LocalStorageProvider {
    constructor(config) {
        this.config = config;
        this.logger = new common_1.Logger(LocalStorageProvider_1.name);
        this.uploadDir = this.config.local.uploadDir;
        this.baseUrl = this.config.local.baseUrl;
    }
    async upload(file, originalName, options) {
        const ext = path.extname(originalName);
        const filename = options?.filename || `${(0, uuid_1.v4)()}${ext}`;
        const folder = options?.folder || this.getDateFolder();
        const relativePath = path.join(folder, filename);
        const fullPath = path.join(this.uploadDir, relativePath);
        await fs.mkdir(path.dirname(fullPath), { recursive: true });
        await fs.writeFile(fullPath, file);
        const stats = await fs.stat(fullPath);
        return {
            path: relativePath.replace(/\\/g, '/'),
            url: `${this.baseUrl}/${relativePath.replace(/\\/g, '/')}`,
            size: stats.size,
            mimeType: options?.mimeType || 'application/octet-stream',
            filename,
        };
    }
    async delete(filePath) {
        try {
            const fullPath = path.join(this.uploadDir, filePath);
            await fs.unlink(fullPath);
            return true;
        }
        catch (_error) {
            this.logger.warn(`Failed to delete file: ${filePath}`);
            return false;
        }
    }
    async exists(filePath) {
        try {
            const fullPath = path.join(this.uploadDir, filePath);
            await fs.access(fullPath);
            return true;
        }
        catch {
            return false;
        }
    }
    getUrl(filePath) {
        return `${this.baseUrl}/${filePath.replace(/\\/g, '/')}`;
    }
    getDateFolder() {
        const now = new Date();
        return `${now.getFullYear()}/${String(now.getMonth() + 1).padStart(2, '0')}`;
    }
};
exports.LocalStorageProvider = LocalStorageProvider;
exports.LocalStorageProvider = LocalStorageProvider = LocalStorageProvider_1 = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, common_1.Inject)('STORAGE_CONFIG')),
    __metadata("design:paramtypes", [Object])
], LocalStorageProvider);


/***/ }),
/* 24 */
/***/ ((module) => {

module.exports = require("fs/promises");

/***/ }),
/* 25 */
/***/ ((module) => {

module.exports = require("uuid");

/***/ }),
/* 26 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var S3StorageProvider_1;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.S3StorageProvider = void 0;
const common_1 = __webpack_require__(2);
const client_s3_1 = __webpack_require__(27);
const s3_request_presigner_1 = __webpack_require__(28);
const path = __webpack_require__(3);
const uuid_1 = __webpack_require__(25);
let S3StorageProvider = S3StorageProvider_1 = class S3StorageProvider {
    constructor(config) {
        this.config = config;
        this.logger = new common_1.Logger(S3StorageProvider_1.name);
        this.client = null;
        this.bucket = this.config.s3.bucket || '';
        this.publicUrl = this.config.s3.publicUrl || '';
        if (this.config.s3.accessKeyId && this.config.s3.secretAccessKey && this.bucket) {
            this.client = new client_s3_1.S3Client({
                region: this.config.s3.region,
                endpoint: this.config.s3.endpoint,
                credentials: {
                    accessKeyId: this.config.s3.accessKeyId,
                    secretAccessKey: this.config.s3.secretAccessKey,
                },
                forcePathStyle: this.config.s3.forcePathStyle,
            });
            this.logger.log('✅ S3 storage initialized');
        }
    }
    isConfigured() {
        return this.client !== null;
    }
    async upload(file, originalName, options) {
        if (!this.client) {
            throw new Error('S3 storage not configured');
        }
        const ext = path.extname(originalName);
        const filename = options?.filename || `${(0, uuid_1.v4)()}${ext}`;
        const folder = options?.folder || this.getDateFolder();
        const key = `${folder}/${filename}`;
        await this.client.send(new client_s3_1.PutObjectCommand({
            Bucket: this.bucket,
            Key: key,
            Body: file,
            ContentType: options?.mimeType,
            Metadata: options?.metadata,
        }));
        return {
            path: key,
            url: this.getUrl(key),
            size: file.length,
            mimeType: options?.mimeType || 'application/octet-stream',
            filename,
        };
    }
    async delete(key) {
        if (!this.client)
            return false;
        try {
            await this.client.send(new client_s3_1.DeleteObjectCommand({
                Bucket: this.bucket,
                Key: key,
            }));
            return true;
        }
        catch (_error) {
            this.logger.warn(`Failed to delete S3 object: ${key}`);
            return false;
        }
    }
    async exists(key) {
        if (!this.client)
            return false;
        try {
            await this.client.send(new client_s3_1.HeadObjectCommand({
                Bucket: this.bucket,
                Key: key,
            }));
            return true;
        }
        catch {
            return false;
        }
    }
    getUrl(key) {
        if (this.publicUrl) {
            return `${this.publicUrl}/${key}`;
        }
        if (this.config.s3.endpoint) {
            return `${this.config.s3.endpoint}/${this.bucket}/${key}`;
        }
        return `https://${this.bucket}.s3.${this.config.s3.region}.amazonaws.com/${key}`;
    }
    async getPresignedUrl(key, options) {
        if (!this.client) {
            throw new Error('S3 storage not configured');
        }
        const command = new client_s3_1.GetObjectCommand({
            Bucket: this.bucket,
            Key: key,
        });
        return (0, s3_request_presigner_1.getSignedUrl)(this.client, command, {
            expiresIn: options?.expiresIn || 3600,
        });
    }
    getDateFolder() {
        const now = new Date();
        return `${now.getFullYear()}/${String(now.getMonth() + 1).padStart(2, '0')}`;
    }
};
exports.S3StorageProvider = S3StorageProvider;
exports.S3StorageProvider = S3StorageProvider = S3StorageProvider_1 = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, common_1.Inject)('STORAGE_CONFIG')),
    __metadata("design:paramtypes", [Object])
], S3StorageProvider);


/***/ }),
/* 27 */
/***/ ((module) => {

module.exports = require("@aws-sdk/client-s3");

/***/ }),
/* 28 */
/***/ ((module) => {

module.exports = require("@aws-sdk/s3-request-presigner");

/***/ }),
/* 29 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 QueueModule_1;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.QueueModule = exports.FallbackQueueService = exports.QUEUE_NOTIFICATIONS = exports.QUEUE_IMAGE = exports.QUEUE_EMAIL = void 0;
const common_1 = __webpack_require__(2);
const config_1 = __webpack_require__(13);
var queue_service_1 = __webpack_require__(30);
Object.defineProperty(exports, "QUEUE_EMAIL", ({ enumerable: true, get: function () { return queue_service_1.QUEUE_EMAIL; } }));
Object.defineProperty(exports, "QUEUE_IMAGE", ({ enumerable: true, get: function () { return queue_service_1.QUEUE_IMAGE; } }));
Object.defineProperty(exports, "QUEUE_NOTIFICATIONS", ({ enumerable: true, get: function () { return queue_service_1.QUEUE_NOTIFICATIONS; } }));
const isRedisConfigured = () => {
    return !!process.env.REDIS_HOST;
};
class FallbackQueueService {
    constructor() {
        this.logger = new common_1.Logger('FallbackQueueService');
        this.logger.warn('⚠️ Queue system running in fallback mode (no Redis). Jobs will be processed synchronously.');
    }
    async addEmailJob(data) {
        this.logger.debug(`[Sync] Would queue email job: ${data.to}`);
        return { id: `sync-${Date.now()}`, data };
    }
    async addBulkEmailJobs(emails) {
        this.logger.debug(`[Sync] Would queue ${emails.length} email jobs`);
        return emails.map((data, i) => ({ id: `sync-bulk-${Date.now()}-${i}`, data }));
    }
    async addImageJob(data) {
        this.logger.debug(`[Sync] Would queue image job: ${data.sourcePath}`);
        return { id: `sync-${Date.now()}`, data };
    }
    async addNotificationJob(data) {
        this.logger.debug(`[Sync] Would queue notification job: ${data.userId}`);
        return { id: `sync-${Date.now()}`, data };
    }
    async getQueueStats() {
        return {
            email: { waiting: 0, active: 0, completed: 0, failed: 0 },
            image: { waiting: 0, active: 0, completed: 0, failed: 0 },
            notifications: { waiting: 0, active: 0, completed: 0, failed: 0 },
        };
    }
    async pauseQueue() {
        this.logger.warn('[Sync] Queue pause not available in fallback mode');
    }
    async resumeQueue() {
        this.logger.warn('[Sync] Queue resume not available in fallback mode');
    }
}
exports.FallbackQueueService = FallbackQueueService;
let QueueModule = QueueModule_1 = class QueueModule {
    static forRoot() {
        const logger = new common_1.Logger('QueueModule');
        if (!isRedisConfigured()) {
            logger.warn('⚠️ Redis not configured - Queue system disabled. Set REDIS_HOST to enable background jobs.');
            return {
                module: QueueModule_1,
                imports: [config_1.ConfigModule],
                providers: [
                    {
                        provide: 'QueueService',
                        useClass: FallbackQueueService,
                    },
                ],
                exports: ['QueueService'],
            };
        }
        logger.log('✅ Redis configured - initializing BullMQ queues');
        const { BullModule } = __webpack_require__(31);
        const { QueueService } = __webpack_require__(30);
        const { EmailQueueProcessor } = __webpack_require__(33);
        const { ImageQueueProcessor } = __webpack_require__(35);
        return {
            module: QueueModule_1,
            imports: [
                config_1.ConfigModule,
                BullModule.forRootAsync({
                    imports: [config_1.ConfigModule],
                    useFactory: (configService) => {
                        const redisHost = configService.get('REDIS_HOST', 'localhost');
                        const redisPort = configService.get('REDIS_PORT', 6379);
                        const redisPassword = configService.get('REDIS_PASSWORD');
                        logger.log(`📋 Queue system configured (Redis: ${redisHost}:${redisPort})`);
                        return {
                            connection: {
                                host: redisHost,
                                port: redisPort,
                                password: redisPassword || undefined,
                                maxRetriesPerRequest: null,
                            },
                            defaultJobOptions: {
                                removeOnComplete: 100,
                                removeOnFail: 500,
                                attempts: 3,
                                backoff: {
                                    type: 'exponential',
                                    delay: 1000,
                                },
                            },
                        };
                    },
                    inject: [config_1.ConfigService],
                }),
                BullModule.registerQueue({ name: 'email' }, { name: 'image' }, { name: 'notifications' }),
            ],
            providers: [
                {
                    provide: 'QueueService',
                    useClass: QueueService,
                },
                EmailQueueProcessor,
                ImageQueueProcessor,
            ],
            exports: ['QueueService', BullModule],
        };
    }
};
exports.QueueModule = QueueModule;
exports.QueueModule = QueueModule = QueueModule_1 = __decorate([
    (0, common_1.Global)(),
    (0, common_1.Module)({})
], QueueModule);


/***/ }),
/* 30 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var QueueService_1;
var _a, _b, _c;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.QueueService = exports.QUEUE_NOTIFICATIONS = exports.QUEUE_IMAGE = exports.QUEUE_EMAIL = void 0;
const common_1 = __webpack_require__(2);
const bullmq_1 = __webpack_require__(31);
const bullmq_2 = __webpack_require__(32);
exports.QUEUE_EMAIL = 'email';
exports.QUEUE_IMAGE = 'image';
exports.QUEUE_NOTIFICATIONS = 'notifications';
let QueueService = QueueService_1 = class QueueService {
    constructor(emailQueue, imageQueue, notificationQueue) {
        this.emailQueue = emailQueue;
        this.imageQueue = imageQueue;
        this.notificationQueue = notificationQueue;
        this.logger = new common_1.Logger(QueueService_1.name);
    }
    async addEmailJob(data, options) {
        try {
            const job = await this.emailQueue.add('send', data, {
                priority: 2,
                ...options,
            });
            this.logger.debug(`Email job added: ${job.id} -> ${data.to}`);
            return job;
        }
        catch (error) {
            this.logger.error(`Failed to add email job: ${error.message}`);
            throw error;
        }
    }
    async addBulkEmailJobs(emails, options) {
        const jobs = emails.map((data) => ({
            name: 'send',
            data,
            opts: { priority: 3, ...options },
        }));
        return this.emailQueue.addBulk(jobs);
    }
    async addImageJob(data, options) {
        try {
            const job = await this.imageQueue.add('process', data, {
                priority: 1,
                ...options,
            });
            this.logger.debug(`Image job added: ${job.id}`);
            return job;
        }
        catch (error) {
            this.logger.error(`Failed to add image job: ${error.message}`);
            throw error;
        }
    }
    async addNotificationJob(data, options) {
        try {
            const job = await this.notificationQueue.add('send', data, options);
            this.logger.debug(`Notification job added: ${job.id}`);
            return job;
        }
        catch (error) {
            this.logger.error(`Failed to add notification job: ${error.message}`);
            throw error;
        }
    }
    async getQueueStats() {
        const [emailCounts, imageCounts, notificationCounts] = await Promise.all([
            this.emailQueue.getJobCounts(),
            this.imageQueue.getJobCounts(),
            this.notificationQueue.getJobCounts(),
        ]);
        return {
            email: emailCounts,
            image: imageCounts,
            notifications: notificationCounts,
        };
    }
    async pauseQueue(queueName) {
        const queue = this.getQueueByName(queueName);
        await queue.pause();
        this.logger.log(`Queue ${queueName} paused`);
    }
    async resumeQueue(queueName) {
        const queue = this.getQueueByName(queueName);
        await queue.resume();
        this.logger.log(`Queue ${queueName} resumed`);
    }
    getQueueByName(name) {
        switch (name) {
            case 'email':
                return this.emailQueue;
            case 'image':
                return this.imageQueue;
            case 'notifications':
                return this.notificationQueue;
            default:
                throw new Error(`Unknown queue: ${name}`);
        }
    }
};
exports.QueueService = QueueService;
exports.QueueService = QueueService = QueueService_1 = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, bullmq_1.InjectQueue)(exports.QUEUE_EMAIL)),
    __param(1, (0, bullmq_1.InjectQueue)(exports.QUEUE_IMAGE)),
    __param(2, (0, bullmq_1.InjectQueue)(exports.QUEUE_NOTIFICATIONS)),
    __metadata("design:paramtypes", [typeof (_a = typeof bullmq_2.Queue !== "undefined" && bullmq_2.Queue) === "function" ? _a : Object, typeof (_b = typeof bullmq_2.Queue !== "undefined" && bullmq_2.Queue) === "function" ? _b : Object, typeof (_c = typeof bullmq_2.Queue !== "undefined" && bullmq_2.Queue) === "function" ? _c : Object])
], QueueService);


/***/ }),
/* 31 */
/***/ ((module) => {

module.exports = require("@nestjs/bullmq");

/***/ }),
/* 32 */
/***/ ((module) => {

module.exports = require("bullmq");

/***/ }),
/* 33 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 EmailQueueProcessor_1;
var _a, _b, _c, _d;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.EmailQueueProcessor = void 0;
const bullmq_1 = __webpack_require__(31);
const common_1 = __webpack_require__(2);
const bullmq_2 = __webpack_require__(32);
const config_1 = __webpack_require__(13);
const nodemailer = __webpack_require__(34);
const queue_service_1 = __webpack_require__(30);
let EmailQueueProcessor = EmailQueueProcessor_1 = class EmailQueueProcessor extends bullmq_1.WorkerHost {
    constructor(configService) {
        super();
        this.configService = configService;
        this.logger = new common_1.Logger(EmailQueueProcessor_1.name);
        this.transporter = null;
        this.initializeTransporter();
    }
    initializeTransporter() {
        const host = this.configService.get('SMTP_HOST');
        const port = this.configService.get('SMTP_PORT', 587);
        if (host) {
            this.transporter = nodemailer.createTransport({
                host,
                port,
                secure: this.configService.get('SMTP_SECURE', false),
                auth: {
                    user: this.configService.get('SMTP_USER'),
                    pass: this.configService.get('SMTP_PASS'),
                },
            });
            this.logger.log('📧 Email processor initialized');
        }
        else {
            this.logger.warn('📧 SMTP not configured - emails will be logged only');
        }
    }
    async process(job) {
        const { to, toName, subject, html, text } = job.data;
        this.logger.debug(`Processing email job ${job.id}: ${subject} -> ${to}`);
        if (!this.transporter) {
            this.logger.log(`[DRY RUN] Email to ${to}: ${subject}`);
            return { success: true, dryRun: true };
        }
        try {
            const fromEmail = this.configService.get('SMTP_FROM');
            const fromName = this.configService.get('SMTP_FROM_NAME', 'WordPress Node');
            const info = await this.transporter.sendMail({
                from: `"${fromName}" <${fromEmail}>`,
                to: toName ? `"${toName}" <${to}>` : to,
                subject,
                html,
                text: text || this.htmlToText(html),
            });
            this.logger.log(`Email sent: ${info.messageId} -> ${to}`);
            return { success: true, messageId: info.messageId };
        }
        catch (error) {
            this.logger.error(`Failed to send email to ${to}: ${error.message}`);
            throw error;
        }
    }
    htmlToText(html) {
        return html
            .replace(/<br\s*\/?>/gi, '\n')
            .replace(/<\/p>/gi, '\n\n')
            .replace(/<[^>]+>/g, '')
            .replace(/&nbsp;/g, ' ')
            .replace(/&amp;/g, '&')
            .replace(/&lt;/g, '<')
            .replace(/&gt;/g, '>')
            .trim();
    }
    onCompleted(job) {
        this.logger.debug(`Email job ${job.id} completed`);
    }
    onFailed(job, error) {
        this.logger.error(`Email job ${job.id} failed: ${error.message}`);
    }
};
exports.EmailQueueProcessor = EmailQueueProcessor;
__decorate([
    (0, bullmq_1.OnWorkerEvent)('completed'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_b = typeof bullmq_2.Job !== "undefined" && bullmq_2.Job) === "function" ? _b : Object]),
    __metadata("design:returntype", void 0)
], EmailQueueProcessor.prototype, "onCompleted", null);
__decorate([
    (0, bullmq_1.OnWorkerEvent)('failed'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_c = typeof bullmq_2.Job !== "undefined" && bullmq_2.Job) === "function" ? _c : Object, typeof (_d = typeof Error !== "undefined" && Error) === "function" ? _d : Object]),
    __metadata("design:returntype", void 0)
], EmailQueueProcessor.prototype, "onFailed", null);
exports.EmailQueueProcessor = EmailQueueProcessor = EmailQueueProcessor_1 = __decorate([
    (0, bullmq_1.Processor)(queue_service_1.QUEUE_EMAIL),
    __metadata("design:paramtypes", [typeof (_a = typeof config_1.ConfigService !== "undefined" && config_1.ConfigService) === "function" ? _a : Object])
], EmailQueueProcessor);


/***/ }),
/* 34 */
/***/ ((module) => {

module.exports = require("nodemailer");

/***/ }),
/* 35 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 ImageQueueProcessor_1;
var _a, _b, _c;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ImageQueueProcessor = void 0;
const bullmq_1 = __webpack_require__(31);
const common_1 = __webpack_require__(2);
const bullmq_2 = __webpack_require__(32);
const fs = __webpack_require__(24);
const path = __webpack_require__(3);
const queue_service_1 = __webpack_require__(30);
let sharpModule = null;
try {
    sharpModule = __webpack_require__(36);
}
catch {
}
let ImageQueueProcessor = ImageQueueProcessor_1 = class ImageQueueProcessor extends bullmq_1.WorkerHost {
    constructor() {
        super();
        this.logger = new common_1.Logger(ImageQueueProcessor_1.name);
        if (!sharpModule) {
            this.logger.warn('Sharp not installed - image processing will be skipped. Install with: npm install sharp');
        }
    }
    async process(job) {
        const { sourcePath, operations, outputPath } = job.data;
        this.logger.debug(`Processing image job ${job.id}: ${sourcePath}`);
        if (!sharpModule) {
            this.logger.warn('Sharp not installed - skipping image processing');
            return { success: false, reason: 'sharp not installed' };
        }
        try {
            await fs.access(sourcePath);
            let image = sharpModule(sourcePath);
            if (operations.resize) {
                image = image.resize(operations.resize.width, operations.resize.height, {
                    fit: 'inside',
                    withoutEnlargement: true,
                });
            }
            if (operations.format) {
                image = image.toFormat(operations.format, {
                    quality: operations.quality || 80,
                });
            }
            if (operations.thumbnail) {
                image = image.resize(300, 300, { fit: 'cover' });
            }
            const ext = operations.format || 'webp';
            const output = outputPath || sourcePath.replace(/\.[^.]+$/, `.optimized.${ext}`);
            await fs.mkdir(path.dirname(output), { recursive: true });
            await image.toFile(output);
            this.logger.log(`Image processed: ${output}`);
            return { success: true, outputPath: output };
        }
        catch (error) {
            this.logger.error(`Failed to process image: ${error.message}`);
            throw error;
        }
    }
    onCompleted(job) {
        this.logger.debug(`Image job ${job.id} completed`);
    }
    onFailed(job, error) {
        this.logger.error(`Image job ${job.id} failed: ${error.message}`);
    }
};
exports.ImageQueueProcessor = ImageQueueProcessor;
__decorate([
    (0, bullmq_1.OnWorkerEvent)('completed'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_a = typeof bullmq_2.Job !== "undefined" && bullmq_2.Job) === "function" ? _a : Object]),
    __metadata("design:returntype", void 0)
], ImageQueueProcessor.prototype, "onCompleted", null);
__decorate([
    (0, bullmq_1.OnWorkerEvent)('failed'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_b = typeof bullmq_2.Job !== "undefined" && bullmq_2.Job) === "function" ? _b : Object, typeof (_c = typeof Error !== "undefined" && Error) === "function" ? _c : Object]),
    __metadata("design:returntype", void 0)
], ImageQueueProcessor.prototype, "onFailed", null);
exports.ImageQueueProcessor = ImageQueueProcessor = ImageQueueProcessor_1 = __decorate([
    (0, bullmq_1.Processor)(queue_service_1.QUEUE_IMAGE),
    __metadata("design:paramtypes", [])
], ImageQueueProcessor);


/***/ }),
/* 36 */
/***/ ((module) => {

module.exports = require("sharp");

/***/ }),
/* 37 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.HealthModule = void 0;
const common_1 = __webpack_require__(2);
const terminus_1 = __webpack_require__(38);
const health_controller_1 = __webpack_require__(39);
const prisma_health_1 = __webpack_require__(40);
const redis_health_1 = __webpack_require__(41);
const prisma_module_1 = __webpack_require__(15);
let HealthModule = class HealthModule {
};
exports.HealthModule = HealthModule;
exports.HealthModule = HealthModule = __decorate([
    (0, common_1.Module)({
        imports: [terminus_1.TerminusModule, prisma_module_1.PrismaModule],
        controllers: [health_controller_1.HealthController],
        providers: [prisma_health_1.PrismaHealthIndicator, redis_health_1.RedisHealthIndicator],
        exports: [prisma_health_1.PrismaHealthIndicator, redis_health_1.RedisHealthIndicator],
    })
], HealthModule);


/***/ }),
/* 38 */
/***/ ((module) => {

module.exports = require("@nestjs/terminus");

/***/ }),
/* 39 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b, _c, _d, _e;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.HealthController = void 0;
const common_1 = __webpack_require__(2);
const terminus_1 = __webpack_require__(38);
const prisma_health_1 = __webpack_require__(40);
const redis_health_1 = __webpack_require__(41);
let HealthController = class HealthController {
    constructor(health, prismaHealth, redisHealth, memory, disk) {
        this.health = health;
        this.prismaHealth = prismaHealth;
        this.redisHealth = redisHealth;
        this.memory = memory;
        this.disk = disk;
    }
    async check() {
        return this.health.check([() => this.prismaHealth.isHealthy('database')]);
    }
    async checkReadiness() {
        return this.health.check([
            () => this.prismaHealth.isHealthy('database'),
            () => this.redisHealth.isHealthy('redis'),
            () => this.memory.checkHeap('memory_heap', 500 * 1024 * 1024),
            () => this.memory.checkRSS('memory_rss', 1024 * 1024 * 1024),
        ]);
    }
    async checkDetailed() {
        return this.health.check([
            () => this.prismaHealth.isHealthy('database'),
            () => this.redisHealth.isHealthy('redis'),
            () => this.memory.checkHeap('memory_heap', 500 * 1024 * 1024),
            () => this.memory.checkRSS('memory_rss', 1024 * 1024 * 1024),
            () => this.disk.checkStorage('disk', {
                path: process.cwd(),
                thresholdPercent: 0.9,
            }),
        ]);
    }
    ping() {
        return {
            status: 'ok',
            timestamp: new Date().toISOString(),
            uptime: process.uptime(),
        };
    }
    info() {
        return {
            version: process.env.npm_package_version || '1.0.0',
            node: process.version,
            platform: process.platform,
            arch: process.arch,
            uptime: process.uptime(),
            memory: process.memoryUsage(),
            env: process.env.NODE_ENV || 'development',
            instance: process.env.INSTANCE_ID || 'primary',
        };
    }
};
exports.HealthController = HealthController;
__decorate([
    (0, common_1.Get)(),
    (0, terminus_1.HealthCheck)(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], HealthController.prototype, "check", null);
__decorate([
    (0, common_1.Get)('ready'),
    (0, terminus_1.HealthCheck)(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], HealthController.prototype, "checkReadiness", null);
__decorate([
    (0, common_1.Get)('detailed'),
    (0, terminus_1.HealthCheck)(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], HealthController.prototype, "checkDetailed", null);
__decorate([
    (0, common_1.Get)('ping'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], HealthController.prototype, "ping", null);
__decorate([
    (0, common_1.Get)('info'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], HealthController.prototype, "info", null);
exports.HealthController = HealthController = __decorate([
    (0, common_1.Controller)('health'),
    __metadata("design:paramtypes", [typeof (_a = typeof terminus_1.HealthCheckService !== "undefined" && terminus_1.HealthCheckService) === "function" ? _a : Object, typeof (_b = typeof prisma_health_1.PrismaHealthIndicator !== "undefined" && prisma_health_1.PrismaHealthIndicator) === "function" ? _b : Object, typeof (_c = typeof redis_health_1.RedisHealthIndicator !== "undefined" && redis_health_1.RedisHealthIndicator) === "function" ? _c : Object, typeof (_d = typeof terminus_1.MemoryHealthIndicator !== "undefined" && terminus_1.MemoryHealthIndicator) === "function" ? _d : Object, typeof (_e = typeof terminus_1.DiskHealthIndicator !== "undefined" && terminus_1.DiskHealthIndicator) === "function" ? _e : Object])
], HealthController);


/***/ }),
/* 40 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PrismaHealthIndicator = void 0;
const common_1 = __webpack_require__(2);
const terminus_1 = __webpack_require__(38);
const prisma_service_1 = __webpack_require__(16);
let PrismaHealthIndicator = class PrismaHealthIndicator extends terminus_1.HealthIndicator {
    constructor(prisma) {
        super();
        this.prisma = prisma;
    }
    async isHealthy(key) {
        try {
            const start = Date.now();
            await this.prisma.$queryRaw `SELECT 1`;
            const responseTime = Date.now() - start;
            return this.getStatus(key, true, { responseTime });
        }
        catch (error) {
            throw new terminus_1.HealthCheckError('Database check failed', this.getStatus(key, false, { error: error.message }));
        }
    }
};
exports.PrismaHealthIndicator = PrismaHealthIndicator;
exports.PrismaHealthIndicator = PrismaHealthIndicator = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], PrismaHealthIndicator);


/***/ }),
/* 41 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.RedisHealthIndicator = void 0;
const common_1 = __webpack_require__(2);
const terminus_1 = __webpack_require__(38);
const redis_service_1 = __webpack_require__(19);
let RedisHealthIndicator = class RedisHealthIndicator extends terminus_1.HealthIndicator {
    constructor(redis) {
        super();
        this.redis = redis;
    }
    async isHealthy(key) {
        if (!this.redis) {
            return this.getStatus(key, true, { status: 'not_configured' });
        }
        if (!this.redis.isAvailable()) {
            return this.getStatus(key, true, { status: 'unavailable' });
        }
        try {
            const start = Date.now();
            const client = this.redis.getClient();
            if (client) {
                await client.ping();
                const responseTime = Date.now() - start;
                return this.getStatus(key, true, { responseTime, status: 'connected' });
            }
            return this.getStatus(key, true, { status: 'not_connected' });
        }
        catch (error) {
            return this.getStatus(key, true, { status: 'error', error: error.message });
        }
    }
};
exports.RedisHealthIndicator = RedisHealthIndicator;
exports.RedisHealthIndicator = RedisHealthIndicator = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, common_1.Optional)()),
    __metadata("design:paramtypes", [typeof (_a = typeof redis_service_1.RedisService !== "undefined" && redis_service_1.RedisService) === "function" ? _a : Object])
], RedisHealthIndicator);


/***/ }),
/* 42 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.AuthModule = void 0;
const common_1 = __webpack_require__(2);
const jwt_1 = __webpack_require__(43);
const passport_1 = __webpack_require__(44);
const config_1 = __webpack_require__(13);
const auth_service_1 = __webpack_require__(45);
const auth_controller_1 = __webpack_require__(56);
const jwt_strategy_1 = __webpack_require__(64);
const local_strategy_1 = __webpack_require__(66);
const users_module_1 = __webpack_require__(68);
const prisma_module_1 = __webpack_require__(15);
const email_module_1 = __webpack_require__(77);
let AuthModule = class AuthModule {
};
exports.AuthModule = AuthModule;
exports.AuthModule = AuthModule = __decorate([
    (0, common_1.Module)({
        imports: [
            users_module_1.UsersModule,
            passport_1.PassportModule,
            prisma_module_1.PrismaModule,
            email_module_1.EmailModule,
            jwt_1.JwtModule.registerAsync({
                imports: [config_1.ConfigModule],
                useFactory: async (configService) => ({
                    secret: configService.get('JWT_SECRET') || 'default-secret-change-in-production',
                    signOptions: {
                        expiresIn: 604800,
                    },
                }),
                inject: [config_1.ConfigService],
            }),
        ],
        providers: [auth_service_1.AuthService, jwt_strategy_1.JwtStrategy, local_strategy_1.LocalStrategy],
        controllers: [auth_controller_1.AuthController],
        exports: [auth_service_1.AuthService],
    })
], AuthModule);


/***/ }),
/* 43 */
/***/ ((module) => {

module.exports = require("@nestjs/jwt");

/***/ }),
/* 44 */
/***/ ((module) => {

module.exports = require("@nestjs/passport");

/***/ }),
/* 45 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b, _c, _d, _e;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.AuthService = void 0;
const common_1 = __webpack_require__(2);
const jwt_1 = __webpack_require__(43);
const config_1 = __webpack_require__(13);
const bcrypt = __webpack_require__(46);
const speakeasy = __webpack_require__(47);
const crypto = __webpack_require__(48);
const users_service_1 = __webpack_require__(49);
const prisma_service_1 = __webpack_require__(16);
const client_1 = __webpack_require__(17);
const email_service_1 = __webpack_require__(50);
const password_reset_template_1 = __webpack_require__(54);
let AuthService = class AuthService {
    constructor(usersService, jwtService, prisma, emailService, configService) {
        this.usersService = usersService;
        this.jwtService = jwtService;
        this.prisma = prisma;
        this.emailService = emailService;
        this.configService = configService;
        this.MAX_FAILED_ATTEMPTS = 50;
        this.LOCKOUT_DURATION_MINUTES = 1;
        this.PASSWORD_RESET_EXPIRY_HOURS = 1;
    }
    async validateUser(email, password) {
        const user = await this.usersService.findByEmail(email);
        if (!user) {
            return null;
        }
        const isPasswordValid = await bcrypt.compare(password, user.password);
        if (!isPasswordValid) {
            return null;
        }
        const { password: _password, ...result } = user;
        void _password;
        return result;
    }
    async login(loginDto, ip, userAgent) {
        const user = await this.usersService.findByEmail(loginDto.email);
        if (user && user.accountLockedUntil && user.accountLockedUntil > new Date()) {
            await this.logSecurityEvent(user.id, client_1.SecurityEventType.LOCKOUT_TRIGGERED, ip, userAgent);
            const minutesLeft = Math.ceil((user.accountLockedUntil.getTime() - Date.now()) / 60000);
            throw new common_1.UnauthorizedException(`Account is locked due to too many failed login attempts. Try again in ${minutesLeft} minutes.`);
        }
        const validatedUser = await this.validateUser(loginDto.email, loginDto.password);
        if (!validatedUser) {
            if (user) {
                await this.handleFailedLogin(user.id, ip, userAgent);
            }
            else {
                await this.logSecurityEvent(null, client_1.SecurityEventType.FAILED_LOGIN, ip, userAgent, {
                    email: loginDto.email,
                });
            }
            throw new common_1.UnauthorizedException('Invalid credentials');
        }
        if (validatedUser.twoFactorEnabled) {
            return {
                requires2FA: true,
                tempToken: this.jwtService.sign({ email: validatedUser.email, sub: validatedUser.id, temp: true }, { expiresIn: '5m' }),
                user: {
                    id: validatedUser.id,
                    email: validatedUser.email,
                    name: validatedUser.name,
                },
            };
        }
        await this.handleSuccessfulLogin(validatedUser.id, ip);
        const payload = { email: validatedUser.email, sub: validatedUser.id, role: validatedUser.role };
        return {
            access_token: this.jwtService.sign(payload),
            user: {
                id: validatedUser.id,
                email: validatedUser.email,
                name: validatedUser.name,
                role: validatedUser.role,
                twoFactorEnabled: validatedUser.twoFactorEnabled,
            },
        };
    }
    async register(registerDto) {
        const hashedPassword = await bcrypt.hash(registerDto.password, 10);
        const user = await this.usersService.create({
            ...registerDto,
            password: hashedPassword,
        });
        return user;
    }
    async verifyToken(token) {
        try {
            return this.jwtService.verify(token);
        }
        catch (_error) {
            throw new common_1.UnauthorizedException('Invalid token');
        }
    }
    async verify2FAAndLogin(tempToken, twoFactorCode, ip, userAgent) {
        let payload;
        try {
            payload = this.jwtService.verify(tempToken);
            if (!payload.temp) {
                throw new Error('Invalid token');
            }
        }
        catch (_error) {
            throw new common_1.UnauthorizedException('Invalid or expired token');
        }
        const user = await this.usersService.findById(payload.sub);
        if (!user || !user.twoFactorEnabled || !user.twoFactorSecret) {
            throw new common_1.UnauthorizedException('2FA not configured');
        }
        const isValid = speakeasy.totp.verify({
            secret: user.twoFactorSecret,
            encoding: 'base32',
            token: twoFactorCode,
            window: 2,
        });
        if (!isValid) {
            let recoveryCodeValid = false;
            if (user.recoveryCodes && Array.isArray(user.recoveryCodes)) {
                for (const hashedCode of user.recoveryCodes) {
                    const matches = await bcrypt.compare(twoFactorCode, hashedCode);
                    if (matches) {
                        recoveryCodeValid = true;
                        const updatedCodes = user.recoveryCodes.filter((code) => code !== hashedCode);
                        await this.prisma.user.update({
                            where: { id: user.id },
                            data: { recoveryCodes: updatedCodes },
                        });
                        break;
                    }
                }
            }
            if (!recoveryCodeValid) {
                await this.logSecurityEvent(user.id, client_1.SecurityEventType.FAILED_2FA, ip, userAgent);
                throw new common_1.UnauthorizedException('Invalid 2FA code');
            }
        }
        await this.handleSuccessfulLogin(user.id, ip);
        const finalPayload = { email: user.email, sub: user.id, role: user.role };
        return {
            access_token: this.jwtService.sign(finalPayload),
            user: {
                id: user.id,
                email: user.email,
                name: user.name,
                role: user.role,
                twoFactorEnabled: user.twoFactorEnabled,
            },
        };
    }
    async handleFailedLogin(userId, ip, userAgent) {
        const user = await this.prisma.user.findUnique({ where: { id: userId } });
        if (!user)
            return;
        const failedAttempts = user.failedLoginAttempts + 1;
        const updateData = {
            failedLoginAttempts: failedAttempts,
            lastFailedLogin: new Date(),
        };
        if (failedAttempts >= this.MAX_FAILED_ATTEMPTS) {
            const lockoutUntil = new Date(Date.now() + this.LOCKOUT_DURATION_MINUTES * 60 * 1000);
            updateData.accountLockedUntil = lockoutUntil;
            await this.logSecurityEvent(userId, client_1.SecurityEventType.LOCKOUT_TRIGGERED, ip, userAgent, {
                failedAttempts,
                lockoutUntil,
            });
        }
        await this.prisma.user.update({
            where: { id: userId },
            data: updateData,
        });
        await this.logSecurityEvent(userId, client_1.SecurityEventType.FAILED_LOGIN, ip, userAgent);
    }
    async handleSuccessfulLogin(userId, ip) {
        await this.prisma.user.update({
            where: { id: userId },
            data: {
                failedLoginAttempts: 0,
                accountLockedUntil: null,
                lastLoginAt: new Date(),
                lastLoginIp: ip,
            },
        });
        await this.logSecurityEvent(userId, client_1.SecurityEventType.SUCCESS_LOGIN, ip);
    }
    async logSecurityEvent(userId, type, ip, userAgent, metadata) {
        try {
            await this.prisma.securityEvent.create({
                data: {
                    userId,
                    type,
                    ip,
                    userAgent,
                    metadata: metadata || {},
                },
            });
        }
        catch (error) {
            console.error('Failed to log security event:', error);
        }
    }
    async forgotPassword(email) {
        const user = await this.prisma.user.findUnique({
            where: { email: email.toLowerCase() },
        });
        const successMessage = {
            message: 'If an account with that email exists, a password reset link has been sent.',
        };
        if (!user) {
            return successMessage;
        }
        const resetToken = crypto.randomBytes(32).toString('hex');
        const hashedToken = crypto.createHash('sha256').update(resetToken).digest('hex');
        const expiresAt = new Date(Date.now() + this.PASSWORD_RESET_EXPIRY_HOURS * 60 * 60 * 1000);
        await this.prisma.user.update({
            where: { id: user.id },
            data: {
                passwordResetToken: hashedToken,
                passwordResetExpires: expiresAt,
            },
        });
        const siteContext = await this.emailService.getSiteContext();
        const resetUrl = `${siteContext.adminUrl}/reset-password?token=${resetToken}`;
        const supportUrl = `mailto:${siteContext.supportEmail}`;
        const emailHtml = (0, password_reset_template_1.getPasswordResetTemplate)({
            user: { firstName: user.name.split(' ')[0] || user.name },
            resetUrl,
            expiresIn: `${this.PASSWORD_RESET_EXPIRY_HOURS} hour`,
            supportUrl,
        });
        try {
            await this.emailService.send({
                to: user.email,
                toName: user.name,
                subject: 'Reset Your Password',
                html: emailHtml,
                recipientId: user.id,
                metadata: { type: 'password_reset' },
            });
            await this.logSecurityEvent(user.id, client_1.SecurityEventType.PASSWORD_RESET_REQUESTED, undefined, undefined, { email: user.email });
        }
        catch (error) {
            console.error('Failed to send password reset email:', error);
        }
        return successMessage;
    }
    async resetPassword(token, newPassword) {
        const hashedToken = crypto.createHash('sha256').update(token).digest('hex');
        const user = await this.prisma.user.findFirst({
            where: {
                passwordResetToken: hashedToken,
                passwordResetExpires: {
                    gt: new Date(),
                },
            },
        });
        if (!user) {
            throw new common_1.BadRequestException('Invalid or expired password reset token');
        }
        this.validatePasswordStrength(newPassword);
        const hashedPassword = await bcrypt.hash(newPassword, 10);
        await this.prisma.user.update({
            where: { id: user.id },
            data: {
                password: hashedPassword,
                passwordResetToken: null,
                passwordResetExpires: null,
                failedLoginAttempts: 0,
                accountLockedUntil: null,
            },
        });
        await this.prisma.passwordHistory.create({
            data: {
                userId: user.id,
                password: hashedPassword,
            },
        });
        await this.logSecurityEvent(user.id, client_1.SecurityEventType.PASSWORD_CHANGE, undefined, undefined, {
            method: 'reset_token',
        });
        return {
            message: 'Password has been reset successfully. You can now log in with your new password.',
        };
    }
    validatePasswordStrength(password) {
        const minLength = 8;
        const hasUppercase = /[A-Z]/.test(password);
        const hasLowercase = /[a-z]/.test(password);
        const hasNumber = /[0-9]/.test(password);
        const hasSpecial = /[!@#$%^&*()_+\-=\[\]{};\':"|,.<>\/?`~]/.test(password);
        const errors = [];
        if (password.length < minLength) {
            errors.push(`Password must be at least ${minLength} characters long`);
        }
        if (!hasUppercase) {
            errors.push('Password must contain at least one uppercase letter');
        }
        if (!hasLowercase) {
            errors.push('Password must contain at least one lowercase letter');
        }
        if (!hasNumber) {
            errors.push('Password must contain at least one number');
        }
        if (!hasSpecial) {
            errors.push('Password must contain at least one special character');
        }
        if (errors.length > 0) {
            throw new common_1.BadRequestException(errors.join('. '));
        }
    }
};
exports.AuthService = AuthService;
exports.AuthService = AuthService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof users_service_1.UsersService !== "undefined" && users_service_1.UsersService) === "function" ? _a : Object, typeof (_b = typeof jwt_1.JwtService !== "undefined" && jwt_1.JwtService) === "function" ? _b : Object, typeof (_c = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _c : Object, typeof (_d = typeof email_service_1.EmailService !== "undefined" && email_service_1.EmailService) === "function" ? _d : Object, typeof (_e = typeof config_1.ConfigService !== "undefined" && config_1.ConfigService) === "function" ? _e : Object])
], AuthService);


/***/ }),
/* 46 */
/***/ ((module) => {

module.exports = require("bcrypt");

/***/ }),
/* 47 */
/***/ ((module) => {

module.exports = require("speakeasy");

/***/ }),
/* 48 */
/***/ ((module) => {

module.exports = require("crypto");

/***/ }),
/* 49 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UsersService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const bcrypt = __webpack_require__(46);
let UsersService = class UsersService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async create(createUserDto) {
        const existingUser = await this.prisma.user.findUnique({
            where: { email: createUserDto.email },
        });
        if (existingUser) {
            throw new common_1.ConflictException('User with this email already exists');
        }
        return this.prisma.user.create({
            data: createUserDto,
            select: {
                id: true,
                email: true,
                name: true,
                role: true,
                avatar: true,
                bio: true,
                createdAt: true,
                updatedAt: true,
            },
        });
    }
    async findAll(page = 1, limit = 10, search) {
        const skip = (page - 1) * limit;
        const where = search
            ? {
                OR: [
                    { name: { contains: search, mode: 'insensitive' } },
                    { email: { contains: search, mode: 'insensitive' } },
                ],
            }
            : {};
        const [users, total] = await Promise.all([
            this.prisma.user.findMany({
                where,
                skip,
                take: limit,
                select: {
                    id: true,
                    email: true,
                    name: true,
                    role: true,
                    avatar: true,
                    createdAt: true,
                    updatedAt: true,
                },
                orderBy: { createdAt: 'desc' },
            }),
            this.prisma.user.count({ where }),
        ]);
        return {
            users,
            meta: {
                total,
                page,
                limit,
                totalPages: Math.ceil(total / limit),
            },
        };
    }
    async findById(id) {
        const user = await this.prisma.user.findUnique({
            where: { id },
        });
        if (!user) {
            throw new common_1.NotFoundException('User not found');
        }
        return user;
    }
    async findByEmail(email) {
        return this.prisma.user.findUnique({
            where: { email },
        });
    }
    async update(id, updateUserDto) {
        await this.findById(id);
        if (updateUserDto.password) {
            updateUserDto.password = await bcrypt.hash(updateUserDto.password, 10);
        }
        return this.prisma.user.update({
            where: { id },
            data: updateUserDto,
            select: {
                id: true,
                email: true,
                name: true,
                role: true,
                avatar: true,
                bio: true,
                createdAt: true,
                updatedAt: true,
            },
        });
    }
    async remove(id) {
        await this.findById(id);
        return this.prisma.user.delete({
            where: { id },
        });
    }
};
exports.UsersService = UsersService;
exports.UsersService = UsersService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], UsersService);


/***/ }),
/* 50 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 EmailService_1;
var _a, _b, _c;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.EmailService = void 0;
const common_1 = __webpack_require__(2);
const config_1 = __webpack_require__(13);
const nodemailer = __webpack_require__(34);
const Handlebars = __webpack_require__(51);
const prisma_service_1 = __webpack_require__(16);
const client_1 = __webpack_require__(17);
const system_config_service_1 = __webpack_require__(52);
let EmailService = EmailService_1 = class EmailService {
    constructor(configService, prisma, systemConfig) {
        this.configService = configService;
        this.prisma = prisma;
        this.systemConfig = systemConfig;
        this.logger = new common_1.Logger(EmailService_1.name);
        this.transporter = null;
        this.defaultFrom = '';
        this.defaultFromName = 'WordPress Node CMS';
        this.smtpConfig = null;
    }
    async onModuleInit() {
        await this.initializeTransporter();
    }
    async initializeTransporter() {
        try {
            this.smtpConfig = await this.systemConfig.getSmtpConfig();
        }
        catch {
            this.smtpConfig = {
                host: this.configService.get('SMTP_HOST', 'smtp.gmail.com'),
                port: parseInt(this.configService.get('SMTP_PORT', '587'), 10),
                secure: this.configService.get('SMTP_SECURE', 'false') === 'true',
                user: this.configService.get('SMTP_USER', ''),
                pass: this.configService.get('SMTP_PASS', ''),
                fromEmail: this.configService.get('SMTP_FROM', ''),
                fromName: this.configService.get('SMTP_FROM_NAME', 'WordPress Node CMS'),
            };
        }
        this.defaultFrom = this.smtpConfig.fromEmail || this.smtpConfig.user;
        this.defaultFromName = this.smtpConfig.fromName;
        if (!this.smtpConfig.user || !this.smtpConfig.pass) {
            this.logger.warn('SMTP credentials not configured. Email sending will fail.');
            this.transporter = null;
            return;
        }
        this.transporter = nodemailer.createTransport({
            host: this.smtpConfig.host,
            port: this.smtpConfig.port,
            secure: this.smtpConfig.secure,
            auth: { user: this.smtpConfig.user, pass: this.smtpConfig.pass },
        });
        this.logger.log(`Email transporter initialized: ${this.smtpConfig.host}:${this.smtpConfig.port}`);
    }
    async reloadConfig() {
        await this.initializeTransporter();
    }
    async send(options) {
        const fromEmail = options.from || this.defaultFrom;
        const fromName = options.fromName || this.defaultFromName;
        const emailLog = await this.prisma.emailLog.create({
            data: {
                templateId: options.templateId,
                recipientId: options.recipientId,
                toEmail: options.to,
                toName: options.toName,
                fromEmail,
                fromName,
                subject: options.subject,
                htmlContent: options.html,
                textContent: options.text,
                status: client_1.EmailStatus.PENDING,
                metadata: options.metadata,
            },
        });
        if (!this.transporter) {
            await this.prisma.emailLog.update({
                where: { id: emailLog.id },
                data: {
                    status: client_1.EmailStatus.FAILED,
                    failedAt: new Date(),
                    errorMessage: 'SMTP transporter not configured',
                },
            });
            return { success: false, error: 'SMTP not configured', logId: emailLog.id };
        }
        try {
            const result = await this.transporter.sendMail({
                from: `"${fromName}" <${fromEmail}>`,
                to: options.toName ? `"${options.toName}" <${options.to}>` : options.to,
                subject: options.subject,
                html: options.html,
                text: options.text || this.htmlToText(options.html),
            });
            await this.prisma.emailLog.update({
                where: { id: emailLog.id },
                data: {
                    status: client_1.EmailStatus.SENT,
                    sentAt: new Date(),
                    providerMessageId: result.messageId,
                    providerResponse: result,
                },
            });
            this.logger.log(`Email sent to ${options.to}: ${result.messageId}`);
            return { success: true, messageId: result.messageId, logId: emailLog.id };
        }
        catch (error) {
            const errorMessage = error instanceof Error ? error.message : 'Unknown error';
            await this.prisma.emailLog.update({
                where: { id: emailLog.id },
                data: {
                    status: client_1.EmailStatus.FAILED,
                    failedAt: new Date(),
                    errorMessage,
                },
            });
            this.logger.error(`Failed to send email to ${options.to}: ${errorMessage}`);
            return { success: false, error: errorMessage, logId: emailLog.id };
        }
    }
    renderTemplate(template, variables) {
        const compiled = Handlebars.compile(template);
        return compiled(variables);
    }
    async getSiteContext() {
        const domainConfig = await this.systemConfig.getDomainConfig();
        return {
            site: {
                name: domainConfig.siteName || 'WordPress Node CMS',
                logo: undefined,
                address: undefined,
            },
            year: new Date().getFullYear(),
            loginUrl: `${domainConfig.adminUrl}/login`,
            supportEmail: domainConfig.supportEmail || 'support@example.com',
            helpUrl: `${domainConfig.frontendUrl}/help`,
            frontendUrl: domainConfig.frontendUrl,
            adminUrl: domainConfig.adminUrl,
        };
    }
    htmlToText(html) {
        return html
            .replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '')
            .replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
            .replace(/<[^>]+>/g, ' ')
            .replace(/\s+/g, ' ')
            .trim();
    }
    async verifyConnection() {
        if (!this.transporter)
            return false;
        try {
            await this.transporter.verify();
            return true;
        }
        catch {
            return false;
        }
    }
};
exports.EmailService = EmailService;
exports.EmailService = EmailService = EmailService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof config_1.ConfigService !== "undefined" && config_1.ConfigService) === "function" ? _a : Object, typeof (_b = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _b : Object, typeof (_c = typeof system_config_service_1.SystemConfigService !== "undefined" && system_config_service_1.SystemConfigService) === "function" ? _c : Object])
], EmailService);


/***/ }),
/* 51 */
/***/ ((module) => {

module.exports = require("handlebars");

/***/ }),
/* 52 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 SystemConfigService_1;
var _a, _b, _c;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SystemConfigService = void 0;
const common_1 = __webpack_require__(2);
const config_1 = __webpack_require__(13);
const prisma_service_1 = __webpack_require__(16);
const encryption_service_1 = __webpack_require__(53);
const ENCRYPTED_KEYS = [
    'smtp_pass',
    'api_key',
    'webhook_secret',
    'stripe_secret_key',
    'stripe_webhook_secret',
];
let SystemConfigService = SystemConfigService_1 = class SystemConfigService {
    constructor(prisma, encryption, configService) {
        this.prisma = prisma;
        this.encryption = encryption;
        this.configService = configService;
        this.logger = new common_1.Logger(SystemConfigService_1.name);
        this.configCache = new Map();
    }
    async onModuleInit() {
        await this.loadConfigCache();
    }
    async loadConfigCache() {
        try {
            const configs = await this.prisma.systemConfig.findMany();
            for (const config of configs) {
                const value = config.isEncrypted ? this.encryption.decrypt(config.value) : config.value;
                this.configCache.set(config.key, value);
            }
            this.logger.log(`Loaded ${configs.length} system config values`);
        }
        catch (_error) {
            this.logger.warn('Failed to load system config cache (table may not exist yet)');
        }
    }
    async get(key, defaultValue) {
        if (this.configCache.has(key)) {
            return this.configCache.get(key);
        }
        const config = await this.prisma.systemConfig.findUnique({ where: { key } });
        if (config) {
            const value = config.isEncrypted ? this.encryption.decrypt(config.value) : config.value;
            this.configCache.set(key, value);
            return value;
        }
        const envKey = key.toUpperCase();
        const envValue = this.configService.get(envKey);
        if (envValue)
            return envValue;
        return defaultValue || '';
    }
    async set(key, value, group, description) {
        const shouldEncrypt = ENCRYPTED_KEYS.includes(key);
        const storedValue = shouldEncrypt ? this.encryption.encrypt(value) : value;
        await this.prisma.systemConfig.upsert({
            where: { key },
            update: { value: storedValue, isEncrypted: shouldEncrypt, group, description },
            create: { key, value: storedValue, isEncrypted: shouldEncrypt, group, description },
        });
        this.configCache.set(key, value);
        this.logger.log(`Config updated: ${key} (group: ${group})`);
    }
    async delete(key) {
        await this.prisma.systemConfig.delete({ where: { key } }).catch(() => { });
        this.configCache.delete(key);
    }
    async getGroup(group) {
        const configs = await this.prisma.systemConfig.findMany({ where: { group } });
        const result = {};
        for (const config of configs) {
            result[config.key] = config.isEncrypted
                ? this.encryption.decrypt(config.value)
                : config.value;
        }
        return result;
    }
    async getSmtpConfig() {
        return {
            host: await this.get('smtp_host', this.configService.get('SMTP_HOST', 'smtp.gmail.com')),
            port: parseInt(await this.get('smtp_port', this.configService.get('SMTP_PORT', '587')), 10),
            secure: (await this.get('smtp_secure', 'false')) === 'true',
            user: await this.get('smtp_user', this.configService.get('SMTP_USER', '')),
            pass: await this.get('smtp_pass', this.configService.get('SMTP_PASS', '')),
            fromEmail: await this.get('smtp_from', this.configService.get('SMTP_FROM', '')),
            fromName: await this.get('smtp_from_name', this.configService.get('SMTP_FROM_NAME', 'WordPress Node CMS')),
        };
    }
    async saveSmtpConfig(config) {
        await this.set('smtp_host', config.host, 'email', 'SMTP server hostname');
        await this.set('smtp_port', config.port.toString(), 'email', 'SMTP server port');
        await this.set('smtp_secure', config.secure.toString(), 'email', 'Use TLS/SSL');
        await this.set('smtp_user', config.user, 'email', 'SMTP username');
        if (config.pass) {
            await this.set('smtp_pass', config.pass, 'email', 'SMTP password (encrypted)');
        }
        await this.set('smtp_from', config.fromEmail || config.user, 'email', 'Default from email');
        await this.set('smtp_from_name', config.fromName || 'WordPress Node CMS', 'email', 'Default from name');
    }
    async getDomainConfig() {
        return {
            frontendUrl: await this.get('frontend_url', this.configService.get('FRONTEND_URL', 'http://localhost:3000')),
            adminUrl: await this.get('admin_url', this.configService.get('ADMIN_URL', 'http://localhost:3000/admin')),
            supportEmail: await this.get('support_email', this.configService.get('SUPPORT_EMAIL', '')),
            siteName: await this.get('site_name', this.configService.get('SITE_NAME', 'WordPress Node CMS')),
        };
    }
    async saveDomainConfig(config) {
        await this.set('frontend_url', config.frontendUrl, 'domain', 'Frontend URL');
        await this.set('admin_url', config.adminUrl, 'domain', 'Admin panel URL');
        await this.set('support_email', config.supportEmail, 'domain', 'Support email address');
        await this.set('site_name', config.siteName, 'domain', 'Site name');
    }
    async getMarketplaceConfig() {
        return {
            platformFeePercent: parseFloat(await this.get('marketplace_fee_percent', '10')),
            minPayoutAmount: parseFloat(await this.get('marketplace_min_payout', '10')),
            maxEscrowDays: parseInt(await this.get('marketplace_max_escrow_days', '90'), 10),
            autoReleaseDays: parseInt(await this.get('marketplace_auto_release_days', '14'), 10),
            enabled: (await this.get('marketplace_enabled', 'true')) === 'true',
        };
    }
    async saveMarketplaceConfig(config) {
        await this.set('marketplace_fee_percent', config.platformFeePercent.toString(), 'marketplace', 'Platform fee percentage');
        await this.set('marketplace_min_payout', config.minPayoutAmount.toString(), 'marketplace', 'Minimum payout amount');
        await this.set('marketplace_max_escrow_days', config.maxEscrowDays.toString(), 'marketplace', 'Maximum escrow days');
        await this.set('marketplace_auto_release_days', config.autoReleaseDays.toString(), 'marketplace', 'Auto-release days after completion');
        await this.set('marketplace_enabled', config.enabled.toString(), 'marketplace', 'Marketplace enabled');
    }
    async getPlatformFeePercent() {
        return parseFloat(await this.get('marketplace_fee_percent', '10'));
    }
    async getStripeConfig() {
        const publishableKey = await this.get('stripe_publishable_key', this.configService.get('STRIPE_PUBLISHABLE_KEY', ''));
        const secretKey = await this.get('stripe_secret_key', this.configService.get('STRIPE_SECRET_KEY', ''));
        const webhookSecret = await this.get('stripe_webhook_secret', this.configService.get('STRIPE_WEBHOOK_SECRET', ''));
        const isLiveMode = publishableKey.startsWith('pk_live_') || secretKey.startsWith('sk_live_');
        const isConfigured = !!(publishableKey && secretKey);
        return {
            publishableKey,
            secretKey,
            webhookSecret,
            isLiveMode,
            isConfigured,
        };
    }
    async saveStripeConfig(config) {
        if (config.publishableKey) {
            await this.set('stripe_publishable_key', config.publishableKey, 'payment', 'Stripe publishable key');
        }
        if (config.secretKey) {
            await this.set('stripe_secret_key', config.secretKey, 'payment', 'Stripe secret key (encrypted)');
        }
        if (config.webhookSecret) {
            await this.set('stripe_webhook_secret', config.webhookSecret, 'payment', 'Stripe webhook secret (encrypted)');
        }
    }
    async isSetupComplete() {
        try {
            const status = await this.prisma.setupStatus.findFirst();
            return status?.setupComplete ?? false;
        }
        catch {
            return false;
        }
    }
    async markSetupComplete() {
        await this.prisma.setupStatus.upsert({
            where: { id: 'setup' },
            update: { setupComplete: true, completedAt: new Date() },
            create: {
                id: 'setup',
                setupComplete: true,
                adminCreated: true,
                smtpConfigured: true,
                completedAt: new Date(),
            },
        });
    }
    async getSetupStatus() {
        let status = await this.prisma.setupStatus.findFirst();
        if (!status) {
            const adminExists = await this.prisma.user.findFirst({ where: { role: 'ADMIN' } });
            status = await this.prisma.setupStatus.create({
                data: {
                    id: 'setup',
                    adminCreated: !!adminExists,
                    setupComplete: false,
                },
            });
        }
        return status;
    }
    async invalidateCache() {
        this.configCache.clear();
        await this.loadConfigCache();
    }
};
exports.SystemConfigService = SystemConfigService;
exports.SystemConfigService = SystemConfigService = SystemConfigService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof encryption_service_1.EncryptionService !== "undefined" && encryption_service_1.EncryptionService) === "function" ? _b : Object, typeof (_c = typeof config_1.ConfigService !== "undefined" && config_1.ConfigService) === "function" ? _c : Object])
], SystemConfigService);


/***/ }),
/* 53 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 EncryptionService_1;
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.EncryptionService = void 0;
const common_1 = __webpack_require__(2);
const config_1 = __webpack_require__(13);
const crypto = __webpack_require__(48);
let EncryptionService = EncryptionService_1 = class EncryptionService {
    constructor(configService) {
        this.configService = configService;
        this.logger = new common_1.Logger(EncryptionService_1.name);
        this.algorithm = 'aes-256-gcm';
        this.ivLength = 16;
        this.authTagLength = 16;
    }
    onModuleInit() {
        this.initializeKey();
    }
    initializeKey() {
        let keySource = this.configService.get('ENCRYPTION_KEY');
        if (!keySource) {
            keySource = this.configService.get('JWT_SECRET');
            if (keySource) {
                this.logger.warn('ENCRYPTION_KEY not set, deriving from JWT_SECRET. Set ENCRYPTION_KEY for production.');
            }
        }
        if (!keySource) {
            this.logger.error('No encryption key available! Using random key - data will not persist across restarts!');
            this.encryptionKey = crypto.randomBytes(32);
            return;
        }
        this.encryptionKey = crypto.pbkdf2Sync(keySource, 'wordpress-node-salt', 100000, 32, 'sha256');
        this.logger.log('Encryption service initialized');
    }
    encrypt(plaintext) {
        if (!plaintext)
            return '';
        const iv = crypto.randomBytes(this.ivLength);
        const cipher = crypto.createCipheriv(this.algorithm, this.encryptionKey, iv);
        let encrypted = cipher.update(plaintext, 'utf8', 'base64');
        encrypted += cipher.final('base64');
        const authTag = cipher.getAuthTag();
        return `${iv.toString('base64')}:${authTag.toString('base64')}:${encrypted}`;
    }
    decrypt(ciphertext) {
        if (!ciphertext)
            return '';
        try {
            const parts = ciphertext.split(':');
            if (parts.length !== 3) {
                throw new Error('Invalid encrypted format');
            }
            const iv = Buffer.from(parts[0], 'base64');
            const authTag = Buffer.from(parts[1], 'base64');
            const encrypted = parts[2];
            const decipher = crypto.createDecipheriv(this.algorithm, this.encryptionKey, iv);
            decipher.setAuthTag(authTag);
            let decrypted = decipher.update(encrypted, 'base64', 'utf8');
            decrypted += decipher.final('utf8');
            return decrypted;
        }
        catch (error) {
            this.logger.error(`Decryption failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
            throw new Error('Failed to decrypt value');
        }
    }
    generateToken(length = 32) {
        return crypto.randomBytes(length).toString('hex');
    }
    hash(value) {
        return crypto.createHash('sha256').update(value).digest('hex');
    }
};
exports.EncryptionService = EncryptionService;
exports.EncryptionService = EncryptionService = EncryptionService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof config_1.ConfigService !== "undefined" && config_1.ConfigService) === "function" ? _a : Object])
], EncryptionService);


/***/ }),
/* 54 */
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getPasswordResetTemplate = getPasswordResetTemplate;
const base_template_1 = __webpack_require__(55);
function getPasswordResetTemplate(data) {
    const { user, resetUrl, expiresIn, supportUrl } = data;
    const content = `
<!-- Hero Section -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="text-align: center; padding-bottom: 32px;">
      <div style="width: 100px; height: 100px; margin: 0 auto 20px; background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 48px; box-shadow: 0 8px 16px rgba(245, 158, 11, 0.2);">
        🔐
      </div>
      <h1 style="margin: 0 0 12px; font-size: 32px; font-weight: 800; color: #111827; letter-spacing: -1px;">
        Reset Your Password
      </h1>
      <p style="margin: 0; font-size: 16px; color: #6b7280;">
        Secure your account with a new password
      </p>
    </td>
  </tr>
</table>

<!-- Main Message -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="padding-bottom: 32px;">
      <p style="margin: 0 0 16px; font-size: 16px; line-height: 1.8; color: #374151;">
        Hi {{user.firstName}},
      </p>
      <p style="margin: 0; font-size: 16px; line-height: 1.8; color: #374151;">
        We received a request to reset your password. Click the button below to create a new, secure password for your account.
      </p>
    </td>
  </tr>
</table>

<!-- CTA Button -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="text-align: center; padding-bottom: 32px;">
      <a href="{{resetUrl}}" style="display: inline-block; padding: 16px 40px; background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); color: #ffffff; font-size: 16px; font-weight: 700; text-decoration: none; border-radius: 8px; box-shadow: 0 8px 16px rgba(245, 158, 11, 0.3);">
        Reset Password Now
      </a>
    </td>
  </tr>
</table>

<!-- Security Alert -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="padding-bottom: 32px;">
      <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
        <tr>
          <td style="background: linear-gradient(135deg, #fef3c7 0%, #fef08a 100%); border-left: 4px solid #f59e0b; border-radius: 8px; padding: 20px;">
            <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
              <tr>
                <td style="width: 30px; vertical-align: top; padding-right: 12px; font-size: 20px;">⏰</td>
                <td style="vertical-align: top;">
                  <p style="margin: 0 0 8px; font-size: 14px; font-weight: 700; color: #92400e;">
                    Link Expires in {{expiresIn}}
                  </p>
                  <p style="margin: 0; font-size: 13px; color: #b45309; line-height: 1.6;">
                    For security reasons, this password reset link will expire after {{expiresIn}}. If you don't reset your password within this time, you'll need to request a new link.
                  </p>
                </td>
              </tr>
            </table>
          </td>
        </tr>
      </table>
    </td>
  </tr>
</table>

<!-- Security Tips -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="padding-bottom: 32px;">
      <h3 style="margin: 0 0 16px; font-size: 16px; font-weight: 700; color: #111827;">🛡️ Security Tips</h3>
      <ul style="margin: 0; padding-left: 20px; color: #6b7280; font-size: 14px; line-height: 1.8;">
        <li style="margin-bottom: 8px;">Use a strong password with uppercase, lowercase, numbers, and symbols</li>
        <li style="margin-bottom: 8px;">Never share your password with anyone</li>
        <li>If you didn't request this reset, your account may be at risk. Contact support immediately.</li>
      </ul>
    </td>
  </tr>
</table>

<!-- Fallback Link -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="padding-bottom: 24px; border-top: 1px solid #e5e7eb; padding-top: 24px;">
      <p style="margin: 0 0 12px; font-size: 13px; color: #6b7280;">
        If the button above doesn't work, copy and paste this link into your browser:
      </p>
      <p style="margin: 0; font-size: 12px; color: #9ca3af; word-break: break-all; background-color: #f3f4f6; padding: 12px; border-radius: 6px; font-family: monospace;">
        {{resetUrl}}
      </p>
    </td>
  </tr>
</table>

<!-- Support -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="padding-top: 16px;">
      <p style="margin: 0; font-size: 13px; color: #6b7280;">
        <strong style="color: #111827;">Didn't request this?</strong> <a href="${supportUrl}" style="color: #f59e0b; text-decoration: none; font-weight: 600;">Contact our support team</a> immediately if you believe your account has been compromised.
      </p>
    </td>
  </tr>
</table>`;
    const processedContent = content
        .replace(/\{\{user\.firstName\}\}/g, user.firstName)
        .replace(/\{\{resetUrl\}\}/g, resetUrl)
        .replace(/\{\{expiresIn\}\}/g, expiresIn)
        .replace(/\{\{supportUrl\}\}/g, supportUrl);
    return (0, base_template_1.getBaseEmailTemplate)(processedContent, { preheader: 'Reset your password securely' });
}


/***/ }),
/* 55 */
/***/ ((__unused_webpack_module, exports) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getBaseEmailTemplate = getBaseEmailTemplate;
function getBaseEmailTemplate(content, options = {}) {
    return `<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="x-apple-disable-message-reformatting">
  <title>{{site.name}}</title>
  <!--[if mso]>
  <noscript>
    <xml>
      <o:OfficeDocumentSettings>
        <o:PixelsPerInch>96</o:PixelsPerInch>
      </o:OfficeDocumentSettings>
    </xml>
  </noscript>
  <![endif]-->
  <style>
    /* Reset styles */
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body, table, td, a { -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
    table, td { mso-table-lspace: 0pt; mso-table-rspace: 0pt; }
    img { -ms-interpolation-mode: bicubic; border: 0; height: auto; line-height: 100%; outline: none; text-decoration: none; }
    
    /* Base styles */
    body {
      width: 100% !important;
      height: 100% !important;
      margin: 0 !important;
      padding: 0 !important;
      background-color: #f4f4f5;
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    }
    
    /* Container */
    .email-container {
      max-width: 600px;
      margin: 0 auto;
      background-color: #ffffff;
    }
    
    /* Responsive styles */
    @media screen and (max-width: 600px) {
      .email-container { width: 100% !important; }
      .fluid { max-width: 100% !important; height: auto !important; margin-left: auto !important; margin-right: auto !important; }
      .stack-column { display: block !important; width: 100% !important; max-width: 100% !important; }
      .center-on-narrow { text-align: center !important; display: block !important; margin-left: auto !important; margin-right: auto !important; float: none !important; }
      .mobile-padding { padding-left: 20px !important; padding-right: 20px !important; }
    }
  </style>
</head>
<body style="margin: 0; padding: 0; background-color: #f4f4f5;">
  ${options.preheader ? `<div style="display: none; max-height: 0; overflow: hidden;">${options.preheader}</div>` : ''}
  
  <!-- Background wrapper -->
  <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="background-color: #f4f4f5;">
    <tr>
      <td style="padding: 40px 20px;">
        <!-- Email container -->
        <table role="presentation" cellspacing="0" cellpadding="0" border="0" class="email-container" style="margin: 0 auto; max-width: 600px; background-color: #ffffff; border-radius: 12px; overflow: hidden; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);">
          
          <!-- Header -->
          <tr>
            <td style="padding: 32px 40px; text-align: center; background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);">
              {{#if site.logo}}
                <img src="{{site.logo}}" alt="{{site.name}}" width="150" style="max-width: 150px; height: auto;">
              {{else}}
                <h1 style="margin: 0; font-size: 28px; font-weight: 700; color: #ffffff; letter-spacing: -0.5px;">{{site.name}}</h1>
              {{/if}}
            </td>
          </tr>
          
          <!-- Content -->
          <tr>
            <td style="padding: 40px;" class="mobile-padding">
              ${content}
            </td>
          </tr>
          
          <!-- Footer -->
          <tr>
            <td style="padding: 32px 40px; background-color: #f9fafb; border-top: 1px solid #e5e7eb;">
              <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
                <tr>
                  <td style="text-align: center;">
                    <p style="margin: 0 0 8px; font-size: 14px; color: #6b7280;">
                      © {{year}} {{site.name}}. All rights reserved.
                    </p>
                    <p style="margin: 0; font-size: 12px; color: #9ca3af;">
                      {{#if site.address}}{{site.address}}{{/if}}
                    </p>
                    {{#if unsubscribeUrl}}
                    <p style="margin: 16px 0 0; font-size: 12px;">
                      <a href="{{unsubscribeUrl}}" style="color: #9ca3af; text-decoration: underline;">Unsubscribe</a>
                    </p>
                    {{/if}}
                  </td>
                </tr>
              </table>
            </td>
          </tr>
          
        </table>
      </td>
    </tr>
  </table>
</body>
</html>`;
}


/***/ }),
/* 56 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.AuthController = void 0;
const common_1 = __webpack_require__(2);
const express_1 = __webpack_require__(57);
const auth_service_1 = __webpack_require__(45);
const login_dto_1 = __webpack_require__(58);
const register_dto_1 = __webpack_require__(60);
const jwt_auth_guard_1 = __webpack_require__(61);
const current_user_decorator_1 = __webpack_require__(63);
let AuthController = class AuthController {
    constructor(authService) {
        this.authService = authService;
    }
    async login(loginDto, req) {
        const ip = req.ip;
        const userAgent = req.headers['user-agent'];
        return this.authService.login(loginDto, ip, userAgent);
    }
    async verify2FA(body, req) {
        const ip = req.ip;
        const userAgent = req.headers['user-agent'];
        return this.authService.verify2FAAndLogin(body.tempToken, body.code, ip, userAgent);
    }
    async register(registerDto) {
        return this.authService.register(registerDto);
    }
    async getProfile(user) {
        return user;
    }
    async logout() {
        return { message: 'Logged out successfully' };
    }
    async forgotPassword(body) {
        return this.authService.forgotPassword(body.email);
    }
    async resetPassword(body) {
        return this.authService.resetPassword(body.token, body.password);
    }
};
exports.AuthController = AuthController;
__decorate([
    (0, common_1.Post)('login'),
    (0, common_1.HttpCode)(common_1.HttpStatus.OK),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, common_1.Req)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_b = typeof login_dto_1.LoginDto !== "undefined" && login_dto_1.LoginDto) === "function" ? _b : Object, typeof (_c = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _c : Object]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "login", null);
__decorate([
    (0, common_1.Post)('verify-2fa'),
    (0, common_1.HttpCode)(common_1.HttpStatus.OK),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, common_1.Req)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, typeof (_d = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _d : Object]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "verify2FA", null);
__decorate([
    (0, common_1.Post)('register'),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_e = typeof register_dto_1.RegisterDto !== "undefined" && register_dto_1.RegisterDto) === "function" ? _e : Object]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "register", null);
__decorate([
    (0, common_1.Get)('me'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, current_user_decorator_1.CurrentUser)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "getProfile", null);
__decorate([
    (0, common_1.Post)('logout'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    (0, common_1.HttpCode)(common_1.HttpStatus.OK),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "logout", null);
__decorate([
    (0, common_1.Post)('forgot-password'),
    (0, common_1.HttpCode)(common_1.HttpStatus.OK),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "forgotPassword", null);
__decorate([
    (0, common_1.Post)('reset-password'),
    (0, common_1.HttpCode)(common_1.HttpStatus.OK),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], AuthController.prototype, "resetPassword", null);
exports.AuthController = AuthController = __decorate([
    (0, common_1.Controller)('api/auth'),
    __metadata("design:paramtypes", [typeof (_a = typeof auth_service_1.AuthService !== "undefined" && auth_service_1.AuthService) === "function" ? _a : Object])
], AuthController);


/***/ }),
/* 57 */
/***/ ((module) => {

module.exports = require("express");

/***/ }),
/* 58 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.LoginDto = void 0;
const class_validator_1 = __webpack_require__(59);
class LoginDto {
}
exports.LoginDto = LoginDto;
__decorate([
    (0, class_validator_1.IsEmail)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], LoginDto.prototype, "email", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    (0, class_validator_1.MinLength)(6),
    __metadata("design:type", String)
], LoginDto.prototype, "password", void 0);


/***/ }),
/* 59 */
/***/ ((module) => {

module.exports = require("class-validator");

/***/ }),
/* 60 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.RegisterDto = void 0;
const class_validator_1 = __webpack_require__(59);
const client_1 = __webpack_require__(17);
class RegisterDto {
}
exports.RegisterDto = RegisterDto;
__decorate([
    (0, class_validator_1.IsEmail)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], RegisterDto.prototype, "email", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], RegisterDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    (0, class_validator_1.MinLength)(6),
    __metadata("design:type", String)
], RegisterDto.prototype, "password", void 0);
__decorate([
    (0, class_validator_1.IsEnum)(client_1.UserRole),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_a = typeof client_1.UserRole !== "undefined" && client_1.UserRole) === "function" ? _a : Object)
], RegisterDto.prototype, "role", void 0);


/***/ }),
/* 61 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.JwtAuthGuard = void 0;
const common_1 = __webpack_require__(2);
const core_1 = __webpack_require__(1);
const passport_1 = __webpack_require__(44);
const public_decorator_1 = __webpack_require__(62);
let JwtAuthGuard = class JwtAuthGuard extends (0, passport_1.AuthGuard)('jwt') {
    constructor(reflector) {
        super();
        this.reflector = reflector;
    }
    canActivate(context) {
        const isPublic = this.reflector.getAllAndOverride(public_decorator_1.IS_PUBLIC_KEY, [
            context.getHandler(),
            context.getClass(),
        ]);
        if (isPublic) {
            return true;
        }
        return super.canActivate(context);
    }
};
exports.JwtAuthGuard = JwtAuthGuard;
exports.JwtAuthGuard = JwtAuthGuard = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof core_1.Reflector !== "undefined" && core_1.Reflector) === "function" ? _a : Object])
], JwtAuthGuard);


/***/ }),
/* 62 */
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Public = exports.IS_PUBLIC_KEY = void 0;
const common_1 = __webpack_require__(2);
exports.IS_PUBLIC_KEY = 'isPublic';
const Public = () => (0, common_1.SetMetadata)(exports.IS_PUBLIC_KEY, true);
exports.Public = Public;


/***/ }),
/* 63 */
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CurrentUser = void 0;
const common_1 = __webpack_require__(2);
exports.CurrentUser = (0, common_1.createParamDecorator)((data, ctx) => {
    const request = ctx.switchToHttp().getRequest();
    return request.user;
});


/***/ }),
/* 64 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.JwtStrategy = void 0;
const common_1 = __webpack_require__(2);
const passport_1 = __webpack_require__(44);
const passport_jwt_1 = __webpack_require__(65);
const config_1 = __webpack_require__(13);
const users_service_1 = __webpack_require__(49);
const tokenExtractor = (req) => {
    const authHeader = req?.headers?.authorization;
    if (authHeader && authHeader.startsWith('Bearer ')) {
        return authHeader.substring(7);
    }
    if (req && req.cookies && req.cookies.access_token) {
        return req.cookies.access_token;
    }
    return null;
};
let JwtStrategy = class JwtStrategy extends (0, passport_1.PassportStrategy)(passport_jwt_1.Strategy) {
    constructor(configService, usersService) {
        const jwtSecret = configService.get('JWT_SECRET') || 'default-secret-change-in-production';
        super({
            jwtFromRequest: tokenExtractor,
            ignoreExpiration: false,
            secretOrKey: jwtSecret,
        });
        this.configService = configService;
        this.usersService = usersService;
    }
    async validate(payload) {
        try {
            const user = await this.usersService.findById(payload.sub);
            if (!user) {
                throw new common_1.UnauthorizedException();
            }
            const { password: _password, ...result } = user;
            void _password;
            return result;
        }
        catch (_error) {
            throw new common_1.UnauthorizedException();
        }
    }
};
exports.JwtStrategy = JwtStrategy;
exports.JwtStrategy = JwtStrategy = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof config_1.ConfigService !== "undefined" && config_1.ConfigService) === "function" ? _a : Object, typeof (_b = typeof users_service_1.UsersService !== "undefined" && users_service_1.UsersService) === "function" ? _b : Object])
], JwtStrategy);


/***/ }),
/* 65 */
/***/ ((module) => {

module.exports = require("passport-jwt");

/***/ }),
/* 66 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.LocalStrategy = void 0;
const common_1 = __webpack_require__(2);
const passport_1 = __webpack_require__(44);
const passport_local_1 = __webpack_require__(67);
const auth_service_1 = __webpack_require__(45);
let LocalStrategy = class LocalStrategy extends (0, passport_1.PassportStrategy)(passport_local_1.Strategy) {
    constructor(authService) {
        super({
            usernameField: 'email',
        });
        this.authService = authService;
    }
    async validate(email, password) {
        const user = await this.authService.validateUser(email, password);
        if (!user) {
            throw new common_1.UnauthorizedException('Invalid credentials');
        }
        return user;
    }
};
exports.LocalStrategy = LocalStrategy;
exports.LocalStrategy = LocalStrategy = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof auth_service_1.AuthService !== "undefined" && auth_service_1.AuthService) === "function" ? _a : Object])
], LocalStrategy);


/***/ }),
/* 67 */
/***/ ((module) => {

module.exports = require("passport-local");

/***/ }),
/* 68 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UsersModule = void 0;
const common_1 = __webpack_require__(2);
const prisma_module_1 = __webpack_require__(15);
const users_service_1 = __webpack_require__(49);
const users_controller_1 = __webpack_require__(69);
const profiles_service_1 = __webpack_require__(74);
const profiles_controller_1 = __webpack_require__(75);
let UsersModule = class UsersModule {
};
exports.UsersModule = UsersModule;
exports.UsersModule = UsersModule = __decorate([
    (0, common_1.Module)({
        imports: [prisma_module_1.PrismaModule],
        providers: [users_service_1.UsersService, profiles_service_1.ProfilesService],
        controllers: [users_controller_1.UsersController, profiles_controller_1.ProfilesController],
        exports: [users_service_1.UsersService, profiles_service_1.ProfilesService],
    })
], UsersModule);


/***/ }),
/* 69 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UsersController = void 0;
const common_1 = __webpack_require__(2);
const users_service_1 = __webpack_require__(49);
const create_user_dto_1 = __webpack_require__(70);
const update_user_dto_1 = __webpack_require__(71);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const client_1 = __webpack_require__(17);
let UsersController = class UsersController {
    constructor(usersService) {
        this.usersService = usersService;
    }
    create(createUserDto) {
        return this.usersService.create(createUserDto);
    }
    findAll(page, limit, search) {
        return this.usersService.findAll(page ? parseInt(page) : 1, limit ? parseInt(limit) : 10, search);
    }
    findOne(id) {
        return this.usersService.findById(id);
    }
    update(id, updateUserDto) {
        return this.usersService.update(id, updateUserDto);
    }
    remove(id) {
        return this.usersService.remove(id);
    }
};
exports.UsersController = UsersController;
__decorate([
    (0, common_1.Post)(),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_b = typeof create_user_dto_1.CreateUserDto !== "undefined" && create_user_dto_1.CreateUserDto) === "function" ? _b : Object]),
    __metadata("design:returntype", void 0)
], UsersController.prototype, "create", null);
__decorate([
    (0, common_1.Get)(),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Query)('page')),
    __param(1, (0, common_1.Query)('limit')),
    __param(2, (0, common_1.Query)('search')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, String]),
    __metadata("design:returntype", void 0)
], UsersController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], UsersController.prototype, "findOne", null);
__decorate([
    (0, common_1.Patch)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_c = typeof update_user_dto_1.UpdateUserDto !== "undefined" && update_user_dto_1.UpdateUserDto) === "function" ? _c : Object]),
    __metadata("design:returntype", void 0)
], UsersController.prototype, "update", null);
__decorate([
    (0, common_1.Delete)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], UsersController.prototype, "remove", null);
exports.UsersController = UsersController = __decorate([
    (0, common_1.Controller)('api/users'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof users_service_1.UsersService !== "undefined" && users_service_1.UsersService) === "function" ? _a : Object])
], UsersController);


/***/ }),
/* 70 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CreateUserDto = void 0;
const class_validator_1 = __webpack_require__(59);
const client_1 = __webpack_require__(17);
class CreateUserDto {
    constructor() {
        this.role = client_1.UserRole.AUTHOR;
    }
}
exports.CreateUserDto = CreateUserDto;
__decorate([
    (0, class_validator_1.IsEmail)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], CreateUserDto.prototype, "email", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], CreateUserDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    (0, class_validator_1.MinLength)(6),
    __metadata("design:type", String)
], CreateUserDto.prototype, "password", void 0);
__decorate([
    (0, class_validator_1.IsEnum)(client_1.UserRole),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_a = typeof client_1.UserRole !== "undefined" && client_1.UserRole) === "function" ? _a : Object)
], CreateUserDto.prototype, "role", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateUserDto.prototype, "avatar", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateUserDto.prototype, "bio", void 0);


/***/ }),
/* 71 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UpdateUserDto = void 0;
const class_validator_1 = __webpack_require__(59);
const client_1 = __webpack_require__(17);
class UpdateUserDto {
}
exports.UpdateUserDto = UpdateUserDto;
__decorate([
    (0, class_validator_1.IsEmail)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateUserDto.prototype, "email", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateUserDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.MinLength)(6),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateUserDto.prototype, "password", void 0);
__decorate([
    (0, class_validator_1.IsEnum)(client_1.UserRole),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_a = typeof client_1.UserRole !== "undefined" && client_1.UserRole) === "function" ? _a : Object)
], UpdateUserDto.prototype, "role", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateUserDto.prototype, "avatar", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateUserDto.prototype, "bio", void 0);


/***/ }),
/* 72 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 RolesGuard_1;
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.RolesGuard = void 0;
const common_1 = __webpack_require__(2);
const core_1 = __webpack_require__(1);
const roles_decorator_1 = __webpack_require__(73);
let RolesGuard = RolesGuard_1 = class RolesGuard {
    constructor(reflector) {
        this.reflector = reflector;
        this.logger = new common_1.Logger(RolesGuard_1.name);
    }
    canActivate(context) {
        const requiredRoles = this.reflector.getAllAndOverride(roles_decorator_1.ROLES_KEY, [
            context.getHandler(),
            context.getClass(),
        ]);
        if (!requiredRoles || requiredRoles.length === 0) {
            return true;
        }
        const { user } = context.switchToHttp().getRequest();
        if (!user) {
            this.logger.warn('RolesGuard: No user found in request');
            throw new common_1.ForbiddenException('Authentication required to access this resource');
        }
        this.logger.debug(`RolesGuard: User role = "${user.role}", Required roles = [${requiredRoles.join(', ')}]`);
        const hasRole = requiredRoles.some((role) => user.role === role);
        if (!hasRole) {
            const rolesList = requiredRoles.join(', ').toUpperCase();
            this.logger.warn(`RolesGuard: Access denied. User role "${user.role}" not in required roles [${rolesList}]`);
            throw new common_1.ForbiddenException(`Insufficient permissions. Required roles: ${rolesList}. Your role: ${user.role}`);
        }
        return true;
    }
};
exports.RolesGuard = RolesGuard;
exports.RolesGuard = RolesGuard = RolesGuard_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof core_1.Reflector !== "undefined" && core_1.Reflector) === "function" ? _a : Object])
], RolesGuard);


/***/ }),
/* 73 */
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Roles = exports.ROLES_KEY = void 0;
const common_1 = __webpack_require__(2);
exports.ROLES_KEY = 'roles';
const Roles = (...roles) => (0, common_1.SetMetadata)(exports.ROLES_KEY, roles);
exports.Roles = Roles;


/***/ }),
/* 74 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ProfilesService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let ProfilesService = class ProfilesService {
    constructor(prisma) {
        this.prisma = prisma;
        this.publicProfileSelect = {
            id: true,
            username: true,
            name: true,
            avatar: true,
            coverImage: true,
            bio: true,
            about: true,
            headline: true,
            location: true,
            website: true,
            company: true,
            jobTitle: true,
            skills: true,
            interests: true,
            socialLinks: true,
            isPublic: true,
            followersCount: true,
            followingCount: true,
            postsCount: true,
            coursesCount: true,
            createdAt: true,
            role: true,
        };
    }
    async getPublicProfile(identifier, viewerId) {
        const user = await this.prisma.user.findFirst({
            where: {
                OR: [{ username: identifier }, { id: identifier }],
            },
            select: {
                ...this.publicProfileSelect,
                posts: {
                    where: { status: 'PUBLISHED' },
                    take: 6,
                    orderBy: { createdAt: 'desc' },
                    select: {
                        id: true,
                        title: true,
                        slug: true,
                        excerpt: true,
                        featuredImage: true,
                        createdAt: true,
                    },
                },
                instructedCourses: {
                    where: { status: 'PUBLISHED' },
                    take: 4,
                    select: {
                        id: true,
                        title: true,
                        slug: true,
                        shortDescription: true,
                        featuredImage: true,
                        level: true,
                        priceType: true,
                        priceAmount: true,
                    },
                },
                certificates: {
                    take: 6,
                    orderBy: { issuedAt: 'desc' },
                    select: {
                        id: true,
                        issuedAt: true,
                        course: {
                            select: { title: true, slug: true },
                        },
                    },
                },
                badges: {
                    orderBy: { earnedAt: 'desc' },
                    select: {
                        id: true,
                        earnedAt: true,
                        badge: true,
                    },
                },
            },
        });
        if (!user) {
            throw new common_1.NotFoundException('User not found');
        }
        const isOwnProfile = viewerId && user.id === viewerId;
        if (!user.isPublic && !isOwnProfile) {
            throw new common_1.ForbiddenException('This profile is private');
        }
        return user;
    }
    async getMyProfile(userId) {
        const user = await this.prisma.user.findUnique({
            where: { id: userId },
            select: {
                ...this.publicProfileSelect,
                email: true,
                twoFactorEnabled: true,
            },
        });
        if (!user) {
            throw new common_1.NotFoundException('User not found');
        }
        return user;
    }
    async updateProfile(userId, data) {
        if (data.username) {
            const existing = await this.prisma.user.findFirst({
                where: {
                    username: data.username,
                    NOT: { id: userId },
                },
            });
            if (existing) {
                throw new common_1.ConflictException('Username is already taken');
            }
        }
        return this.prisma.user.update({
            where: { id: userId },
            data,
            select: this.publicProfileSelect,
        });
    }
    async followUser(followerId, followingId) {
        if (followerId === followingId) {
            throw new common_1.ConflictException('You cannot follow yourself');
        }
        const existing = await this.prisma.userFollow.findUnique({
            where: {
                followerId_followingId: { followerId, followingId },
            },
        });
        if (existing) {
            throw new common_1.ConflictException('Already following this user');
        }
        await this.prisma.$transaction([
            this.prisma.userFollow.create({
                data: { followerId, followingId },
            }),
            this.prisma.user.update({
                where: { id: followingId },
                data: { followersCount: { increment: 1 } },
            }),
            this.prisma.user.update({
                where: { id: followerId },
                data: { followingCount: { increment: 1 } },
            }),
        ]);
        return { message: 'Successfully followed user' };
    }
    async unfollowUser(followerId, followingId) {
        const existing = await this.prisma.userFollow.findUnique({
            where: {
                followerId_followingId: { followerId, followingId },
            },
        });
        if (!existing) {
            throw new common_1.NotFoundException('Not following this user');
        }
        await this.prisma.$transaction([
            this.prisma.userFollow.delete({
                where: { followerId_followingId: { followerId, followingId } },
            }),
            this.prisma.user.update({
                where: { id: followingId },
                data: { followersCount: { decrement: 1 } },
            }),
            this.prisma.user.update({
                where: { id: followerId },
                data: { followingCount: { decrement: 1 } },
            }),
        ]);
        return { message: 'Successfully unfollowed user' };
    }
    async isFollowing(followerId, followingId) {
        const follow = await this.prisma.userFollow.findUnique({
            where: {
                followerId_followingId: { followerId, followingId },
            },
        });
        return { isFollowing: !!follow };
    }
    async getFollowers(userId, page = 1, limit = 20) {
        const skip = (page - 1) * limit;
        const [followers, total] = await Promise.all([
            this.prisma.userFollow.findMany({
                where: { followingId: userId },
                skip,
                take: limit,
                orderBy: { createdAt: 'desc' },
                select: {
                    createdAt: true,
                    follower: {
                        select: {
                            id: true,
                            username: true,
                            name: true,
                            avatar: true,
                            headline: true,
                        },
                    },
                },
            }),
            this.prisma.userFollow.count({ where: { followingId: userId } }),
        ]);
        return {
            data: followers.map((f) => ({ ...f.follower, followedAt: f.createdAt })),
            pagination: { page, limit, total, pages: Math.ceil(total / limit) },
        };
    }
    async getFollowing(userId, page = 1, limit = 20) {
        const skip = (page - 1) * limit;
        const [following, total] = await Promise.all([
            this.prisma.userFollow.findMany({
                where: { followerId: userId },
                skip,
                take: limit,
                orderBy: { createdAt: 'desc' },
                select: {
                    createdAt: true,
                    following: {
                        select: {
                            id: true,
                            username: true,
                            name: true,
                            avatar: true,
                            headline: true,
                        },
                    },
                },
            }),
            this.prisma.userFollow.count({ where: { followerId: userId } }),
        ]);
        return {
            data: following.map((f) => ({ ...f.following, followedAt: f.createdAt })),
            pagination: { page, limit, total, pages: Math.ceil(total / limit) },
        };
    }
    async getActivity(userId, page = 1, limit = 20) {
        const skip = (page - 1) * limit;
        const [posts, enrollments, certificates] = await Promise.all([
            this.prisma.post.findMany({
                where: { authorId: userId, status: 'PUBLISHED' },
                take: 10,
                orderBy: { publishedAt: 'desc' },
                select: {
                    id: true,
                    title: true,
                    slug: true,
                    publishedAt: true,
                },
            }),
            this.prisma.enrollment.findMany({
                where: { userId },
                take: 10,
                orderBy: { enrolledAt: 'desc' },
                select: {
                    id: true,
                    enrolledAt: true,
                    completedAt: true,
                    course: { select: { title: true, slug: true } },
                },
            }),
            this.prisma.certificate.findMany({
                where: { userId },
                take: 10,
                orderBy: { issuedAt: 'desc' },
                select: {
                    id: true,
                    issuedAt: true,
                    course: { select: { title: true, slug: true } },
                },
            }),
        ]);
        const activities = [
            ...posts.map((p) => ({
                type: 'post_published',
                title: `Published "${p.title}"`,
                link: `/post/${p.slug}`,
                date: p.publishedAt,
            })),
            ...enrollments.map((e) => ({
                type: e.completedAt ? 'course_completed' : 'course_enrolled',
                title: e.completedAt ? `Completed "${e.course.title}"` : `Enrolled in "${e.course.title}"`,
                link: `/courses/${e.course.slug}`,
                date: e.completedAt || e.enrolledAt,
            })),
            ...certificates.map((c) => ({
                type: 'certificate_earned',
                title: `Earned certificate for "${c.course.title}"`,
                link: `/courses/${c.course.slug}`,
                date: c.issuedAt,
            })),
        ]
            .filter((a) => a.date !== null)
            .sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime())
            .slice(skip, skip + limit);
        return { activities };
    }
    async getStats(userId) {
        const [posts, courses, certificates, enrollments] = await Promise.all([
            this.prisma.post.count({ where: { authorId: userId, status: 'PUBLISHED' } }),
            this.prisma.course.count({ where: { instructorId: userId, status: 'PUBLISHED' } }),
            this.prisma.certificate.count({ where: { userId } }),
            this.prisma.enrollment.count({ where: { userId } }),
        ]);
        const completedCourses = await this.prisma.enrollment.count({
            where: { userId, status: 'COMPLETED' },
        });
        return {
            postsPublished: posts,
            coursesCreated: courses,
            coursesEnrolled: enrollments,
            coursesCompleted: completedCourses,
            certificatesEarned: certificates,
        };
    }
    async searchUsers(query, page = 1, limit = 20) {
        const skip = (page - 1) * limit;
        const [users, total] = await Promise.all([
            this.prisma.user.findMany({
                where: {
                    isPublic: true,
                    OR: [
                        { name: { contains: query, mode: 'insensitive' } },
                        { username: { contains: query, mode: 'insensitive' } },
                        { headline: { contains: query, mode: 'insensitive' } },
                    ],
                },
                skip,
                take: limit,
                select: {
                    id: true,
                    username: true,
                    name: true,
                    avatar: true,
                    headline: true,
                    followersCount: true,
                },
            }),
            this.prisma.user.count({
                where: {
                    isPublic: true,
                    OR: [
                        { name: { contains: query, mode: 'insensitive' } },
                        { username: { contains: query, mode: 'insensitive' } },
                        { headline: { contains: query, mode: 'insensitive' } },
                    ],
                },
            }),
        ]);
        return {
            users,
            pagination: { page, limit, total, pages: Math.ceil(total / limit) },
        };
    }
};
exports.ProfilesService = ProfilesService;
exports.ProfilesService = ProfilesService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], ProfilesService);


/***/ }),
/* 75 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ProfilesController = void 0;
const common_1 = __webpack_require__(2);
const profiles_service_1 = __webpack_require__(74);
const jwt_auth_guard_1 = __webpack_require__(61);
const optional_jwt_auth_guard_1 = __webpack_require__(76);
let ProfilesController = class ProfilesController {
    constructor(profilesService) {
        this.profilesService = profilesService;
    }
    async getMyProfile(req) {
        return this.profilesService.getMyProfile(req.user.id);
    }
    async updateMyProfile(req, data) {
        return this.profilesService.updateProfile(req.user.id, data);
    }
    async getMyStats(req) {
        return this.profilesService.getStats(req.user.id);
    }
    async getMyActivity(req, page, limit) {
        return this.profilesService.getActivity(req.user.id, parseInt(page || '1'), parseInt(limit || '20'));
    }
    async getMyFollowers(req, page, limit) {
        return this.profilesService.getFollowers(req.user.id, parseInt(page || '1'), parseInt(limit || '20'));
    }
    async getMyFollowing(req, page, limit) {
        return this.profilesService.getFollowing(req.user.id, parseInt(page || '1'), parseInt(limit || '20'));
    }
    async searchUsers(query, page, limit) {
        return this.profilesService.searchUsers(query || '', parseInt(page || '1'), parseInt(limit || '20'));
    }
    async getPublicProfile(req, identifier) {
        const viewerId = req.user?.id;
        return this.profilesService.getPublicProfile(identifier, viewerId);
    }
    async getUserStats(req, identifier) {
        const viewerId = req.user?.id;
        const profile = await this.profilesService.getPublicProfile(identifier, viewerId);
        return this.profilesService.getStats(profile.id);
    }
    async getUserActivity(req, identifier, page, limit) {
        const viewerId = req.user?.id;
        const profile = await this.profilesService.getPublicProfile(identifier, viewerId);
        return this.profilesService.getActivity(profile.id, parseInt(page || '1'), parseInt(limit || '20'));
    }
    async getFollowingStatus(req, identifier) {
        const profile = await this.profilesService.getPublicProfile(identifier, req.user.id);
        return this.profilesService.isFollowing(req.user.id, profile.id);
    }
    async followUser(req, identifier) {
        const profile = await this.profilesService.getPublicProfile(identifier, req.user.id);
        return this.profilesService.followUser(req.user.id, profile.id);
    }
    async unfollowUser(req, identifier) {
        const profile = await this.profilesService.getPublicProfile(identifier, req.user.id);
        return this.profilesService.unfollowUser(req.user.id, profile.id);
    }
    async getUserFollowers(req, identifier, page, limit) {
        const viewerId = req.user?.id;
        const profile = await this.profilesService.getPublicProfile(identifier, viewerId);
        return this.profilesService.getFollowers(profile.id, parseInt(page || '1'), parseInt(limit || '20'));
    }
    async getUserFollowing(req, identifier, page, limit) {
        const viewerId = req.user?.id;
        const profile = await this.profilesService.getPublicProfile(identifier, viewerId);
        return this.profilesService.getFollowing(profile.id, parseInt(page || '1'), parseInt(limit || '20'));
    }
};
exports.ProfilesController = ProfilesController;
__decorate([
    (0, common_1.Get)('me'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], ProfilesController.prototype, "getMyProfile", null);
__decorate([
    (0, common_1.Put)('me'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, typeof (_b = typeof profiles_service_1.UpdateProfileDto !== "undefined" && profiles_service_1.UpdateProfileDto) === "function" ? _b : Object]),
    __metadata("design:returntype", Promise)
], ProfilesController.prototype, "updateMyProfile", null);
__decorate([
    (0, common_1.Get)('me/stats'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], ProfilesController.prototype, "getMyStats", null);
__decorate([
    (0, common_1.Get)('me/activity'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Query)('page')),
    __param(2, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, String]),
    __metadata("design:returntype", Promise)
], ProfilesController.prototype, "getMyActivity", null);
__decorate([
    (0, common_1.Get)('me/followers'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Query)('page')),
    __param(2, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, String]),
    __metadata("design:returntype", Promise)
], ProfilesController.prototype, "getMyFollowers", null);
__decorate([
    (0, common_1.Get)('me/following'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Query)('page')),
    __param(2, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, String]),
    __metadata("design:returntype", Promise)
], ProfilesController.prototype, "getMyFollowing", null);
__decorate([
    (0, common_1.Get)('search'),
    __param(0, (0, common_1.Query)('q')),
    __param(1, (0, common_1.Query)('page')),
    __param(2, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, String]),
    __metadata("design:returntype", Promise)
], ProfilesController.prototype, "searchUsers", null);
__decorate([
    (0, common_1.Get)(':identifier'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('identifier')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String]),
    __metadata("design:returntype", Promise)
], ProfilesController.prototype, "getPublicProfile", null);
__decorate([
    (0, common_1.Get)(':identifier/stats'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('identifier')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String]),
    __metadata("design:returntype", Promise)
], ProfilesController.prototype, "getUserStats", null);
__decorate([
    (0, common_1.Get)(':identifier/activity'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('identifier')),
    __param(2, (0, common_1.Query)('page')),
    __param(3, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, String, String]),
    __metadata("design:returntype", Promise)
], ProfilesController.prototype, "getUserActivity", null);
__decorate([
    (0, common_1.Get)(':identifier/following-status'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('identifier')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String]),
    __metadata("design:returntype", Promise)
], ProfilesController.prototype, "getFollowingStatus", null);
__decorate([
    (0, common_1.Post)(':identifier/follow'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('identifier')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String]),
    __metadata("design:returntype", Promise)
], ProfilesController.prototype, "followUser", null);
__decorate([
    (0, common_1.Delete)(':identifier/follow'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('identifier')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String]),
    __metadata("design:returntype", Promise)
], ProfilesController.prototype, "unfollowUser", null);
__decorate([
    (0, common_1.Get)(':identifier/followers'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('identifier')),
    __param(2, (0, common_1.Query)('page')),
    __param(3, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, String, String]),
    __metadata("design:returntype", Promise)
], ProfilesController.prototype, "getUserFollowers", null);
__decorate([
    (0, common_1.Get)(':identifier/following'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('identifier')),
    __param(2, (0, common_1.Query)('page')),
    __param(3, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, String, String]),
    __metadata("design:returntype", Promise)
], ProfilesController.prototype, "getUserFollowing", null);
exports.ProfilesController = ProfilesController = __decorate([
    (0, common_1.Controller)('api/profiles'),
    __metadata("design:paramtypes", [typeof (_a = typeof profiles_service_1.ProfilesService !== "undefined" && profiles_service_1.ProfilesService) === "function" ? _a : Object])
], ProfilesController);


/***/ }),
/* 76 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.OptionalJwtAuthGuard = void 0;
const common_1 = __webpack_require__(2);
const passport_1 = __webpack_require__(44);
let OptionalJwtAuthGuard = class OptionalJwtAuthGuard extends (0, passport_1.AuthGuard)('jwt') {
    async canActivate(context) {
        try {
            await super.canActivate(context);
        }
        catch {
        }
        return true;
    }
    handleRequest(err, user) {
        return user || null;
    }
};
exports.OptionalJwtAuthGuard = OptionalJwtAuthGuard;
exports.OptionalJwtAuthGuard = OptionalJwtAuthGuard = __decorate([
    (0, common_1.Injectable)()
], OptionalJwtAuthGuard);


/***/ }),
/* 77 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.EmailModule = void 0;
const common_1 = __webpack_require__(2);
const config_1 = __webpack_require__(13);
const prisma_module_1 = __webpack_require__(15);
const settings_module_1 = __webpack_require__(78);
const email_service_1 = __webpack_require__(50);
const email_templates_service_1 = __webpack_require__(84);
const email_logs_service_1 = __webpack_require__(85);
const bulk_email_service_1 = __webpack_require__(86);
const email_templates_seeder_service_1 = __webpack_require__(87);
const email_controller_1 = __webpack_require__(93);
let EmailModule = class EmailModule {
};
exports.EmailModule = EmailModule;
exports.EmailModule = EmailModule = __decorate([
    (0, common_1.Module)({
        imports: [config_1.ConfigModule, prisma_module_1.PrismaModule, settings_module_1.SettingsModule],
        controllers: [email_controller_1.EmailController],
        providers: [
            email_service_1.EmailService,
            email_templates_service_1.EmailTemplatesService,
            email_logs_service_1.EmailLogsService,
            bulk_email_service_1.BulkEmailService,
            email_templates_seeder_service_1.EmailTemplatesSeederService,
        ],
        exports: [email_service_1.EmailService, email_templates_service_1.EmailTemplatesService, email_logs_service_1.EmailLogsService, bulk_email_service_1.BulkEmailService],
    })
], EmailModule);


/***/ }),
/* 78 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SettingsModule = void 0;
const common_1 = __webpack_require__(2);
const config_1 = __webpack_require__(13);
const prisma_module_1 = __webpack_require__(15);
const settings_service_1 = __webpack_require__(79);
const settings_controller_1 = __webpack_require__(80);
const encryption_service_1 = __webpack_require__(53);
const system_config_service_1 = __webpack_require__(52);
const system_config_controller_1 = __webpack_require__(81);
const setup_wizard_controller_1 = __webpack_require__(83);
let SettingsModule = class SettingsModule {
};
exports.SettingsModule = SettingsModule;
exports.SettingsModule = SettingsModule = __decorate([
    (0, common_1.Global)(),
    (0, common_1.Module)({
        imports: [prisma_module_1.PrismaModule, config_1.ConfigModule],
        providers: [settings_service_1.SettingsService, encryption_service_1.EncryptionService, system_config_service_1.SystemConfigService],
        controllers: [settings_controller_1.SettingsController, system_config_controller_1.SystemConfigController, setup_wizard_controller_1.SetupWizardController],
        exports: [settings_service_1.SettingsService, encryption_service_1.EncryptionService, system_config_service_1.SystemConfigService],
    })
], SettingsModule);


/***/ }),
/* 79 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SettingsService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let SettingsService = class SettingsService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async findAll(group) {
        const where = {};
        if (group) {
            where.group = group;
        }
        return this.prisma.setting.findMany({
            where,
            orderBy: { key: 'asc' },
        });
    }
    async findByKey(key) {
        return this.prisma.setting.findUnique({
            where: { key },
        });
    }
    async set(key, value, type, group) {
        return this.prisma.setting.upsert({
            where: { key },
            update: { value, type, group },
            create: { key, value, type, group },
        });
    }
    async remove(key) {
        return this.prisma.setting.delete({
            where: { key },
        });
    }
    async getSettings(keys) {
        const settings = await this.prisma.setting.findMany({
            where: {
                key: { in: keys },
            },
        });
        return settings.reduce((acc, setting) => {
            acc[setting.key] = setting.value;
            return acc;
        }, {});
    }
};
exports.SettingsService = SettingsService;
exports.SettingsService = SettingsService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], SettingsService);


/***/ }),
/* 80 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SettingsController = void 0;
const common_1 = __webpack_require__(2);
const settings_service_1 = __webpack_require__(79);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const client_1 = __webpack_require__(17);
let SettingsController = class SettingsController {
    constructor(settingsService) {
        this.settingsService = settingsService;
    }
    findAll(group) {
        return this.settingsService.findAll(group);
    }
    findOne(key) {
        return this.settingsService.findByKey(key);
    }
    set(data) {
        return this.settingsService.set(data.key, data.value, data.type, data.group);
    }
    remove(key) {
        return this.settingsService.remove(key);
    }
};
exports.SettingsController = SettingsController;
__decorate([
    (0, common_1.Get)(),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Query)('group')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], SettingsController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)(':key'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Param)('key')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], SettingsController.prototype, "findOne", null);
__decorate([
    (0, common_1.Post)(),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], SettingsController.prototype, "set", null);
__decorate([
    (0, common_1.Delete)(':key'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('key')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], SettingsController.prototype, "remove", null);
exports.SettingsController = SettingsController = __decorate([
    (0, common_1.Controller)('api/settings'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof settings_service_1.SettingsService !== "undefined" && settings_service_1.SettingsService) === "function" ? _a : Object])
], SettingsController);


/***/ }),
/* 81 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SystemConfigController = void 0;
const common_1 = __webpack_require__(2);
const system_config_service_1 = __webpack_require__(52);
const stripe_1 = __webpack_require__(82);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const client_1 = __webpack_require__(17);
const nodemailer = __webpack_require__(34);
let SystemConfigController = class SystemConfigController {
    constructor(systemConfig) {
        this.systemConfig = systemConfig;
    }
    async getEmailConfig() {
        const config = await this.systemConfig.getSmtpConfig();
        return {
            host: config.host,
            port: config.port,
            secure: config.secure,
            user: config.user,
            pass: config.pass ? '********' : '',
            fromEmail: config.fromEmail,
            fromName: config.fromName,
            isConfigured: !!(config.host && config.user && config.pass),
        };
    }
    async saveEmailConfig(config) {
        const pass = config.pass || config.password;
        if (!config.host || !config.user) {
            throw new common_1.HttpException('Host and user are required', common_1.HttpStatus.BAD_REQUEST);
        }
        const configToSave = {
            ...config,
            pass: pass || '',
        };
        await this.systemConfig.saveSmtpConfig(configToSave);
        return { success: true, message: 'Email settings saved successfully' };
    }
    async testEmailConfig(body) {
        if (!body.testEmail) {
            throw new common_1.HttpException('Test email address is required', common_1.HttpStatus.BAD_REQUEST);
        }
        const config = await this.systemConfig.getSmtpConfig();
        if (!config.host || !config.user || !config.pass) {
            throw new common_1.HttpException('SMTP not configured', common_1.HttpStatus.BAD_REQUEST);
        }
        try {
            const transporter = nodemailer.createTransport({
                host: config.host,
                port: config.port,
                secure: config.secure,
                auth: { user: config.user, pass: config.pass },
            });
            await transporter.verify();
            await transporter.sendMail({
                from: `"${config.fromName}" <${config.fromEmail || config.user}>`,
                to: body.testEmail,
                subject: 'WordPress Node CMS - Test Email',
                html: `
          <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
            <h2 style="color: #3b82f6;">🎉 Email Configuration Successful!</h2>
            <p>Your SMTP settings are working correctly.</p>
            <p><strong>Server:</strong> ${config.host}:${config.port}</p>
            <p><strong>From:</strong> ${config.fromName} &lt;${config.fromEmail || config.user}&gt;</p>
            <hr style="border: none; border-top: 1px solid #e5e7eb; margin: 20px 0;">
            <p style="color: #6b7280; font-size: 12px;">
              This is a test email from WordPress Node CMS.
            </p>
          </div>
        `,
            });
            return { success: true, message: `Test email sent to ${body.testEmail}` };
        }
        catch (error) {
            const message = error instanceof Error ? error.message : 'Unknown error';
            throw new common_1.HttpException(`Failed to send test email: ${message}`, common_1.HttpStatus.BAD_REQUEST);
        }
    }
    async getDomainConfig() {
        return this.systemConfig.getDomainConfig();
    }
    async saveDomainConfig(config) {
        await this.systemConfig.saveDomainConfig(config);
        return { success: true, message: 'Domain settings saved successfully' };
    }
    async getSetupStatus() {
        return this.systemConfig.getSetupStatus();
    }
    async getMarketplaceConfig() {
        return this.systemConfig.getMarketplaceConfig();
    }
    async saveMarketplaceConfig(config) {
        if (config.platformFeePercent < 0 || config.platformFeePercent > 50) {
            throw new common_1.HttpException('Platform fee must be between 0% and 50%', common_1.HttpStatus.BAD_REQUEST);
        }
        if (config.minPayoutAmount < 1) {
            throw new common_1.HttpException('Minimum payout must be at least $1', common_1.HttpStatus.BAD_REQUEST);
        }
        await this.systemConfig.saveMarketplaceConfig(config);
        return { success: true, message: 'Marketplace settings saved successfully' };
    }
    async getPaymentConfig() {
        const config = await this.systemConfig.getStripeConfig();
        const maskKey = (key) => {
            if (!key || key.length < 8)
                return key ? '****' : '';
            return `${key.substring(0, 7)}...${key.slice(-4)}`;
        };
        return {
            publishableKey: maskKey(config.publishableKey),
            secretKey: maskKey(config.secretKey),
            webhookSecret: maskKey(config.webhookSecret),
            isLiveMode: config.isLiveMode,
            isConfigured: config.isConfigured,
            provider: 'stripe',
        };
    }
    async savePaymentConfig(body) {
        const publishableKey = body.publishableKey?.trim() || '';
        const secretKey = body.secretKey?.trim() || '';
        const webhookSecret = body.webhookSecret?.trim() || '';
        if (publishableKey && !publishableKey.startsWith('pk_')) {
            throw new common_1.HttpException('Invalid publishable key format. Must start with pk_test_ or pk_live_', common_1.HttpStatus.BAD_REQUEST);
        }
        if (secretKey && !secretKey.startsWith('sk_')) {
            throw new common_1.HttpException('Invalid secret key format. Must start with sk_test_ or sk_live_', common_1.HttpStatus.BAD_REQUEST);
        }
        if (webhookSecret && !webhookSecret.startsWith('whsec_')) {
            throw new common_1.HttpException('Invalid webhook secret format. Must start with whsec_', common_1.HttpStatus.BAD_REQUEST);
        }
        if (publishableKey && secretKey) {
            const pubIsLive = publishableKey.startsWith('pk_live_');
            const secIsLive = secretKey.startsWith('sk_live_');
            if (pubIsLive !== secIsLive) {
                throw new common_1.HttpException('Key mode mismatch: Cannot mix test and live keys', common_1.HttpStatus.BAD_REQUEST);
            }
        }
        await this.systemConfig.saveStripeConfig({
            publishableKey,
            secretKey,
            webhookSecret,
        });
        return { success: true, message: 'Payment settings saved successfully' };
    }
    async testPaymentConfig() {
        const config = await this.systemConfig.getStripeConfig();
        if (!config.secretKey) {
            throw new common_1.HttpException('Stripe secret key is not configured', common_1.HttpStatus.BAD_REQUEST);
        }
        try {
            const stripe = new stripe_1.default(config.secretKey);
            const account = await stripe.accounts.retrieve();
            return {
                success: true,
                message: 'Stripe connection successful',
                accountId: account.id,
                isLiveMode: config.isLiveMode,
            };
        }
        catch (error) {
            const message = error instanceof Error ? error.message : 'Unknown error';
            throw new common_1.HttpException(`Stripe connection failed: ${message}`, common_1.HttpStatus.BAD_REQUEST);
        }
    }
};
exports.SystemConfigController = SystemConfigController;
__decorate([
    (0, common_1.Get)('email'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SystemConfigController.prototype, "getEmailConfig", null);
__decorate([
    (0, common_1.Put)('email'),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SystemConfigController.prototype, "saveEmailConfig", null);
__decorate([
    (0, common_1.Post)('email/test'),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SystemConfigController.prototype, "testEmailConfig", null);
__decorate([
    (0, common_1.Get)('domain'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SystemConfigController.prototype, "getDomainConfig", null);
__decorate([
    (0, common_1.Put)('domain'),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_c = typeof system_config_service_1.DomainConfig !== "undefined" && system_config_service_1.DomainConfig) === "function" ? _c : Object]),
    __metadata("design:returntype", Promise)
], SystemConfigController.prototype, "saveDomainConfig", null);
__decorate([
    (0, common_1.Get)('setup-status'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SystemConfigController.prototype, "getSetupStatus", null);
__decorate([
    (0, common_1.Get)('marketplace'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SystemConfigController.prototype, "getMarketplaceConfig", null);
__decorate([
    (0, common_1.Put)('marketplace'),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_d = typeof system_config_service_1.MarketplaceConfig !== "undefined" && system_config_service_1.MarketplaceConfig) === "function" ? _d : Object]),
    __metadata("design:returntype", Promise)
], SystemConfigController.prototype, "saveMarketplaceConfig", null);
__decorate([
    (0, common_1.Get)('payment'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SystemConfigController.prototype, "getPaymentConfig", null);
__decorate([
    (0, common_1.Put)('payment'),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SystemConfigController.prototype, "savePaymentConfig", null);
__decorate([
    (0, common_1.Post)('payment/test'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SystemConfigController.prototype, "testPaymentConfig", null);
exports.SystemConfigController = SystemConfigController = __decorate([
    (0, common_1.Controller)('api/system-config'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __metadata("design:paramtypes", [typeof (_a = typeof system_config_service_1.SystemConfigService !== "undefined" && system_config_service_1.SystemConfigService) === "function" ? _a : Object])
], SystemConfigController);


/***/ }),
/* 82 */
/***/ ((module) => {

module.exports = require("stripe");

/***/ }),
/* 83 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SetupWizardController = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const system_config_service_1 = __webpack_require__(52);
const bcrypt = __webpack_require__(46);
const nodemailer = __webpack_require__(34);
let SetupWizardController = class SetupWizardController {
    constructor(prisma, systemConfig) {
        this.prisma = prisma;
        this.systemConfig = systemConfig;
    }
    async getSetupStatus() {
        const status = await this.systemConfig.getSetupStatus();
        const adminExists = await this.prisma.user.findFirst({ where: { role: 'ADMIN' } });
        return {
            setupRequired: !status.setupComplete,
            adminCreated: !!adminExists,
            smtpConfigured: status.smtpConfigured,
            domainConfigured: status.domainConfigured,
        };
    }
    async createAdmin(dto) {
        await this.ensureSetupNotComplete();
        if (!dto.email || !dto.password || !dto.name) {
            throw new common_1.HttpException('Email, name, and password are required', common_1.HttpStatus.BAD_REQUEST);
        }
        if (dto.password.length < 8) {
            throw new common_1.HttpException('Password must be at least 8 characters', common_1.HttpStatus.BAD_REQUEST);
        }
        const existingAdmin = await this.prisma.user.findFirst({ where: { role: 'ADMIN' } });
        if (existingAdmin) {
            throw new common_1.HttpException('Admin account already exists', common_1.HttpStatus.CONFLICT);
        }
        const hashedPassword = await bcrypt.hash(dto.password, 12);
        const admin = await this.prisma.user.create({
            data: {
                email: dto.email,
                name: dto.name,
                password: hashedPassword,
                role: 'ADMIN',
            },
        });
        await this.prisma.setupStatus.upsert({
            where: { id: 'setup' },
            update: { adminCreated: true },
            create: { id: 'setup', adminCreated: true },
        });
        return { success: true, message: 'Admin account created', adminId: admin.id };
    }
    async configureSmtp(config) {
        await this.ensureSetupNotComplete();
        try {
            const transporter = nodemailer.createTransport({
                host: config.host,
                port: config.port,
                secure: config.secure,
                auth: { user: config.user, pass: config.pass },
            });
            await transporter.verify();
        }
        catch (error) {
            const msg = error instanceof Error ? error.message : 'Unknown error';
            throw new common_1.HttpException(`SMTP connection failed: ${msg}`, common_1.HttpStatus.BAD_REQUEST);
        }
        await this.systemConfig.saveSmtpConfig(config);
        await this.prisma.setupStatus.upsert({
            where: { id: 'setup' },
            update: { smtpConfigured: true },
            create: { id: 'setup', smtpConfigured: true },
        });
        return { success: true, message: 'SMTP configured successfully' };
    }
    async completeSetup(dto) {
        await this.ensureSetupNotComplete();
        if (dto.admin) {
            const existingAdmin = await this.prisma.user.findFirst({ where: { role: 'ADMIN' } });
            if (!existingAdmin) {
                const hashedPassword = await bcrypt.hash(dto.admin.password, 12);
                await this.prisma.user.create({
                    data: {
                        email: dto.admin.email,
                        name: dto.admin.name,
                        password: hashedPassword,
                        role: 'ADMIN',
                    },
                });
            }
        }
        if (dto.smtp) {
            await this.systemConfig.saveSmtpConfig(dto.smtp);
        }
        if (dto.domain) {
            await this.systemConfig.saveDomainConfig(dto.domain);
        }
        await this.systemConfig.markSetupComplete();
        return { success: true, message: 'Setup completed successfully' };
    }
    async ensureSetupNotComplete() {
        const isComplete = await this.systemConfig.isSetupComplete();
        if (isComplete) {
            throw new common_1.HttpException('Setup already completed', common_1.HttpStatus.FORBIDDEN);
        }
    }
};
exports.SetupWizardController = SetupWizardController;
__decorate([
    (0, common_1.Get)('status'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SetupWizardController.prototype, "getSetupStatus", null);
__decorate([
    (0, common_1.Post)('admin'),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SetupWizardController.prototype, "createAdmin", null);
__decorate([
    (0, common_1.Post)('smtp'),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_c = typeof system_config_service_1.SmtpConfig !== "undefined" && system_config_service_1.SmtpConfig) === "function" ? _c : Object]),
    __metadata("design:returntype", Promise)
], SetupWizardController.prototype, "configureSmtp", null);
__decorate([
    (0, common_1.Post)('complete'),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SetupWizardController.prototype, "completeSetup", null);
exports.SetupWizardController = SetupWizardController = __decorate([
    (0, common_1.Controller)('api/setup'),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof system_config_service_1.SystemConfigService !== "undefined" && system_config_service_1.SystemConfigService) === "function" ? _b : Object])
], SetupWizardController);


/***/ }),
/* 84 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.EmailTemplatesService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const email_service_1 = __webpack_require__(50);
const client_1 = __webpack_require__(17);
let EmailTemplatesService = class EmailTemplatesService {
    constructor(prisma, emailService) {
        this.prisma = prisma;
        this.emailService = emailService;
    }
    async create(dto, userId) {
        const existing = await this.prisma.emailTemplate.findUnique({
            where: { slug: dto.slug },
        });
        if (existing) {
            throw new common_1.ConflictException(`Template with slug "${dto.slug}" already exists`);
        }
        return this.prisma.emailTemplate.create({
            data: {
                name: dto.name,
                slug: dto.slug,
                type: dto.type || client_1.EmailTemplateType.CUSTOM,
                subject: dto.subject,
                htmlContent: dto.htmlContent,
                textContent: dto.textContent,
                variables: dto.variables ? JSON.parse(JSON.stringify(dto.variables)) : undefined,
                isActive: dto.isActive ?? true,
                isSystem: dto.isSystem ?? false,
                createdById: userId,
            },
        });
    }
    async findAll(page = 1, limit = 20, type) {
        const skip = (page - 1) * limit;
        const where = type ? { type } : {};
        const [templates, total] = await Promise.all([
            this.prisma.emailTemplate.findMany({
                where,
                skip,
                take: limit,
                orderBy: { createdAt: 'desc' },
                include: {
                    createdBy: { select: { id: true, name: true, email: true } },
                    _count: { select: { emailLogs: true } },
                },
            }),
            this.prisma.emailTemplate.count({ where }),
        ]);
        return {
            data: templates,
            total,
            page,
            limit,
            totalPages: Math.ceil(total / limit),
        };
    }
    async findById(id) {
        const template = await this.prisma.emailTemplate.findUnique({
            where: { id },
            include: {
                createdBy: { select: { id: true, name: true, email: true } },
                _count: { select: { emailLogs: true } },
            },
        });
        if (!template) {
            throw new common_1.NotFoundException(`Template with ID "${id}" not found`);
        }
        return template;
    }
    async findBySlug(slug) {
        const template = await this.prisma.emailTemplate.findUnique({
            where: { slug },
        });
        if (!template) {
            throw new common_1.NotFoundException(`Template with slug "${slug}" not found`);
        }
        return template;
    }
    async update(id, dto) {
        const template = await this.findById(id);
        if (template.isSystem && dto.isSystem === false) {
            throw new common_1.ConflictException('Cannot change system template status');
        }
        if (dto.slug && dto.slug !== template.slug) {
            const existing = await this.prisma.emailTemplate.findUnique({
                where: { slug: dto.slug },
            });
            if (existing) {
                throw new common_1.ConflictException(`Template with slug "${dto.slug}" already exists`);
            }
        }
        const updateData = { ...dto };
        if (dto.variables) {
            updateData.variables = JSON.parse(JSON.stringify(dto.variables));
        }
        return this.prisma.emailTemplate.update({
            where: { id },
            data: updateData,
        });
    }
    async delete(id) {
        const template = await this.findById(id);
        if (template.isSystem) {
            throw new common_1.ConflictException('Cannot delete system templates');
        }
        return this.prisma.emailTemplate.delete({ where: { id } });
    }
    async preview(id, variables) {
        const template = await this.findById(id);
        const renderedHtml = this.emailService.renderTemplate(template.htmlContent, variables);
        const renderedSubject = this.emailService.renderTemplate(template.subject, variables);
        return {
            subject: renderedSubject,
            html: renderedHtml,
            text: template.textContent
                ? this.emailService.renderTemplate(template.textContent, variables)
                : null,
        };
    }
};
exports.EmailTemplatesService = EmailTemplatesService;
exports.EmailTemplatesService = EmailTemplatesService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof email_service_1.EmailService !== "undefined" && email_service_1.EmailService) === "function" ? _b : Object])
], EmailTemplatesService);


/***/ }),
/* 85 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.EmailLogsService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const client_1 = __webpack_require__(17);
let EmailLogsService = class EmailLogsService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async findAll(page = 1, limit = 20, filters = {}) {
        const skip = (page - 1) * limit;
        const where = {};
        if (filters.status) {
            where.status = filters.status;
        }
        if (filters.templateId) {
            where.templateId = filters.templateId;
        }
        if (filters.recipientId) {
            where.recipientId = filters.recipientId;
        }
        if (filters.toEmail) {
            where.toEmail = { contains: filters.toEmail, mode: 'insensitive' };
        }
        if (filters.startDate || filters.endDate) {
            where.createdAt = {};
            if (filters.startDate) {
                where.createdAt.gte = filters.startDate;
            }
            if (filters.endDate) {
                where.createdAt.lte = filters.endDate;
            }
        }
        const [logs, total] = await Promise.all([
            this.prisma.emailLog.findMany({
                where,
                skip,
                take: limit,
                orderBy: { createdAt: 'desc' },
                include: {
                    template: { select: { id: true, name: true, slug: true, type: true } },
                    recipient: { select: { id: true, name: true, email: true } },
                },
            }),
            this.prisma.emailLog.count({ where }),
        ]);
        return {
            data: logs,
            total,
            page,
            limit,
            totalPages: Math.ceil(total / limit),
        };
    }
    async findById(id) {
        const log = await this.prisma.emailLog.findUnique({
            where: { id },
            include: {
                template: { select: { id: true, name: true, slug: true, type: true } },
                recipient: { select: { id: true, name: true, email: true } },
            },
        });
        if (!log) {
            throw new common_1.NotFoundException(`Email log with ID "${id}" not found`);
        }
        return log;
    }
    async getStats(startDate, endDate) {
        const where = {};
        if (startDate || endDate) {
            where.createdAt = {};
            if (startDate)
                where.createdAt.gte = startDate;
            if (endDate)
                where.createdAt.lte = endDate;
        }
        const [total, sent, delivered, failed, pending] = await Promise.all([
            this.prisma.emailLog.count({ where }),
            this.prisma.emailLog.count({ where: { ...where, status: client_1.EmailStatus.SENT } }),
            this.prisma.emailLog.count({ where: { ...where, status: client_1.EmailStatus.DELIVERED } }),
            this.prisma.emailLog.count({ where: { ...where, status: client_1.EmailStatus.FAILED } }),
            this.prisma.emailLog.count({ where: { ...where, status: client_1.EmailStatus.PENDING } }),
        ]);
        const byTemplate = await this.prisma.emailLog.groupBy({
            by: ['templateId'],
            _count: { id: true },
            where,
        });
        return {
            total,
            sent,
            delivered,
            failed,
            pending,
            successRate: total > 0 ? (((sent + delivered) / total) * 100).toFixed(2) : '0.00',
            byTemplate,
        };
    }
    async getRecentActivity(limit = 10) {
        return this.prisma.emailLog.findMany({
            take: limit,
            orderBy: { createdAt: 'desc' },
            include: {
                template: { select: { name: true, type: true } },
                recipient: { select: { name: true, email: true } },
            },
        });
    }
    async cleanupOldLogs(daysOld = 90) {
        const cutoffDate = new Date();
        cutoffDate.setDate(cutoffDate.getDate() - daysOld);
        const result = await this.prisma.emailLog.deleteMany({
            where: { createdAt: { lt: cutoffDate } },
        });
        return { deleted: result.count };
    }
};
exports.EmailLogsService = EmailLogsService;
exports.EmailLogsService = EmailLogsService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], EmailLogsService);


/***/ }),
/* 86 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 BulkEmailService_1;
var _a, _b, _c;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.BulkEmailService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const email_service_1 = __webpack_require__(50);
const email_templates_service_1 = __webpack_require__(84);
let BulkEmailService = BulkEmailService_1 = class BulkEmailService {
    constructor(prisma, emailService, templatesService) {
        this.prisma = prisma;
        this.emailService = emailService;
        this.templatesService = templatesService;
        this.logger = new common_1.Logger(BulkEmailService_1.name);
    }
    async sendBulkEmail(options) {
        const template = await this.templatesService.findById(options.templateId);
        const recipients = await this.getRecipients(options);
        if (recipients.length === 0) {
            throw new common_1.BadRequestException('No recipients found');
        }
        if (options.sendTestTo) {
            await this.sendTestEmail(options.sendTestTo, template, options.variables || {});
        }
        const result = {
            totalRecipients: recipients.length,
            successful: 0,
            failed: 0,
            errors: [],
        };
        const batchSize = 10;
        for (let i = 0; i < recipients.length; i += batchSize) {
            const batch = recipients.slice(i, i + batchSize);
            await Promise.all(batch.map(async (user) => {
                const userVars = {
                    ...options.variables,
                    user: {
                        id: user.id,
                        name: user.name,
                        email: user.email,
                        firstName: user.name.split(' ')[0],
                    },
                };
                const renderedHtml = this.emailService.renderTemplate(template.htmlContent, userVars);
                const subject = options.subject
                    ? this.emailService.renderTemplate(options.subject, userVars)
                    : this.emailService.renderTemplate(template.subject, userVars);
                const sendResult = await this.emailService.send({
                    to: user.email,
                    toName: user.name,
                    subject,
                    html: renderedHtml,
                    text: template.textContent
                        ? this.emailService.renderTemplate(template.textContent, userVars)
                        : undefined,
                    templateId: template.id,
                    recipientId: user.id,
                    metadata: { bulkEmail: true, ...options.variables },
                });
                if (sendResult.success) {
                    result.successful++;
                }
                else {
                    result.failed++;
                    result.errors.push({ email: user.email, error: sendResult.error || 'Unknown error' });
                }
            }));
            if (i + batchSize < recipients.length) {
                await new Promise((resolve) => setTimeout(resolve, 1000));
            }
        }
        this.logger.log(`Bulk email sent: ${result.successful}/${result.totalRecipients} successful`);
        return result;
    }
    async getRecipients(options) {
        if (options.recipientType === 'specific' && options.userIds?.length) {
            return this.prisma.user.findMany({
                where: { id: { in: options.userIds } },
                select: { id: true, name: true, email: true },
            });
        }
        if (options.recipientType === 'role' && options.role) {
            return this.prisma.user.findMany({
                where: { role: options.role },
                select: { id: true, name: true, email: true },
            });
        }
        return this.prisma.user.findMany({
            select: { id: true, name: true, email: true },
        });
    }
    async sendTestEmail(testEmail, template, variables) {
        const testVars = {
            ...variables,
            user: { id: 'test', name: 'Test User', email: testEmail, firstName: 'Test' },
        };
        await this.emailService.send({
            to: testEmail,
            toName: 'Test User',
            subject: `[TEST] ${this.emailService.renderTemplate(template.subject, testVars)}`,
            html: this.emailService.renderTemplate(template.htmlContent, testVars),
            templateId: template.id,
            metadata: { testEmail: true },
        });
    }
};
exports.BulkEmailService = BulkEmailService;
exports.BulkEmailService = BulkEmailService = BulkEmailService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof email_service_1.EmailService !== "undefined" && email_service_1.EmailService) === "function" ? _b : Object, typeof (_c = typeof email_templates_service_1.EmailTemplatesService !== "undefined" && email_templates_service_1.EmailTemplatesService) === "function" ? _c : Object])
], BulkEmailService);


/***/ }),
/* 87 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 EmailTemplatesSeederService_1;
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.EmailTemplatesSeederService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const client_1 = __webpack_require__(17);
const templates_1 = __webpack_require__(88);
let EmailTemplatesSeederService = EmailTemplatesSeederService_1 = class EmailTemplatesSeederService {
    constructor(prisma) {
        this.prisma = prisma;
        this.logger = new common_1.Logger(EmailTemplatesSeederService_1.name);
    }
    async onModuleInit() {
        await this.seedTemplates();
    }
    async seedTemplates() {
        const templates = [
            {
                slug: 'welcome-email',
                name: 'Welcome Email',
                type: client_1.EmailTemplateType.WELCOME,
                subject: 'Welcome to {{site.name}}! 🎉',
                htmlContent: (0, templates_1.getWelcomeTemplate)(),
                variables: [
                    { name: 'user.name', description: 'User full name' },
                    { name: 'user.firstName', description: 'User first name' },
                    { name: 'user.email', description: 'User email' },
                    { name: 'site.name', description: 'Site name' },
                    { name: 'site.url', description: 'Site URL' },
                    { name: 'loginUrl', description: 'Login URL' },
                ],
                isSystem: true,
            },
            {
                slug: 'password-reset',
                name: 'Password Reset',
                type: client_1.EmailTemplateType.PASSWORD_RESET,
                subject: 'Reset Your Password - {{site.name}}',
                htmlContent: (0, templates_1.getPasswordResetTemplate)({
                    user: { firstName: '{{user.firstName}}' },
                    resetUrl: '{{resetUrl}}',
                    expiresIn: '{{expiresIn}}',
                    supportUrl: '{{supportUrl}}',
                }),
                variables: [
                    { name: 'user.firstName', description: 'User first name' },
                    { name: 'resetUrl', description: 'Password reset URL' },
                    { name: 'expiresIn', description: 'Link expiration time' },
                    { name: 'supportUrl', description: 'Support page URL' },
                    { name: 'site.name', description: 'Site name' },
                ],
                isSystem: true,
            },
            {
                slug: 'order-confirmation',
                name: 'Order Confirmation',
                type: client_1.EmailTemplateType.ORDER_CONFIRMATION,
                subject: 'Order Confirmed #{{order.number}} - {{site.name}}',
                htmlContent: (0, templates_1.getOrderConfirmationTemplate)(),
                variables: [
                    { name: 'user.name', description: 'Customer name' },
                    { name: 'order.number', description: 'Order number' },
                    { name: 'order.total', description: 'Order total' },
                    { name: 'order.items', description: 'Order items array' },
                    { name: 'order.shippingAddress', description: 'Shipping address' },
                    { name: 'site.name', description: 'Site name' },
                ],
                isSystem: true,
            },
            {
                slug: 'course-enrollment',
                name: 'Course Enrollment',
                type: client_1.EmailTemplateType.COURSE_ENROLLMENT,
                subject: "You're Enrolled! 📚 {{course.title}}",
                htmlContent: (0, templates_1.getCourseEnrollmentTemplate)(),
                variables: [
                    { name: 'user.name', description: 'Student name' },
                    { name: 'course.title', description: 'Course title' },
                    { name: 'course.description', description: 'Course description' },
                    { name: 'course.thumbnail', description: 'Course thumbnail URL' },
                    { name: 'courseUrl', description: 'Course URL' },
                    { name: 'site.name', description: 'Site name' },
                ],
                isSystem: true,
            },
            {
                slug: 'newsletter',
                name: 'Newsletter',
                type: client_1.EmailTemplateType.NEWSLETTER,
                subject: '{{subject}} - {{site.name}}',
                htmlContent: (0, templates_1.getNewsletterTemplate)(),
                variables: [
                    { name: 'user.name', description: 'Recipient name' },
                    { name: 'subject', description: 'Email subject' },
                    { name: 'content', description: 'Newsletter content (HTML)' },
                    { name: 'site.name', description: 'Site name' },
                    { name: 'unsubscribeUrl', description: 'Unsubscribe URL' },
                ],
                isSystem: true,
            },
        ];
        for (const template of templates) {
            const existing = await this.prisma.emailTemplate.findUnique({
                where: { slug: template.slug },
            });
            if (!existing) {
                await this.prisma.emailTemplate.create({
                    data: {
                        ...template,
                        isActive: true,
                    },
                });
                this.logger.log(`Created email template: ${template.name}`);
            }
        }
        this.logger.log('Email templates seeding complete');
    }
};
exports.EmailTemplatesSeederService = EmailTemplatesSeederService;
exports.EmailTemplatesSeederService = EmailTemplatesSeederService = EmailTemplatesSeederService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], EmailTemplatesSeederService);


/***/ }),
/* 88 */
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getNewsletterTemplate = exports.getCourseEnrollmentTemplate = exports.getOrderConfirmationTemplate = exports.getPasswordResetTemplate = exports.getWelcomeTemplate = exports.getBaseEmailTemplate = void 0;
var base_template_1 = __webpack_require__(55);
Object.defineProperty(exports, "getBaseEmailTemplate", ({ enumerable: true, get: function () { return base_template_1.getBaseEmailTemplate; } }));
var welcome_template_1 = __webpack_require__(89);
Object.defineProperty(exports, "getWelcomeTemplate", ({ enumerable: true, get: function () { return welcome_template_1.getWelcomeTemplate; } }));
var password_reset_template_1 = __webpack_require__(54);
Object.defineProperty(exports, "getPasswordResetTemplate", ({ enumerable: true, get: function () { return password_reset_template_1.getPasswordResetTemplate; } }));
var order_confirmation_template_1 = __webpack_require__(90);
Object.defineProperty(exports, "getOrderConfirmationTemplate", ({ enumerable: true, get: function () { return order_confirmation_template_1.getOrderConfirmationTemplate; } }));
var course_enrollment_template_1 = __webpack_require__(91);
Object.defineProperty(exports, "getCourseEnrollmentTemplate", ({ enumerable: true, get: function () { return course_enrollment_template_1.getCourseEnrollmentTemplate; } }));
var newsletter_template_1 = __webpack_require__(92);
Object.defineProperty(exports, "getNewsletterTemplate", ({ enumerable: true, get: function () { return newsletter_template_1.getNewsletterTemplate; } }));


/***/ }),
/* 89 */
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getWelcomeTemplate = getWelcomeTemplate;
const base_template_1 = __webpack_require__(55);
function getWelcomeTemplate() {
    const content = `
<!-- Hero Section -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="text-align: center; padding-bottom: 32px;">
      <div style="width: 100px; height: 100px; margin: 0 auto 20px; background: linear-gradient(135deg, #10b981 0%, #059669 100%); border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 48px; box-shadow: 0 8px 16px rgba(16, 185, 129, 0.2);">
        🎉
      </div>
      <h1 style="margin: 0 0 12px; font-size: 32px; font-weight: 800; color: #111827; letter-spacing: -1px;">
        Welcome, {{user.firstName}}!
      </h1>
      <p style="margin: 0; font-size: 18px; color: #6b7280; font-weight: 500;">
        Your journey starts here
      </p>
    </td>
  </tr>
</table>

<!-- Main Message -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="padding-bottom: 32px;">
      <p style="margin: 0 0 16px; font-size: 16px; line-height: 1.8; color: #374151;">
        We're absolutely thrilled to have you join <strong style="color: #111827;">{{site.name}}</strong>! Your account has been successfully created, and you're now part of our amazing community.
      </p>
      <p style="margin: 0; font-size: 16px; line-height: 1.8; color: #374151;">
        Whether you're here to learn, shop, or connect with others, we've got everything you need to get started.
      </p>
    </td>
  </tr>
</table>

<!-- Account Info Card -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="padding-bottom: 32px;">
      <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
        <tr>
          <td style="background: linear-gradient(135deg, #f0f9ff 0%, #f0fdf4 100%); border-radius: 12px; padding: 24px; border-left: 4px solid #10b981;">
            <h3 style="margin: 0 0 16px; font-size: 16px; font-weight: 700; color: #111827;">Your Account Details</h3>
            <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
              <tr>
                <td style="padding: 8px 0;">
                  <p style="margin: 0; font-size: 14px; color: #6b7280;">
                    <span style="color: #111827; font-weight: 600;">Email:</span> {{user.email}}
                  </p>
                </td>
              </tr>
              <tr>
                <td style="padding: 8px 0;">
                  <p style="margin: 0; font-size: 14px; color: #6b7280;">
                    <span style="color: #111827; font-weight: 600;">Name:</span> {{user.name}}
                  </p>
                </td>
              </tr>
              <tr>
                <td style="padding: 8px 0;">
                  <p style="margin: 0; font-size: 14px; color: #6b7280;">
                    <span style="color: #111827; font-weight: 600;">Joined:</span> {{joinDate}}
                  </p>
                </td>
              </tr>
            </table>
          </td>
        </tr>
      </table>
    </td>
  </tr>
</table>

<!-- Quick Start Section -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="padding-bottom: 32px;">
      <h3 style="margin: 0 0 20px; font-size: 18px; font-weight: 700; color: #111827;">Quick Start Guide</h3>

      <!-- Step 1 -->
      <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="margin-bottom: 16px;">
        <tr>
          <td style="width: 50px; vertical-align: top; padding-right: 16px;">
            <div style="width: 40px; height: 40px; background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: white; font-weight: 700; font-size: 18px;">1</div>
          </td>
          <td style="vertical-align: top;">
            <h4 style="margin: 0 0 4px; font-size: 15px; font-weight: 600; color: #111827;">Complete Your Profile</h4>
            <p style="margin: 0; font-size: 14px; color: #6b7280;">Add a profile picture and bio to personalize your account</p>
          </td>
        </tr>
      </table>

      <!-- Step 2 -->
      <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="margin-bottom: 16px;">
        <tr>
          <td style="width: 50px; vertical-align: top; padding-right: 16px;">
            <div style="width: 40px; height: 40px; background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: white; font-weight: 700; font-size: 18px;">2</div>
          </td>
          <td style="vertical-align: top;">
            <h4 style="margin: 0 0 4px; font-size: 15px; font-weight: 600; color: #111827;">Explore Our Content</h4>
            <p style="margin: 0; font-size: 14px; color: #6b7280;">Browse courses, products, and articles tailored to your interests</p>
          </td>
        </tr>
      </table>

      <!-- Step 3 -->
      <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
        <tr>
          <td style="width: 50px; vertical-align: top; padding-right: 16px;">
            <div style="width: 40px; height: 40px; background: linear-gradient(135deg, #ec4899 0%, #db2777 100%); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: white; font-weight: 700; font-size: 18px;">3</div>
          </td>
          <td style="vertical-align: top;">
            <h4 style="margin: 0 0 4px; font-size: 15px; font-weight: 600; color: #111827;">Connect & Learn</h4>
            <p style="margin: 0; font-size: 14px; color: #6b7280;">Join our community and start your learning journey today</p>
          </td>
        </tr>
      </table>
    </td>
  </tr>
</table>

<!-- CTA Button -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="text-align: center; padding-bottom: 24px;">
      <a href="{{loginUrl}}" style="display: inline-block; padding: 16px 40px; background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%); color: #ffffff; font-size: 16px; font-weight: 700; text-decoration: none; border-radius: 8px; box-shadow: 0 8px 16px rgba(99, 102, 241, 0.3); transition: all 0.3s ease;">
        Get Started Now →
      </a>
    </td>
  </tr>
</table>

<!-- Support Section -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="padding-top: 24px; border-top: 1px solid #e5e7eb;">
      <p style="margin: 0 0 12px; font-size: 14px; color: #6b7280;">
        <strong style="color: #111827;">Need help?</strong> Our support team is here for you. Visit our <a href="{{helpUrl}}" style="color: #6366f1; text-decoration: none; font-weight: 600;">help center</a> or <a href="mailto:{{supportEmail}}" style="color: #6366f1; text-decoration: none; font-weight: 600;">contact us</a>.
      </p>
    </td>
  </tr>
</table>`;
    return (0, base_template_1.getBaseEmailTemplate)(content, {
        preheader: 'Welcome to our community! Get started in 3 easy steps.',
    });
}


/***/ }),
/* 90 */
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getOrderConfirmationTemplate = getOrderConfirmationTemplate;
const base_template_1 = __webpack_require__(55);
function getOrderConfirmationTemplate() {
    const content = `
<!-- Hero Section -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="text-align: center; padding-bottom: 32px;">
      <div style="width: 100px; height: 100px; margin: 0 auto 20px; background: linear-gradient(135deg, #10b981 0%, #059669 100%); border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 48px; box-shadow: 0 8px 16px rgba(16, 185, 129, 0.2);">
        ✓
      </div>
      <h1 style="margin: 0 0 12px; font-size: 32px; font-weight: 800; color: #111827; letter-spacing: -1px;">
        Order Confirmed!
      </h1>
      <p style="margin: 0; font-size: 16px; color: #6b7280;">
        Order #<strong style="color: #111827;">{{order.number}}</strong> • {{order.date}}
      </p>
    </td>
  </tr>
</table>

<!-- Main Message -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="padding-bottom: 32px;">
      <p style="margin: 0 0 16px; font-size: 16px; line-height: 1.8; color: #374151;">
        Hi {{user.firstName}},
      </p>
      <p style="margin: 0; font-size: 16px; line-height: 1.8; color: #374151;">
        Thank you for your order! We've received it and are getting everything ready to ship. You'll receive a tracking number as soon as your order leaves our warehouse.
      </p>
    </td>
  </tr>
</table>
<!-- Order Items -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="padding-bottom: 32px;">
      <h3 style="margin: 0 0 16px; font-size: 16px; font-weight: 700; color: #111827;">Order Items</h3>
      <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="background-color: #f9fafb; border-radius: 12px; overflow: hidden;">
        {{#each order.items}}
        <tr>
          <td style="padding: 16px 20px; border-bottom: 1px solid #e5e7eb;">
            <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
              <tr>
                <td style="width: 70px; vertical-align: top; padding-right: 12px;">
                  {{#if this.image}}
                  <img src="{{this.image}}" alt="{{this.name}}" width="60" height="60" style="border-radius: 8px; object-fit: cover; display: block;">
                  {{else}}
                  <div style="width: 60px; height: 60px; background: linear-gradient(135deg, #e5e7eb 0%, #d1d5db 100%); border-radius: 8px;"></div>
                  {{/if}}
                </td>
                <td style="vertical-align: top;">
                  <p style="margin: 0 0 4px; font-size: 15px; font-weight: 600; color: #111827;">{{this.name}}</p>
                  <p style="margin: 0 0 8px; font-size: 13px; color: #6b7280;">Quantity: <strong>{{this.quantity}}</strong></p>
                  {{#if this.sku}}<p style="margin: 0; font-size: 12px; color: #9ca3af;">SKU: {{this.sku}}</p>{{/if}}
                </td>
                <td style="text-align: right; vertical-align: top;">
                  <p style="margin: 0; font-size: 15px; font-weight: 700; color: #111827;">\${{this.total}}</p>
                  {{#if this.discount}}<p style="margin: 4px 0 0; font-size: 12px; color: #10b981; text-decoration: line-through; color: #6b7280;">\${{this.price}}</p>{{/if}}
                </td>
              </tr>
            </table>
          </td>
        </tr>
        {{/each}}
      </table>
    </td>
  </tr>
</table>

<!-- Order Summary -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="padding-bottom: 32px;">
      <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="background: linear-gradient(135deg, #f0f9ff 0%, #f0fdf4 100%); border-radius: 12px; padding: 24px; border: 1px solid #e0f2fe;">
        <tr>
          <td style="padding-bottom: 12px; border-bottom: 1px solid #bfdbfe;">
            <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
              <tr>
                <td><p style="margin: 0; font-size: 14px; color: #6b7280;">Subtotal</p></td>
                <td style="text-align: right;"><p style="margin: 0; font-size: 14px; color: #111827;">\${{order.subtotal}}</p></td>
              </tr>
            </table>
          </td>
        </tr>
        {{#if order.discount}}
        <tr>
          <td style="padding: 12px 0; border-bottom: 1px solid #bfdbfe;">
            <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
              <tr>
                <td><p style="margin: 0; font-size: 14px; color: #6b7280;">Discount</p></td>
                <td style="text-align: right;"><p style="margin: 0; font-size: 14px; color: #10b981; font-weight: 600;">-\${{order.discount}}</p></td>
              </tr>
            </table>
          </td>
        </tr>
        {{/if}}
        <tr>
          <td style="padding: 12px 0; border-bottom: 1px solid #bfdbfe;">
            <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
              <tr>
                <td><p style="margin: 0; font-size: 14px; color: #6b7280;">Shipping</p></td>
                <td style="text-align: right;"><p style="margin: 0; font-size: 14px; color: #111827;">{{#if order.shipping}}\${{order.shipping}}{{else}}<span style="color: #10b981; font-weight: 600;">Free</span>{{/if}}</p></td>
              </tr>
            </table>
          </td>
        </tr>
        {{#if order.tax}}
        <tr>
          <td style="padding: 12px 0; border-bottom: 1px solid #bfdbfe;">
            <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
              <tr>
                <td><p style="margin: 0; font-size: 14px; color: #6b7280;">Tax</p></td>
                <td style="text-align: right;"><p style="margin: 0; font-size: 14px; color: #111827;">\${{order.tax}}</p></td>
              </tr>
            </table>
          </td>
        </tr>
        {{/if}}
        <tr>
          <td style="padding-top: 12px;">
            <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
              <tr>
                <td><p style="margin: 0; font-size: 16px; font-weight: 800; color: #111827;">Total</p></td>
                <td style="text-align: right;"><p style="margin: 0; font-size: 20px; font-weight: 800; color: #10b981;">\${{order.total}}</p></td>
              </tr>
            </table>
          </td>
        </tr>
      </table>
    </td>
  </tr>
</table>
<!-- Shipping & Billing Info -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="padding-bottom: 32px;">
      <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
        <tr>
          {{#if order.shippingAddress}}
          <td style="width: 50%; padding-right: 12px; vertical-align: top;">
            <h4 style="margin: 0 0 12px; font-size: 14px; font-weight: 700; color: #111827;">📦 Shipping Address</h4>
            <p style="margin: 0; font-size: 13px; line-height: 1.8; color: #6b7280;">
              {{order.shippingAddress.name}}<br>
              {{order.shippingAddress.street}}<br>
              {{order.shippingAddress.city}}, {{order.shippingAddress.state}} {{order.shippingAddress.zip}}<br>
              {{order.shippingAddress.country}}
            </p>
          </td>
          {{/if}}
          {{#if order.billingAddress}}
          <td style="width: 50%; padding-left: 12px; vertical-align: top;">
            <h4 style="margin: 0 0 12px; font-size: 14px; font-weight: 700; color: #111827;">💳 Billing Address</h4>
            <p style="margin: 0; font-size: 13px; line-height: 1.8; color: #6b7280;">
              {{order.billingAddress.name}}<br>
              {{order.billingAddress.street}}<br>
              {{order.billingAddress.city}}, {{order.billingAddress.state}} {{order.billingAddress.zip}}<br>
              {{order.billingAddress.country}}
            </p>
          </td>
          {{/if}}
        </tr>
      </table>
    </td>
  </tr>
</table>

<!-- Next Steps -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="padding-bottom: 32px;">
      <h3 style="margin: 0 0 16px; font-size: 16px; font-weight: 700; color: #111827;">What's Next?</h3>
      <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
        <tr>
          <td style="padding: 12px 0; border-bottom: 1px solid #e5e7eb;">
            <table role="presentation" cellspacing="0" cellpadding="0" border="0">
              <tr>
                <td style="width: 30px; vertical-align: top; padding-right: 12px; font-size: 18px;">📧</td>
                <td>
                  <p style="margin: 0; font-size: 14px; color: #6b7280;">
                    <strong style="color: #111827;">Shipping Confirmation</strong> - You'll receive a tracking number via email when your order ships
                  </p>
                </td>
              </tr>
            </table>
          </td>
        </tr>
        <tr>
          <td style="padding: 12px 0;">
            <table role="presentation" cellspacing="0" cellpadding="0" border="0">
              <tr>
                <td style="width: 30px; vertical-align: top; padding-right: 12px; font-size: 18px;">🎁</td>
                <td>
                  <p style="margin: 0; font-size: 14px; color: #6b7280;">
                    <strong style="color: #111827;">Track Your Order</strong> - Click the button below to view your order status and tracking information
                  </p>
                </td>
              </tr>
            </table>
          </td>
        </tr>
      </table>
    </td>
  </tr>
</table>

<!-- CTA Button -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="text-align: center; padding-bottom: 24px;">
      <a href="{{orderUrl}}" style="display: inline-block; padding: 16px 40px; background: linear-gradient(135deg, #10b981 0%, #059669 100%); color: #ffffff; font-size: 16px; font-weight: 700; text-decoration: none; border-radius: 8px; box-shadow: 0 8px 16px rgba(16, 185, 129, 0.3);">
        Track Your Order →
      </a>
    </td>
  </tr>
</table>

<!-- Support -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="padding-top: 24px; border-top: 1px solid #e5e7eb;">
      <p style="margin: 0; font-size: 13px; color: #6b7280;">
        <strong style="color: #111827;">Questions?</strong> Our customer support team is ready to help. <a href="{{supportUrl}}" style="color: #10b981; text-decoration: none; font-weight: 600;">Contact us</a> anytime.
      </p>
    </td>
  </tr>
</table>`;
    return (0, base_template_1.getBaseEmailTemplate)(content, {
        preheader: 'Your order has been confirmed! Track your shipment.',
    });
}


/***/ }),
/* 91 */
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getCourseEnrollmentTemplate = getCourseEnrollmentTemplate;
const base_template_1 = __webpack_require__(55);
function getCourseEnrollmentTemplate() {
    const content = `
<!-- Hero Section -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="text-align: center; padding-bottom: 32px;">
      <div style="width: 100px; height: 100px; margin: 0 auto 20px; background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%); border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 48px; box-shadow: 0 8px 16px rgba(59, 130, 246, 0.2);">
        📚
      </div>
      <h1 style="margin: 0 0 12px; font-size: 32px; font-weight: 800; color: #111827; letter-spacing: -1px;">
        You're Enrolled!
      </h1>
      <p style="margin: 0; font-size: 16px; color: #6b7280;">
        Welcome to your learning journey
      </p>
    </td>
  </tr>
</table>

<!-- Main Message -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="padding-bottom: 32px;">
      <p style="margin: 0 0 16px; font-size: 16px; line-height: 1.8; color: #374151;">
        Hi {{user.firstName}},
      </p>
      <p style="margin: 0; font-size: 16px; line-height: 1.8; color: #374151;">
        Congratulations! You've successfully enrolled in <strong style="color: #111827;">{{course.title}}</strong>. Your learning journey starts now, and we're excited to have you on board!
      </p>
    </td>
  </tr>
</table>
<!-- Course Card -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="padding-bottom: 32px;">
      <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="background: linear-gradient(135deg, #f0f9ff 0%, #f0fdf4 100%); border-radius: 12px; overflow: hidden; border: 1px solid #bfdbfe;">
        {{#if course.thumbnail}}
        <tr>
          <td style="height: 200px; overflow: hidden;">
            <img src="{{course.thumbnail}}" alt="{{course.title}}" width="560" style="width: 100%; height: 100%; object-fit: cover; display: block;">
          </td>
        </tr>
        {{/if}}
        <tr>
          <td style="padding: 28px;">
            <h2 style="margin: 0 0 12px; font-size: 24px; font-weight: 800; color: #111827; line-height: 1.3;">
              {{course.title}}
            </h2>
            {{#if course.description}}
            <p style="margin: 0 0 20px; font-size: 15px; line-height: 1.7; color: #6b7280;">
              {{course.description}}
            </p>
            {{/if}}

            <!-- Course Stats -->
            <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
              {{#if course.instructor}}
              <tr>
                <td style="padding: 8px 0; border-bottom: 1px solid #e0f2fe;">
                  <table role="presentation" cellspacing="0" cellpadding="0" border="0">
                    <tr>
                      <td style="width: 30px; vertical-align: top; padding-right: 12px; font-size: 18px;">👨‍🏫</td>
                      <td>
                        <p style="margin: 0; font-size: 14px; color: #6b7280;">
                          <strong style="color: #111827;">Instructor:</strong> {{course.instructor}}
                        </p>
                      </td>
                    </tr>
                  </table>
                </td>
              </tr>
              {{/if}}
              {{#if course.lessons}}
              <tr>
                <td style="padding: 8px 0; border-bottom: 1px solid #e0f2fe;">
                  <table role="presentation" cellspacing="0" cellpadding="0" border="0">
                    <tr>
                      <td style="width: 30px; vertical-align: top; padding-right: 12px; font-size: 18px;">📖</td>
                      <td>
                        <p style="margin: 0; font-size: 14px; color: #6b7280;">
                          <strong style="color: #111827;">Lessons:</strong> {{course.lessons}} lessons
                        </p>
                      </td>
                    </tr>
                  </table>
                </td>
              </tr>
              {{/if}}
              {{#if course.duration}}
              <tr>
                <td style="padding: 8px 0;">
                  <table role="presentation" cellspacing="0" cellpadding="0" border="0">
                    <tr>
                      <td style="width: 30px; vertical-align: top; padding-right: 12px; font-size: 18px;">⏱️</td>
                      <td>
                        <p style="margin: 0; font-size: 14px; color: #6b7280;">
                          <strong style="color: #111827;">Duration:</strong> {{course.duration}}
                        </p>
                      </td>
                    </tr>
                  </table>
                </td>
              </tr>
              {{/if}}
            </table>
          </td>
        </tr>
      </table>
    </td>
  </tr>
</table>
<!-- Tips for Success -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="padding-bottom: 32px;">
      <h3 style="margin: 0 0 20px; font-size: 16px; font-weight: 700; color: #111827;">💡 Tips for Success</h3>

      <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="margin-bottom: 12px;">
        <tr>
          <td style="background: linear-gradient(135deg, #fef3c7 0%, #fef08a 100%); border-radius: 8px; padding: 16px; border-left: 4px solid #f59e0b;">
            <table role="presentation" cellspacing="0" cellpadding="0" border="0">
              <tr>
                <td style="width: 30px; vertical-align: top; padding-right: 12px; font-size: 20px;">🎯</td>
                <td>
                  <p style="margin: 0; font-size: 14px; color: #92400e;">
                    <strong>Set a Schedule</strong> - Dedicate regular time each week for learning
                  </p>
                </td>
              </tr>
            </table>
          </td>
        </tr>
      </table>

      <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="margin-bottom: 12px;">
        <tr>
          <td style="background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%); border-radius: 8px; padding: 16px; border-left: 4px solid #3b82f6;">
            <table role="presentation" cellspacing="0" cellpadding="0" border="0">
              <tr>
                <td style="width: 30px; vertical-align: top; padding-right: 12px; font-size: 20px;">📝</td>
                <td>
                  <p style="margin: 0; font-size: 14px; color: #1e40af;">
                    <strong>Take Notes</strong> - Writing helps with retention and understanding
                  </p>
                </td>
              </tr>
            </table>
          </td>
        </tr>
      </table>

      <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
        <tr>
          <td style="background: linear-gradient(135deg, #dcfce7 0%, #bbf7d0 100%); border-radius: 8px; padding: 16px; border-left: 4px solid #10b981;">
            <table role="presentation" cellspacing="0" cellpadding="0" border="0">
              <tr>
                <td style="width: 30px; vertical-align: top; padding-right: 12px; font-size: 20px;">🏆</td>
                <td>
                  <p style="margin: 0; font-size: 14px; color: #065f46;">
                    <strong>Complete Quizzes</strong> - Test your knowledge and track progress
                  </p>
                </td>
              </tr>
            </table>
          </td>
        </tr>
      </table>
    </td>
  </tr>
</table>

<!-- CTA Button -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="text-align: center; padding-bottom: 24px;">
      <a href="{{courseUrl}}" style="display: inline-block; padding: 16px 40px; background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%); color: #ffffff; font-size: 16px; font-weight: 700; text-decoration: none; border-radius: 8px; box-shadow: 0 8px 16px rgba(59, 130, 246, 0.3);">
        Start Learning Now →
      </a>
    </td>
  </tr>
</table>

<!-- Support -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="padding-top: 24px; border-top: 1px solid #e5e7eb;">
      <p style="margin: 0; font-size: 13px; color: #6b7280;">
        <strong style="color: #111827;">Need help?</strong> Check out our <a href="{{helpUrl}}" style="color: #3b82f6; text-decoration: none; font-weight: 600;">learning resources</a> or <a href="mailto:{{supportEmail}}" style="color: #3b82f6; text-decoration: none; font-weight: 600;">contact support</a>.
      </p>
    </td>
  </tr>
</table>`;
    return (0, base_template_1.getBaseEmailTemplate)(content, {
        preheader: 'Your course enrollment is confirmed! Start learning today.',
    });
}


/***/ }),
/* 92 */
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getNewsletterTemplate = getNewsletterTemplate;
const base_template_1 = __webpack_require__(55);
function getNewsletterTemplate() {
    const content = `
<!-- Greeting -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="padding-bottom: 24px;">
      <h2 style="margin: 0 0 12px; font-size: 24px; font-weight: 800; color: #111827;">
        {{newsletter.title}}
      </h2>
      <p style="margin: 0; font-size: 16px; color: #6b7280;">
        {{newsletter.subtitle}}
      </p>
    </td>
  </tr>
</table>

<!-- Main Content -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="padding-bottom: 32px;">
      <p style="margin: 0 0 16px; font-size: 16px; line-height: 1.8; color: #374151;">
        Hi {{user.firstName}},
      </p>
      <!-- Dynamic content inserted here -->
      <div style="font-size: 16px; line-height: 1.8; color: #374151;">
        {{{content}}}
      </div>
    </td>
  </tr>
</table>
<!-- Featured Items -->
{{#if featuredItems}}
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="padding-bottom: 32px;">
      <h3 style="margin: 0 0 20px; font-size: 18px; font-weight: 700; color: #111827;">✨ Featured This Week</h3>
      <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
        {{#each featuredItems}}
        <tr>
          <td style="padding: 20px; background: linear-gradient(135deg, #f9fafb 0%, #f3f4f6 100%); border-radius: 12px; margin-bottom: 16px; border: 1px solid #e5e7eb; transition: all 0.3s ease;">
            <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
              <tr>
                {{#if this.image}}
                <td style="width: 90px; vertical-align: top; padding-right: 16px;">
                  <img src="{{this.image}}" alt="{{this.title}}" width="80" height="80" style="border-radius: 8px; object-fit: cover; display: block;">
                </td>
                {{/if}}
                <td style="vertical-align: top;">
                  <h4 style="margin: 0 0 8px; font-size: 16px; font-weight: 700; color: #111827;">
                    <a href="{{this.url}}" style="color: #111827; text-decoration: none; border-bottom: 2px solid #6366f1;">{{this.title}}</a>
                  </h4>
                  <p style="margin: 0 0 8px; font-size: 14px; line-height: 1.6; color: #6b7280;">{{this.description}}</p>
                  {{#if this.category}}<p style="margin: 0; font-size: 12px; color: #9ca3af; font-weight: 600;">📁 {{this.category}}</p>{{/if}}
                </td>
              </tr>
            </table>
          </td>
        </tr>
        {{/each}}
      </table>
    </td>
  </tr>
</table>
{{/if}}
<!-- CTA Button -->
{{#if callToAction}}
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="text-align: center; padding-bottom: 32px;">
      <a href="{{callToAction.url}}" style="display: inline-block; padding: 16px 40px; background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%); color: #ffffff; font-size: 16px; font-weight: 700; text-decoration: none; border-radius: 8px; box-shadow: 0 8px 16px rgba(99, 102, 241, 0.3);">
        {{callToAction.text}} →
      </a>
    </td>
  </tr>
</table>
{{/if}}

<!-- Social Links & Footer -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
  <tr>
    <td style="border-top: 2px solid #e5e7eb; padding-top: 32px;">
      <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
        <tr>
          <td style="text-align: center;">
            <p style="margin: 0 0 20px; font-size: 14px; font-weight: 600; color: #111827;">
              Follow us for more updates
            </p>
            <table role="presentation" cellspacing="0" cellpadding="0" border="0" style="margin: 0 auto;">
              <tr>
                {{#if social.twitter}}
                <td style="padding: 0 10px;">
                  <a href="{{social.twitter}}" style="display: inline-block; width: 44px; height: 44px; background: linear-gradient(135deg, #1da1f2 0%, #1a8cd8 100%); border-radius: 50%; text-align: center; line-height: 44px; color: #fff; text-decoration: none; font-size: 18px; font-weight: 700; box-shadow: 0 4px 8px rgba(29, 161, 242, 0.2);">𝕏</a>
                </td>
                {{/if}}
                {{#if social.facebook}}
                <td style="padding: 0 10px;">
                  <a href="{{social.facebook}}" style="display: inline-block; width: 44px; height: 44px; background: linear-gradient(135deg, #1877f2 0%, #0a66c2 100%); border-radius: 50%; text-align: center; line-height: 44px; color: #fff; text-decoration: none; font-size: 18px; font-weight: 700; box-shadow: 0 4px 8px rgba(24, 119, 242, 0.2);">f</a>
                </td>
                {{/if}}
                {{#if social.linkedin}}
                <td style="padding: 0 10px;">
                  <a href="{{social.linkedin}}" style="display: inline-block; width: 44px; height: 44px; background: linear-gradient(135deg, #0a66c2 0%, #004182 100%); border-radius: 50%; text-align: center; line-height: 44px; color: #fff; text-decoration: none; font-size: 16px; font-weight: 700; box-shadow: 0 4px 8px rgba(10, 102, 194, 0.2);">in</a>
                </td>
                {{/if}}
                {{#if social.instagram}}
                <td style="padding: 0 10px;">
                  <a href="{{social.instagram}}" style="display: inline-block; width: 44px; height: 44px; background: linear-gradient(45deg, #f09433, #e6683c, #dc2743, #cc2366, #bc1888); border-radius: 50%; text-align: center; line-height: 44px; color: #fff; text-decoration: none; font-size: 18px; font-weight: 700; box-shadow: 0 4px 8px rgba(224, 136, 51, 0.2);">📷</a>
                </td>
                {{/if}}
              </tr>
            </table>
          </td>
        </tr>
      </table>
    </td>
  </tr>
</table>`;
    return (0, base_template_1.getBaseEmailTemplate)(content, {
        preheader: "Check out this week's featured content and updates",
    });
}


/***/ }),
/* 93 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.EmailController = void 0;
const common_1 = __webpack_require__(2);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const current_user_decorator_1 = __webpack_require__(63);
const client_1 = __webpack_require__(17);
const email_service_1 = __webpack_require__(50);
const email_templates_service_1 = __webpack_require__(84);
const email_logs_service_1 = __webpack_require__(85);
const bulk_email_service_1 = __webpack_require__(86);
const email_template_dto_1 = __webpack_require__(94);
const send_email_dto_1 = __webpack_require__(96);
let EmailController = class EmailController {
    constructor(emailService, templatesService, logsService, bulkEmailService) {
        this.emailService = emailService;
        this.templatesService = templatesService;
        this.logsService = logsService;
        this.bulkEmailService = bulkEmailService;
    }
    async getTemplates(page, limit, type) {
        return this.templatesService.findAll(page ? parseInt(page) : 1, limit ? parseInt(limit) : 20, type);
    }
    async getTemplate(id) {
        return this.templatesService.findById(id);
    }
    async createTemplate(dto, user) {
        return this.templatesService.create(dto, user.id);
    }
    async updateTemplate(id, dto) {
        return this.templatesService.update(id, dto);
    }
    async deleteTemplate(id) {
        return this.templatesService.delete(id);
    }
    async previewTemplate(id, dto) {
        return this.templatesService.preview(id, dto.variables || {});
    }
    async sendEmail(dto) {
        return this.emailService.send(dto);
    }
    async sendTemplateEmail(dto) {
        const template = await this.templatesService.findById(dto.templateId);
        const variables = dto.variables || {};
        const renderedHtml = this.emailService.renderTemplate(template.htmlContent, variables);
        const subject = dto.subject
            ? this.emailService.renderTemplate(dto.subject, variables)
            : this.emailService.renderTemplate(template.subject, variables);
        return this.emailService.send({
            to: dto.to,
            toName: dto.toName,
            subject,
            html: renderedHtml,
            text: template.textContent
                ? this.emailService.renderTemplate(template.textContent, variables)
                : undefined,
            templateId: template.id,
        });
    }
    async sendBulkEmail(dto) {
        return this.bulkEmailService.sendBulkEmail(dto);
    }
    async sendTestEmail(dto) {
        const template = await this.templatesService.findById(dto.templateId);
        const variables = {
            ...dto.variables,
            user: { id: 'test', name: 'Test User', email: dto.to, firstName: 'Test' },
        };
        const renderedHtml = this.emailService.renderTemplate(template.htmlContent, variables);
        const subject = `[TEST] ${this.emailService.renderTemplate(template.subject, variables)}`;
        return this.emailService.send({
            to: dto.to,
            toName: 'Test User',
            subject,
            html: renderedHtml,
            templateId: template.id,
            metadata: { testEmail: true },
        });
    }
    async verifyConnection() {
        const connected = await this.emailService.verifyConnection();
        return {
            connected,
            message: connected ? 'SMTP connection successful' : 'SMTP connection failed',
        };
    }
    async getLogs(page, limit, status, templateId, toEmail, startDate, endDate) {
        return this.logsService.findAll(page ? parseInt(page) : 1, limit ? parseInt(limit) : 20, {
            status,
            templateId,
            toEmail,
            startDate: startDate ? new Date(startDate) : undefined,
            endDate: endDate ? new Date(endDate) : undefined,
        });
    }
    async getLogStats(startDate, endDate) {
        return this.logsService.getStats(startDate ? new Date(startDate) : undefined, endDate ? new Date(endDate) : undefined);
    }
    async getRecentActivity(limit) {
        return this.logsService.getRecentActivity(limit ? parseInt(limit) : 10);
    }
    async getLog(id) {
        return this.logsService.findById(id);
    }
    async cleanupLogs(daysOld) {
        return this.logsService.cleanupOldLogs(daysOld ? parseInt(daysOld) : 90);
    }
};
exports.EmailController = EmailController;
__decorate([
    (0, common_1.Get)('templates'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Query)('page')),
    __param(1, (0, common_1.Query)('limit')),
    __param(2, (0, common_1.Query)('type')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, typeof (_e = typeof client_1.EmailTemplateType !== "undefined" && client_1.EmailTemplateType) === "function" ? _e : Object]),
    __metadata("design:returntype", Promise)
], EmailController.prototype, "getTemplates", null);
__decorate([
    (0, common_1.Get)('templates/:id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], EmailController.prototype, "getTemplate", null);
__decorate([
    (0, common_1.Post)('templates'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, current_user_decorator_1.CurrentUser)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_f = typeof email_template_dto_1.CreateEmailTemplateDto !== "undefined" && email_template_dto_1.CreateEmailTemplateDto) === "function" ? _f : Object, Object]),
    __metadata("design:returntype", Promise)
], EmailController.prototype, "createTemplate", null);
__decorate([
    (0, common_1.Put)('templates/:id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_g = typeof email_template_dto_1.UpdateEmailTemplateDto !== "undefined" && email_template_dto_1.UpdateEmailTemplateDto) === "function" ? _g : Object]),
    __metadata("design:returntype", Promise)
], EmailController.prototype, "updateTemplate", null);
__decorate([
    (0, common_1.Delete)('templates/:id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], EmailController.prototype, "deleteTemplate", null);
__decorate([
    (0, common_1.Post)('templates/:id/preview'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_h = typeof email_template_dto_1.PreviewTemplateDto !== "undefined" && email_template_dto_1.PreviewTemplateDto) === "function" ? _h : Object]),
    __metadata("design:returntype", Promise)
], EmailController.prototype, "previewTemplate", null);
__decorate([
    (0, common_1.Post)('send'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_j = typeof send_email_dto_1.SendEmailDto !== "undefined" && send_email_dto_1.SendEmailDto) === "function" ? _j : Object]),
    __metadata("design:returntype", Promise)
], EmailController.prototype, "sendEmail", null);
__decorate([
    (0, common_1.Post)('send-template'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_k = typeof send_email_dto_1.SendTemplateEmailDto !== "undefined" && send_email_dto_1.SendTemplateEmailDto) === "function" ? _k : Object]),
    __metadata("design:returntype", Promise)
], EmailController.prototype, "sendTemplateEmail", null);
__decorate([
    (0, common_1.Post)('send-bulk'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_l = typeof send_email_dto_1.SendBulkEmailDto !== "undefined" && send_email_dto_1.SendBulkEmailDto) === "function" ? _l : Object]),
    __metadata("design:returntype", Promise)
], EmailController.prototype, "sendBulkEmail", null);
__decorate([
    (0, common_1.Post)('send-test'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_m = typeof send_email_dto_1.SendTestEmailDto !== "undefined" && send_email_dto_1.SendTestEmailDto) === "function" ? _m : Object]),
    __metadata("design:returntype", Promise)
], EmailController.prototype, "sendTestEmail", null);
__decorate([
    (0, common_1.Get)('verify'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], EmailController.prototype, "verifyConnection", null);
__decorate([
    (0, common_1.Get)('logs'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Query)('page')),
    __param(1, (0, common_1.Query)('limit')),
    __param(2, (0, common_1.Query)('status')),
    __param(3, (0, common_1.Query)('templateId')),
    __param(4, (0, common_1.Query)('toEmail')),
    __param(5, (0, common_1.Query)('startDate')),
    __param(6, (0, common_1.Query)('endDate')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, typeof (_o = typeof client_1.EmailStatus !== "undefined" && client_1.EmailStatus) === "function" ? _o : Object, String, String, String, String]),
    __metadata("design:returntype", Promise)
], EmailController.prototype, "getLogs", null);
__decorate([
    (0, common_1.Get)('logs/stats'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Query)('startDate')),
    __param(1, (0, common_1.Query)('endDate')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", Promise)
], EmailController.prototype, "getLogStats", null);
__decorate([
    (0, common_1.Get)('logs/recent'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], EmailController.prototype, "getRecentActivity", null);
__decorate([
    (0, common_1.Get)('logs/:id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], EmailController.prototype, "getLog", null);
__decorate([
    (0, common_1.Delete)('logs/cleanup'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Query)('daysOld')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], EmailController.prototype, "cleanupLogs", null);
exports.EmailController = EmailController = __decorate([
    (0, common_1.Controller)('api/email'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof email_service_1.EmailService !== "undefined" && email_service_1.EmailService) === "function" ? _a : Object, typeof (_b = typeof email_templates_service_1.EmailTemplatesService !== "undefined" && email_templates_service_1.EmailTemplatesService) === "function" ? _b : Object, typeof (_c = typeof email_logs_service_1.EmailLogsService !== "undefined" && email_logs_service_1.EmailLogsService) === "function" ? _c : Object, typeof (_d = typeof bulk_email_service_1.BulkEmailService !== "undefined" && bulk_email_service_1.BulkEmailService) === "function" ? _d : Object])
], EmailController);


/***/ }),
/* 94 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b, _c;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PreviewTemplateDto = exports.UpdateEmailTemplateDto = exports.CreateEmailTemplateDto = exports.TemplateVariableDto = void 0;
const class_validator_1 = __webpack_require__(59);
const class_transformer_1 = __webpack_require__(95);
const client_1 = __webpack_require__(17);
class TemplateVariableDto {
}
exports.TemplateVariableDto = TemplateVariableDto;
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], TemplateVariableDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], TemplateVariableDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], TemplateVariableDto.prototype, "example", void 0);
class CreateEmailTemplateDto {
}
exports.CreateEmailTemplateDto = CreateEmailTemplateDto;
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateEmailTemplateDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateEmailTemplateDto.prototype, "slug", void 0);
__decorate([
    (0, class_validator_1.IsEnum)(client_1.EmailTemplateType),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_a = typeof client_1.EmailTemplateType !== "undefined" && client_1.EmailTemplateType) === "function" ? _a : Object)
], CreateEmailTemplateDto.prototype, "type", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateEmailTemplateDto.prototype, "subject", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateEmailTemplateDto.prototype, "htmlContent", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateEmailTemplateDto.prototype, "textContent", void 0);
__decorate([
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.ValidateNested)({ each: true }),
    (0, class_transformer_1.Type)(() => TemplateVariableDto),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], CreateEmailTemplateDto.prototype, "variables", void 0);
__decorate([
    (0, class_validator_1.IsBoolean)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Boolean)
], CreateEmailTemplateDto.prototype, "isActive", void 0);
__decorate([
    (0, class_validator_1.IsBoolean)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Boolean)
], CreateEmailTemplateDto.prototype, "isSystem", void 0);
class UpdateEmailTemplateDto {
}
exports.UpdateEmailTemplateDto = UpdateEmailTemplateDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateEmailTemplateDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateEmailTemplateDto.prototype, "slug", void 0);
__decorate([
    (0, class_validator_1.IsEnum)(client_1.EmailTemplateType),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_b = typeof client_1.EmailTemplateType !== "undefined" && client_1.EmailTemplateType) === "function" ? _b : Object)
], UpdateEmailTemplateDto.prototype, "type", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateEmailTemplateDto.prototype, "subject", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateEmailTemplateDto.prototype, "htmlContent", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateEmailTemplateDto.prototype, "textContent", void 0);
__decorate([
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.ValidateNested)({ each: true }),
    (0, class_transformer_1.Type)(() => TemplateVariableDto),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], UpdateEmailTemplateDto.prototype, "variables", void 0);
__decorate([
    (0, class_validator_1.IsBoolean)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Boolean)
], UpdateEmailTemplateDto.prototype, "isActive", void 0);
__decorate([
    (0, class_validator_1.IsBoolean)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Boolean)
], UpdateEmailTemplateDto.prototype, "isSystem", void 0);
class PreviewTemplateDto {
}
exports.PreviewTemplateDto = PreviewTemplateDto;
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_c = typeof Record !== "undefined" && Record) === "function" ? _c : Object)
], PreviewTemplateDto.prototype, "variables", void 0);


/***/ }),
/* 95 */
/***/ ((module) => {

module.exports = require("class-transformer");

/***/ }),
/* 96 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b, _c, _d;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SendTestEmailDto = exports.SendBulkEmailDto = exports.SendTemplateEmailDto = exports.SendEmailDto = void 0;
const class_validator_1 = __webpack_require__(59);
const client_1 = __webpack_require__(17);
class SendEmailDto {
}
exports.SendEmailDto = SendEmailDto;
__decorate([
    (0, class_validator_1.IsEmail)(),
    __metadata("design:type", String)
], SendEmailDto.prototype, "to", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], SendEmailDto.prototype, "toName", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], SendEmailDto.prototype, "subject", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], SendEmailDto.prototype, "html", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], SendEmailDto.prototype, "text", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], SendEmailDto.prototype, "templateId", void 0);
class SendTemplateEmailDto {
}
exports.SendTemplateEmailDto = SendTemplateEmailDto;
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], SendTemplateEmailDto.prototype, "templateId", void 0);
__decorate([
    (0, class_validator_1.IsEmail)(),
    __metadata("design:type", String)
], SendTemplateEmailDto.prototype, "to", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], SendTemplateEmailDto.prototype, "toName", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], SendTemplateEmailDto.prototype, "subject", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_a = typeof Record !== "undefined" && Record) === "function" ? _a : Object)
], SendTemplateEmailDto.prototype, "variables", void 0);
class SendBulkEmailDto {
}
exports.SendBulkEmailDto = SendBulkEmailDto;
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], SendBulkEmailDto.prototype, "templateId", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], SendBulkEmailDto.prototype, "subject", void 0);
__decorate([
    (0, class_validator_1.IsEnum)(['all', 'role', 'specific']),
    __metadata("design:type", String)
], SendBulkEmailDto.prototype, "recipientType", void 0);
__decorate([
    (0, class_validator_1.IsEnum)(client_1.UserRole),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_b = typeof client_1.UserRole !== "undefined" && client_1.UserRole) === "function" ? _b : Object)
], SendBulkEmailDto.prototype, "role", void 0);
__decorate([
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.IsString)({ each: true }),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], SendBulkEmailDto.prototype, "userIds", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_c = typeof Record !== "undefined" && Record) === "function" ? _c : Object)
], SendBulkEmailDto.prototype, "variables", void 0);
__decorate([
    (0, class_validator_1.IsEmail)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], SendBulkEmailDto.prototype, "sendTestTo", void 0);
class SendTestEmailDto {
}
exports.SendTestEmailDto = SendTestEmailDto;
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], SendTestEmailDto.prototype, "templateId", void 0);
__decorate([
    (0, class_validator_1.IsEmail)(),
    __metadata("design:type", String)
], SendTestEmailDto.prototype, "to", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_d = typeof Record !== "undefined" && Record) === "function" ? _d : Object)
], SendTestEmailDto.prototype, "variables", void 0);


/***/ }),
/* 97 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ContentModule = void 0;
const common_1 = __webpack_require__(2);
const prisma_module_1 = __webpack_require__(15);
const posts_service_1 = __webpack_require__(98);
const pages_service_1 = __webpack_require__(100);
const content_types_service_1 = __webpack_require__(101);
const posts_controller_1 = __webpack_require__(102);
const pages_controller_1 = __webpack_require__(105);
const content_types_controller_1 = __webpack_require__(108);
const page_customization_service_1 = __webpack_require__(111);
const post_customization_service_1 = __webpack_require__(112);
const page_customization_controller_1 = __webpack_require__(113);
const post_customization_controller_1 = __webpack_require__(116);
const customization_export_service_1 = __webpack_require__(119);
const customization_export_controller_1 = __webpack_require__(120);
const customization_presets_service_1 = __webpack_require__(121);
const customization_presets_controller_1 = __webpack_require__(122);
let ContentModule = class ContentModule {
};
exports.ContentModule = ContentModule;
exports.ContentModule = ContentModule = __decorate([
    (0, common_1.Module)({
        imports: [prisma_module_1.PrismaModule],
        providers: [
            posts_service_1.PostsService,
            pages_service_1.PagesService,
            content_types_service_1.ContentTypesService,
            page_customization_service_1.PageCustomizationService,
            post_customization_service_1.PostCustomizationService,
            customization_export_service_1.CustomizationExportService,
            customization_presets_service_1.CustomizationPresetsService,
        ],
        controllers: [
            posts_controller_1.PostsController,
            pages_controller_1.PagesController,
            content_types_controller_1.ContentTypesController,
            page_customization_controller_1.PageCustomizationController,
            post_customization_controller_1.PostCustomizationController,
            customization_export_controller_1.CustomizationExportController,
            customization_presets_controller_1.CustomizationPresetsController,
        ],
        exports: [
            posts_service_1.PostsService,
            pages_service_1.PagesService,
            content_types_service_1.ContentTypesService,
            page_customization_service_1.PageCustomizationService,
            post_customization_service_1.PostCustomizationService,
            customization_export_service_1.CustomizationExportService,
            customization_presets_service_1.CustomizationPresetsService,
        ],
    })
], ContentModule);


/***/ }),
/* 98 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PostsService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const client_1 = __webpack_require__(17);
const slugify_1 = __webpack_require__(99);
let PostsService = class PostsService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async generateSlug(title, excludeId) {
        const slug = (0, slugify_1.default)(title, { lower: true, strict: true });
        let counter = 1;
        let uniqueSlug = slug;
        while (true) {
            const existing = await this.prisma.post.findUnique({
                where: { slug: uniqueSlug },
            });
            if (!existing || existing.id === excludeId) {
                break;
            }
            uniqueSlug = `${slug}-${counter}`;
            counter++;
        }
        return uniqueSlug;
    }
    async create(createPostDto, authorId) {
        const slug = await this.generateSlug(createPostDto.title);
        return this.prisma.post.create({
            data: {
                ...createPostDto,
                slug,
                authorId,
                publishedAt: createPostDto.status === client_1.PostStatus.PUBLISHED ? new Date() : null,
            },
            include: {
                author: {
                    select: {
                        id: true,
                        name: true,
                        email: true,
                    },
                },
            },
        });
    }
    async findAll(page = 1, limit = 10, status, authorId) {
        const skip = (page - 1) * limit;
        const where = {};
        if (status) {
            where.status = status;
        }
        if (authorId) {
            where.authorId = authorId;
        }
        const [posts, total] = await Promise.all([
            this.prisma.post.findMany({
                where,
                skip,
                take: limit,
                include: {
                    author: {
                        select: {
                            id: true,
                            name: true,
                            email: true,
                        },
                    },
                },
                orderBy: { createdAt: 'desc' },
            }),
            this.prisma.post.count({ where }),
        ]);
        return {
            data: posts,
            meta: {
                total,
                page,
                limit,
                totalPages: Math.ceil(total / limit),
            },
        };
    }
    async findById(id) {
        const post = await this.prisma.post.findUnique({
            where: { id },
            include: {
                author: {
                    select: {
                        id: true,
                        name: true,
                        email: true,
                        avatar: true,
                    },
                },
            },
        });
        if (!post) {
            throw new common_1.NotFoundException('Post not found');
        }
        return post;
    }
    async findBySlug(slug) {
        const post = await this.prisma.post.findUnique({
            where: { slug },
            include: {
                author: {
                    select: {
                        id: true,
                        name: true,
                        email: true,
                        avatar: true,
                    },
                },
            },
        });
        if (!post) {
            throw new common_1.NotFoundException('Post not found');
        }
        return post;
    }
    async update(id, updatePostDto) {
        const existingPost = await this.findById(id);
        const data = { ...updatePostDto };
        if (updatePostDto.slug && updatePostDto.slug !== existingPost.slug) {
            const slugExists = await this.prisma.post.findFirst({
                where: {
                    slug: updatePostDto.slug,
                    id: { not: id },
                },
            });
            if (slugExists) {
                throw new Error(`Slug "${updatePostDto.slug}" is already in use`);
            }
            data.slug = updatePostDto.slug;
        }
        else if (updatePostDto.title &&
            updatePostDto.title !== existingPost.title &&
            !updatePostDto.slug) {
            data.slug = await this.generateSlug(updatePostDto.title, id);
        }
        else {
            delete data.slug;
        }
        if (updatePostDto.status === client_1.PostStatus.PUBLISHED) {
            const post = await this.prisma.post.findUnique({ where: { id } });
            if (post && !post.publishedAt) {
                data.publishedAt = new Date();
            }
        }
        return this.prisma.post.update({
            where: { id },
            data,
            include: {
                author: {
                    select: {
                        id: true,
                        name: true,
                        email: true,
                    },
                },
            },
        });
    }
    async remove(id) {
        await this.findById(id);
        return this.prisma.post.delete({
            where: { id },
        });
    }
};
exports.PostsService = PostsService;
exports.PostsService = PostsService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], PostsService);


/***/ }),
/* 99 */
/***/ ((module) => {

module.exports = require("slugify");

/***/ }),
/* 100 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PagesService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const client_1 = __webpack_require__(17);
const slugify_1 = __webpack_require__(99);
let PagesService = class PagesService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async generateSlug(title, excludeId) {
        const slug = (0, slugify_1.default)(title, { lower: true, strict: true });
        let counter = 1;
        let uniqueSlug = slug;
        while (true) {
            const existing = await this.prisma.page.findUnique({
                where: { slug: uniqueSlug },
            });
            if (!existing || existing.id === excludeId) {
                break;
            }
            uniqueSlug = `${slug}-${counter}`;
            counter++;
        }
        return uniqueSlug;
    }
    async create(createPageDto, authorId) {
        const slug = await this.generateSlug(createPageDto.title);
        return this.prisma.page.create({
            data: {
                ...createPageDto,
                slug,
                authorId,
                publishedAt: createPageDto.status === client_1.PostStatus.PUBLISHED ? new Date() : null,
            },
            include: {
                author: {
                    select: {
                        id: true,
                        name: true,
                        email: true,
                    },
                },
            },
        });
    }
    async findAll(page = 1, limit = 10, status) {
        const skip = (page - 1) * limit;
        const where = {};
        if (status) {
            where.status = status;
        }
        const [pages, total] = await Promise.all([
            this.prisma.page.findMany({
                where,
                skip,
                take: limit,
                include: {
                    author: {
                        select: {
                            id: true,
                            name: true,
                            email: true,
                        },
                    },
                    parent: {
                        select: {
                            id: true,
                            title: true,
                            slug: true,
                        },
                    },
                },
                orderBy: { createdAt: 'desc' },
            }),
            this.prisma.page.count({ where }),
        ]);
        return {
            data: pages,
            meta: {
                total,
                page,
                limit,
                totalPages: Math.ceil(total / limit),
            },
        };
    }
    async findById(id) {
        const page = await this.prisma.page.findUnique({
            where: { id },
            include: {
                author: {
                    select: {
                        id: true,
                        name: true,
                        email: true,
                        avatar: true,
                    },
                },
                parent: true,
                children: true,
            },
        });
        if (!page) {
            throw new common_1.NotFoundException('Page not found');
        }
        return page;
    }
    async findBySlug(slug) {
        const page = await this.prisma.page.findUnique({
            where: { slug },
            include: {
                author: {
                    select: {
                        id: true,
                        name: true,
                        email: true,
                        avatar: true,
                    },
                },
            },
        });
        if (!page) {
            throw new common_1.NotFoundException('Page not found');
        }
        return page;
    }
    async update(id, updatePageDto) {
        const existingPage = await this.findById(id);
        const data = { ...updatePageDto };
        if (updatePageDto.slug && updatePageDto.slug !== existingPage.slug) {
            const slugExists = await this.prisma.page.findFirst({
                where: {
                    slug: updatePageDto.slug,
                    id: { not: id },
                },
            });
            if (slugExists) {
                throw new Error(`Slug "${updatePageDto.slug}" is already in use`);
            }
            data.slug = updatePageDto.slug;
        }
        else if (updatePageDto.title &&
            updatePageDto.title !== existingPage.title &&
            !updatePageDto.slug) {
            data.slug = await this.generateSlug(updatePageDto.title, id);
        }
        else {
            delete data.slug;
        }
        if (updatePageDto.status === client_1.PostStatus.PUBLISHED) {
            const page = await this.prisma.page.findUnique({ where: { id } });
            if (page && !page.publishedAt) {
                data.publishedAt = new Date();
            }
        }
        return this.prisma.page.update({
            where: { id },
            data,
            include: {
                author: {
                    select: {
                        id: true,
                        name: true,
                        email: true,
                    },
                },
            },
        });
    }
    async remove(id) {
        await this.findById(id);
        return this.prisma.page.delete({
            where: { id },
        });
    }
};
exports.PagesService = PagesService;
exports.PagesService = PagesService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], PagesService);


/***/ }),
/* 101 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ContentTypesService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const slugify_1 = __webpack_require__(99);
let ContentTypesService = class ContentTypesService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async create(createContentTypeDto) {
        const slug = (0, slugify_1.default)(createContentTypeDto.name, { lower: true, strict: true });
        const existing = await this.prisma.contentType.findUnique({
            where: { slug },
        });
        if (existing) {
            throw new common_1.ConflictException('Content type with this name already exists');
        }
        return this.prisma.contentType.create({
            data: {
                ...createContentTypeDto,
                slug,
            },
        });
    }
    async findAll() {
        return this.prisma.contentType.findMany({
            orderBy: { createdAt: 'desc' },
        });
    }
    async findById(id) {
        const contentType = await this.prisma.contentType.findUnique({
            where: { id },
        });
        if (!contentType) {
            throw new common_1.NotFoundException('Content type not found');
        }
        return contentType;
    }
    async update(id, updateContentTypeDto) {
        await this.findById(id);
        return this.prisma.contentType.update({
            where: { id },
            data: updateContentTypeDto,
        });
    }
    async remove(id) {
        await this.findById(id);
        return this.prisma.contentType.delete({
            where: { id },
        });
    }
};
exports.ContentTypesService = ContentTypesService;
exports.ContentTypesService = ContentTypesService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], ContentTypesService);


/***/ }),
/* 102 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PostsController = void 0;
const common_1 = __webpack_require__(2);
const posts_service_1 = __webpack_require__(98);
const create_post_dto_1 = __webpack_require__(103);
const update_post_dto_1 = __webpack_require__(104);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const current_user_decorator_1 = __webpack_require__(63);
const client_1 = __webpack_require__(17);
let PostsController = class PostsController {
    constructor(postsService) {
        this.postsService = postsService;
    }
    create(createPostDto, user) {
        return this.postsService.create(createPostDto, user.id);
    }
    findAll(page, limit, status, authorId) {
        return this.postsService.findAll(page ? parseInt(page) : 1, limit ? parseInt(limit) : 10, status, authorId);
    }
    findOne(id) {
        return this.postsService.findById(id);
    }
    findBySlug(slug) {
        return this.postsService.findBySlug(slug);
    }
    update(id, updatePostDto) {
        return this.postsService.update(id, updatePostDto);
    }
    remove(id) {
        return this.postsService.remove(id);
    }
};
exports.PostsController = PostsController;
__decorate([
    (0, common_1.Post)(),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR, client_1.UserRole.AUTHOR),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, current_user_decorator_1.CurrentUser)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_b = typeof create_post_dto_1.CreatePostDto !== "undefined" && create_post_dto_1.CreatePostDto) === "function" ? _b : Object, Object]),
    __metadata("design:returntype", void 0)
], PostsController.prototype, "create", null);
__decorate([
    (0, common_1.Get)(),
    __param(0, (0, common_1.Query)('page')),
    __param(1, (0, common_1.Query)('limit')),
    __param(2, (0, common_1.Query)('status')),
    __param(3, (0, common_1.Query)('authorId')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, typeof (_c = typeof client_1.PostStatus !== "undefined" && client_1.PostStatus) === "function" ? _c : Object, String]),
    __metadata("design:returntype", void 0)
], PostsController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)(':id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], PostsController.prototype, "findOne", null);
__decorate([
    (0, common_1.Get)('slug/:slug'),
    __param(0, (0, common_1.Param)('slug')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], PostsController.prototype, "findBySlug", null);
__decorate([
    (0, common_1.Patch)(':id'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR, client_1.UserRole.AUTHOR),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_d = typeof update_post_dto_1.UpdatePostDto !== "undefined" && update_post_dto_1.UpdatePostDto) === "function" ? _d : Object]),
    __metadata("design:returntype", void 0)
], PostsController.prototype, "update", null);
__decorate([
    (0, common_1.Delete)(':id'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], PostsController.prototype, "remove", null);
exports.PostsController = PostsController = __decorate([
    (0, common_1.Controller)('api/posts'),
    __metadata("design:paramtypes", [typeof (_a = typeof posts_service_1.PostsService !== "undefined" && posts_service_1.PostsService) === "function" ? _a : Object])
], PostsController);


/***/ }),
/* 103 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CreatePostDto = void 0;
const class_validator_1 = __webpack_require__(59);
const client_1 = __webpack_require__(17);
class CreatePostDto {
    constructor() {
        this.status = client_1.PostStatus.DRAFT;
    }
}
exports.CreatePostDto = CreatePostDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], CreatePostDto.prototype, "title", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], CreatePostDto.prototype, "content", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreatePostDto.prototype, "slug", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreatePostDto.prototype, "excerpt", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreatePostDto.prototype, "featuredImage", void 0);
__decorate([
    (0, class_validator_1.IsEnum)(client_1.PostStatus),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_a = typeof client_1.PostStatus !== "undefined" && client_1.PostStatus) === "function" ? _a : Object)
], CreatePostDto.prototype, "status", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreatePostDto.prototype, "metaTitle", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreatePostDto.prototype, "metaDescription", void 0);
__decorate([
    (0, class_validator_1.IsObject)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Object)
], CreatePostDto.prototype, "customFields", void 0);


/***/ }),
/* 104 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UpdatePostDto = void 0;
const class_validator_1 = __webpack_require__(59);
const client_1 = __webpack_require__(17);
class UpdatePostDto {
}
exports.UpdatePostDto = UpdatePostDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdatePostDto.prototype, "title", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.Matches)(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, {
        message: 'Slug must be lowercase with hyphens only (e.g., my-post-title)',
    }),
    __metadata("design:type", String)
], UpdatePostDto.prototype, "slug", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdatePostDto.prototype, "content", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdatePostDto.prototype, "excerpt", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdatePostDto.prototype, "featuredImage", void 0);
__decorate([
    (0, class_validator_1.IsEnum)(client_1.PostStatus),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_a = typeof client_1.PostStatus !== "undefined" && client_1.PostStatus) === "function" ? _a : Object)
], UpdatePostDto.prototype, "status", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdatePostDto.prototype, "metaTitle", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdatePostDto.prototype, "metaDescription", void 0);
__decorate([
    (0, class_validator_1.IsObject)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Object)
], UpdatePostDto.prototype, "customFields", void 0);


/***/ }),
/* 105 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PagesController = void 0;
const common_1 = __webpack_require__(2);
const pages_service_1 = __webpack_require__(100);
const create_page_dto_1 = __webpack_require__(106);
const update_page_dto_1 = __webpack_require__(107);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const current_user_decorator_1 = __webpack_require__(63);
const client_1 = __webpack_require__(17);
let PagesController = class PagesController {
    constructor(pagesService) {
        this.pagesService = pagesService;
    }
    create(createPageDto, user) {
        return this.pagesService.create(createPageDto, user.id);
    }
    findAll(page, limit, status) {
        return this.pagesService.findAll(page ? parseInt(page) : 1, limit ? parseInt(limit) : 10, status);
    }
    findOne(id) {
        return this.pagesService.findById(id);
    }
    findBySlug(slug) {
        return this.pagesService.findBySlug(slug);
    }
    update(id, updatePageDto) {
        return this.pagesService.update(id, updatePageDto);
    }
    remove(id) {
        return this.pagesService.remove(id);
    }
};
exports.PagesController = PagesController;
__decorate([
    (0, common_1.Post)(),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR, client_1.UserRole.AUTHOR),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, current_user_decorator_1.CurrentUser)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_b = typeof create_page_dto_1.CreatePageDto !== "undefined" && create_page_dto_1.CreatePageDto) === "function" ? _b : Object, Object]),
    __metadata("design:returntype", void 0)
], PagesController.prototype, "create", null);
__decorate([
    (0, common_1.Get)(),
    __param(0, (0, common_1.Query)('page')),
    __param(1, (0, common_1.Query)('limit')),
    __param(2, (0, common_1.Query)('status')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, typeof (_c = typeof client_1.PostStatus !== "undefined" && client_1.PostStatus) === "function" ? _c : Object]),
    __metadata("design:returntype", void 0)
], PagesController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)(':id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], PagesController.prototype, "findOne", null);
__decorate([
    (0, common_1.Get)('slug/:slug'),
    __param(0, (0, common_1.Param)('slug')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], PagesController.prototype, "findBySlug", null);
__decorate([
    (0, common_1.Patch)(':id'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR, client_1.UserRole.AUTHOR),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_d = typeof update_page_dto_1.UpdatePageDto !== "undefined" && update_page_dto_1.UpdatePageDto) === "function" ? _d : Object]),
    __metadata("design:returntype", void 0)
], PagesController.prototype, "update", null);
__decorate([
    (0, common_1.Delete)(':id'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], PagesController.prototype, "remove", null);
exports.PagesController = PagesController = __decorate([
    (0, common_1.Controller)('api/pages'),
    __metadata("design:paramtypes", [typeof (_a = typeof pages_service_1.PagesService !== "undefined" && pages_service_1.PagesService) === "function" ? _a : Object])
], PagesController);


/***/ }),
/* 106 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CreatePageDto = void 0;
const class_validator_1 = __webpack_require__(59);
const client_1 = __webpack_require__(17);
class CreatePageDto {
    constructor() {
        this.status = client_1.PostStatus.DRAFT;
    }
}
exports.CreatePageDto = CreatePageDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], CreatePageDto.prototype, "title", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], CreatePageDto.prototype, "content", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreatePageDto.prototype, "slug", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreatePageDto.prototype, "template", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreatePageDto.prototype, "featuredImage", void 0);
__decorate([
    (0, class_validator_1.IsEnum)(client_1.PostStatus),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_a = typeof client_1.PostStatus !== "undefined" && client_1.PostStatus) === "function" ? _a : Object)
], CreatePageDto.prototype, "status", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreatePageDto.prototype, "metaTitle", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreatePageDto.prototype, "metaDescription", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreatePageDto.prototype, "parentId", void 0);
__decorate([
    (0, class_validator_1.IsObject)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Object)
], CreatePageDto.prototype, "customFields", void 0);


/***/ }),
/* 107 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UpdatePageDto = void 0;
const class_validator_1 = __webpack_require__(59);
const client_1 = __webpack_require__(17);
class UpdatePageDto {
}
exports.UpdatePageDto = UpdatePageDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdatePageDto.prototype, "title", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.Matches)(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, {
        message: 'Slug must be lowercase with hyphens only (e.g., my-page-title)',
    }),
    __metadata("design:type", String)
], UpdatePageDto.prototype, "slug", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdatePageDto.prototype, "content", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdatePageDto.prototype, "template", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdatePageDto.prototype, "featuredImage", void 0);
__decorate([
    (0, class_validator_1.IsEnum)(client_1.PostStatus),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_a = typeof client_1.PostStatus !== "undefined" && client_1.PostStatus) === "function" ? _a : Object)
], UpdatePageDto.prototype, "status", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdatePageDto.prototype, "metaTitle", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdatePageDto.prototype, "metaDescription", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdatePageDto.prototype, "parentId", void 0);
__decorate([
    (0, class_validator_1.IsObject)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Object)
], UpdatePageDto.prototype, "customFields", void 0);


/***/ }),
/* 108 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ContentTypesController = void 0;
const common_1 = __webpack_require__(2);
const content_types_service_1 = __webpack_require__(101);
const create_content_type_dto_1 = __webpack_require__(109);
const update_content_type_dto_1 = __webpack_require__(110);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const client_1 = __webpack_require__(17);
let ContentTypesController = class ContentTypesController {
    constructor(contentTypesService) {
        this.contentTypesService = contentTypesService;
    }
    create(createContentTypeDto) {
        return this.contentTypesService.create(createContentTypeDto);
    }
    findAll() {
        return this.contentTypesService.findAll();
    }
    findOne(id) {
        return this.contentTypesService.findById(id);
    }
    update(id, updateContentTypeDto) {
        return this.contentTypesService.update(id, updateContentTypeDto);
    }
    remove(id) {
        return this.contentTypesService.remove(id);
    }
};
exports.ContentTypesController = ContentTypesController;
__decorate([
    (0, common_1.Post)(),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_b = typeof create_content_type_dto_1.CreateContentTypeDto !== "undefined" && create_content_type_dto_1.CreateContentTypeDto) === "function" ? _b : Object]),
    __metadata("design:returntype", void 0)
], ContentTypesController.prototype, "create", null);
__decorate([
    (0, common_1.Get)(),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], ContentTypesController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], ContentTypesController.prototype, "findOne", null);
__decorate([
    (0, common_1.Patch)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_c = typeof update_content_type_dto_1.UpdateContentTypeDto !== "undefined" && update_content_type_dto_1.UpdateContentTypeDto) === "function" ? _c : Object]),
    __metadata("design:returntype", void 0)
], ContentTypesController.prototype, "update", null);
__decorate([
    (0, common_1.Delete)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], ContentTypesController.prototype, "remove", null);
exports.ContentTypesController = ContentTypesController = __decorate([
    (0, common_1.Controller)('api/content-types'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof content_types_service_1.ContentTypesService !== "undefined" && content_types_service_1.ContentTypesService) === "function" ? _a : Object])
], ContentTypesController);


/***/ }),
/* 109 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CreateContentTypeDto = void 0;
const class_validator_1 = __webpack_require__(59);
class CreateContentTypeDto {
    constructor() {
        this.isActive = true;
    }
}
exports.CreateContentTypeDto = CreateContentTypeDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], CreateContentTypeDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateContentTypeDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateContentTypeDto.prototype, "icon", void 0);
__decorate([
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", Array)
], CreateContentTypeDto.prototype, "fields", void 0);
__decorate([
    (0, class_validator_1.IsBoolean)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Boolean)
], CreateContentTypeDto.prototype, "isActive", void 0);


/***/ }),
/* 110 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UpdateContentTypeDto = void 0;
const class_validator_1 = __webpack_require__(59);
class UpdateContentTypeDto {
}
exports.UpdateContentTypeDto = UpdateContentTypeDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateContentTypeDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateContentTypeDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateContentTypeDto.prototype, "icon", void 0);
__decorate([
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], UpdateContentTypeDto.prototype, "fields", void 0);
__decorate([
    (0, class_validator_1.IsBoolean)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Boolean)
], UpdateContentTypeDto.prototype, "isActive", void 0);


/***/ }),
/* 111 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PageCustomizationService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let PageCustomizationService = class PageCustomizationService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async findAll() {
        return this.prisma.pageCustomization.findMany({
            include: {
                page: {
                    select: { id: true, title: true, slug: true },
                },
            },
            orderBy: { updatedAt: 'desc' },
        });
    }
    async findById(id) {
        const customization = await this.prisma.pageCustomization.findUnique({
            where: { id },
            include: {
                page: {
                    select: { id: true, title: true, slug: true },
                },
            },
        });
        if (!customization) {
            throw new common_1.NotFoundException('Page customization not found');
        }
        return customization;
    }
    async findByPageId(pageId) {
        return this.prisma.pageCustomization.findUnique({
            where: { pageId },
            include: {
                page: {
                    select: { id: true, title: true, slug: true },
                },
            },
        });
    }
    async create(dto) {
        const page = await this.prisma.page.findUnique({
            where: { id: dto.pageId },
        });
        if (!page) {
            throw new common_1.BadRequestException('Page not found');
        }
        const existing = await this.prisma.pageCustomization.findUnique({
            where: { pageId: dto.pageId },
        });
        if (existing) {
            throw new common_1.BadRequestException('Customization already exists for this page');
        }
        return this.prisma.pageCustomization.create({
            data: {
                pageId: dto.pageId,
                layout: dto.layout || 'default',
                showHeader: dto.showHeader ?? true,
                showFooter: dto.showFooter ?? true,
                showSidebar: dto.showSidebar ?? false,
                customCSS: dto.customCSS,
                backgroundColor: dto.backgroundColor,
                textColor: dto.textColor,
                headerStyle: dto.headerStyle || 'default',
                footerStyle: dto.footerStyle || 'default',
                featuredImagePosition: dto.featuredImagePosition || 'top',
                customFields: dto.customFields,
            },
            include: {
                page: {
                    select: { id: true, title: true, slug: true },
                },
            },
        });
    }
    async update(id, dto) {
        await this.findById(id);
        return this.prisma.pageCustomization.update({
            where: { id },
            data: {
                ...(dto.layout && { layout: dto.layout }),
                ...(dto.showHeader !== undefined && { showHeader: dto.showHeader }),
                ...(dto.showFooter !== undefined && { showFooter: dto.showFooter }),
                ...(dto.showSidebar !== undefined && { showSidebar: dto.showSidebar }),
                ...(dto.customCSS !== undefined && { customCSS: dto.customCSS }),
                ...(dto.backgroundColor && { backgroundColor: dto.backgroundColor }),
                ...(dto.textColor && { textColor: dto.textColor }),
                ...(dto.headerStyle && { headerStyle: dto.headerStyle }),
                ...(dto.footerStyle && { footerStyle: dto.footerStyle }),
                ...(dto.featuredImagePosition && { featuredImagePosition: dto.featuredImagePosition }),
                ...(dto.customFields && { customFields: dto.customFields }),
            },
            include: {
                page: {
                    select: { id: true, title: true, slug: true },
                },
            },
        });
    }
    async delete(id) {
        await this.findById(id);
        return this.prisma.pageCustomization.delete({
            where: { id },
        });
    }
    async deleteByPageId(pageId) {
        return this.prisma.pageCustomization.deleteMany({
            where: { pageId },
        });
    }
};
exports.PageCustomizationService = PageCustomizationService;
exports.PageCustomizationService = PageCustomizationService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], PageCustomizationService);


/***/ }),
/* 112 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PostCustomizationService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let PostCustomizationService = class PostCustomizationService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async findAll() {
        return this.prisma.postCustomization.findMany({
            include: {
                post: {
                    select: { id: true, title: true, slug: true },
                },
            },
            orderBy: { updatedAt: 'desc' },
        });
    }
    async findById(id) {
        const customization = await this.prisma.postCustomization.findUnique({
            where: { id },
            include: {
                post: {
                    select: { id: true, title: true, slug: true },
                },
            },
        });
        if (!customization) {
            throw new common_1.NotFoundException('Post customization not found');
        }
        return customization;
    }
    async findByPostId(postId) {
        return this.prisma.postCustomization.findUnique({
            where: { postId },
            include: {
                post: {
                    select: { id: true, title: true, slug: true },
                },
            },
        });
    }
    async create(dto) {
        const post = await this.prisma.post.findUnique({
            where: { id: dto.postId },
        });
        if (!post) {
            throw new common_1.BadRequestException('Post not found');
        }
        const existing = await this.prisma.postCustomization.findUnique({
            where: { postId: dto.postId },
        });
        if (existing) {
            throw new common_1.BadRequestException('Customization already exists for this post');
        }
        return this.prisma.postCustomization.create({
            data: {
                postId: dto.postId,
                layout: dto.layout || 'default',
                showHeader: dto.showHeader ?? true,
                showFooter: dto.showFooter ?? true,
                showSidebar: dto.showSidebar ?? false,
                showAuthor: dto.showAuthor ?? true,
                showDate: dto.showDate ?? true,
                showCategory: dto.showCategory ?? true,
                showTags: dto.showTags ?? true,
                showRelatedPosts: dto.showRelatedPosts ?? true,
                relatedPostsCount: dto.relatedPostsCount || 3,
                customCSS: dto.customCSS,
                backgroundColor: dto.backgroundColor,
                textColor: dto.textColor,
                featuredImagePosition: dto.featuredImagePosition || 'top',
                customFields: dto.customFields,
            },
            include: {
                post: {
                    select: { id: true, title: true, slug: true },
                },
            },
        });
    }
    async update(id, dto) {
        await this.findById(id);
        return this.prisma.postCustomization.update({
            where: { id },
            data: {
                ...(dto.layout && { layout: dto.layout }),
                ...(dto.showHeader !== undefined && { showHeader: dto.showHeader }),
                ...(dto.showFooter !== undefined && { showFooter: dto.showFooter }),
                ...(dto.showSidebar !== undefined && { showSidebar: dto.showSidebar }),
                ...(dto.showAuthor !== undefined && { showAuthor: dto.showAuthor }),
                ...(dto.showDate !== undefined && { showDate: dto.showDate }),
                ...(dto.showCategory !== undefined && { showCategory: dto.showCategory }),
                ...(dto.showTags !== undefined && { showTags: dto.showTags }),
                ...(dto.showRelatedPosts !== undefined && { showRelatedPosts: dto.showRelatedPosts }),
                ...(dto.relatedPostsCount && { relatedPostsCount: dto.relatedPostsCount }),
                ...(dto.customCSS !== undefined && { customCSS: dto.customCSS }),
                ...(dto.backgroundColor && { backgroundColor: dto.backgroundColor }),
                ...(dto.textColor && { textColor: dto.textColor }),
                ...(dto.featuredImagePosition && { featuredImagePosition: dto.featuredImagePosition }),
                ...(dto.customFields && { customFields: dto.customFields }),
            },
            include: {
                post: {
                    select: { id: true, title: true, slug: true },
                },
            },
        });
    }
    async delete(id) {
        await this.findById(id);
        return this.prisma.postCustomization.delete({
            where: { id },
        });
    }
    async deleteByPostId(postId) {
        return this.prisma.postCustomization.deleteMany({
            where: { postId },
        });
    }
};
exports.PostCustomizationService = PostCustomizationService;
exports.PostCustomizationService = PostCustomizationService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], PostCustomizationService);


/***/ }),
/* 113 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PageCustomizationController = void 0;
const common_1 = __webpack_require__(2);
const client_1 = __webpack_require__(17);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const page_customization_service_1 = __webpack_require__(111);
const create_page_customization_dto_1 = __webpack_require__(114);
const update_page_customization_dto_1 = __webpack_require__(115);
let PageCustomizationController = class PageCustomizationController {
    constructor(pageCustomizationService) {
        this.pageCustomizationService = pageCustomizationService;
    }
    async findAll() {
        return this.pageCustomizationService.findAll();
    }
    async findById(id) {
        return this.pageCustomizationService.findById(id);
    }
    async findByPageId(pageId) {
        return this.pageCustomizationService.findByPageId(pageId);
    }
    async create(dto) {
        return this.pageCustomizationService.create(dto);
    }
    async update(id, dto) {
        return this.pageCustomizationService.update(id, dto);
    }
    async delete(id) {
        await this.pageCustomizationService.delete(id);
    }
};
exports.PageCustomizationController = PageCustomizationController;
__decorate([
    (0, common_1.Get)(),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], PageCustomizationController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], PageCustomizationController.prototype, "findById", null);
__decorate([
    (0, common_1.Get)('page/:pageId'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Param)('pageId')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], PageCustomizationController.prototype, "findByPageId", null);
__decorate([
    (0, common_1.Post)(),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    (0, common_1.HttpCode)(common_1.HttpStatus.CREATED),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_b = typeof create_page_customization_dto_1.CreatePageCustomizationDto !== "undefined" && create_page_customization_dto_1.CreatePageCustomizationDto) === "function" ? _b : Object]),
    __metadata("design:returntype", Promise)
], PageCustomizationController.prototype, "create", null);
__decorate([
    (0, common_1.Put)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_c = typeof update_page_customization_dto_1.UpdatePageCustomizationDto !== "undefined" && update_page_customization_dto_1.UpdatePageCustomizationDto) === "function" ? _c : Object]),
    __metadata("design:returntype", Promise)
], PageCustomizationController.prototype, "update", null);
__decorate([
    (0, common_1.Delete)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    (0, common_1.HttpCode)(common_1.HttpStatus.NO_CONTENT),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], PageCustomizationController.prototype, "delete", null);
exports.PageCustomizationController = PageCustomizationController = __decorate([
    (0, common_1.Controller)('api/page-customizations'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof page_customization_service_1.PageCustomizationService !== "undefined" && page_customization_service_1.PageCustomizationService) === "function" ? _a : Object])
], PageCustomizationController);


/***/ }),
/* 114 */
/***/ ((__unused_webpack_module, exports) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CreatePageCustomizationDto = void 0;
class CreatePageCustomizationDto {
}
exports.CreatePageCustomizationDto = CreatePageCustomizationDto;


/***/ }),
/* 115 */
/***/ ((__unused_webpack_module, exports) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UpdatePageCustomizationDto = void 0;
class UpdatePageCustomizationDto {
}
exports.UpdatePageCustomizationDto = UpdatePageCustomizationDto;


/***/ }),
/* 116 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PostCustomizationController = void 0;
const common_1 = __webpack_require__(2);
const client_1 = __webpack_require__(17);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const post_customization_service_1 = __webpack_require__(112);
const create_post_customization_dto_1 = __webpack_require__(117);
const update_post_customization_dto_1 = __webpack_require__(118);
let PostCustomizationController = class PostCustomizationController {
    constructor(postCustomizationService) {
        this.postCustomizationService = postCustomizationService;
    }
    async findAll() {
        return this.postCustomizationService.findAll();
    }
    async findById(id) {
        return this.postCustomizationService.findById(id);
    }
    async findByPostId(postId) {
        return this.postCustomizationService.findByPostId(postId);
    }
    async create(dto) {
        return this.postCustomizationService.create(dto);
    }
    async update(id, dto) {
        return this.postCustomizationService.update(id, dto);
    }
    async delete(id) {
        await this.postCustomizationService.delete(id);
    }
};
exports.PostCustomizationController = PostCustomizationController;
__decorate([
    (0, common_1.Get)(),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], PostCustomizationController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], PostCustomizationController.prototype, "findById", null);
__decorate([
    (0, common_1.Get)('post/:postId'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Param)('postId')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], PostCustomizationController.prototype, "findByPostId", null);
__decorate([
    (0, common_1.Post)(),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    (0, common_1.HttpCode)(common_1.HttpStatus.CREATED),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_b = typeof create_post_customization_dto_1.CreatePostCustomizationDto !== "undefined" && create_post_customization_dto_1.CreatePostCustomizationDto) === "function" ? _b : Object]),
    __metadata("design:returntype", Promise)
], PostCustomizationController.prototype, "create", null);
__decorate([
    (0, common_1.Put)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_c = typeof update_post_customization_dto_1.UpdatePostCustomizationDto !== "undefined" && update_post_customization_dto_1.UpdatePostCustomizationDto) === "function" ? _c : Object]),
    __metadata("design:returntype", Promise)
], PostCustomizationController.prototype, "update", null);
__decorate([
    (0, common_1.Delete)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    (0, common_1.HttpCode)(common_1.HttpStatus.NO_CONTENT),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], PostCustomizationController.prototype, "delete", null);
exports.PostCustomizationController = PostCustomizationController = __decorate([
    (0, common_1.Controller)('api/post-customizations'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof post_customization_service_1.PostCustomizationService !== "undefined" && post_customization_service_1.PostCustomizationService) === "function" ? _a : Object])
], PostCustomizationController);


/***/ }),
/* 117 */
/***/ ((__unused_webpack_module, exports) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CreatePostCustomizationDto = void 0;
class CreatePostCustomizationDto {
}
exports.CreatePostCustomizationDto = CreatePostCustomizationDto;


/***/ }),
/* 118 */
/***/ ((__unused_webpack_module, exports) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UpdatePostCustomizationDto = void 0;
class UpdatePostCustomizationDto {
}
exports.UpdatePostCustomizationDto = UpdatePostCustomizationDto;


/***/ }),
/* 119 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CustomizationExportService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let CustomizationExportService = class CustomizationExportService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async exportPageCustomizations() {
        const pages = await this.prisma.pageCustomization.findMany({
            include: {
                page: {
                    select: {
                        id: true,
                        title: true,
                        slug: true,
                    },
                },
            },
        });
        return {
            version: '1.0.0',
            exportedAt: new Date().toISOString(),
            pages: pages.map((p) => ({
                ...p,
                pageTitle: p.page?.title,
                pageSlug: p.page?.slug,
            })),
            posts: [],
        };
    }
    async exportPostCustomizations() {
        const posts = await this.prisma.postCustomization.findMany({
            include: {
                post: {
                    select: {
                        id: true,
                        title: true,
                        slug: true,
                    },
                },
            },
        });
        return {
            version: '1.0.0',
            exportedAt: new Date().toISOString(),
            pages: [],
            posts: posts.map((p) => ({
                ...p,
                postTitle: p.post?.title,
                postSlug: p.post?.slug,
            })),
        };
    }
    async exportAllCustomizations() {
        const [pages, posts] = await Promise.all([
            this.prisma.pageCustomization.findMany({
                include: {
                    page: {
                        select: {
                            id: true,
                            title: true,
                            slug: true,
                        },
                    },
                },
            }),
            this.prisma.postCustomization.findMany({
                include: {
                    post: {
                        select: {
                            id: true,
                            title: true,
                            slug: true,
                        },
                    },
                },
            }),
        ]);
        return {
            version: '1.0.0',
            exportedAt: new Date().toISOString(),
            pages: pages.map((p) => ({
                ...p,
                pageTitle: p.page?.title,
                pageSlug: p.page?.slug,
            })),
            posts: posts.map((p) => ({
                ...p,
                postTitle: p.post?.title,
                postSlug: p.post?.slug,
            })),
        };
    }
    async importCustomizations(data) {
        if (!data.version || !data.exportedAt) {
            throw new common_1.BadRequestException('Invalid export file format');
        }
        let imported = 0;
        let failed = 0;
        for (const pageCustom of data.pages || []) {
            try {
                await this.prisma.pageCustomization.upsert({
                    where: { pageId: pageCustom.pageId },
                    update: {
                        layout: pageCustom.layout,
                        showHeader: pageCustom.showHeader,
                        showFooter: pageCustom.showFooter,
                        showSidebar: pageCustom.showSidebar,
                        customCSS: pageCustom.customCSS,
                        backgroundColor: pageCustom.backgroundColor,
                        textColor: pageCustom.textColor,
                        headerStyle: pageCustom.headerStyle,
                        footerStyle: pageCustom.footerStyle,
                        featuredImagePosition: pageCustom.featuredImagePosition,
                        customFields: pageCustom.customFields,
                    },
                    create: {
                        pageId: pageCustom.pageId,
                        layout: pageCustom.layout,
                        showHeader: pageCustom.showHeader,
                        showFooter: pageCustom.showFooter,
                        showSidebar: pageCustom.showSidebar,
                        customCSS: pageCustom.customCSS,
                        backgroundColor: pageCustom.backgroundColor,
                        textColor: pageCustom.textColor,
                        headerStyle: pageCustom.headerStyle,
                        footerStyle: pageCustom.footerStyle,
                        featuredImagePosition: pageCustom.featuredImagePosition,
                        customFields: pageCustom.customFields,
                    },
                });
                imported++;
            }
            catch (error) {
                console.error(`Failed to import page customization: ${error.message}`);
                failed++;
            }
        }
        for (const postCustom of data.posts || []) {
            try {
                await this.prisma.postCustomization.upsert({
                    where: { postId: postCustom.postId },
                    update: {
                        layout: postCustom.layout,
                        showHeader: postCustom.showHeader,
                        showFooter: postCustom.showFooter,
                        showSidebar: postCustom.showSidebar,
                        showAuthor: postCustom.showAuthor,
                        showDate: postCustom.showDate,
                        showCategory: postCustom.showCategory,
                        showTags: postCustom.showTags,
                        showRelatedPosts: postCustom.showRelatedPosts,
                        relatedPostsCount: postCustom.relatedPostsCount,
                        customCSS: postCustom.customCSS,
                        backgroundColor: postCustom.backgroundColor,
                        textColor: postCustom.textColor,
                        featuredImagePosition: postCustom.featuredImagePosition,
                        customFields: postCustom.customFields,
                    },
                    create: {
                        postId: postCustom.postId,
                        layout: postCustom.layout,
                        showHeader: postCustom.showHeader,
                        showFooter: postCustom.showFooter,
                        showSidebar: postCustom.showSidebar,
                        showAuthor: postCustom.showAuthor,
                        showDate: postCustom.showDate,
                        showCategory: postCustom.showCategory,
                        showTags: postCustom.showTags,
                        showRelatedPosts: postCustom.showRelatedPosts,
                        relatedPostsCount: postCustom.relatedPostsCount,
                        customCSS: postCustom.customCSS,
                        backgroundColor: postCustom.backgroundColor,
                        textColor: postCustom.textColor,
                        featuredImagePosition: postCustom.featuredImagePosition,
                        customFields: postCustom.customFields,
                    },
                });
                imported++;
            }
            catch (error) {
                console.error(`Failed to import post customization: ${error.message}`);
                failed++;
            }
        }
        return { imported, failed };
    }
};
exports.CustomizationExportService = CustomizationExportService;
exports.CustomizationExportService = CustomizationExportService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], CustomizationExportService);


/***/ }),
/* 120 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CustomizationExportController = void 0;
const common_1 = __webpack_require__(2);
const express_1 = __webpack_require__(57);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const client_1 = __webpack_require__(17);
const customization_export_service_1 = __webpack_require__(119);
let CustomizationExportController = class CustomizationExportController {
    constructor(exportService) {
        this.exportService = exportService;
    }
    async exportPages(res) {
        try {
            const data = await this.exportService.exportPageCustomizations();
            const filename = `page-customizations-${new Date().toISOString().split('T')[0]}.json`;
            res.setHeader('Content-Type', 'application/json');
            res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
            res.send(JSON.stringify(data, null, 2));
        }
        catch (error) {
            res.status(500).json({ error: error.message });
        }
    }
    async exportPosts(res) {
        try {
            const data = await this.exportService.exportPostCustomizations();
            const filename = `post-customizations-${new Date().toISOString().split('T')[0]}.json`;
            res.setHeader('Content-Type', 'application/json');
            res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
            res.send(JSON.stringify(data, null, 2));
        }
        catch (error) {
            res.status(500).json({ error: error.message });
        }
    }
    async exportAll(res) {
        try {
            const data = await this.exportService.exportAllCustomizations();
            const filename = `all-customizations-${new Date().toISOString().split('T')[0]}.json`;
            res.setHeader('Content-Type', 'application/json');
            res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
            res.send(JSON.stringify(data, null, 2));
        }
        catch (error) {
            res.status(500).json({ error: error.message });
        }
    }
    async import(data) {
        try {
            const result = await this.exportService.importCustomizations(data);
            return {
                success: true,
                message: `Successfully imported ${result.imported} customizations`,
                imported: result.imported,
                failed: result.failed,
            };
        }
        catch (error) {
            return {
                success: false,
                error: error.message,
            };
        }
    }
};
exports.CustomizationExportController = CustomizationExportController;
__decorate([
    (0, common_1.Get)('export/pages'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_b = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _b : Object]),
    __metadata("design:returntype", Promise)
], CustomizationExportController.prototype, "exportPages", null);
__decorate([
    (0, common_1.Get)('export/posts'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_c = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _c : Object]),
    __metadata("design:returntype", Promise)
], CustomizationExportController.prototype, "exportPosts", null);
__decorate([
    (0, common_1.Get)('export/all'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_d = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _d : Object]),
    __metadata("design:returntype", Promise)
], CustomizationExportController.prototype, "exportAll", null);
__decorate([
    (0, common_1.Post)('import'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], CustomizationExportController.prototype, "import", null);
exports.CustomizationExportController = CustomizationExportController = __decorate([
    (0, common_1.Controller)('api/customizations'),
    __metadata("design:paramtypes", [typeof (_a = typeof customization_export_service_1.CustomizationExportService !== "undefined" && customization_export_service_1.CustomizationExportService) === "function" ? _a : Object])
], CustomizationExportController);


/***/ }),
/* 121 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CustomizationPresetsService = void 0;
const common_1 = __webpack_require__(2);
let CustomizationPresetsService = class CustomizationPresetsService {
    constructor() {
        this.presets = [
            {
                id: 'minimal',
                name: 'Minimal',
                description: 'Clean and minimal design with no sidebar',
                category: 'both',
                settings: {
                    layout: 'full-width',
                    showHeader: true,
                    showFooter: true,
                    showSidebar: false,
                    backgroundColor: '#ffffff',
                    textColor: '#000000',
                },
            },
            {
                id: 'sidebar-right',
                name: 'Sidebar Right',
                description: 'Default layout with sidebar on the right',
                category: 'both',
                settings: {
                    layout: 'sidebar-right',
                    showHeader: true,
                    showFooter: true,
                    showSidebar: true,
                    backgroundColor: '#ffffff',
                    textColor: '#000000',
                },
            },
            {
                id: 'sidebar-left',
                name: 'Sidebar Left',
                description: 'Layout with sidebar on the left',
                category: 'both',
                settings: {
                    layout: 'sidebar-left',
                    showHeader: true,
                    showFooter: true,
                    showSidebar: true,
                    backgroundColor: '#ffffff',
                    textColor: '#000000',
                },
            },
            {
                id: 'dark-mode',
                name: 'Dark Mode',
                description: 'Dark theme with light text',
                category: 'both',
                settings: {
                    layout: 'default',
                    backgroundColor: '#1a1a1a',
                    textColor: '#ffffff',
                    showHeader: true,
                    showFooter: true,
                    showSidebar: true,
                    customCSS: 'body { background-color: #1a1a1a; color: #ffffff; }',
                },
            },
            {
                id: 'blog-focused',
                name: 'Blog Focused',
                description: 'Optimized for blog posts with author and date',
                category: 'post',
                settings: {
                    layout: 'full-width',
                    showHeader: true,
                    showFooter: true,
                    showSidebar: false,
                    showAuthor: true,
                    showDate: true,
                    showCategory: true,
                    showTags: true,
                    showRelatedPosts: true,
                    relatedPostsCount: 5,
                },
            },
            {
                id: 'landing-page',
                name: 'Landing Page',
                description: 'Full-width layout without header and footer',
                category: 'page',
                settings: {
                    layout: 'full-width',
                    showHeader: false,
                    showFooter: false,
                    showSidebar: false,
                    backgroundColor: '#ffffff',
                    textColor: '#000000',
                },
            },
            {
                id: 'product-showcase',
                name: 'Product Showcase',
                description: 'Minimal layout for product pages',
                category: 'page',
                settings: {
                    layout: 'full-width',
                    showHeader: true,
                    showFooter: true,
                    showSidebar: false,
                    backgroundColor: '#f8f9fa',
                    textColor: '#000000',
                },
            },
            {
                id: 'course-page',
                name: 'Course Page',
                description: 'Optimized layout for course pages',
                category: 'page',
                settings: {
                    layout: 'sidebar-right',
                    showHeader: true,
                    showFooter: true,
                    showSidebar: true,
                    backgroundColor: '#ffffff',
                    textColor: '#000000',
                },
            },
        ];
    }
    getAllPresets() {
        return this.presets;
    }
    getPresetsByCategory(category) {
        return this.presets.filter((p) => p.category === category || p.category === 'both');
    }
    getPresetById(id) {
        return this.presets.find((p) => p.id === id);
    }
    getPresetSettings(id) {
        const preset = this.getPresetById(id);
        return preset?.settings;
    }
    addPreset(preset) {
        const newPreset = {
            ...preset,
            id: `custom-${Date.now()}`,
        };
        this.presets.push(newPreset);
        return newPreset;
    }
    removePreset(id) {
        const index = this.presets.findIndex((p) => p.id === id);
        if (index > -1) {
            this.presets.splice(index, 1);
            return true;
        }
        return false;
    }
};
exports.CustomizationPresetsService = CustomizationPresetsService;
exports.CustomizationPresetsService = CustomizationPresetsService = __decorate([
    (0, common_1.Injectable)()
], CustomizationPresetsService);


/***/ }),
/* 122 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CustomizationPresetsController = void 0;
const common_1 = __webpack_require__(2);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const client_1 = __webpack_require__(17);
const customization_presets_service_1 = __webpack_require__(121);
let CustomizationPresetsController = class CustomizationPresetsController {
    constructor(presetsService) {
        this.presetsService = presetsService;
    }
    getAllPresets() {
        return this.presetsService.getAllPresets();
    }
    getPresetsByCategory(category) {
        return this.presetsService.getPresetsByCategory(category);
    }
    getPresetById(id) {
        const preset = this.presetsService.getPresetById(id);
        if (!preset) {
            return { error: 'Preset not found' };
        }
        return preset;
    }
    getPresetSettings(id) {
        const settings = this.presetsService.getPresetSettings(id);
        if (!settings) {
            return { error: 'Preset not found' };
        }
        return settings;
    }
    addPreset(data) {
        return this.presetsService.addPreset(data);
    }
    removePreset(id) {
        const success = this.presetsService.removePreset(id);
        if (!success) {
            return { error: 'Preset not found' };
        }
        return { message: 'Preset removed successfully' };
    }
};
exports.CustomizationPresetsController = CustomizationPresetsController;
__decorate([
    (0, common_1.Get)(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], CustomizationPresetsController.prototype, "getAllPresets", null);
__decorate([
    (0, common_1.Get)('category/:category'),
    __param(0, (0, common_1.Param)('category')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], CustomizationPresetsController.prototype, "getPresetsByCategory", null);
__decorate([
    (0, common_1.Get)(':id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], CustomizationPresetsController.prototype, "getPresetById", null);
__decorate([
    (0, common_1.Get)(':id/settings'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], CustomizationPresetsController.prototype, "getPresetSettings", null);
__decorate([
    (0, common_1.Post)(),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], CustomizationPresetsController.prototype, "addPreset", null);
__decorate([
    (0, common_1.Delete)(':id'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], CustomizationPresetsController.prototype, "removePreset", null);
exports.CustomizationPresetsController = CustomizationPresetsController = __decorate([
    (0, common_1.Controller)('api/customizations/presets'),
    __metadata("design:paramtypes", [typeof (_a = typeof customization_presets_service_1.CustomizationPresetsService !== "undefined" && customization_presets_service_1.CustomizationPresetsService) === "function" ? _a : Object])
], CustomizationPresetsController);


/***/ }),
/* 123 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.MediaModule = void 0;
const common_1 = __webpack_require__(2);
const platform_express_1 = __webpack_require__(124);
const multer_1 = __webpack_require__(125);
const prisma_module_1 = __webpack_require__(15);
const media_service_1 = __webpack_require__(126);
const media_controller_1 = __webpack_require__(127);
let MediaModule = class MediaModule {
};
exports.MediaModule = MediaModule;
exports.MediaModule = MediaModule = __decorate([
    (0, common_1.Module)({
        imports: [
            prisma_module_1.PrismaModule,
            platform_express_1.MulterModule.register({
                storage: (0, multer_1.memoryStorage)(),
                limits: {
                    fileSize: parseInt(process.env.MAX_FILE_SIZE || '524288000', 10),
                },
            }),
        ],
        providers: [media_service_1.MediaService],
        controllers: [media_controller_1.MediaController],
        exports: [media_service_1.MediaService],
    })
], MediaModule);


/***/ }),
/* 124 */
/***/ ((module) => {

module.exports = require("@nestjs/platform-express");

/***/ }),
/* 125 */
/***/ ((module) => {

module.exports = require("multer");

/***/ }),
/* 126 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 MediaService_1;
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.MediaService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const fs = __webpack_require__(24);
const path = __webpack_require__(3);
let MediaService = MediaService_1 = class MediaService {
    constructor(prisma) {
        this.prisma = prisma;
        this.logger = new common_1.Logger(MediaService_1.name);
        this.uploadDir = path.join(process.cwd(), 'uploads');
        this.ensureUploadDir();
    }
    async ensureUploadDir() {
        try {
            await fs.access(this.uploadDir);
            this.logger.log(`📁 Upload directory ready: ${this.uploadDir}`);
        }
        catch {
            await fs.mkdir(this.uploadDir, { recursive: true });
            this.logger.log(`📁 Created upload directory: ${this.uploadDir}`);
        }
    }
    sanitizeFilename(filename) {
        return filename
            .replace(/[/\\:*?"<>|]/g, '_')
            .replace(/\s+/g, '_')
            .substring(0, 200);
    }
    async upload(file, userId) {
        if (!file || !file.buffer) {
            throw new common_1.BadRequestException('Invalid file upload - no file data received');
        }
        const sanitizedName = this.sanitizeFilename(file.originalname);
        const filename = `${Date.now()}-${sanitizedName}`;
        const filepath = path.join(this.uploadDir, filename);
        try {
            await fs.writeFile(filepath, file.buffer);
            this.logger.log(`📤 File uploaded: ${filename} (${file.size} bytes)`);
        }
        catch (error) {
            this.logger.error(`Failed to write file: ${error.message}`);
            throw new common_1.BadRequestException('Failed to save file to disk');
        }
        let width;
        let height;
        return this.prisma.media.create({
            data: {
                filename,
                originalName: file.originalname,
                path: `/uploads/${filename}`,
                mimeType: file.mimetype,
                size: file.size,
                width,
                height,
                uploadedById: userId,
            },
        });
    }
    async findAll(page = 1, limit = 20, mimeType) {
        const skip = (page - 1) * limit;
        const where = {};
        if (mimeType) {
            where.mimeType = { contains: mimeType };
        }
        const [media, total] = await Promise.all([
            this.prisma.media.findMany({
                where,
                skip,
                take: limit,
                include: {
                    uploadedBy: {
                        select: {
                            id: true,
                            name: true,
                            email: true,
                        },
                    },
                },
                orderBy: { createdAt: 'desc' },
            }),
            this.prisma.media.count({ where }),
        ]);
        return {
            data: media,
            meta: {
                total,
                page,
                limit,
                totalPages: Math.ceil(total / limit),
            },
        };
    }
    async findById(id) {
        const media = await this.prisma.media.findUnique({
            where: { id },
            include: {
                uploadedBy: {
                    select: {
                        id: true,
                        name: true,
                        email: true,
                    },
                },
            },
        });
        if (!media) {
            throw new common_1.NotFoundException('Media not found');
        }
        return media;
    }
    async update(id, alt, caption) {
        await this.findById(id);
        return this.prisma.media.update({
            where: { id },
            data: { alt, caption },
        });
    }
    async remove(id) {
        const media = await this.findById(id);
        const filepath = path.join(process.cwd(), media.path);
        try {
            await fs.unlink(filepath);
        }
        catch (error) {
            console.error('Error deleting file:', error);
        }
        return this.prisma.media.delete({
            where: { id },
        });
    }
};
exports.MediaService = MediaService;
exports.MediaService = MediaService = MediaService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], MediaService);


/***/ }),
/* 127 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.MediaController = void 0;
const common_1 = __webpack_require__(2);
const platform_express_1 = __webpack_require__(124);
const media_service_1 = __webpack_require__(126);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const current_user_decorator_1 = __webpack_require__(63);
const client_1 = __webpack_require__(17);
let MediaController = class MediaController {
    constructor(mediaService) {
        this.mediaService = mediaService;
    }
    upload(file, user) {
        if (!file) {
            throw new common_1.BadRequestException('No file uploaded');
        }
        if (!file.buffer) {
            throw new common_1.BadRequestException('File buffer is empty - upload failed');
        }
        return this.mediaService.upload(file, user.id);
    }
    findAll(page, limit, mimeType) {
        return this.mediaService.findAll(page ? parseInt(page) : 1, limit ? parseInt(limit) : 20, mimeType);
    }
    findOne(id) {
        return this.mediaService.findById(id);
    }
    update(id, updateData) {
        return this.mediaService.update(id, updateData.alt, updateData.caption);
    }
    remove(id) {
        return this.mediaService.remove(id);
    }
};
exports.MediaController = MediaController;
__decorate([
    (0, common_1.Post)('upload'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR, client_1.UserRole.AUTHOR),
    (0, common_1.UseInterceptors)((0, platform_express_1.FileInterceptor)('file')),
    __param(0, (0, common_1.UploadedFile)()),
    __param(1, (0, current_user_decorator_1.CurrentUser)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_c = typeof Express !== "undefined" && (_b = Express.Multer) !== void 0 && _b.File) === "function" ? _c : Object, Object]),
    __metadata("design:returntype", void 0)
], MediaController.prototype, "upload", null);
__decorate([
    (0, common_1.Get)(),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR, client_1.UserRole.AUTHOR),
    __param(0, (0, common_1.Query)('page')),
    __param(1, (0, common_1.Query)('limit')),
    __param(2, (0, common_1.Query)('mimeType')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, String]),
    __metadata("design:returntype", void 0)
], MediaController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR, client_1.UserRole.AUTHOR),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], MediaController.prototype, "findOne", null);
__decorate([
    (0, common_1.Patch)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR, client_1.UserRole.AUTHOR),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", void 0)
], MediaController.prototype, "update", null);
__decorate([
    (0, common_1.Delete)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], MediaController.prototype, "remove", null);
exports.MediaController = MediaController = __decorate([
    (0, common_1.Controller)('api/media'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof media_service_1.MediaService !== "undefined" && media_service_1.MediaService) === "function" ? _a : Object])
], MediaController);


/***/ }),
/* 128 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ThemesModule = void 0;
const common_1 = __webpack_require__(2);
const jwt_1 = __webpack_require__(43);
const config_1 = __webpack_require__(13);
const prisma_module_1 = __webpack_require__(15);
const themes_service_1 = __webpack_require__(129);
const themes_controller_1 = __webpack_require__(131);
const theme_renderer_service_1 = __webpack_require__(132);
const theme_editor_service_1 = __webpack_require__(137);
const theme_editor_controller_1 = __webpack_require__(138);
const custom_themes_service_1 = __webpack_require__(139);
const custom_themes_controller_1 = __webpack_require__(140);
const ai_theme_generator_service_1 = __webpack_require__(144);
const customization_renderer_service_1 = __webpack_require__(134);
const theme_customization_service_1 = __webpack_require__(145);
const theme_customization_controller_1 = __webpack_require__(146);
const marketplace_service_1 = __webpack_require__(150);
const marketplace_controller_1 = __webpack_require__(151);
const content_module_1 = __webpack_require__(97);
const settings_module_1 = __webpack_require__(78);
const menus_module_1 = __webpack_require__(152);
const email_module_1 = __webpack_require__(77);
const subscriptions_module_1 = __webpack_require__(156);
let ThemesModule = class ThemesModule {
};
exports.ThemesModule = ThemesModule;
exports.ThemesModule = ThemesModule = __decorate([
    (0, common_1.Module)({
        imports: [
            prisma_module_1.PrismaModule,
            content_module_1.ContentModule,
            settings_module_1.SettingsModule,
            menus_module_1.MenusModule,
            email_module_1.EmailModule,
            subscriptions_module_1.SubscriptionsModule,
            jwt_1.JwtModule.registerAsync({
                imports: [config_1.ConfigModule],
                useFactory: async (configService) => ({
                    secret: configService.get('JWT_SECRET'),
                    signOptions: { expiresIn: '15m' },
                }),
                inject: [config_1.ConfigService],
            }),
        ],
        providers: [
            themes_service_1.ThemesService,
            theme_renderer_service_1.ThemeRendererService,
            theme_editor_service_1.ThemeEditorService,
            custom_themes_service_1.CustomThemesService,
            ai_theme_generator_service_1.AiThemeGeneratorService,
            customization_renderer_service_1.CustomizationRendererService,
            theme_customization_service_1.ThemeCustomizationService,
            marketplace_service_1.MarketplaceService,
        ],
        controllers: [
            themes_controller_1.ThemesController,
            theme_editor_controller_1.ThemeEditorController,
            custom_themes_controller_1.CustomThemesController,
            theme_customization_controller_1.ThemeCustomizationController,
            marketplace_controller_1.MarketplaceController,
        ],
        exports: [
            themes_service_1.ThemesService,
            theme_renderer_service_1.ThemeRendererService,
            theme_editor_service_1.ThemeEditorService,
            custom_themes_service_1.CustomThemesService,
            ai_theme_generator_service_1.AiThemeGeneratorService,
            customization_renderer_service_1.CustomizationRendererService,
            theme_customization_service_1.ThemeCustomizationService,
            marketplace_service_1.MarketplaceService,
        ],
    })
], ThemesModule);


/***/ }),
/* 129 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ThemesService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const fs = __webpack_require__(24);
const path = __webpack_require__(3);
const AdmZip = __webpack_require__(130);
const REQUIRED_TEMPLATES = [
    'templates/home.hbs',
    'templates/single-post.hbs',
    'templates/single-page.hbs',
];
const REQUIRED_THEME_JSON_FIELDS = ['name', 'version', 'author'];
const MAX_THEME_SIZE = 10 * 1024 * 1024;
let ThemesService = class ThemesService {
    constructor(prisma) {
        this.prisma = prisma;
        this.themesDir = path.join(process.cwd(), 'themes');
    }
    async onModuleInit() {
        try {
            await this.scanThemes();
        }
        catch (error) {
            console.error('Error scanning themes on module init:', error);
        }
    }
    async scanThemes() {
        try {
            const dirs = await fs.readdir(this.themesDir);
            const themes = [];
            for (const dir of dirs) {
                const themePath = path.join(this.themesDir, dir);
                const stat = await fs.stat(themePath);
                if (stat.isDirectory()) {
                    const configPath = path.join(themePath, 'theme.json');
                    try {
                        const configContent = await fs.readFile(configPath, 'utf-8');
                        const config = JSON.parse(configContent);
                        const theme = await this.prisma.theme.upsert({
                            where: { slug: dir },
                            update: {
                                name: config.name,
                                version: config.version,
                                author: config.author,
                                description: config.description,
                                thumbnail: config.thumbnail,
                                config,
                            },
                            create: {
                                name: config.name,
                                slug: dir,
                                version: config.version,
                                author: config.author,
                                description: config.description,
                                thumbnail: config.thumbnail,
                                path: `/themes/${dir}`,
                                config,
                            },
                        });
                        themes.push(theme);
                    }
                    catch (error) {
                        console.error(`Error loading theme ${dir}:`, error.message);
                    }
                }
            }
            await this.ensureSingleActiveTheme();
            return themes;
        }
        catch (error) {
            console.error('Error scanning themes:', error);
            return [];
        }
    }
    async ensureSingleActiveTheme() {
        const activeThemes = await this.prisma.theme.findMany({
            where: { isActive: true },
            orderBy: { updatedAt: 'desc' },
        });
        if (activeThemes.length > 1) {
            const [keepActive, ...deactivate] = activeThemes;
            console.log(`Fixing data: ${deactivate.length} extra active themes found. Keeping "${keepActive.name}" as active.`);
            await this.prisma.theme.updateMany({
                where: {
                    id: { in: deactivate.map((t) => t.id) },
                },
                data: { isActive: false },
            });
        }
        else if (activeThemes.length === 0) {
            const firstTheme = await this.prisma.theme.findFirst({
                orderBy: { name: 'asc' },
            });
            if (firstTheme) {
                await this.prisma.theme.update({
                    where: { id: firstTheme.id },
                    data: { isActive: true },
                });
                console.log(`No active theme found. Activated "${firstTheme.name}".`);
            }
        }
    }
    async findAll() {
        await this.ensureSingleActiveTheme();
        return this.prisma.theme.findMany({
            orderBy: { name: 'asc' },
        });
    }
    async findById(id) {
        const theme = await this.prisma.theme.findUnique({
            where: { id },
        });
        if (!theme) {
            throw new common_1.NotFoundException('Theme not found');
        }
        return theme;
    }
    async getActiveTheme() {
        const theme = await this.prisma.theme.findFirst({
            where: { isActive: true },
        });
        if (!theme) {
            throw new common_1.NotFoundException('No active theme found');
        }
        return theme;
    }
    async activate(id) {
        await this.prisma.theme.updateMany({
            data: { isActive: false },
        });
        return this.prisma.theme.update({
            where: { id },
            data: { isActive: true },
        });
    }
    getTemplatePath(themeSlug, template) {
        return path.join(this.themesDir, themeSlug, 'templates', `${template}.hbs`);
    }
    getPartialsPath(themeSlug) {
        return path.join(this.themesDir, themeSlug, 'partials');
    }
    validateThemeZip(file) {
        const errors = [];
        const warnings = [];
        if (!file.originalname.endsWith('.zip')) {
            errors.push('Only ZIP files are allowed');
            return { valid: false, errors, warnings };
        }
        if (file.size > MAX_THEME_SIZE) {
            errors.push(`File size exceeds maximum allowed size of ${MAX_THEME_SIZE / 1024 / 1024}MB`);
            return { valid: false, errors, warnings };
        }
        try {
            const zip = new AdmZip(file.buffer);
            const zipEntries = zip.getEntries();
            const entryNames = zipEntries
                .filter((e) => !e.entryName.includes('__MACOSX'))
                .map((e) => e.entryName);
            let themeConfig = null;
            let themeSlug = null;
            let rootFolder = null;
            for (const entry of zipEntries) {
                if (entry.entryName.endsWith('theme.json') && !entry.entryName.includes('__MACOSX')) {
                    try {
                        const configContent = entry.getData().toString('utf8');
                        themeConfig = JSON.parse(configContent);
                        const parts = entry.entryName.split('/');
                        rootFolder = parts.length > 1 ? parts[0] : null;
                        themeSlug = rootFolder || file.originalname.replace('.zip', '');
                    }
                    catch (_parseError) {
                        errors.push('theme.json contains invalid JSON');
                        return { valid: false, errors, warnings };
                    }
                    break;
                }
            }
            if (!themeConfig) {
                errors.push('Missing required file: theme.json');
                return { valid: false, errors, warnings };
            }
            for (const field of REQUIRED_THEME_JSON_FIELDS) {
                if (!themeConfig[field]) {
                    errors.push(`theme.json missing required field: ${field}`);
                }
            }
            for (const template of REQUIRED_TEMPLATES) {
                const templatePath = rootFolder ? `${rootFolder}/${template}` : template;
                const found = entryNames.some((name) => name === templatePath || name === template || name.endsWith(`/${template}`));
                if (!found) {
                    errors.push(`Missing required template: ${template}`);
                }
            }
            const hasScreenshot = entryNames.some((name) => name.endsWith('screenshot.png') || name.endsWith('screenshot.jpg'));
            if (!hasScreenshot) {
                warnings.push('No screenshot.png found. A preview image is recommended.');
            }
            const hasArchive = entryNames.some((name) => name.endsWith('templates/archive.hbs') || name === 'archive.hbs');
            if (!hasArchive) {
                warnings.push('No archive.hbs template found. This template is optional but recommended.');
            }
            return {
                valid: errors.length === 0,
                errors,
                warnings,
                themeConfig,
                themeSlug: themeSlug,
                rootFolder: rootFolder || undefined,
                hasScreenshot,
            };
        }
        catch (error) {
            errors.push('Failed to read ZIP file: ' + error.message);
            return { valid: false, errors, warnings };
        }
    }
    async validateTheme(file) {
        const validation = this.validateThemeZip(file);
        if (validation.valid && validation.themeSlug) {
            const existingTheme = await this.prisma.theme.findUnique({
                where: { slug: validation.themeSlug },
            });
            if (existingTheme) {
                validation.errors.push(`Theme "${validation.themeSlug}" already exists. Please delete it first or use a different folder name.`);
                validation.valid = false;
                return { ...validation, exists: true };
            }
        }
        return validation;
    }
    async uploadTheme(file) {
        const validation = await this.validateTheme(file);
        if (!validation.valid) {
            throw new common_1.BadRequestException({
                message: 'Theme validation failed',
                errors: validation.errors,
                warnings: validation.warnings,
            });
        }
        const { themeConfig, themeSlug, rootFolder } = validation;
        try {
            const zip = new AdmZip(file.buffer);
            const zipEntries = zip.getEntries();
            const themePath = path.join(this.themesDir, themeSlug);
            await fs.mkdir(themePath, { recursive: true });
            for (const entry of zipEntries) {
                if (entry.entryName.includes('__MACOSX'))
                    continue;
                let entryPath = entry.entryName;
                if (rootFolder && entryPath.startsWith(rootFolder + '/')) {
                    entryPath = entryPath.substring(rootFolder.length + 1);
                }
                if (!entryPath)
                    continue;
                const fullPath = path.join(themePath, entryPath);
                if (entry.isDirectory) {
                    await fs.mkdir(fullPath, { recursive: true });
                }
                else {
                    await fs.mkdir(path.dirname(fullPath), { recursive: true });
                    await fs.writeFile(fullPath, entry.getData());
                }
            }
            let thumbnailPath = themeConfig.thumbnail || null;
            if (!thumbnailPath && validation.hasScreenshot) {
                thumbnailPath = `/themes/${themeSlug}/screenshot.png`;
            }
            const theme = await this.prisma.theme.create({
                data: {
                    name: themeConfig.name,
                    slug: themeSlug,
                    version: themeConfig.version,
                    author: themeConfig.author || 'Unknown',
                    description: themeConfig.description || '',
                    thumbnail: thumbnailPath,
                    path: `/themes/${themeSlug}`,
                    config: themeConfig,
                },
            });
            return {
                ...theme,
                warnings: validation.warnings,
            };
        }
        catch (error) {
            try {
                const themePath = path.join(this.themesDir, themeSlug);
                await fs.rm(themePath, { recursive: true, force: true });
            }
            catch { }
            if (error instanceof common_1.BadRequestException) {
                throw error;
            }
            console.error('Error uploading theme:', error);
            throw new common_1.BadRequestException('Failed to upload theme: ' + error.message);
        }
    }
    async deleteTheme(id) {
        const theme = await this.findById(id);
        if (theme.isActive) {
            throw new common_1.BadRequestException('Cannot delete the active theme. Please activate another theme first.');
        }
        const themePath = path.join(this.themesDir, theme.slug);
        try {
            await fs.rm(themePath, { recursive: true, force: true });
        }
        catch (error) {
            console.error('Error deleting theme directory:', error);
        }
        return this.prisma.theme.delete({
            where: { id },
        });
    }
    async generateTheme(config) {
        const slug = config.name
            .toLowerCase()
            .replace(/[^a-z0-9]+/g, '-')
            .replace(/^-|-$/g, '');
        const existingTheme = await this.prisma.theme.findUnique({
            where: { slug },
        });
        if (existingTheme) {
            throw new common_1.BadRequestException(`Theme "${slug}" already exists. Please choose a different name.`);
        }
        const themePath = path.join(this.themesDir, slug);
        try {
            await fs.mkdir(themePath, { recursive: true });
            await fs.mkdir(path.join(themePath, 'templates'), { recursive: true });
            await fs.mkdir(path.join(themePath, 'assets'), { recursive: true });
            await fs.mkdir(path.join(themePath, 'assets', 'css'), { recursive: true });
            await fs.mkdir(path.join(themePath, 'assets', 'media'), { recursive: true });
            if (config.mediaBlocks && config.mediaBlocks.length > 0) {
                await this.copyMediaFiles(config.mediaBlocks, themePath);
            }
            const themeJson = {
                name: config.name,
                version: config.version,
                author: config.author,
                description: config.description || `Custom theme created with Theme Designer`,
                thumbnail: `/themes/${slug}/screenshot.png`,
                designConfig: JSON.parse(JSON.stringify(config)),
                mediaBlocks: config.mediaBlocks || [],
            };
            await fs.writeFile(path.join(themePath, 'theme.json'), JSON.stringify(themeJson, null, 2));
            const cssContent = this.generateThemeCSS(config);
            await fs.writeFile(path.join(themePath, 'assets', 'css', 'theme.css'), cssContent);
            const templates = this.generateThemeTemplates(config, slug);
            for (const [name, content] of Object.entries(templates)) {
                await fs.writeFile(path.join(themePath, 'templates', `${name}.hbs`), content);
            }
            await this.generateScreenshotPlaceholder(themePath, config);
            const theme = await this.prisma.theme.create({
                data: {
                    name: config.name,
                    slug,
                    version: config.version,
                    author: config.author,
                    description: config.description || `Custom theme created with Theme Designer`,
                    thumbnail: `/themes/${slug}/screenshot.png`,
                    path: `/themes/${slug}`,
                    config: JSON.parse(JSON.stringify(themeJson)),
                },
            });
            return theme;
        }
        catch (error) {
            try {
                await fs.rm(themePath, { recursive: true, force: true });
            }
            catch { }
            if (error instanceof common_1.BadRequestException) {
                throw error;
            }
            console.error('Error generating theme:', error);
            throw new common_1.BadRequestException('Failed to generate theme: ' + error.message);
        }
    }
    generateThemeCSS(config) {
        const { colors, typography, layout, spacing, borders } = config;
        return `/* Theme: ${config.name} - Generated by Theme Designer */

:root {
  /* Colors */
  --color-primary: ${colors.primary};
  --color-secondary: ${colors.secondary};
  --color-background: ${colors.background};
  --color-surface: ${colors.surface};
  --color-text: ${colors.text};
  --color-text-muted: ${colors.textMuted};
  --color-heading: ${colors.heading};
  --color-link: ${colors.link};
  --color-link-hover: ${colors.linkHover};
  --color-border: ${colors.border};
  --color-accent: ${colors.accent};

  /* Typography */
  --font-heading: ${typography.headingFont};
  --font-body: ${typography.bodyFont};
  --font-size-base: ${typography.baseFontSize}px;
  --line-height: ${typography.lineHeight};
  --heading-weight: ${typography.headingWeight};

  /* Layout */
  --content-width: ${layout.contentWidth}px;
  --sidebar-position: ${layout.sidebarPosition};

  /* Spacing */
  --section-padding: ${spacing.sectionPadding}px;
  --element-spacing: ${spacing.elementSpacing}px;
  --container-padding: ${spacing.containerPadding}px;

  /* Borders */
  --border-radius: ${borders.radius}px;
  --border-width: ${borders.width}px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: var(--font-body), system-ui, sans-serif;
  font-size: var(--font-size-base);
  line-height: var(--line-height);
  color: var(--color-text);
  background-color: var(--color-background);
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-heading), system-ui, sans-serif;
  font-weight: var(--heading-weight);
  color: var(--color-heading);
  margin-bottom: var(--element-spacing);
}

h1 { font-size: 2.5rem; }
h2 { font-size: 2rem; }
h3 { font-size: 1.5rem; }
h4 { font-size: 1.25rem; }

a {
  color: var(--color-link);
  text-decoration: none;
  transition: color 0.2s ease;
}
a:hover { color: var(--color-link-hover); }

p { margin-bottom: var(--element-spacing); }

.container {
  max-width: var(--content-width);
  margin: 0 auto;
  padding: 0 var(--container-padding);
}

/* Header */
.site-header {
  background-color: var(--color-surface);
  border-bottom: var(--border-width) solid var(--color-border);
  padding: var(--section-padding) 0;
}

.site-header.header-centered { text-align: center; }
.site-header.header-minimal { padding: calc(var(--section-padding) / 2) 0; }

.site-title {
  font-size: 1.75rem;
  font-weight: var(--heading-weight);
  color: var(--color-heading);
  margin: 0;
}

.site-header .container {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.site-nav {
  display: flex;
  gap: 1.5rem;
  flex: 1;
}

.site-nav.nav-centered { justify-content: center; }
.site-nav a { color: var(--color-text); font-weight: 500; }
.site-nav a:hover { color: var(--color-primary); }

.header-actions {
  display: flex;
  gap: 1rem;
  align-items: center;
}

.cart-link {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  background: var(--color-primary);
  color: white !important;
  border-radius: var(--border-radius);
  font-weight: 500;
}
.cart-link:hover {
  background: var(--color-primary-hover, var(--color-primary));
  opacity: 0.9;
}

/* Main Content */
.site-main {
  padding: var(--section-padding) 0;
  min-height: 60vh;
}

.content-wrapper {
  display: ${layout.sidebarPosition === 'none' ? 'block' : 'grid'};
  ${layout.sidebarPosition !== 'none' ? `grid-template-columns: ${layout.sidebarPosition === 'left' ? '280px 1fr' : '1fr 280px'};` : ''}
  gap: calc(var(--section-padding) * 1.5);
}

.main-content { min-width: 0; }

/* Sidebar */
.sidebar {
  ${layout.sidebarPosition === 'left' ? 'order: -1;' : ''}
}

.widget {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--border-radius);
  padding: var(--section-padding);
  margin-bottom: var(--element-spacing);
}

.widget-title {
  font-size: 1.1rem;
  margin-bottom: calc(var(--element-spacing) * 0.75);
  padding-bottom: calc(var(--element-spacing) * 0.5);
  border-bottom: var(--border-width) solid var(--color-border);
}

/* Posts */
.post, .page-content {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--border-radius);
  padding: var(--section-padding);
  margin-bottom: var(--element-spacing);
}

.post-title {
  font-size: 1.75rem;
  margin-bottom: calc(var(--element-spacing) * 0.5);
}

.post-title a { color: var(--color-heading); }
.post-title a:hover { color: var(--color-primary); }

.post-meta {
  color: var(--color-text-muted);
  font-size: 0.875rem;
  margin-bottom: var(--element-spacing);
}

.post-excerpt, .post-content { line-height: 1.7; }

.read-more {
  display: inline-block;
  margin-top: var(--element-spacing);
  padding: 0.5rem 1rem;
  background: var(--color-primary);
  color: white;
  border-radius: var(--border-radius);
  font-weight: 500;
}
.read-more:hover { background: var(--color-secondary); color: white; }

/* Footer */
.site-footer {
  background: var(--color-surface);
  border-top: var(--border-width) solid var(--color-border);
  padding: var(--section-padding) 0;
  text-align: center;
  color: var(--color-text-muted);
}

/* Utility */
.btn {
  display: inline-block;
  padding: 0.75rem 1.5rem;
  background: var(--color-primary);
  color: white;
  border: none;
  border-radius: var(--border-radius);
  cursor: pointer;
  font-weight: 500;
  transition: background 0.2s ease;
}
.btn:hover { background: var(--color-secondary); color: white; }

.card {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--border-radius);
  padding: var(--section-padding);
}

/* Footer Navigation */
.footer-nav {
  display: flex;
  gap: 1.5rem;
  justify-content: center;
  margin-bottom: 1rem;
  flex-wrap: wrap;
}
.footer-nav a {
  color: var(--color-text);
  opacity: 0.8;
}
.footer-nav a:hover {
  color: var(--color-primary);
  opacity: 1;
}

@media (max-width: 768px) {
  .content-wrapper { grid-template-columns: 1fr; }
  .sidebar { order: 1; }
  h1 { font-size: 2rem; }
  h2 { font-size: 1.5rem; }
  .site-nav, .footer-nav { flex-direction: column; gap: 0.5rem; text-align: center; }
}

/* WYSIWYG Content Blocks */
.wysiwyg-content {
  margin-bottom: var(--section-padding);
}

.wysiwyg-block {
  margin-bottom: var(--element-spacing);
}

.wysiwyg-text {
  font-size: var(--font-size-base);
  line-height: var(--line-height);
  color: var(--color-text);
}

.wysiwyg-image img,
.wysiwyg-video video {
  max-width: 100%;
  height: auto;
  border-radius: var(--border-radius);
}

.wysiwyg-audio {
  padding: 1rem;
  background: var(--color-surface);
  border-radius: var(--border-radius);
}

.wysiwyg-audio audio {
  width: 100%;
  max-width: 400px;
}

.wysiwyg-audio p {
  margin-top: 0.5rem;
  font-weight: 500;
}

/* Shop Styles */
.products-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: var(--section-padding);
}

.product-card {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--border-radius);
  overflow: hidden;
  transition: transform 0.2s, box-shadow 0.2s;
}
.product-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 8px 20px rgba(0,0,0,0.1);
}

.product-card .product-image img {
  width: 100%;
  height: 200px;
  object-fit: cover;
}

.product-info {
  padding: 1rem;
}

.product-name {
  font-size: 1.1rem;
  margin: 0 0 0.5rem;
}
.product-name a {
  color: var(--color-heading);
}

.product-price {
  font-size: 1.25rem;
  font-weight: bold;
  color: var(--color-primary);
  margin-bottom: 1rem;
}
.price-sale {
  color: #e53e3e;
}
.price-regular {
  text-decoration: line-through;
  color: var(--color-text-muted);
  font-size: 0.9rem;
  margin-left: 0.5rem;
}

.btn-primary {
  display: inline-block;
  background: var(--color-primary);
  color: white;
  padding: 0.75rem 1.5rem;
  border-radius: var(--border-radius);
  text-decoration: none;
  font-weight: 500;
  border: none;
  cursor: pointer;
}
.btn-primary:hover {
  opacity: 0.9;
}
.btn-lg {
  padding: 1rem 2rem;
  font-size: 1.1rem;
}

/* Single Product */
.product-single {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: calc(var(--section-padding) * 2);
}
.product-gallery img {
  width: 100%;
  border-radius: var(--border-radius);
}
.product-thumbnails {
  display: flex;
  gap: 0.5rem;
  margin-top: 1rem;
}
.product-thumb {
  width: 80px;
  height: 80px;
  object-fit: cover;
  border-radius: var(--border-radius);
  cursor: pointer;
}
.product-title {
  font-size: 2rem;
  margin: 0 0 1rem;
}
.product-actions {
  margin: 1.5rem 0;
}
.quantity-input {
  width: 80px;
  padding: 0.5rem;
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--border-radius);
  margin-right: 1rem;
}
.product-description {
  margin-top: 2rem;
  padding-top: 2rem;
  border-top: var(--border-width) solid var(--color-border);
}

/* Cart */
.cart-items {
  margin-bottom: 2rem;
}
.cart-item {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  padding: 1rem;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--border-radius);
  margin-bottom: 1rem;
}
.cart-item-image {
  width: 100px;
  height: 100px;
  object-fit: cover;
  border-radius: var(--border-radius);
}
.cart-item-info {
  flex: 1;
}
.cart-item-info h3 {
  margin: 0 0 0.5rem;
}
.cart-summary {
  text-align: right;
  padding: 1.5rem;
  background: var(--color-surface);
  border-radius: var(--border-radius);
}
.cart-total {
  font-size: 1.5rem;
  margin-bottom: 1rem;
}
.btn-remove {
  background: #e53e3e;
  color: white;
  border: none;
  padding: 0.5rem 1rem;
  border-radius: var(--border-radius);
  cursor: pointer;
}

@media (max-width: 768px) {
  .product-single { grid-template-columns: 1fr; }
  .cart-item { flex-wrap: wrap; }
}
`;
    }
    generateMediaBlocksHtml(mediaBlocks, slug) {
        if (!mediaBlocks || mediaBlocks.length === 0)
            return '';
        return mediaBlocks
            .map((block) => {
            const alignStyle = block.align ? `text-align: ${block.align};` : '';
            const widthStyle = block.width ? `max-width: ${block.width}%;` : '';
            switch (block.type) {
                case 'text':
                    return `<div class="wysiwyg-block wysiwyg-text" style="${alignStyle}">${block.content || ''}</div>`;
                case 'image':
                    if (!block.src)
                        return '';
                    const imgSrc = block.src.startsWith('/uploads/')
                        ? `/themes/${slug}/assets/media/${block.src.replace(/^\/uploads\//, '')}`
                        : block.src;
                    return `<div class="wysiwyg-block wysiwyg-image" style="${alignStyle}"><img src="${imgSrc}" alt="" style="${widthStyle} display: inline-block;"></div>`;
                case 'video':
                    if (!block.src)
                        return '';
                    const videoSrc = block.src.startsWith('/uploads/')
                        ? `/themes/${slug}/assets/media/${block.src.replace(/^\/uploads\//, '')}`
                        : block.src;
                    return `<div class="wysiwyg-block wysiwyg-video" style="${alignStyle}"><video src="${videoSrc}" controls style="${widthStyle} display: inline-block;"></video></div>`;
                case 'audio':
                    if (!block.src)
                        return '';
                    const audioSrc = block.src.startsWith('/uploads/')
                        ? `/themes/${slug}/assets/media/${block.src.replace(/^\/uploads\//, '')}`
                        : block.src;
                    return `<div class="wysiwyg-block wysiwyg-audio" style="${alignStyle}"><audio src="${audioSrc}" controls></audio><p>${block.title || 'Audio Track'}</p></div>`;
                default:
                    return '';
            }
        })
            .join('\n          ');
    }
    generateThemeTemplates(config, slug) {
        const { layout } = config;
        const headerClass = layout.headerStyle === 'centered'
            ? 'header-centered'
            : layout.headerStyle === 'minimal'
                ? 'header-minimal'
                : '';
        const navClass = layout.headerStyle === 'centered' ? 'nav-centered' : '';
        const wysiwygContent = this.generateMediaBlocksHtml(config.mediaBlocks, slug);
        const hasSidebar = layout.sidebarPosition !== 'none';
        const adminBarStyles = `
  <style id="admin-bar-styles">
    .admin-bar { display: none; position: fixed; top: 0; left: 0; right: 0; height: 32px; background: #1e1e1e; color: #fff; font-size: 13px; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; z-index: 99999; box-shadow: 0 1px 3px rgba(0,0,0,0.2); }
    .admin-bar.visible { display: flex; }
    .admin-bar-container { display: flex; align-items: center; justify-content: space-between; max-width: 1400px; margin: 0 auto; padding: 0 16px; height: 100%; }
    .admin-bar-left, .admin-bar-right { display: flex; align-items: center; gap: 12px; }
    .admin-bar a { color: #a0aec0; text-decoration: none; padding: 4px 8px; border-radius: 4px; transition: all 0.2s; }
    .admin-bar a:hover { color: #fff; background: rgba(255,255,255,0.1); }
    .admin-bar .customize-btn { background: #3b82f6; color: #fff; font-weight: 500; }
    .admin-bar .customize-btn:hover { background: #2563eb; }
    .admin-bar .user-info { color: #718096; }
    body.has-admin-bar { padding-top: 32px; }
    body.has-admin-bar .site-header { top: 32px; }
  </style>`;
        const adminBarHtml = `
  <div id="admin-bar" class="admin-bar">
    <div class="admin-bar-container">
      <div class="admin-bar-left">
        <a id="admin-link-dashboard" href="#">← Dashboard</a>
        <a id="admin-link-posts" href="#">Posts</a>
        <a id="admin-link-pages" href="#">Pages</a>
        <a id="admin-link-customize" href="#" class="customize-btn">✎ Customize</a>
      </div>
      <div class="admin-bar-right">
        <span class="user-info" id="admin-bar-user"></span>
        <a id="admin-link-settings" href="#">Settings</a>
      </div>
    </div>
  </div>`;
        const layoutStart = `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>{{#if title}}{{title}} - {{/if}}{{site.name}}</title>
  <link rel="stylesheet" href="/themes/${slug}/assets/css/theme.css">
  ${adminBarStyles}
</head>
<body>
  ${adminBarHtml}
  <header class="site-header ${headerClass}">
    <div class="container">
      <h1 class="site-title"><a href="/">{{site.name}}</a></h1>
      <nav class="site-nav ${navClass}">
        {{#if menus.header}}
          {{#each menus.header.items}}
          <a href="{{this.url}}" target="{{this.target}}">{{this.label}}</a>
          {{/each}}
        {{else}}
          <a href="/">Home</a>
          <a href="/blog">Blog</a>
          <a href="/shop">Shop</a>
          <a href="/about">About</a>
          <a href="/contact">Contact</a>
        {{/if}}
      </nav>
      <div class="header-actions">
        <a href="/shop/cart" class="cart-link">🛒 Cart</a>
      </div>
    </div>
  </header>

  <main class="site-main">
    <div class="container">
      <div class="content-wrapper">
        <div class="main-content">`;
        const sidebarContent = hasSidebar
            ? `
        <aside class="sidebar">
          <div class="widget">
            <h3 class="widget-title">About</h3>
            <p>{{site.description}}</p>
          </div>
          <div class="widget">
            <h3 class="widget-title">Categories</h3>
            <ul>
              {{#each categories}}
              <li><a href="/category/{{this.slug}}">{{this.name}}</a></li>
              {{/each}}
            </ul>
          </div>
          <div class="widget">
            <h3 class="widget-title">Recent Posts</h3>
            <ul>
              {{#each recentPosts}}
              <li><a href="/{{this.slug}}">{{this.title}}</a></li>
              {{/each}}
            </ul>
          </div>
        </aside>`
            : '';
        const adminBarScript = `
  <script>
    (function() {
      try {
        var authData = localStorage.getItem('auth-storage');
        if (!authData) return;
        var parsed = JSON.parse(authData);
        var user = parsed && parsed.state && parsed.state.user;
        if (user && (user.role === 'ADMIN' || user.role === 'EDITOR')) {
          var adminBar = document.getElementById('admin-bar');
          var userInfo = document.getElementById('admin-bar-user');
          if (adminBar) { adminBar.classList.add('visible'); document.body.classList.add('has-admin-bar'); }
          if (userInfo) { userInfo.textContent = 'Logged in as ' + user.name + ' (' + user.role + ')'; }
          // Set admin panel URLs dynamically
          var adminBase = window.location.port === '3000' ? 'http://localhost:5173' : '';
          var setLink = function(id, path) { var el = document.getElementById(id); if (el) el.href = adminBase + path; };
          setLink('admin-link-dashboard', '/admin');
          setLink('admin-link-posts', '/admin/posts');
          setLink('admin-link-pages', '/admin/pages');
          setLink('admin-link-customize', '/admin/customize');
          setLink('admin-link-settings', '/admin/settings');
        }
      } catch (e) {}
    })();
  </script>`;
        const layoutEnd = `
        </div>${sidebarContent}
      </div>
    </div>
  </main>

  <footer class="site-footer">
    <div class="container">
      {{#if menus.footer}}
      <nav class="footer-nav">
        {{#each menus.footer.items}}
        <a href="{{this.url}}" target="{{this.target}}">{{this.label}}</a>
        {{/each}}
      </nav>
      {{/if}}
      <p>&copy; {{year}} {{site.name}}. All rights reserved.</p>
    </div>
  </footer>
  ${adminBarScript}
</body>
</html>`;
        return {
            home: `${layoutStart}
          ${wysiwygContent
                ? `<!-- Custom WYSIWYG Content -->
          <section class="wysiwyg-content">
          ${wysiwygContent}
          </section>
          <hr style="margin: 2rem 0; border-color: var(--color-border);">`
                : ''}
          <h2>Latest Posts</h2>
          {{#each posts}}
          <article class="post">
            <h2 class="post-title"><a href="/{{this.slug}}">{{this.title}}</a></h2>
            <div class="post-meta">
              <span>By {{this.author.name}}</span> &bull;
              <span>{{formatDate this.createdAt}}</span>
              {{#if this.category}}
              &bull; <a href="/category/{{this.category.slug}}">{{this.category.name}}</a>
              {{/if}}
            </div>
            <div class="post-excerpt">
              {{truncate this.content 200}}
            </div>
            <a href="/{{this.slug}}" class="read-more">Read More</a>
          </article>
          {{else}}
          <p>No posts yet. Check back soon!</p>
          {{/each}}

          {{#if pagination}}
          <nav class="pagination">
            {{#if pagination.hasPrev}}<a href="?page={{pagination.prevPage}}">&larr; Previous</a>{{/if}}
            <span>Page {{pagination.currentPage}} of {{pagination.totalPages}}</span>
            {{#if pagination.hasNext}}<a href="?page={{pagination.nextPage}}">Next &rarr;</a>{{/if}}
          </nav>
          {{/if}}
${layoutEnd}`,
            'single-post': `${layoutStart}
          <article class="post">
            <h1 class="post-title">{{post.title}}</h1>
            <div class="post-meta">
              <span>By {{post.author.name}}</span> &bull;
              <span>{{formatDate post.createdAt}}</span>
              {{#if post.category}}
              &bull; <a href="/category/{{post.category.slug}}">{{post.category.name}}</a>
              {{/if}}
            </div>
            {{#if post.featuredImage}}
            <img src="{{post.featuredImage}}" alt="{{post.title}}" class="post-image">
            {{/if}}
            <div class="post-content">
              {{{post.content}}}
            </div>
            {{#if post.tags.length}}
            <div class="post-tags">
              <strong>Tags:</strong>
              {{#each post.tags}}<a href="/tag/{{this.slug}}">{{this.name}}</a>{{#unless @last}}, {{/unless}}{{/each}}
            </div>
            {{/if}}
          </article>

          <nav class="post-navigation">
            {{#if prevPost}}<a href="/{{prevPost.slug}}">&larr; {{prevPost.title}}</a>{{/if}}
            {{#if nextPost}}<a href="/{{nextPost.slug}}">{{nextPost.title}} &rarr;</a>{{/if}}
          </nav>
${layoutEnd}`,
            'single-page': `${layoutStart}
          <article class="page-content">
            <h1 class="post-title">{{page.title}}</h1>
            <div class="post-content">
              {{{page.content}}}
            </div>
          </article>
${layoutEnd}`,
            archive: `${layoutStart}
          <h1>{{#if category}}Category: {{category.name}}{{else if tag}}Tag: {{tag.name}}{{else}}Archive{{/if}}</h1>

          {{#each posts}}
          <article class="post">
            <h2 class="post-title"><a href="/{{this.slug}}">{{this.title}}</a></h2>
            <div class="post-meta">
              <span>By {{this.author.name}}</span> &bull;
              <span>{{formatDate this.createdAt}}</span>
            </div>
            <div class="post-excerpt">
              {{truncate this.content 150}}
            </div>
            <a href="/{{this.slug}}" class="read-more">Read More</a>
          </article>
          {{else}}
          <p>No posts found.</p>
          {{/each}}

          {{#if pagination}}
          <nav class="pagination">
            {{#if pagination.hasPrev}}<a href="?page={{pagination.prevPage}}">&larr; Previous</a>{{/if}}
            <span>Page {{pagination.currentPage}} of {{pagination.totalPages}}</span>
            {{#if pagination.hasNext}}<a href="?page={{pagination.nextPage}}">Next &rarr;</a>{{/if}}
          </nav>
          {{/if}}
${layoutEnd}`,
            shop: `${layoutStart}
          <h1 class="page-title">Shop</h1>
          <div class="products-grid">
            {{#each products}}
            <div class="product-card">
              {{#if this.featuredImage}}
              <a href="/shop/product/{{this.slug}}" class="product-image">
                <img src="{{this.featuredImage}}" alt="{{this.name}}">
              </a>
              {{/if}}
              <div class="product-info">
                <h3 class="product-name"><a href="/shop/product/{{this.slug}}">{{this.name}}</a></h3>
                <div class="product-price">
                  {{#if this.salePrice}}
                  <span class="price-sale">\${{this.salePrice}}</span>
                  <span class="price-regular">\${{this.price}}</span>
                  {{else}}
                  <span class="price">\${{this.price}}</span>
                  {{/if}}
                </div>
                <a href="/shop/product/{{this.slug}}" class="btn btn-primary">View Product</a>
              </div>
            </div>
            {{else}}
            <p>No products available yet.</p>
            {{/each}}
          </div>
${layoutEnd}`,
            'single-product': `${layoutStart}
          <div class="product-single">
            <div class="product-gallery">
              {{#if product.featuredImage}}
              <img src="{{product.featuredImage}}" alt="{{product.name}}" class="product-main-image">
              {{/if}}
              {{#if product.images}}
              <div class="product-thumbnails">
                {{#each product.images}}
                <img src="{{this}}" alt="{{../product.name}}" class="product-thumb">
                {{/each}}
              </div>
              {{/if}}
            </div>
            <div class="product-details">
              <h1 class="product-title">{{product.name}}</h1>
              <div class="product-price">
                {{#if product.salePrice}}
                <span class="price-sale">\${{product.salePrice}}</span>
                <span class="price-regular">\${{product.price}}</span>
                {{else}}
                <span class="price">\${{product.price}}</span>
                {{/if}}
              </div>
              {{#if product.shortDescription}}
              <p class="product-short-desc">{{product.shortDescription}}</p>
              {{/if}}
              <div class="product-actions">
                <form action="/shop/cart/add" method="POST">
                  <input type="hidden" name="productId" value="{{product.id}}">
                  <input type="number" name="quantity" value="1" min="1" class="quantity-input">
                  <button type="submit" class="btn btn-primary btn-lg">Add to Cart</button>
                </form>
              </div>
              {{#if product.description}}
              <div class="product-description">
                <h3>Description</h3>
                {{{product.description}}}
              </div>
              {{/if}}
            </div>
          </div>
${layoutEnd}`,
            cart: `${layoutStart}
          <h1 class="page-title">Shopping Cart</h1>
          {{#if cart.items.length}}
          <div class="cart-items">
            {{#each cart.items}}
            <div class="cart-item">
              {{#if this.product.featuredImage}}
              <img src="{{this.product.featuredImage}}" alt="{{this.product.name}}" class="cart-item-image">
              {{/if}}
              <div class="cart-item-info">
                <h3>{{this.product.name}}</h3>
                <p class="cart-item-price">\${{this.product.price}}</p>
              </div>
              <div class="cart-item-quantity">
                <form action="/shop/cart/update" method="POST">
                  <input type="hidden" name="itemId" value="{{this.id}}">
                  <input type="number" name="quantity" value="{{this.quantity}}" min="1" class="quantity-input">
                  <button type="submit">Update</button>
                </form>
              </div>
              <form action="/shop/cart/remove" method="POST">
                <input type="hidden" name="itemId" value="{{this.id}}">
                <button type="submit" class="btn-remove">Remove</button>
              </form>
            </div>
            {{/each}}
          </div>
          <div class="cart-summary">
            <p class="cart-total"><strong>Total:</strong> \${{cart.total}}</p>
            <a href="/shop/checkout" class="btn btn-primary btn-lg">Proceed to Checkout</a>
          </div>
          {{else}}
          <p>Your cart is empty. <a href="/shop">Continue shopping</a></p>
          {{/if}}
${layoutEnd}`,
        };
    }
    async generateScreenshotPlaceholder(themePath, config) {
        const { colors } = config;
        const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="900" viewBox="0 0 1200 900">
  <rect fill="${colors.background}" width="1200" height="900"/>
  <rect fill="${colors.surface}" x="0" y="0" width="1200" height="80"/>
  <text x="40" y="50" font-family="system-ui" font-size="24" font-weight="bold" fill="${colors.heading}">${config.name}</text>
  <rect fill="${colors.surface}" x="40" y="120" width="800" height="400" rx="${config.borders.radius}"/>
  <rect fill="${colors.primary}" x="60" y="140" width="200" height="20" rx="4"/>
  <rect fill="${colors.textMuted}" x="60" y="180" width="720" height="12" rx="2"/>
  <rect fill="${colors.textMuted}" x="60" y="200" width="680" height="12" rx="2"/>
  <rect fill="${colors.textMuted}" x="60" y="220" width="700" height="12" rx="2"/>
  <rect fill="${colors.primary}" x="60" y="480" width="120" height="30" rx="${config.borders.radius}"/>
  <rect fill="${colors.surface}" x="880" y="120" width="280" height="200" rx="${config.borders.radius}"/>
  <rect fill="${colors.border}" x="900" y="140" width="240" height="2"/>
  <rect fill="${colors.surface}" x="880" y="340" width="280" height="180" rx="${config.borders.radius}"/>
  <rect fill="${colors.surface}" x="0" y="820" width="1200" height="80"/>
  <text x="600" y="860" font-family="system-ui" font-size="14" fill="${colors.textMuted}" text-anchor="middle">Theme Preview - ${config.name}</text>
</svg>`;
        await fs.writeFile(path.join(themePath, 'screenshot.svg'), svg);
        await fs.writeFile(path.join(themePath, 'screenshot.png'), svg);
    }
    async copyMediaFiles(mediaBlocks, themePath) {
        const uploadsDir = path.join(process.cwd(), 'uploads');
        const mediaDir = path.join(themePath, 'assets', 'media');
        for (const block of mediaBlocks) {
            if (block.src &&
                (block.type === 'image' || block.type === 'video' || block.type === 'audio')) {
                try {
                    const srcPath = block.src.replace(/^\/uploads\//, '');
                    const sourcePath = path.join(uploadsDir, srcPath);
                    const destPath = path.join(mediaDir, path.basename(srcPath));
                    try {
                        await fs.access(sourcePath);
                        await fs.copyFile(sourcePath, destPath);
                    }
                    catch {
                        console.log(`Media file not found: ${sourcePath}`);
                    }
                }
                catch (error) {
                    console.error(`Error copying media file: ${block.src}`, error);
                }
            }
            if (block.coverImage && block.type === 'audio') {
                try {
                    const srcPath = block.coverImage.replace(/^\/uploads\//, '');
                    const sourcePath = path.join(uploadsDir, srcPath);
                    const destPath = path.join(mediaDir, path.basename(srcPath));
                    try {
                        await fs.access(sourcePath);
                        await fs.copyFile(sourcePath, destPath);
                    }
                    catch {
                        console.log(`Cover image not found: ${sourcePath}`);
                    }
                }
                catch (error) {
                    console.error(`Error copying cover image: ${block.coverImage}`, error);
                }
            }
        }
    }
};
exports.ThemesService = ThemesService;
exports.ThemesService = ThemesService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], ThemesService);


/***/ }),
/* 130 */
/***/ ((module) => {

module.exports = require("adm-zip");

/***/ }),
/* 131 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e, _f;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ThemesController = void 0;
const common_1 = __webpack_require__(2);
const platform_express_1 = __webpack_require__(124);
const themes_service_1 = __webpack_require__(129);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const client_1 = __webpack_require__(17);
let ThemesController = class ThemesController {
    constructor(themesService) {
        this.themesService = themesService;
    }
    scan() {
        return this.themesService.scanThemes();
    }
    findAll() {
        return this.themesService.findAll();
    }
    getActive() {
        return this.themesService.getActiveTheme();
    }
    findOne(id) {
        return this.themesService.findById(id);
    }
    activate(id) {
        return this.themesService.activate(id);
    }
    validate(file) {
        return this.themesService.validateTheme(file);
    }
    upload(file) {
        return this.themesService.uploadTheme(file);
    }
    generate(config) {
        return this.themesService.generateTheme(config);
    }
    delete(id) {
        return this.themesService.deleteTheme(id);
    }
};
exports.ThemesController = ThemesController;
__decorate([
    (0, common_1.Post)('scan'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], ThemesController.prototype, "scan", null);
__decorate([
    (0, common_1.Get)(),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], ThemesController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)('active'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], ThemesController.prototype, "getActive", null);
__decorate([
    (0, common_1.Get)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], ThemesController.prototype, "findOne", null);
__decorate([
    (0, common_1.Post)(':id/activate'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], ThemesController.prototype, "activate", null);
__decorate([
    (0, common_1.Post)('validate'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    (0, common_1.UseInterceptors)((0, platform_express_1.FileInterceptor)('file')),
    __param(0, (0, common_1.UploadedFile)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_c = typeof Express !== "undefined" && (_b = Express.Multer) !== void 0 && _b.File) === "function" ? _c : Object]),
    __metadata("design:returntype", void 0)
], ThemesController.prototype, "validate", null);
__decorate([
    (0, common_1.Post)('upload'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    (0, common_1.UseInterceptors)((0, platform_express_1.FileInterceptor)('file')),
    __param(0, (0, common_1.UploadedFile)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_e = typeof Express !== "undefined" && (_d = Express.Multer) !== void 0 && _d.File) === "function" ? _e : Object]),
    __metadata("design:returntype", void 0)
], ThemesController.prototype, "upload", null);
__decorate([
    (0, common_1.Post)('generate'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_f = typeof themes_service_1.ThemeDesignConfig !== "undefined" && themes_service_1.ThemeDesignConfig) === "function" ? _f : Object]),
    __metadata("design:returntype", void 0)
], ThemesController.prototype, "generate", null);
__decorate([
    (0, common_1.Delete)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], ThemesController.prototype, "delete", null);
exports.ThemesController = ThemesController = __decorate([
    (0, common_1.Controller)('api/themes'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof themes_service_1.ThemesService !== "undefined" && themes_service_1.ThemesService) === "function" ? _a : Object])
], ThemesController);


/***/ }),
/* 132 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b, _c, _d, _e;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ThemeRendererService = void 0;
const common_1 = __webpack_require__(2);
const themes_service_1 = __webpack_require__(129);
const settings_service_1 = __webpack_require__(79);
const menus_service_1 = __webpack_require__(133);
const customization_renderer_service_1 = __webpack_require__(134);
const subscriptions_service_1 = __webpack_require__(135);
const device_detection_1 = __webpack_require__(136);
const Handlebars = __webpack_require__(51);
const fs = __webpack_require__(24);
let ThemeRendererService = class ThemeRendererService {
    constructor(themesService, settingsService, menusService, customizationRenderer, subscriptionsService) {
        this.themesService = themesService;
        this.settingsService = settingsService;
        this.menusService = menusService;
        this.customizationRenderer = customizationRenderer;
        this.subscriptionsService = subscriptionsService;
        this.registerHelpers();
        this.registerSubscriptionHelpers();
    }
    registerHelpers() {
        Handlebars.registerHelper('formatDate', (date) => {
            return new Date(date).toLocaleDateString();
        });
        Handlebars.registerHelper('excerpt', (text, length = 150) => {
            if (!text)
                return '';
            const textStr = String(text).replace(/<[^>]*>/g, '');
            const lengthNum = typeof length === 'number' ? length : 150;
            if (textStr.length <= lengthNum)
                return textStr;
            return textStr.substring(0, lengthNum) + '...';
        });
        Handlebars.registerHelper('truncate', (text, length = 150) => {
            if (!text)
                return '';
            const textStr = String(text).replace(/<[^>]*>/g, '');
            const lengthNum = typeof length === 'number' ? length : 150;
            if (textStr.length <= lengthNum)
                return textStr;
            return textStr.substring(0, lengthNum) + '...';
        });
        Handlebars.registerHelper('substring', (text, start, end) => {
            if (!text)
                return '';
            return text.substring(start, end);
        });
        Handlebars.registerHelper('eq', (a, b) => a === b);
        Handlebars.registerHelper('ne', (a, b) => a !== b);
        Handlebars.registerHelper('subtract', (a, b) => {
            const numA = parseFloat(a) || 0;
            const numB = parseFloat(b) || 0;
            return (numA - numB).toFixed(2);
        });
        Handlebars.registerHelper('add', (a, b) => {
            const numA = parseInt(a) || 0;
            const numB = parseInt(b) || 0;
            return numA + numB;
        });
        Handlebars.registerHelper('gt', (a, b) => a > b);
        Handlebars.registerHelper('lt', (a, b) => a < b);
        Handlebars.registerHelper('gte', (a, b) => a >= b);
        Handlebars.registerHelper('lte', (a, b) => a <= b);
        Handlebars.registerHelper('lowercase', (str) => {
            return str ? String(str).toLowerCase() : '';
        });
        Handlebars.registerHelper('uppercase', (str) => {
            return str ? String(str).toUpperCase() : '';
        });
    }
    registerSubscriptionHelpers() {
        Handlebars.registerHelper('hasFeature', function (feature, options) {
            const subscription = this.subscription;
            if (!subscription || !subscription.features) {
                return options.inverse ? options.inverse(this) : '';
            }
            const hasIt = subscription.features.includes(feature);
            return hasIt ? options.fn(this) : options.inverse ? options.inverse(this) : '';
        });
        Handlebars.registerHelper('hasPlan', function (planTier, options) {
            const subscription = this.subscription;
            const planHierarchy = ['free', 'starter', 'professional', 'enterprise'];
            const currentPlanIndex = subscription
                ? planHierarchy.indexOf(subscription.planTier?.toLowerCase() || 'free')
                : 0;
            const requiredPlanIndex = planHierarchy.indexOf(planTier.toLowerCase());
            const hasIt = currentPlanIndex >= requiredPlanIndex;
            return hasIt ? options.fn(this) : options.inverse ? options.inverse(this) : '';
        });
        Handlebars.registerHelper('isFreePlan', function (options) {
            const subscription = this.subscription;
            const isFree = !subscription || subscription.planTier?.toLowerCase() === 'free' || !subscription.isActive;
            return isFree ? options.fn(this) : options.inverse ? options.inverse(this) : '';
        });
        Handlebars.registerHelper('hasActiveSubscription', function (options) {
            const subscription = this.subscription;
            const isActive = subscription && subscription.isActive;
            return isActive ? options.fn(this) : options.inverse ? options.inverse(this) : '';
        });
        Handlebars.registerHelper('currentPlan', function () {
            const subscription = this.subscription;
            return subscription?.planName || 'Free';
        });
        Handlebars.registerHelper('formatPrice', (price, currency = 'USD') => {
            if (typeof price !== 'number')
                return '$0';
            return new Intl.NumberFormat('en-US', {
                style: 'currency',
                currency: currency,
            }).format(price / 100);
        });
        Handlebars.registerHelper('isCurrentPlan', function (planId) {
            const subscription = this.subscription;
            return subscription?.planId === planId;
        });
        Handlebars.registerHelper('upgradeUrl', (planId) => {
            return `/admin/pricing?plan=${planId}`;
        });
    }
    async registerPartials(themeSlug) {
        try {
            const templatePartials = ['header', 'footer', 'sidebar'];
            for (const partial of templatePartials) {
                try {
                    const partialPath = this.themesService.getTemplatePath(themeSlug, partial);
                    const partialContent = await fs.readFile(partialPath, 'utf-8');
                    Handlebars.registerPartial(partial, partialContent);
                }
                catch (_error) {
                }
            }
            const partialsDir = this.themesService.getPartialsPath(themeSlug);
            try {
                const files = await fs.readdir(partialsDir);
                for (const file of files) {
                    if (file.endsWith('.hbs')) {
                        const partialName = file.replace('.hbs', '');
                        const partialPath = `${partialsDir}/${file}`;
                        const partialContent = await fs.readFile(partialPath, 'utf-8');
                        Handlebars.registerPartial(partialName, partialContent);
                    }
                }
            }
            catch (_error) {
            }
        }
        catch (error) {
            console.error('Error registering partials:', error);
        }
    }
    async render(template, data, user, options) {
        try {
            const activeTheme = await this.themesService.getActiveTheme();
            await this.registerPartials(activeTheme.slug);
            const templatePath = this.themesService.getTemplatePath(activeTheme.slug, template);
            const templateContent = await fs.readFile(templatePath, 'utf-8');
            const compiledTemplate = Handlebars.compile(templateContent);
            const siteSettings = await this.settingsService.getSettings([
                'site_name',
                'site_description',
            ]);
            const [headerMenu, footerMenu, subscriptionData] = await Promise.all([
                this.menusService.findByLocation('header').catch(() => null),
                this.menusService.findByLocation('footer').catch(() => null),
                this.getSubscriptionContext(),
            ]);
            const currentYear = new Date().getFullYear();
            const canCustomize = user && (user.role === 'ADMIN' || user.role === 'EDITOR');
            const device = (0, device_detection_1.parseUserAgent)(options?.userAgent);
            const deviceClasses = (0, device_detection_1.getDeviceClasses)(device);
            const renderData = {
                ...data,
                site: siteSettings,
                year: currentYear,
                themeSlug: activeTheme.slug,
                menus: {
                    header: headerMenu,
                    footer: footerMenu,
                },
                device,
                deviceClasses,
                subscription: subscriptionData.currentSubscription,
                plans: subscriptionData.plans,
                user: user
                    ? {
                        id: user.id,
                        role: user.role,
                        name: user.name || user.email || 'User',
                        email: user.email,
                    }
                    : data.user || null,
                currentUser: user
                    ? {
                        id: user.id,
                        role: user.role,
                        canCustomize,
                    }
                    : null,
            };
            return compiledTemplate(renderData);
        }
        catch (error) {
            console.error('Error rendering template:', error);
            throw error;
        }
    }
    async renderHome(posts, shopData, user) {
        return this.render('home', {
            posts,
            featuredProducts: shopData?.featuredProducts || [],
            categories: shopData?.categories || [],
            featuredCourses: shopData?.featuredCourses || [],
        }, user);
    }
    async renderPost(post, user) {
        let html = await this.render('single-post', { post }, user);
        html = await this.customizationRenderer.applyPostCustomization(html, post.id);
        return html;
    }
    async renderPage(page, user) {
        const template = page.template || 'single-page';
        let html = await this.render(template, { page }, user);
        html = await this.customizationRenderer.applyPageCustomization(html, page.id);
        return html;
    }
    async renderArchive(posts, pagination, user, archiveTitle = 'Blog', archiveDescription = 'Latest posts and articles') {
        return this.render('archive', { posts, pagination, archiveTitle, archiveDescription }, user);
    }
    async renderShop(products, categories, pagination, activeCategory, user) {
        return this.render('shop', {
            products,
            categories,
            pagination,
            activeCategory,
        }, user);
    }
    async renderProduct(product, user) {
        return this.render('single-product', { product }, user);
    }
    async renderCourses(courses, categories, pagination, filters, user) {
        return this.render('courses', {
            courses,
            categories,
            pagination,
            currentCategory: filters.category,
            currentLevel: filters.level,
            currentPriceType: filters.priceType,
        }, user);
    }
    async renderCourse(course, isEnrolled = false, user) {
        return this.render('single-course', { course, isEnrolled }, user);
    }
    async renderCertificateVerify(result, user) {
        return this.render('certificate-verify', result, user);
    }
    async renderProfile(profile, stats, user) {
        return this.render('profile', {
            profile,
            stats,
            posts: profile.posts || [],
            courses: profile.instructedCourses || [],
            badges: profile.badges || [],
            certificates: profile.certificates || [],
        }, user);
    }
    async renderLogin(redirect, error, user) {
        return this.render('login', {
            redirect,
            error,
        }, user);
    }
    async renderRegister(error, user) {
        return this.render('register', {
            error,
        }, user);
    }
    async renderCart(user) {
        return this.render('cart', {
            user,
        }, user);
    }
    async renderCheckout(user) {
        return this.render('checkout', {
            user,
        }, user);
    }
    async renderMyAccount(user) {
        return this.render('my-account', {
            user,
        }, user);
    }
    async renderMyCourses(user) {
        return this.render('my-courses', {
            user,
        }, user);
    }
    async renderLearn(courseId, user) {
        return this.render('learn', {
            courseId,
            user,
        }, user);
    }
    async renderThemeDesigner(user) {
        return this.render('theme-designer', {
            user,
            isAdmin: user?.role === 'ADMIN',
        }, user);
    }
    async renderOrderSuccess(order, user) {
        return this.render('order-success', {
            order,
            user,
        }, user);
    }
    async getSubscriptionContext() {
        try {
            const plans = await this.subscriptionsService.getPlans();
            const currentSubscription = await this.subscriptionsService.getSiteSubscription();
            return {
                currentSubscription: currentSubscription
                    ? {
                        planId: currentSubscription.planId,
                        planName: currentSubscription.plan?.name || 'Free',
                        planTier: currentSubscription.plan?.slug?.toUpperCase() || 'FREE',
                        isActive: currentSubscription.status === 'ACTIVE',
                        features: currentSubscription.plan?.features || [],
                        expiresAt: currentSubscription.currentPeriodEnd,
                    }
                    : {
                        planId: null,
                        planName: 'Free',
                        planTier: 'FREE',
                        isActive: false,
                        features: [],
                        expiresAt: null,
                    },
                plans: plans.map((plan) => ({
                    id: plan.id,
                    name: plan.name,
                    slug: plan.slug,
                    description: plan.description,
                    monthlyPrice: plan.monthlyPrice,
                    yearlyPrice: plan.yearlyPrice,
                    features: plan.features,
                    maxUsers: plan.maxUsers,
                    maxStorageMb: plan.maxStorageMb,
                    maxCourses: plan.maxCourses,
                    maxProducts: plan.maxProducts,
                    isFeatured: plan.isFeatured,
                    badgeText: plan.badgeText,
                })),
            };
        }
        catch (error) {
            console.error('Error fetching subscription context:', error);
            return {
                currentSubscription: {
                    planId: null,
                    planName: 'Free',
                    planTier: 'FREE',
                    isActive: false,
                    features: [],
                    expiresAt: null,
                },
                plans: [],
            };
        }
    }
};
exports.ThemeRendererService = ThemeRendererService;
exports.ThemeRendererService = ThemeRendererService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof themes_service_1.ThemesService !== "undefined" && themes_service_1.ThemesService) === "function" ? _a : Object, typeof (_b = typeof settings_service_1.SettingsService !== "undefined" && settings_service_1.SettingsService) === "function" ? _b : Object, typeof (_c = typeof menus_service_1.MenusService !== "undefined" && menus_service_1.MenusService) === "function" ? _c : Object, typeof (_d = typeof customization_renderer_service_1.CustomizationRendererService !== "undefined" && customization_renderer_service_1.CustomizationRendererService) === "function" ? _d : Object, typeof (_e = typeof subscriptions_service_1.SubscriptionsService !== "undefined" && subscriptions_service_1.SubscriptionsService) === "function" ? _e : Object])
], ThemeRendererService);


/***/ }),
/* 133 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.MenusService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const client_1 = __webpack_require__(17);
let MenusService = class MenusService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    computeMenuItemUrl(item) {
        const backendUrl = process.env.BACKEND_URL || 'http://localhost:3000';
        const frontendUrl = process.env.FRONTEND_URL || 'http://localhost:5173';
        switch (item.type) {
            case 'PAGE':
                if (item.page?.slug) {
                    return `${backendUrl}/${item.page.slug}`;
                }
                if (item.url && item.url.startsWith('/')) {
                    return `${backendUrl}${item.url}`;
                }
                return item.url || '#';
            case 'POST':
                if (item.post?.slug) {
                    return `${backendUrl}/post/${item.post.slug}`;
                }
                if (item.url && item.url.startsWith('/')) {
                    return `${backendUrl}${item.url}`;
                }
                return item.url || '#';
            case 'HOME':
                return backendUrl;
            case 'SHOP':
                return `${frontendUrl}/admin/shop`;
            case 'PRODUCT':
                if (item.product?.slug)
                    return `${frontendUrl}/admin/shop/product/${item.product.slug}`;
                break;
            case 'CATEGORY':
                if (item.category?.slug)
                    return `${frontendUrl}/admin/shop?category=${item.category.slug}`;
                break;
            case 'CUSTOM':
            default:
                return item.url || '#';
        }
        return item.url || '#';
    }
    processMenuItems(items) {
        return items.map((item) => ({
            ...item,
            url: this.computeMenuItemUrl(item),
            children: item.children ? this.processMenuItems(item.children) : [],
        }));
    }
    processMenu(menu) {
        if (!menu)
            return menu;
        return {
            ...menu,
            items: this.processMenuItems(menu.items || []),
        };
    }
    async create(createMenuDto) {
        const existing = await this.prisma.menu.findFirst({
            where: {
                OR: [{ name: createMenuDto.name }, { location: createMenuDto.location }],
            },
        });
        if (existing) {
            throw new common_1.ConflictException('A menu with this name or location already exists');
        }
        const { items, ...menuData } = createMenuDto;
        const menu = await this.prisma.menu.create({
            data: menuData,
        });
        if (items && items.length > 0) {
            await this.createMenuItems(menu.id, items);
        }
        return this.findOne(menu.id);
    }
    async createMenuItems(menuId, items, parentId) {
        for (let i = 0; i < items.length; i++) {
            const item = items[i];
            await this.prisma.menuItem.create({
                data: {
                    menuId,
                    parentId: parentId || item.parentId,
                    label: item.label,
                    url: item.url,
                    target: item.target || '_self',
                    type: item.type || client_1.MenuItemType.CUSTOM,
                    pageId: item.pageId,
                    postId: item.postId,
                    order: item.order ?? i,
                    cssClass: item.cssClass,
                    icon: item.icon,
                },
            });
        }
    }
    async findAll() {
        const menus = await this.prisma.menu.findMany({
            include: {
                items: {
                    where: { parentId: null },
                    orderBy: { order: 'asc' },
                    include: {
                        page: { select: { id: true, title: true, slug: true } },
                        post: { select: { id: true, title: true, slug: true } },
                        children: {
                            orderBy: { order: 'asc' },
                            include: {
                                page: { select: { id: true, title: true, slug: true } },
                                post: { select: { id: true, title: true, slug: true } },
                            },
                        },
                    },
                },
            },
            orderBy: { createdAt: 'asc' },
        });
        return menus.map((menu) => this.processMenu(menu));
    }
    async findOne(id) {
        const menu = await this.prisma.menu.findUnique({
            where: { id },
            include: {
                items: {
                    where: { parentId: null },
                    orderBy: { order: 'asc' },
                    include: {
                        page: { select: { id: true, title: true, slug: true } },
                        post: { select: { id: true, title: true, slug: true } },
                        children: {
                            orderBy: { order: 'asc' },
                            include: {
                                page: { select: { id: true, title: true, slug: true } },
                                post: { select: { id: true, title: true, slug: true } },
                            },
                        },
                    },
                },
            },
        });
        if (!menu) {
            throw new common_1.NotFoundException('Menu not found');
        }
        return this.processMenu(menu);
    }
    async findByLocation(location) {
        const menu = await this.prisma.menu.findUnique({
            where: { location },
            include: {
                items: {
                    where: { parentId: null },
                    orderBy: { order: 'asc' },
                    include: {
                        page: { select: { id: true, title: true, slug: true } },
                        post: { select: { id: true, title: true, slug: true } },
                        children: {
                            orderBy: { order: 'asc' },
                            include: {
                                page: { select: { id: true, title: true, slug: true } },
                                post: { select: { id: true, title: true, slug: true } },
                            },
                        },
                    },
                },
            },
        });
        return this.processMenu(menu);
    }
    async update(id, updateMenuDto) {
        await this.findOne(id);
        const { items, ...menuData } = updateMenuDto;
        if (Object.keys(menuData).length > 0) {
            await this.prisma.menu.update({
                where: { id },
                data: menuData,
            });
        }
        if (items !== undefined) {
            await this.prisma.menuItem.deleteMany({
                where: { menuId: id },
            });
            if (items.length > 0) {
                for (let i = 0; i < items.length; i++) {
                    const item = items[i];
                    await this.prisma.menuItem.create({
                        data: {
                            menuId: id,
                            parentId: item.parentId,
                            label: item.label || '',
                            url: item.url,
                            target: item.target || '_self',
                            type: item.type || client_1.MenuItemType.CUSTOM,
                            pageId: item.pageId,
                            postId: item.postId,
                            order: item.order ?? i,
                            cssClass: item.cssClass,
                            icon: item.icon,
                        },
                    });
                }
            }
        }
        return this.findOne(id);
    }
    async remove(id) {
        await this.findOne(id);
        return this.prisma.menu.delete({
            where: { id },
        });
    }
    async getAvailableLinks() {
        const [pages, posts, products, productCategories] = await Promise.all([
            this.prisma.page.findMany({
                where: { status: 'PUBLISHED' },
                select: { id: true, title: true, slug: true },
                orderBy: { title: 'asc' },
            }),
            this.prisma.post.findMany({
                where: { status: 'PUBLISHED' },
                select: { id: true, title: true, slug: true },
                orderBy: { title: 'asc' },
            }),
            this.prisma.product.findMany({
                where: { status: 'ACTIVE' },
                select: { id: true, name: true, slug: true },
                orderBy: { name: 'asc' },
            }),
            this.prisma.productCategory.findMany({
                select: { id: true, name: true, slug: true },
                orderBy: { name: 'asc' },
            }),
        ]);
        return { pages, posts, products, productCategories };
    }
};
exports.MenusService = MenusService;
exports.MenusService = MenusService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], MenusService);


/***/ }),
/* 134 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CustomizationRendererService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let CustomizationRendererService = class CustomizationRendererService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async applyPageCustomization(html, pageId) {
        try {
            const customization = await this.prisma.pageCustomization.findUnique({
                where: { pageId },
            });
            if (!customization) {
                return html;
            }
            return this.applyCustomizationStyles(html, customization);
        }
        catch (error) {
            console.error('Error applying page customization:', error);
            return html;
        }
    }
    async applyPostCustomization(html, postId) {
        try {
            const customization = await this.prisma.postCustomization.findUnique({
                where: { postId },
            });
            if (!customization) {
                return html;
            }
            return this.applyCustomizationStyles(html, customization);
        }
        catch (error) {
            console.error('Error applying post customization:', error);
            return html;
        }
    }
    applyCustomizationStyles(html, customization) {
        let result = html;
        if (customization.layout) {
            result = result.replace(/<main[^>]*>/, `<main class="layout-${customization.layout}">`);
        }
        if (customization.backgroundColor) {
            const bgStyle = `background-color: ${customization.backgroundColor};`;
            result = result.replace(/<main[^>]*>/, (match) => match.replace('>', ` style="${bgStyle}">`));
        }
        if (customization.textColor) {
            const textStyle = `color: ${customization.textColor};`;
            result = result.replace(/<main[^>]*>/, (match) => match.replace('>', ` style="${textStyle}">`));
        }
        if (customization.showHeader === false) {
            result = result.replace(/<header[^>]*>[\s\S]*?<\/header>/i, '');
        }
        if (customization.showFooter === false) {
            result = result.replace(/<footer[^>]*>[\s\S]*?<\/footer>/i, '');
        }
        if (customization.showSidebar === false) {
            result = result.replace(/<aside[^>]*>[\s\S]*?<\/aside>/i, '');
        }
        if (customization.customCSS) {
            const styleTag = `<style>${customization.customCSS}</style>`;
            result = result.replace('</head>', `${styleTag}</head>`);
        }
        return result;
    }
    generateCustomizationCSS(customization) {
        let css = '';
        if (customization.layout) {
            css += `.layout-${customization.layout} { /* Layout styles */ }\n`;
        }
        if (customization.backgroundColor) {
            css += `main { background-color: ${customization.backgroundColor}; }\n`;
        }
        if (customization.textColor) {
            css += `main { color: ${customization.textColor}; }\n`;
        }
        if (customization.headerStyle) {
            css += `.site-header { ${customization.headerStyle} }\n`;
        }
        if (customization.footerStyle) {
            css += `.site-footer { ${customization.footerStyle} }\n`;
        }
        return css;
    }
};
exports.CustomizationRendererService = CustomizationRendererService;
exports.CustomizationRendererService = CustomizationRendererService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], CustomizationRendererService);


/***/ }),
/* 135 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SubscriptionsService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const system_config_service_1 = __webpack_require__(52);
const stripe_1 = __webpack_require__(82);
let SubscriptionsService = class SubscriptionsService {
    constructor(prisma, systemConfig) {
        this.prisma = prisma;
        this.systemConfig = systemConfig;
        this.stripe = null;
        this.initStripe();
    }
    async initStripe() {
        try {
            const config = await this.systemConfig.getStripeConfig();
            if (config?.secretKey) {
                this.stripe = new stripe_1.default(config.secretKey);
            }
        }
        catch {
            console.log('Stripe not configured for subscriptions');
        }
    }
    async getStripe() {
        if (!this.stripe) {
            await this.initStripe();
        }
        if (!this.stripe) {
            throw new common_1.BadRequestException('Stripe is not configured');
        }
        return this.stripe;
    }
    async getPlans(includeInactive = false) {
        return this.prisma.subscriptionPlan.findMany({
            where: includeInactive ? {} : { isActive: true },
            orderBy: { displayOrder: 'asc' },
        });
    }
    async getPlanById(id) {
        const plan = await this.prisma.subscriptionPlan.findUnique({
            where: { id },
        });
        if (!plan)
            throw new common_1.NotFoundException('Plan not found');
        return plan;
    }
    async getPlanBySlug(slug) {
        const plan = await this.prisma.subscriptionPlan.findUnique({
            where: { slug },
        });
        if (!plan)
            throw new common_1.NotFoundException('Plan not found');
        return plan;
    }
    async createPlan(dto) {
        return this.prisma.subscriptionPlan.create({
            data: {
                ...dto,
                features: dto.features || [],
            },
        });
    }
    async updatePlan(id, dto) {
        await this.getPlanById(id);
        return this.prisma.subscriptionPlan.update({
            where: { id },
            data: dto,
        });
    }
    async deletePlan(id) {
        const activeSubscriptions = await this.prisma.subscription.count({
            where: { planId: id, status: 'ACTIVE' },
        });
        if (activeSubscriptions > 0) {
            throw new common_1.BadRequestException('Cannot delete plan with active subscriptions');
        }
        return this.prisma.subscriptionPlan.delete({ where: { id } });
    }
    async getUserSubscription(userId) {
        return this.prisma.subscription.findUnique({
            where: { userId },
            include: { plan: true },
        });
    }
    async createCheckoutSession(userId, dto) {
        const stripe = await this.getStripe();
        const plan = await this.getPlanById(dto.planId);
        const user = await this.prisma.user.findUnique({ where: { id: userId } });
        if (!user)
            throw new common_1.NotFoundException('User not found');
        let customerId;
        const existingSub = await this.prisma.subscription.findUnique({
            where: { userId },
        });
        if (existingSub?.stripeCustomerId) {
            customerId = existingSub.stripeCustomerId;
        }
        else {
            const customer = await stripe.customers.create({
                email: user.email,
                name: user.name,
                metadata: { userId: user.id },
            });
            customerId = customer.id;
        }
        const priceId = dto.billingCycle === 'yearly' ? plan.stripePriceIdYearly : plan.stripePriceIdMonthly;
        if (!priceId) {
            throw new common_1.BadRequestException(`No Stripe price configured for ${dto.billingCycle} billing`);
        }
        const session = await stripe.checkout.sessions.create({
            customer: customerId,
            mode: 'subscription',
            payment_method_types: ['card'],
            line_items: [{ price: priceId, quantity: 1 }],
            success_url: dto.successUrl ||
                `${process.env.FRONTEND_URL || 'http://localhost:3000'}/admin/subscription/success?session_id={CHECKOUT_SESSION_ID}`,
            cancel_url: dto.cancelUrl ||
                `${process.env.FRONTEND_URL || 'http://localhost:3000'}/admin/subscription/canceled`,
            metadata: {
                userId,
                planId: plan.id,
                billingCycle: dto.billingCycle,
            },
            subscription_data: {
                metadata: {
                    userId,
                    planId: plan.id,
                },
            },
        });
        return { sessionId: session.id, url: session.url };
    }
    async createBillingPortalSession(userId) {
        const stripe = await this.getStripe();
        const subscription = await this.getUserSubscription(userId);
        if (!subscription?.stripeCustomerId) {
            throw new common_1.BadRequestException('No active subscription found');
        }
        const session = await stripe.billingPortal.sessions.create({
            customer: subscription.stripeCustomerId,
            return_url: `${process.env.FRONTEND_URL || 'http://localhost:3000'}/admin/settings`,
        });
        return { url: session.url };
    }
    async cancelSubscription(userId) {
        const stripe = await this.getStripe();
        const subscription = await this.getUserSubscription(userId);
        if (!subscription?.stripeSubscriptionId) {
            throw new common_1.BadRequestException('No active subscription found');
        }
        await stripe.subscriptions.update(subscription.stripeSubscriptionId, {
            cancel_at_period_end: true,
        });
        return this.prisma.subscription.update({
            where: { userId },
            data: { cancelAtPeriodEnd: true, canceledAt: new Date() },
        });
    }
    async handleWebhook(payload, signature) {
        const stripe = await this.getStripe();
        const config = await this.systemConfig.getStripeConfig();
        if (!config?.webhookSecret) {
            throw new common_1.BadRequestException('Webhook secret not configured');
        }
        let event;
        try {
            event = stripe.webhooks.constructEvent(payload, signature, config.webhookSecret);
        }
        catch (_err) {
            throw new common_1.BadRequestException(`Webhook signature verification failed`);
        }
        switch (event.type) {
            case 'checkout.session.completed':
                await this.handleCheckoutCompleted(event.data.object);
                break;
            case 'customer.subscription.updated':
                await this.handleSubscriptionUpdated(event.data.object);
                break;
            case 'customer.subscription.deleted':
                await this.handleSubscriptionDeleted(event.data.object);
                break;
            case 'invoice.payment_failed':
                await this.handlePaymentFailed(event.data.object);
                break;
        }
        return { received: true };
    }
    async handleCheckoutCompleted(session) {
        const { userId, planId, billingCycle } = session.metadata || {};
        if (!userId || !planId)
            return;
        const stripe = await this.getStripe();
        const stripeSubscription = (await stripe.subscriptions.retrieve(session.subscription));
        const periodStart = stripeSubscription.current_period_start;
        const periodEnd = stripeSubscription.current_period_end;
        await this.prisma.subscription.upsert({
            where: { userId },
            create: {
                userId,
                planId,
                status: 'ACTIVE',
                billingCycle: billingCycle === 'yearly' ? 'YEARLY' : 'MONTHLY',
                stripeSubscriptionId: stripeSubscription.id,
                stripeCustomerId: session.customer,
                currentPeriodStart: new Date(periodStart * 1000),
                currentPeriodEnd: new Date(periodEnd * 1000),
            },
            update: {
                planId,
                status: 'ACTIVE',
                billingCycle: billingCycle === 'yearly' ? 'YEARLY' : 'MONTHLY',
                stripeSubscriptionId: stripeSubscription.id,
                stripeCustomerId: session.customer,
                currentPeriodStart: new Date(periodStart * 1000),
                currentPeriodEnd: new Date(periodEnd * 1000),
                cancelAtPeriodEnd: false,
                canceledAt: null,
            },
        });
    }
    async handleSubscriptionUpdated(stripeSubscription) {
        const { userId } = stripeSubscription.metadata || {};
        if (!userId)
            return;
        const periodStart = stripeSubscription.current_period_start;
        const periodEnd = stripeSubscription.current_period_end;
        const statusMap = {
            active: 'ACTIVE',
            past_due: 'PAST_DUE',
            canceled: 'CANCELED',
            trialing: 'TRIALING',
            paused: 'PAUSED',
            incomplete: 'INCOMPLETE',
            incomplete_expired: 'INCOMPLETE_EXPIRED',
        };
        await this.prisma.subscription.update({
            where: { userId },
            data: {
                status: (statusMap[stripeSubscription.status] || 'ACTIVE'),
                currentPeriodStart: new Date(periodStart * 1000),
                currentPeriodEnd: new Date(periodEnd * 1000),
                cancelAtPeriodEnd: stripeSubscription.cancel_at_period_end,
            },
        });
    }
    async handleSubscriptionDeleted(stripeSubscription) {
        const { userId } = stripeSubscription.metadata || {};
        if (!userId)
            return;
        await this.prisma.subscription.update({
            where: { userId },
            data: { status: 'CANCELED', canceledAt: new Date() },
        });
    }
    async handlePaymentFailed(invoice) {
        const customerId = invoice.customer;
        const subscription = await this.prisma.subscription.findFirst({
            where: { stripeCustomerId: customerId },
        });
        if (subscription) {
            await this.prisma.subscription.update({
                where: { id: subscription.id },
                data: { status: 'PAST_DUE' },
            });
        }
    }
    async hasFeature(userId, feature) {
        const subscription = await this.getUserSubscription(userId);
        if (!subscription)
            return false;
        const features = subscription.plan.features;
        return features.includes(feature);
    }
    async checkLimit(userId, limitType, currentCount) {
        const subscription = await this.getUserSubscription(userId);
        if (!subscription)
            return false;
        const plan = subscription.plan;
        const limits = {
            users: plan.maxUsers,
            storage: plan.maxStorageMb,
            projects: plan.maxProjects,
            courses: plan.maxCourses,
            products: plan.maxProducts,
        };
        const limit = limits[limitType];
        if (limit === null)
            return true;
        return currentCount < limit;
    }
    async seedDefaultPlans() {
        const existingPlans = await this.prisma.subscriptionPlan.count();
        if (existingPlans > 0)
            return { message: 'Plans already exist' };
        const plans = [
            {
                name: 'Free',
                slug: 'free',
                description: 'Perfect for getting started',
                monthlyPrice: 0,
                yearlyPrice: 0,
                maxUsers: 1,
                maxStorageMb: 100,
                maxProjects: 1,
                maxCourses: 1,
                maxProducts: 5,
                features: ['basic_cms', 'media_library'],
                isActive: true,
                displayOrder: 0,
            },
            {
                name: 'Pro',
                slug: 'pro',
                description: 'For professionals and small teams',
                monthlyPrice: 19,
                yearlyPrice: 190,
                maxUsers: 5,
                maxStorageMb: 10240,
                maxProjects: 10,
                maxCourses: 10,
                maxProducts: 100,
                features: ['basic_cms', 'media_library', 'video_calls', 'lms', 'ecommerce', 'analytics'],
                isActive: true,
                isFeatured: true,
                badgeText: 'Most Popular',
                displayOrder: 1,
            },
            {
                name: 'Business',
                slug: 'business',
                description: 'For growing businesses',
                monthlyPrice: 49,
                yearlyPrice: 490,
                maxUsers: 25,
                maxStorageMb: 102400,
                maxCourses: null,
                maxProducts: null,
                features: [
                    'basic_cms',
                    'media_library',
                    'video_calls',
                    'lms',
                    'ecommerce',
                    'analytics',
                    'api_access',
                    'priority_support',
                    'custom_domain',
                ],
                isActive: true,
                displayOrder: 2,
            },
            {
                name: 'Enterprise',
                slug: 'enterprise',
                description: 'Custom solutions for large organizations',
                monthlyPrice: 199,
                yearlyPrice: 1990,
                maxUsers: null,
                maxStorageMb: null,
                features: [
                    'basic_cms',
                    'media_library',
                    'video_calls',
                    'lms',
                    'ecommerce',
                    'analytics',
                    'api_access',
                    'priority_support',
                    'custom_domain',
                    'sla',
                    'dedicated_support',
                    'custom_integrations',
                ],
                isActive: true,
                badgeText: 'Best Value',
                displayOrder: 3,
            },
        ];
        for (const plan of plans) {
            await this.prisma.subscriptionPlan.create({ data: plan });
        }
        return { message: 'Default plans created', count: plans.length };
    }
    async activateAllPlans() {
        const result = await this.prisma.subscriptionPlan.updateMany({
            data: { isActive: true },
        });
        return { message: 'All plans activated', count: result.count };
    }
    async getSiteSubscription() {
        const admin = await this.prisma.user.findFirst({
            where: { role: 'ADMIN' },
            orderBy: { createdAt: 'asc' },
        });
        if (!admin) {
            return null;
        }
        return this.prisma.subscription.findUnique({
            where: { userId: admin.id },
            include: { plan: true },
        });
    }
    async siteHasFeature(feature) {
        const subscription = await this.getSiteSubscription();
        if (!subscription || subscription.status !== 'ACTIVE') {
            return false;
        }
        const features = subscription.plan?.features || [];
        return features.includes(feature);
    }
    async getSiteSubscriptionStatus() {
        const subscription = await this.getSiteSubscription();
        const plans = await this.getPlans();
        return {
            hasActiveSubscription: subscription?.status === 'ACTIVE',
            currentPlan: subscription?.plan || null,
            currentPlanTier: subscription?.plan?.name || 'Free',
            availablePlans: plans,
        };
    }
};
exports.SubscriptionsService = SubscriptionsService;
exports.SubscriptionsService = SubscriptionsService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof system_config_service_1.SystemConfigService !== "undefined" && system_config_service_1.SystemConfigService) === "function" ? _b : Object])
], SubscriptionsService);


/***/ }),
/* 136 */
/***/ ((__unused_webpack_module, exports) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parseUserAgent = parseUserAgent;
exports.getDeviceClasses = getDeviceClasses;
function parseUserAgent(userAgent) {
    if (!userAgent) {
        return {
            type: 'desktop',
            isMobile: false,
            isTablet: false,
            isDesktop: true,
            browser: 'unknown',
            os: 'unknown',
            isTouchDevice: false,
        };
    }
    const ua = userAgent.toLowerCase();
    let type = 'desktop';
    let isTouchDevice = false;
    const isTablet = /ipad|tablet|playbook|silk|android(?!.*mobile)/i.test(userAgent) ||
        (ua.includes('android') && !ua.includes('mobile'));
    const isMobile = !isTablet &&
        /mobile|android|iphone|ipod|blackberry|windows phone|opera mini|iemobile|wpdesktop/i.test(userAgent);
    if (isTablet) {
        type = 'tablet';
        isTouchDevice = true;
    }
    else if (isMobile) {
        type = 'mobile';
        isTouchDevice = true;
    }
    let browser = 'unknown';
    if (ua.includes('firefox') || ua.includes('fxios')) {
        browser = 'Firefox';
    }
    else if (ua.includes('edg') || ua.includes('edge')) {
        browser = 'Edge';
    }
    else if (ua.includes('opr') || ua.includes('opera')) {
        browser = 'Opera';
    }
    else if (ua.includes('chrome') || ua.includes('crios')) {
        browser = 'Chrome';
    }
    else if (ua.includes('safari')) {
        browser = 'Safari';
    }
    else if (ua.includes('msie') || ua.includes('trident')) {
        browser = 'IE';
    }
    let os = 'unknown';
    if (ua.includes('windows')) {
        os = 'Windows';
    }
    else if (ua.includes('mac os') || ua.includes('macos')) {
        os = 'macOS';
    }
    else if (ua.includes('iphone') || ua.includes('ipad') || ua.includes('ipod')) {
        os = 'iOS';
    }
    else if (ua.includes('android')) {
        os = 'Android';
    }
    else if (ua.includes('linux')) {
        os = 'Linux';
    }
    else if (ua.includes('chromeos')) {
        os = 'ChromeOS';
    }
    return {
        type,
        isMobile: type === 'mobile',
        isTablet: type === 'tablet',
        isDesktop: type === 'desktop',
        browser,
        os,
        isTouchDevice,
    };
}
function getDeviceClasses(device) {
    const classes = [];
    classes.push(`device-${device.type}`);
    if (device.isTouchDevice) {
        classes.push('touch-device');
    }
    else {
        classes.push('no-touch');
    }
    if (device.os !== 'unknown') {
        classes.push(`os-${device.os.toLowerCase().replace(/\s+/g, '-')}`);
    }
    if (device.browser !== 'unknown') {
        classes.push(`browser-${device.browser.toLowerCase()}`);
    }
    return classes.join(' ');
}


/***/ }),
/* 137 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ThemeEditorService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const fs = __webpack_require__(24);
const path = __webpack_require__(3);
const AdmZip = __webpack_require__(130);
let ThemeEditorService = class ThemeEditorService {
    constructor(prisma) {
        this.prisma = prisma;
        this.themesDir = path.join(process.cwd(), 'themes');
        this.backupsDir = path.join(process.cwd(), 'backups', 'themes');
        this.ensureBackupDir();
    }
    async ensureBackupDir() {
        try {
            await fs.mkdir(this.backupsDir, { recursive: true });
        }
        catch (error) {
            console.error('Error creating backup directory:', error);
        }
    }
    async getFileTree(themeSlug) {
        const themePath = path.join(this.themesDir, themeSlug);
        try {
            await fs.access(themePath);
        }
        catch {
            throw new common_1.NotFoundException('Theme not found');
        }
        return this.buildFileTree(themePath, themeSlug);
    }
    async buildFileTree(dirPath, relativePath) {
        const stats = await fs.stat(dirPath);
        const name = path.basename(dirPath);
        if (stats.isFile()) {
            return {
                name,
                path: relativePath,
                type: 'file',
                extension: path.extname(name).slice(1),
            };
        }
        const children = [];
        const entries = await fs.readdir(dirPath);
        for (const entry of entries) {
            if (entry === 'node_modules' || entry.startsWith('.')) {
                continue;
            }
            const fullPath = path.join(dirPath, entry);
            const relPath = path.join(relativePath, entry);
            children.push(await this.buildFileTree(fullPath, relPath));
        }
        return {
            name,
            path: relativePath,
            type: 'directory',
            children: children.sort((a, b) => {
                if (a.type !== b.type) {
                    return a.type === 'directory' ? -1 : 1;
                }
                return a.name.localeCompare(b.name);
            }),
        };
    }
    async readFile(themeSlug, filePath) {
        const fullPath = path.join(this.themesDir, themeSlug, filePath);
        const normalizedPath = path.normalize(fullPath);
        const themePath = path.normalize(path.join(this.themesDir, themeSlug));
        if (!normalizedPath.startsWith(themePath)) {
            throw new common_1.BadRequestException('Invalid file path');
        }
        try {
            const content = await fs.readFile(fullPath, 'utf-8');
            return { content, path: filePath };
        }
        catch (_error) {
            throw new common_1.NotFoundException('File not found');
        }
    }
    async saveFile(themeSlug, filePath, content) {
        const fullPath = path.join(this.themesDir, themeSlug, filePath);
        const normalizedPath = path.normalize(fullPath);
        const themePath = path.normalize(path.join(this.themesDir, themeSlug));
        if (!normalizedPath.startsWith(themePath)) {
            throw new common_1.BadRequestException('Invalid file path');
        }
        try {
            const ext = path.extname(filePath).toLowerCase();
            const allowedExtensions = ['.hbs', '.css', '.js', '.json', '.md'];
            if (!allowedExtensions.includes(ext)) {
                throw new common_1.BadRequestException('File type not allowed for editing');
            }
            await this.createBackup(themeSlug, `auto-backup-${Date.now()}`);
            await fs.writeFile(fullPath, content, 'utf-8');
            return { success: true, message: 'File saved successfully' };
        }
        catch (error) {
            if (error instanceof common_1.BadRequestException) {
                throw error;
            }
            throw new common_1.BadRequestException('Failed to save file: ' + error.message);
        }
    }
    async createBackup(themeSlug, backupName) {
        const themePath = path.join(this.themesDir, themeSlug);
        try {
            await fs.access(themePath);
        }
        catch {
            throw new common_1.NotFoundException('Theme not found');
        }
        const timestamp = Date.now();
        const backupId = backupName || `backup-${timestamp}`;
        const backupFileName = `${themeSlug}-${backupId}.zip`;
        const backupPath = path.join(this.backupsDir, backupFileName);
        try {
            const zip = new AdmZip();
            await this.addDirectoryToZip(zip, themePath, '');
            zip.writeZip(backupPath);
            return {
                success: true,
                backupId,
                message: `Backup created: ${backupFileName}`,
            };
        }
        catch (error) {
            throw new common_1.BadRequestException('Failed to create backup: ' + error.message);
        }
    }
    async addDirectoryToZip(zip, dirPath, zipPath) {
        const entries = await fs.readdir(dirPath);
        for (const entry of entries) {
            if (entry === 'node_modules' || entry.startsWith('.')) {
                continue;
            }
            const fullPath = path.join(dirPath, entry);
            const stats = await fs.stat(fullPath);
            if (stats.isDirectory()) {
                await this.addDirectoryToZip(zip, fullPath, path.join(zipPath, entry));
            }
            else {
                const content = await fs.readFile(fullPath);
                zip.addFile(path.join(zipPath, entry), content);
            }
        }
    }
    async listBackups(themeSlug) {
        try {
            const files = await fs.readdir(this.backupsDir);
            const backups = [];
            for (const file of files) {
                if (file.startsWith(`${themeSlug}-`) && file.endsWith('.zip')) {
                    const filePath = path.join(this.backupsDir, file);
                    const stats = await fs.stat(filePath);
                    const backupId = file.replace(`${themeSlug}-`, '').replace('.zip', '');
                    backups.push({
                        id: backupId,
                        name: file,
                        date: stats.mtime,
                        size: stats.size,
                    });
                }
            }
            return backups.sort((a, b) => b.date.getTime() - a.date.getTime());
        }
        catch (_error) {
            return [];
        }
    }
    async restoreBackup(themeSlug, backupId) {
        const backupFileName = `${themeSlug}-${backupId}.zip`;
        const backupPath = path.join(this.backupsDir, backupFileName);
        const themePath = path.join(this.themesDir, themeSlug);
        try {
            await fs.access(backupPath);
        }
        catch {
            throw new common_1.NotFoundException('Backup not found');
        }
        try {
            await this.createBackup(themeSlug, `pre-restore-${Date.now()}`);
            await fs.rm(themePath, { recursive: true, force: true });
            const zip = new AdmZip(backupPath);
            zip.extractAllTo(themePath, true);
            return {
                success: true,
                message: 'Theme restored successfully from backup',
            };
        }
        catch (error) {
            throw new common_1.BadRequestException('Failed to restore backup: ' + error.message);
        }
    }
    async deleteBackup(themeSlug, backupId) {
        const backupFileName = `${themeSlug}-${backupId}.zip`;
        const backupPath = path.join(this.backupsDir, backupFileName);
        try {
            await fs.unlink(backupPath);
            return {
                success: true,
                message: 'Backup deleted successfully',
            };
        }
        catch (_error) {
            throw new common_1.NotFoundException('Backup not found');
        }
    }
    async validateFile(filePath, content) {
        const ext = path.extname(filePath).toLowerCase();
        const errors = [];
        try {
            if (ext === '.json') {
                JSON.parse(content);
            }
            return { valid: errors.length === 0, errors: errors.length > 0 ? errors : undefined };
        }
        catch (error) {
            return { valid: false, errors: [error.message] };
        }
    }
};
exports.ThemeEditorService = ThemeEditorService;
exports.ThemeEditorService = ThemeEditorService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], ThemeEditorService);


/***/ }),
/* 138 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ThemeEditorController = void 0;
const common_1 = __webpack_require__(2);
const theme_editor_service_1 = __webpack_require__(137);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const client_1 = __webpack_require__(17);
let ThemeEditorController = class ThemeEditorController {
    constructor(themeEditorService) {
        this.themeEditorService = themeEditorService;
    }
    getFileTree(themeSlug) {
        return this.themeEditorService.getFileTree(themeSlug);
    }
    readFile(themeSlug, filePath) {
        return this.themeEditorService.readFile(themeSlug, filePath);
    }
    saveFile(themeSlug, body) {
        return this.themeEditorService.saveFile(themeSlug, body.path, body.content);
    }
    createBackup(themeSlug, body) {
        return this.themeEditorService.createBackup(themeSlug, body?.name);
    }
    listBackups(themeSlug) {
        return this.themeEditorService.listBackups(themeSlug);
    }
    restoreBackup(themeSlug, body) {
        return this.themeEditorService.restoreBackup(themeSlug, body.backupId);
    }
    deleteBackup(themeSlug, backupId) {
        return this.themeEditorService.deleteBackup(themeSlug, backupId);
    }
    validateFile(body) {
        return this.themeEditorService.validateFile(body.path, body.content);
    }
};
exports.ThemeEditorController = ThemeEditorController;
__decorate([
    (0, common_1.Get)(':themeSlug/files'),
    __param(0, (0, common_1.Param)('themeSlug')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], ThemeEditorController.prototype, "getFileTree", null);
__decorate([
    (0, common_1.Get)(':themeSlug/file'),
    __param(0, (0, common_1.Param)('themeSlug')),
    __param(1, (0, common_1.Query)('path')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", void 0)
], ThemeEditorController.prototype, "readFile", null);
__decorate([
    (0, common_1.Post)(':themeSlug/file'),
    __param(0, (0, common_1.Param)('themeSlug')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", void 0)
], ThemeEditorController.prototype, "saveFile", null);
__decorate([
    (0, common_1.Post)(':themeSlug/backup'),
    __param(0, (0, common_1.Param)('themeSlug')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", void 0)
], ThemeEditorController.prototype, "createBackup", null);
__decorate([
    (0, common_1.Get)(':themeSlug/backups'),
    __param(0, (0, common_1.Param)('themeSlug')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], ThemeEditorController.prototype, "listBackups", null);
__decorate([
    (0, common_1.Post)(':themeSlug/restore'),
    __param(0, (0, common_1.Param)('themeSlug')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", void 0)
], ThemeEditorController.prototype, "restoreBackup", null);
__decorate([
    (0, common_1.Delete)(':themeSlug/backup/:backupId'),
    __param(0, (0, common_1.Param)('themeSlug')),
    __param(1, (0, common_1.Param)('backupId')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", void 0)
], ThemeEditorController.prototype, "deleteBackup", null);
__decorate([
    (0, common_1.Post)('validate'),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], ThemeEditorController.prototype, "validateFile", null);
exports.ThemeEditorController = ThemeEditorController = __decorate([
    (0, common_1.Controller)('api/theme-editor'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __metadata("design:paramtypes", [typeof (_a = typeof theme_editor_service_1.ThemeEditorService !== "undefined" && theme_editor_service_1.ThemeEditorService) === "function" ? _a : Object])
], ThemeEditorController);


/***/ }),
/* 139 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CustomThemesService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const path = __webpack_require__(3);
const fs = __webpack_require__(24);
const AdmZip = __webpack_require__(130);
let CustomThemesService = class CustomThemesService {
    constructor(prisma) {
        this.prisma = prisma;
        this.themesDir = path.join(process.cwd(), 'themes');
    }
    async findAll(_userId) {
        return this.prisma.customTheme.findMany({
            orderBy: { updatedAt: 'desc' },
            include: {
                createdBy: {
                    select: { id: true, name: true, email: true },
                },
            },
        });
    }
    async findById(id) {
        const theme = await this.prisma.customTheme.findUnique({
            where: { id },
            include: {
                createdBy: {
                    select: { id: true, name: true, email: true },
                },
            },
        });
        if (!theme) {
            throw new common_1.NotFoundException('Custom theme not found');
        }
        return theme;
    }
    async getActiveTheme() {
        return this.prisma.customTheme.findFirst({
            where: { isActive: true },
        });
    }
    async create(dto, userId) {
        const existing = await this.prisma.customTheme.findUnique({
            where: { name: dto.name },
        });
        if (existing) {
            throw new common_1.ConflictException(`Theme with name "${dto.name}" already exists`);
        }
        if (dto.isDefault) {
            await this.prisma.customTheme.updateMany({
                where: { isDefault: true },
                data: { isDefault: false },
            });
        }
        return this.prisma.customTheme.create({
            data: {
                name: dto.name,
                description: dto.description,
                settings: dto.settings,
                customCSS: dto.customCSS,
                pages: dto.pages,
                isDefault: dto.isDefault || false,
                createdById: userId,
            },
            include: {
                createdBy: {
                    select: { id: true, name: true, email: true },
                },
            },
        });
    }
    async update(id, dto) {
        const theme = await this.findById(id);
        if (dto.name && dto.name !== theme.name) {
            const existing = await this.prisma.customTheme.findUnique({
                where: { name: dto.name },
            });
            if (existing) {
                throw new common_1.ConflictException(`Theme with name "${dto.name}" already exists`);
            }
        }
        if (dto.isDefault) {
            await this.prisma.customTheme.updateMany({
                where: { isDefault: true, id: { not: id } },
                data: { isDefault: false },
            });
        }
        return this.prisma.customTheme.update({
            where: { id },
            data: {
                ...(dto.name && { name: dto.name }),
                ...(dto.description !== undefined && { description: dto.description }),
                ...(dto.settings && { settings: dto.settings }),
                ...(dto.customCSS !== undefined && { customCSS: dto.customCSS }),
                ...(dto.pages !== undefined && { pages: dto.pages }),
                ...(dto.isDefault !== undefined && { isDefault: dto.isDefault }),
            },
            include: {
                createdBy: {
                    select: { id: true, name: true, email: true },
                },
            },
        });
    }
    async delete(id) {
        const theme = await this.findById(id);
        if (theme.isActive) {
            throw new common_1.BadRequestException('Cannot delete the active theme. Please activate another theme first.');
        }
        return this.prisma.customTheme.delete({
            where: { id },
        });
    }
    async duplicate(id, userId, newName) {
        const theme = await this.findById(id);
        let name = newName || `${theme.name} (Copy)`;
        let counter = 1;
        while (await this.prisma.customTheme.findUnique({ where: { name } })) {
            name = newName ? `${newName} (${counter})` : `${theme.name} (Copy ${counter})`;
            counter++;
        }
        return this.prisma.customTheme.create({
            data: {
                name,
                description: theme.description,
                settings: theme.settings,
                customCSS: theme.customCSS,
                pages: theme.pages,
                isDefault: false,
                isActive: false,
                createdById: userId,
            },
            include: {
                createdBy: {
                    select: { id: true, name: true, email: true },
                },
            },
        });
    }
    async activate(id) {
        await this.findById(id);
        await this.prisma.customTheme.updateMany({
            data: { isActive: false },
        });
        return this.prisma.customTheme.update({
            where: { id },
            data: { isActive: true },
        });
    }
    async exportTheme(id) {
        const theme = await this.findById(id);
        return {
            name: theme.name,
            description: theme.description,
            settings: theme.settings,
            customCSS: theme.customCSS,
            pages: theme.pages,
            exportedAt: new Date().toISOString(),
            version: '1.0',
        };
    }
    async importTheme(data, userId) {
        if (!data.name || !data.settings) {
            throw new common_1.BadRequestException('Invalid theme data: missing name or settings');
        }
        let name = data.name;
        let counter = 1;
        while (await this.prisma.customTheme.findUnique({ where: { name } })) {
            name = `${data.name} (Imported ${counter})`;
            counter++;
        }
        return this.prisma.customTheme.create({
            data: {
                name,
                description: data.description,
                settings: data.settings,
                customCSS: data.customCSS,
                pages: data.pages,
                isDefault: false,
                isActive: false,
                createdById: userId,
            },
            include: {
                createdBy: {
                    select: { id: true, name: true, email: true },
                },
            },
        });
    }
    generateCSS(settings, customCSS) {
        const { colors, typography, layout, spacing, borders } = settings;
        let css = `/* Generated Theme CSS */
:root {
  /* Colors */
  --color-primary: ${colors.primary};
  --color-secondary: ${colors.secondary};
  --color-background: ${colors.background};
  --color-surface: ${colors.surface};
  --color-text: ${colors.text};
  --color-text-muted: ${colors.textMuted};
  --color-heading: ${colors.heading};
  --color-link: ${colors.link};
  --color-link-hover: ${colors.linkHover};
  --color-border: ${colors.border};
  --color-accent: ${colors.accent};
  --color-success: ${colors.success || '#22c55e'};
  --color-warning: ${colors.warning || '#f59e0b'};
  --color-error: ${colors.error || '#ef4444'};

  /* Typography */
  --font-heading: '${typography.headingFont}', system-ui, sans-serif;
  --font-body: '${typography.bodyFont}', system-ui, sans-serif;
  --font-size-base: ${typography.baseFontSize}px;
  --line-height: ${typography.lineHeight};
  --heading-weight: ${typography.headingWeight};

  /* Layout */
  --content-width: ${layout.contentWidth}px;

  /* Spacing */
  --section-padding: ${spacing.sectionPadding}px;
  --element-spacing: ${spacing.elementSpacing}px;
  --container-padding: ${spacing.containerPadding}px;

  /* Borders */
  --border-radius: ${borders.radius}px;
  --border-width: ${borders.width}px;

  /* Shadows */
  --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
  --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
  --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
  --transition: all 0.3s ease;
}

/* Reset & Base */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { font-size: var(--font-size-base); scroll-behavior: smooth; }
body {
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: var(--line-height);
  color: var(--color-text);
  background-color: var(--color-background);
  -webkit-font-smoothing: antialiased;
}

/* Typography */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-heading);
  font-weight: var(--heading-weight);
  color: var(--color-heading);
  line-height: 1.2;
  margin-bottom: var(--element-spacing);
}
h1 { font-size: 2.5rem; }
h2 { font-size: 2rem; }
h3 { font-size: 1.75rem; }
h4 { font-size: 1.5rem; }
h5 { font-size: 1.25rem; }
h6 { font-size: 1rem; }
p { margin-bottom: var(--element-spacing); }
a { color: var(--color-link); text-decoration: none; transition: var(--transition); }
a:hover { color: var(--color-link-hover); }
img { max-width: 100%; height: auto; display: block; }

/* Layout */
.container { max-width: var(--content-width); margin: 0 auto; padding: 0 var(--container-padding); }
.main-content { min-height: calc(100vh - 200px); padding: var(--section-padding) 0; }

/* Navigation */
.navbar {
  background: var(--color-surface);
  border-bottom: var(--border-width) solid var(--color-border);
  position: sticky;
  top: 0;
  z-index: 1000;
  backdrop-filter: blur(10px);
}
.nav-wrapper { display: flex; justify-content: space-between; align-items: center; padding: 1rem 0; }
.logo { font-size: 1.5rem; font-weight: 700; color: var(--color-heading); }
.logo:hover { color: var(--color-primary); }
.nav-menu { display: flex; gap: 1.5rem; align-items: center; flex: 1; justify-content: center; }
.nav-link { font-weight: 500; color: var(--color-text); padding: 0.5rem 1rem; border-radius: var(--border-radius); }
.nav-link:hover { background: var(--color-primary); color: #fff; }

/* Nav Actions */
.nav-actions { display: flex; align-items: center; gap: 1rem; }
.nav-icon { display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 50%; color: var(--color-text); transition: var(--transition); position: relative; }
.nav-icon:hover { background: var(--color-background); color: var(--color-primary); }
.cart-count { position: absolute; top: -2px; right: -2px; background: var(--color-primary); color: #fff; font-size: 0.7rem; font-weight: 600; min-width: 18px; height: 18px; border-radius: 9px; display: flex; align-items: center; justify-content: center; padding: 0 4px; }
.nav-auth-link { margin-left: 0.5rem; }
.user-menu { position: relative; }
.user-menu-btn { display: flex; align-items: center; gap: 0.5rem; background: none; border: none; cursor: pointer; padding: 0.25rem; border-radius: var(--border-radius); transition: var(--transition); }
.user-menu-btn:hover { background: var(--color-background); }
.user-avatar { width: 32px; height: 32px; border-radius: 50%; background: var(--color-primary); color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: 0.9rem; text-transform: uppercase; }
.user-name { color: var(--color-text); font-weight: 500; font-size: 0.9rem; }
.user-dropdown { position: absolute; top: calc(100% + 8px); right: 0; background: var(--color-surface); border: var(--border-width) solid var(--color-border); border-radius: calc(var(--border-radius) / 2); min-width: 180px; box-shadow: var(--shadow-lg); opacity: 0; visibility: hidden; transform: translateY(-10px); transition: var(--transition); z-index: 1001; }
.user-dropdown.active { opacity: 1; visibility: visible; transform: translateY(0); }
.dropdown-item { display: block; width: 100%; padding: 0.75rem 1rem; text-align: left; background: none; border: none; color: var(--color-text); font-size: 0.9rem; cursor: pointer; transition: var(--transition); }
.dropdown-item:hover { background: var(--color-background); color: var(--color-primary); }
.dropdown-divider { height: 1px; background: var(--color-border); margin: 0.5rem 0; }

/* Hero Section */
.hero {
  padding: calc(var(--section-padding) * 2) 0;
  text-align: center;
  background: linear-gradient(135deg, var(--color-surface) 0%, var(--color-background) 100%);
}
.hero h1 { font-size: 3rem; margin-bottom: 1rem; }
.hero p { font-size: 1.25rem; color: var(--color-text-muted); max-width: 600px; margin: 0 auto; }

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem 1.5rem;
  font-weight: 600;
  border-radius: var(--border-radius);
  border: none;
  cursor: pointer;
  transition: var(--transition);
  text-decoration: none;
}
.btn-primary { background: var(--color-primary); color: #fff; }
.btn-primary:hover { background: var(--color-link-hover); color: #fff; }
.btn-secondary { background: var(--color-secondary); color: #fff; }
.btn-outline { background: transparent; border: 2px solid var(--color-primary); color: var(--color-primary); }
.btn-outline:hover { background: var(--color-primary); color: #fff; }
.btn-sm { padding: 0.5rem 1rem; font-size: 0.875rem; }

/* Cards */
.card {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--border-radius);
  padding: var(--element-spacing);
  transition: var(--transition);
}
.card:hover { box-shadow: var(--shadow-md); }

/* Posts Grid */
.posts-section { padding: var(--section-padding) 0; }
.posts-section h2 { text-align: center; margin-bottom: calc(var(--section-padding) / 2); }
.posts-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--element-spacing); }

.post-card {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--border-radius);
  overflow: hidden;
  transition: var(--transition);
}
.post-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.post-image { width: 100%; height: 200px; object-fit: cover; }
.post-content { padding: var(--element-spacing); }
.post-content h3 { font-size: 1.25rem; margin-bottom: 0.5rem; }
.post-content h3 a { color: var(--color-heading); }
.post-content h3 a:hover { color: var(--color-primary); }
.post-content p { color: var(--color-text-muted); font-size: 0.9rem; }

/* Single Post/Page */
.single-post, .page-content { padding: var(--section-padding) 0; }
.single-post .container, .page-content .container { max-width: 800px; }
.featured-image { width: 100%; height: 400px; object-fit: cover; border-radius: var(--border-radius); margin-bottom: var(--element-spacing); }
.post-meta { color: var(--color-text-muted); font-size: 0.9rem; margin-bottom: var(--element-spacing); }
.post-body { font-size: 1.1rem; line-height: 1.8; }
.post-body p { margin-bottom: 1.5rem; }
.post-body h2, .post-body h3 { margin-top: 2rem; }
.post-body img { border-radius: var(--border-radius); margin: 1.5rem 0; }
.post-body blockquote {
  border-left: 4px solid var(--color-primary);
  padding-left: 1.5rem;
  margin: 1.5rem 0;
  font-style: italic;
  color: var(--color-text-muted);
}
.post-body pre {
  background: var(--color-surface);
  padding: 1rem;
  border-radius: var(--border-radius);
  overflow-x: auto;
}
.post-body code {
  background: var(--color-surface);
  padding: 0.2rem 0.4rem;
  border-radius: 4px;
  font-size: 0.9rem;
}

/* Footer */
.site-footer {
  background: var(--color-surface);
  border-top: var(--border-width) solid var(--color-border);
  padding: var(--section-padding) 0;
  text-align: center;
  color: var(--color-text-muted);
}

/* Responsive */
@media (max-width: 768px) {
  h1 { font-size: 2rem; }
  .hero h1 { font-size: 2.25rem; }
  .nav-menu { gap: 0.5rem; }
  .nav-link { padding: 0.5rem; font-size: 0.9rem; }
  .posts-grid { grid-template-columns: 1fr; }
}
`;
        if (customCSS) {
            css += `\n/* Custom CSS */\n${customCSS}`;
        }
        return css;
    }
    async installTheme(id) {
        const theme = await this.findById(id);
        const settings = theme.settings;
        const slug = theme.name
            .toLowerCase()
            .replace(/[^a-z0-9]+/g, '-')
            .replace(/^-|-$/g, '');
        const existingTheme = await this.prisma.theme.findUnique({
            where: { slug },
        });
        if (existingTheme) {
            throw new common_1.BadRequestException(`Theme "${slug}" already exists in installed themes. Please rename the theme first.`);
        }
        const themePath = path.join(this.themesDir, slug);
        try {
            await fs.mkdir(themePath, { recursive: true });
            await fs.mkdir(path.join(themePath, 'templates'), { recursive: true });
            await fs.mkdir(path.join(themePath, 'assets'), { recursive: true });
            await fs.mkdir(path.join(themePath, 'assets', 'css'), { recursive: true });
            await fs.mkdir(path.join(themePath, 'assets', 'js'), { recursive: true });
            const themeJson = {
                name: theme.name,
                version: '1.0.0',
                author: 'Theme Designer',
                description: theme.description || `Custom theme created with Theme Designer`,
                thumbnail: `/themes/${slug}/screenshot.png`,
                designConfig: settings,
            };
            await fs.writeFile(path.join(themePath, 'theme.json'), JSON.stringify(themeJson, null, 2));
            const cssContent = this.generateCSS(settings, theme.customCSS || undefined);
            await fs.writeFile(path.join(themePath, 'assets', 'css', 'style.css'), cssContent);
            const jsFiles = this.generateJavaScriptFiles();
            for (const [name, content] of Object.entries(jsFiles)) {
                await fs.writeFile(path.join(themePath, 'assets', 'js', `${name}.js`), content);
            }
            const pages = theme.pages || [];
            const templates = this.generateTemplates(theme.name, settings, slug, pages);
            for (const [name, content] of Object.entries(templates)) {
                await fs.writeFile(path.join(themePath, 'templates', `${name}.hbs`), content);
            }
            await this.generateScreenshot(themePath, settings);
            const installedTheme = await this.prisma.theme.create({
                data: {
                    name: theme.name,
                    slug,
                    version: '1.0.0',
                    author: 'Theme Designer',
                    description: theme.description || `Custom theme created with Theme Designer`,
                    thumbnail: `/themes/${slug}/screenshot.png`,
                    path: `/themes/${slug}`,
                    config: JSON.parse(JSON.stringify(themeJson)),
                },
            });
            return installedTheme;
        }
        catch (error) {
            try {
                await fs.rm(themePath, { recursive: true, force: true });
            }
            catch { }
            if (error instanceof common_1.BadRequestException) {
                throw error;
            }
            console.error('Error installing theme:', error);
            throw new common_1.BadRequestException('Failed to install theme: ' + error.message);
        }
    }
    async exportAsZip(id) {
        const theme = await this.findById(id);
        const settings = theme.settings;
        const slug = theme.name
            .toLowerCase()
            .replace(/[^a-z0-9]+/g, '-')
            .replace(/^-|-$/g, '');
        const zip = new AdmZip();
        const pages = theme.pages || [];
        const templates = this.generateTemplates(theme.name, settings, slug, pages);
        const templateNames = Object.keys(templates).map((name) => `${name}.hbs`);
        const themeJson = {
            name: theme.name,
            version: '1.0.0',
            author: 'Theme Designer',
            description: theme.description || `Custom theme created with Theme Designer`,
            thumbnail: `/themes/${slug}/screenshot.png`,
            templates: templateNames,
            supports: {
                widgets: true,
                menus: true,
                customHeader: true,
                customBackground: true,
                postThumbnails: true,
                responsiveEmbeds: true,
            },
            colors: {
                primary: settings.colors.primary,
                secondary: settings.colors.secondary,
                accent: settings.colors.accent,
                background: settings.colors.background,
                text: settings.colors.text,
            },
            fonts: {
                heading: settings.typography.headingFont,
                body: settings.typography.bodyFont,
            },
            designConfig: settings,
            pages: pages,
        };
        zip.addFile(`${slug}/theme.json`, Buffer.from(JSON.stringify(themeJson, null, 2)));
        const cssContent = this.generateCSS(settings, theme.customCSS || undefined);
        zip.addFile(`${slug}/assets/css/style.css`, Buffer.from(cssContent));
        const jsFiles = this.generateJavaScriptFiles();
        for (const [name, content] of Object.entries(jsFiles)) {
            zip.addFile(`${slug}/assets/js/${name}.js`, Buffer.from(content));
        }
        for (const [name, content] of Object.entries(templates)) {
            zip.addFile(`${slug}/templates/${name}.hbs`, Buffer.from(content));
        }
        const pngPlaceholder = Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==', 'base64');
        zip.addFile(`${slug}/screenshot.png`, pngPlaceholder);
        const screenshotSvg = this.generateScreenshotSVG(settings);
        zip.addFile(`${slug}/screenshot.svg`, Buffer.from(screenshotSvg));
        return zip.toBuffer();
    }
    renderBlockToHTML(block, settings) {
        const { type, props } = block;
        switch (type) {
            case 'hero':
                return `<section class="hero-block" style="background: ${props.backgroundImage ? `linear-gradient(rgba(0,0,0,${props.overlay || 0.5}), rgba(0,0,0,${props.overlay || 0.5})), url('${props.backgroundImage}')` : `linear-gradient(135deg, ${settings.colors.primary}, ${settings.colors.secondary})`}; background-size: cover; background-position: center; padding: 6rem 0; text-align: ${props.alignment || 'center'}; color: #fff;">
  <div class="container">
    <h1 style="font-size: 3rem; margin-bottom: 1rem; color: #fff;">${props.title || 'Welcome'}</h1>
    <p style="font-size: 1.25rem; max-width: 600px; ${props.alignment === 'center' ? 'margin: 0 auto 2rem;' : 'margin-bottom: 2rem;'}">${props.subtitle || ''}</p>
    ${props.ctaText ? `<a href="${props.ctaUrl || '#'}" class="btn btn-primary" style="background: #fff; color: ${settings.colors.primary};">${props.ctaText}</a>` : ''}
  </div>
</section>`;
            case 'features':
                const featuresHTML = (props.features || [])
                    .map((f) => `
      <div class="feature-item" style="text-align: center; padding: 2rem;">
        <div style="font-size: 2.5rem; margin-bottom: 1rem;">${f.icon || '⭐'}</div>
        <h3 style="margin-bottom: 0.5rem;">${f.title || 'Feature'}</h3>
        <p style="color: var(--color-text-muted);">${f.description || ''}</p>
      </div>`)
                    .join('');
                return `<section class="features-block" style="padding: var(--section-padding) 0;">
  <div class="container">
    ${props.title ? `<h2 style="text-align: center; margin-bottom: 3rem;">${props.title}</h2>` : ''}
    <div style="display: grid; grid-template-columns: repeat(${props.columns || 3}, 1fr); gap: 2rem;">
      ${featuresHTML}
    </div>
  </div>
</section>`;
            case 'cta':
                return `<section class="cta-block" style="padding: var(--section-padding) 0; background: ${props.style === 'gradient' ? `linear-gradient(135deg, ${settings.colors.primary}, ${settings.colors.secondary})` : 'var(--color-surface)'}; text-align: center; ${props.style === 'gradient' ? 'color: #fff;' : ''}">
  <div class="container">
    <h2 style="margin-bottom: 1rem; ${props.style === 'gradient' ? 'color: #fff;' : ''}">${props.title || 'Get Started'}</h2>
    <p style="margin-bottom: 2rem; max-width: 600px; margin-left: auto; margin-right: auto;">${props.description || ''}</p>
    <a href="${props.buttonLink || '#'}" class="btn btn-primary" ${props.style === 'gradient' ? 'style="background: #fff; color: ' + settings.colors.primary + ';"' : ''}>${props.buttonText || 'Learn More'}</a>
  </div>
</section>`;
            case 'testimonial':
                return `<section class="testimonial-block" style="padding: var(--section-padding) 0; background: var(--color-surface);">
  <div class="container" style="max-width: 800px;">
    <blockquote style="font-size: 1.5rem; font-style: italic; text-align: center; margin-bottom: 2rem; color: var(--color-heading);">"${props.quote || ''}"</blockquote>
    <div style="display: flex; align-items: center; justify-content: center; gap: 1rem;">
      ${props.avatar ? `<img src="${props.avatar}" alt="${props.author}" style="width: 60px; height: 60px; border-radius: 50%; object-fit: cover;">` : ''}
      <div>
        <div style="font-weight: 600;">${props.author || 'Customer'}</div>
        <div style="color: var(--color-text-muted); font-size: 0.9rem;">${props.role || ''}</div>
      </div>
    </div>
  </div>
</section>`;
            case 'stats':
                const statsHTML = (props.stats || [])
                    .map((s) => `
      <div style="text-align: center; padding: 1.5rem;">
        <div style="font-size: 2.5rem; font-weight: 700; color: var(--color-primary);">${s.value || '0'}</div>
        <div style="color: var(--color-text-muted);">${s.label || ''}</div>
      </div>`)
                    .join('');
                return `<section class="stats-block" style="padding: var(--section-padding) 0; background: var(--color-surface);">
  <div class="container">
    <div style="display: grid; grid-template-columns: repeat(${(props.stats || []).length || 4}, 1fr); gap: 2rem;">
      ${statsHTML}
    </div>
  </div>
</section>`;
            case 'imageText':
                const imgPos = props.imagePosition || 'left';
                return `<section class="image-text-block" style="padding: var(--section-padding) 0;">
  <div class="container">
    <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 4rem; align-items: center;">
      ${imgPos === 'left' ? `<img src="${props.imageUrl || ''}" alt="" style="width: 100%; border-radius: var(--border-radius);">` : ''}
      <div>
        <h2 style="margin-bottom: 1rem;">${props.title || ''}</h2>
        <p style="color: var(--color-text-muted);">${props.text || ''}</p>
      </div>
      ${imgPos === 'right' ? `<img src="${props.imageUrl || ''}" alt="" style="width: 100%; border-radius: var(--border-radius);">` : ''}
    </div>
  </div>
</section>`;
            case 'gallery':
                const images = (props.images || [])
                    .map((img) => `
      <div style="overflow: hidden; border-radius: var(--border-radius);">
        <img src="${img.src || ''}" alt="${img.caption || ''}" style="width: 100%; aspect-ratio: 4/3; object-fit: cover; transition: transform 0.3s;">
      </div>`)
                    .join('');
                return `<section class="gallery-block" style="padding: var(--section-padding) 0;">
  <div class="container">
    <div style="display: grid; grid-template-columns: repeat(${props.columns || 3}, 1fr); gap: 1rem;">
      ${images}
    </div>
  </div>
</section>`;
            case 'button':
                return `<div style="text-align: center; padding: 1rem 0;">
  <a href="${props.url || '#'}" class="btn btn-${props.style === 'outline' ? 'outline' : 'primary'}">${props.text || 'Button'}</a>
</div>`;
            case 'divider':
                return `<hr style="border: none; height: 1px; background: var(--color-border); margin: var(--section-padding) auto; max-width: ${props.width || '100%'};">`;
            case 'pricing':
                const plans = (props.plans || [])
                    .map((plan) => `
      <div class="card" style="padding: 2rem; text-align: center; ${plan.featured ? 'border-color: var(--color-primary); transform: scale(1.05);' : ''}">
        <h3 style="margin-bottom: 0.5rem;">${plan.name || 'Plan'}</h3>
        <div style="font-size: 2.5rem; font-weight: 700; color: var(--color-primary); margin-bottom: 1rem;">$${plan.price || '0'}<span style="font-size: 1rem; font-weight: normal; color: var(--color-text-muted);">/${plan.period || 'mo'}</span></div>
        <ul style="list-style: none; padding: 0; margin-bottom: 2rem; text-align: left;">
          ${(plan.features || []).map((f) => `<li style="padding: 0.5rem 0; border-bottom: 1px solid var(--color-border);">✓ ${f}</li>`).join('')}
        </ul>
        <a href="${plan.buttonLink || '#'}" class="btn btn-${plan.featured ? 'primary' : 'outline'}">${plan.buttonText || 'Choose Plan'}</a>
      </div>`)
                    .join('');
                return `<section class="pricing-block" style="padding: var(--section-padding) 0;">
  <div class="container">
    ${props.title ? `<h2 style="text-align: center; margin-bottom: 3rem;">${props.title}</h2>` : ''}
    <div style="display: grid; grid-template-columns: repeat(${(props.plans || []).length || 3}, 1fr); gap: 2rem; align-items: center;">
      ${plans}
    </div>
  </div>
</section>`;
            case 'newsletter':
                return `<section class="newsletter-block" style="padding: var(--section-padding) 0; background: var(--color-primary); color: #fff; text-align: center;">
  <div class="container" style="max-width: 600px;">
    <h2 style="color: #fff; margin-bottom: 0.5rem;">${props.title || 'Subscribe to Our Newsletter'}</h2>
    <p style="margin-bottom: 2rem; opacity: 0.9;">${props.description || 'Stay updated with our latest news'}</p>
    <form style="display: flex; gap: 1rem;">
      <input type="email" placeholder="${props.placeholder || 'Enter your email'}" style="flex: 1; padding: 1rem; border: none; border-radius: var(--border-radius);">
      <button type="submit" class="btn" style="background: #fff; color: var(--color-primary);">${props.buttonText || 'Subscribe'}</button>
    </form>
  </div>
</section>`;
            case 'card':
                return `<div class="card" style="padding: 2rem;">
  ${props.image ? `<img src="${props.image}" alt="" style="width: 100%; border-radius: var(--border-radius); margin-bottom: 1rem;">` : ''}
  <h3>${props.title || 'Card Title'}</h3>
  <p style="color: var(--color-text-muted);">${props.description || ''}</p>
  ${props.buttonText ? `<a href="${props.buttonLink || '#'}" class="btn btn-primary" style="margin-top: 1rem;">${props.buttonText}</a>` : ''}
</div>`;
            case 'productGrid':
                return `<section class="product-grid-block" style="padding: var(--section-padding) 0;">
  <div class="container">
    <h2 style="text-align: center; margin-bottom: 2rem;">Featured Products</h2>
    <div class="posts-grid">
      {{#each featuredProducts}}
      <article class="post-card">
        {{#if images.[0]}}<img src="{{images.[0]}}" alt="{{name}}" class="post-image">{{/if}}
        <div class="post-content">
          <h3><a href="/shop/product/{{slug}}">{{name}}</a></h3>
          <p style="color: var(--color-primary); font-weight: 600;">{{#if salePrice}}<s style="color: var(--color-text-muted);">$\\{{price}}</s> $\\{{salePrice}}{{else}}$\\{{price}}{{/if}}</p>
          <a href="/shop/product/{{slug}}" class="btn btn-sm btn-primary">View Product</a>
        </div>
      </article>
      {{/each}}
    </div>
  </div>
</section>`;
            case 'courseGrid':
                return `<section class="course-grid-block" style="padding: var(--section-padding) 0;">
  <div class="container">
    <h2 style="text-align: center; margin-bottom: 2rem;">Featured Courses</h2>
    <div class="posts-grid">
      {{#each featuredCourses}}
      <article class="post-card">
        {{#if thumbnail}}<img src="{{thumbnail}}" alt="{{title}}" class="post-image">{{/if}}
        <div class="post-content">
          <h3><a href="/courses/{{slug}}">{{title}}</a></h3>
          <p>{{shortDescription}}</p>
          <a href="/courses/{{slug}}" class="btn btn-sm btn-primary">Learn More</a>
        </div>
      </article>
      {{/each}}
    </div>
  </div>
</section>`;
            case 'audio':
                return `<div class="audio-block" style="padding: 2rem; background: var(--color-surface); border-radius: var(--border-radius);">
  <div style="display: flex; align-items: center; gap: 1rem;">
    ${props.albumArt ? `<img src="${props.albumArt}" alt="${props.title || ''}" style="width: 80px; height: 80px; border-radius: 8px; object-fit: cover;">` : ''}
    <div>
      <h4 style="margin: 0 0 0.25rem;">${props.title || 'Audio Track'}</h4>
      <p style="margin: 0; color: var(--color-text-muted); font-size: 0.9rem;">${props.artist || ''}</p>
    </div>
  </div>
  ${props.audioUrl ? `<audio controls style="width: 100%; margin-top: 1rem;"><source src="${props.audioUrl}" type="audio/mpeg"></audio>` : ''}
</div>`;
            case 'video':
                return `<div class="video-block" style="padding: var(--section-padding) 0;">
  <div class="container">
    ${props.title ? `<h3 style="text-align: center; margin-bottom: 1rem;">${props.title}</h3>` : ''}
    <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; border-radius: var(--border-radius);">
      ${props.videoUrl ? `<iframe src="${props.videoUrl}" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none;" allowfullscreen></iframe>` : `<img src="${props.posterUrl || ''}" alt="" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover;">`}
    </div>
  </div>
</div>`;
            case 'timeline':
                const timelineItems = (props.items || [])
                    .map((item, i) => `
      <div style="display: flex; gap: 1.5rem; margin-bottom: 2rem;">
        <div style="display: flex; flex-direction: column; align-items: center;">
          <div style="width: 12px; height: 12px; border-radius: 50%; background: var(--color-primary);"></div>
          ${i < (props.items || []).length - 1 ? '<div style="flex: 1; width: 2px; background: var(--color-border);"></div>' : ''}
        </div>
        <div style="flex: 1; padding-bottom: 1rem;">
          <div style="font-size: 0.85rem; color: var(--color-text-muted); margin-bottom: 0.25rem;">${item.date || ''}</div>
          <h4 style="margin: 0 0 0.5rem;">${item.title || ''}</h4>
          <p style="margin: 0; color: var(--color-text-muted);">${item.description || ''}</p>
        </div>
      </div>`)
                    .join('');
                return `<section class="timeline-block" style="padding: var(--section-padding) 0;">
  <div class="container" style="max-width: 700px;">
    ${props.title ? `<h2 style="text-align: center; margin-bottom: 3rem;">${props.title}</h2>` : ''}
    ${timelineItems}
  </div>
</section>`;
            case 'accordion':
                const accordionItems = (props.items || [])
                    .map((item, i) => `
      <details style="border: 1px solid var(--color-border); border-radius: var(--border-radius); margin-bottom: 0.5rem;" ${i === 0 ? 'open' : ''}>
        <summary style="padding: 1rem; cursor: pointer; font-weight: 600;">${item.title || 'Question'}</summary>
        <div style="padding: 0 1rem 1rem; color: var(--color-text-muted);">${item.content || ''}</div>
      </details>`)
                    .join('');
                return `<section class="accordion-block" style="padding: var(--section-padding) 0;">
  <div class="container" style="max-width: 800px;">
    ${props.title ? `<h2 style="text-align: center; margin-bottom: 2rem;">${props.title}</h2>` : ''}
    ${accordionItems}
  </div>
</section>`;
            case 'tabs':
                const tabButtons = (props.tabs || [])
                    .map((tab, i) => `<button style="padding: 0.75rem 1.5rem; border: none; background: ${i === 0 ? 'var(--color-primary)' : 'transparent'}; color: ${i === 0 ? '#fff' : 'var(--color-text)'}; cursor: pointer; border-radius: var(--border-radius) var(--border-radius) 0 0;">${tab.title || 'Tab'}</button>`)
                    .join('');
                const tabContent = (props.tabs || [])[0]?.content || '';
                return `<section class="tabs-block" style="padding: var(--section-padding) 0;">
  <div class="container">
    <div style="display: flex; border-bottom: 1px solid var(--color-border);">${tabButtons}</div>
    <div style="padding: 2rem; background: var(--color-surface); border-radius: 0 0 var(--border-radius) var(--border-radius);">${tabContent}</div>
  </div>
</section>`;
            case 'logoCloud':
                const logos = (props.logos || [])
                    .map((logo) => `
      <div style="display: flex; align-items: center; justify-content: center; padding: 1rem;">
        <img src="${logo.src || ''}" alt="${logo.name || ''}" style="max-height: 50px; max-width: 120px; filter: grayscale(100%); opacity: 0.7; transition: all 0.3s;">
      </div>`)
                    .join('');
                return `<section class="logo-cloud-block" style="padding: var(--section-padding) 0; background: var(--color-surface);">
  <div class="container">
    ${props.title ? `<h3 style="text-align: center; margin-bottom: 2rem; color: var(--color-text-muted);">${props.title}</h3>` : ''}
    <div style="display: grid; grid-template-columns: repeat(${props.columns || 5}, 1fr); gap: 2rem; align-items: center;">
      ${logos}
    </div>
  </div>
</section>`;
            case 'socialProof':
                return `<section class="social-proof-block" style="padding: 2rem 0; background: var(--color-surface);">
  <div class="container" style="text-align: center;">
    <div style="display: flex; align-items: center; justify-content: center; gap: 2rem; flex-wrap: wrap;">
      ${props.rating ? `<div style="display: flex; align-items: center; gap: 0.5rem;"><span style="font-size: 1.5rem; font-weight: 700;">${props.rating}</span><span style="color: #fbbf24;">★★★★★</span></div>` : ''}
      ${props.reviewCount ? `<div style="color: var(--color-text-muted);">${props.reviewCount} reviews</div>` : ''}
      ${props.text ? `<div>${props.text}</div>` : ''}
    </div>
  </div>
</section>`;
            case 'countdown':
                return `<section class="countdown-block" style="padding: var(--section-padding) 0; background: var(--color-primary); color: #fff; text-align: center;">
  <div class="container">
    ${props.title ? `<h2 style="color: #fff; margin-bottom: 1rem;">${props.title}</h2>` : ''}
    <div style="display: flex; justify-content: center; gap: 2rem;">
      <div><div style="font-size: 3rem; font-weight: 700;">00</div><div style="font-size: 0.9rem; opacity: 0.8;">Days</div></div>
      <div><div style="font-size: 3rem; font-weight: 700;">00</div><div style="font-size: 0.9rem; opacity: 0.8;">Hours</div></div>
      <div><div style="font-size: 3rem; font-weight: 700;">00</div><div style="font-size: 0.9rem; opacity: 0.8;">Minutes</div></div>
      <div><div style="font-size: 3rem; font-weight: 700;">00</div><div style="font-size: 0.9rem; opacity: 0.8;">Seconds</div></div>
    </div>
    ${props.description ? `<p style="margin-top: 1rem; opacity: 0.9;">${props.description}</p>` : ''}
  </div>
</section>`;
            case 'row':
                return `<div class="row-block" style="display: flex; gap: 2rem; padding: var(--section-padding) 0;">
  <div class="container" style="display: flex; gap: 2rem; flex-wrap: wrap;">
    <!-- Row content rendered by children -->
  </div>
</div>`;
            case 'header':
                return `<!-- Header block - uses theme header partial -->`;
            case 'featuredProduct':
                return `<section class="featured-product-block" style="padding: var(--section-padding) 0;">
  <div class="container">
    <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 3rem; align-items: center;">
      <img src="${props.product?.image || 'https://picsum.photos/600/400'}" alt="${props.product?.title || ''}" style="width: 100%; border-radius: var(--border-radius);">
      <div>
        ${props.product?.badge ? `<span style="display: inline-block; padding: 0.25rem 0.75rem; background: var(--color-primary); color: #fff; border-radius: 999px; font-size: 0.8rem; margin-bottom: 1rem;">${props.product.badge}</span>` : ''}
        <h2 style="margin-bottom: 0.5rem;">${props.product?.title || 'Featured Product'}</h2>
        <div style="display: flex; align-items: center; gap: 1rem; margin-bottom: 1rem;">
          ${props.product?.salePrice ? `<span style="font-size: 1.5rem; font-weight: 700; color: var(--color-primary);">$${props.product.salePrice}</span><s style="color: var(--color-text-muted);">$${props.product.price}</s>` : `<span style="font-size: 1.5rem; font-weight: 700; color: var(--color-primary);">$${props.product?.price || '0'}</span>`}
        </div>
        <p style="color: var(--color-text-muted); margin-bottom: 2rem;">${props.product?.description || ''}</p>
        <a href="/shop/product/${props.product?.id || ''}" class="btn btn-primary">View Product</a>
      </div>
    </div>
  </div>
</section>`;
            case 'productCarousel':
                return `<section class="product-carousel-block" style="padding: var(--section-padding) 0;">
  <div class="container">
    <h2 style="text-align: center; margin-bottom: 2rem;">${props.title || 'Featured Products'}</h2>
    <div class="posts-grid">
      {{#each featuredProducts}}
      <article class="post-card">
        {{#if images.[0]}}<img src="{{images.[0]}}" alt="{{name}}" class="post-image">{{/if}}
        <div class="post-content">
          <h3><a href="/shop/product/{{slug}}">{{name}}</a></h3>
          <p style="color: var(--color-primary); font-weight: 600;">\${{price}}</p>
        </div>
      </article>
      {{/each}}
    </div>
  </div>
</section>`;
            case 'courseCard':
                return `<div class="course-card" style="background: var(--color-surface); border-radius: var(--border-radius); overflow: hidden; border: 1px solid var(--color-border);">
  <img src="${props.course?.thumbnail || 'https://picsum.photos/400/200'}" alt="${props.course?.title || ''}" style="width: 100%; aspect-ratio: 16/9; object-fit: cover;">
  <div style="padding: 1.5rem;">
    <h3 style="margin: 0 0 0.5rem;">${props.course?.title || 'Course Title'}</h3>
    <p style="color: var(--color-text-muted); margin-bottom: 1rem;">${props.course?.shortDescription || ''}</p>
    <a href="/courses/${props.course?.slug || ''}" class="btn btn-primary btn-sm">Learn More</a>
  </div>
</div>`;
            case 'loginForm':
                return `<section class="login-form-block" style="padding: var(--section-padding) 0;">
  <div class="container" style="max-width: 400px;">
    <div style="background: var(--color-surface); padding: 2rem; border-radius: var(--border-radius); border: 1px solid var(--color-border);">
      <h2 style="text-align: center; margin-bottom: 1.5rem;">${props.title || 'Sign In'}</h2>
      <form>
        <div style="margin-bottom: 1rem;">
          <label style="display: block; margin-bottom: 0.5rem; font-weight: 500;">Email</label>
          <input type="email" placeholder="Enter your email" style="width: 100%; padding: 0.75rem; border: 1px solid var(--color-border); border-radius: var(--border-radius);">
        </div>
        <div style="margin-bottom: 1.5rem;">
          <label style="display: block; margin-bottom: 0.5rem; font-weight: 500;">Password</label>
          <input type="password" placeholder="Enter your password" style="width: 100%; padding: 0.75rem; border: 1px solid var(--color-border); border-radius: var(--border-radius);">
        </div>
        <button type="submit" class="btn btn-primary" style="width: 100%;">Sign In</button>
      </form>
    </div>
  </div>
</section>`;
            case 'saleBanner':
                return `<section class="sale-banner-block" style="padding: 1.5rem 0; background: linear-gradient(135deg, ${settings.colors.primary}, ${settings.colors.secondary}); color: #fff; text-align: center;">
  <div class="container">
    <div style="display: flex; align-items: center; justify-content: center; gap: 2rem; flex-wrap: wrap;">
      <span style="font-size: 1.25rem; font-weight: 700;">${props.text || '🔥 Limited Time Offer!'}</span>
      ${props.buttonText ? `<a href="${props.buttonLink || '#'}" class="btn" style="background: #fff; color: ${settings.colors.primary};">${props.buttonText}</a>` : ''}
    </div>
  </div>
</section>`;
            default:
                return `<!-- Block: ${type} -->`;
        }
    }
    renderPageBlocks(blocks, settings) {
        if (!blocks || blocks.length === 0) {
            return '';
        }
        return blocks.map((block) => this.renderBlockToHTML(block, settings)).join('\n\n');
    }
    generateTemplates(themeName, settings, slug, pages = []) {
        const { typography } = settings;
        const header = `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>{{#if post}}{{post.title}} - {{/if}}{{#if page}}{{page.title}} - {{/if}}{{site.name}}</title>
  <meta name="description" content="{{#if post}}{{post.excerpt}}{{else}}{{site.description}}{{/if}}">
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=${typography.headingFont.replace(/ /g, '+')}:wght@400;500;600;700&family=${typography.bodyFont.replace(/ /g, '+')}:wght@400;500;600&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="/themes/${slug}/assets/css/style.css">
</head>
<body>
  <nav class="navbar">
    <div class="container">
      <div class="nav-wrapper">
        <a href="/" class="logo">{{site.name}}</a>
        <div class="nav-menu">
          {{#if menus.header}}
            {{#each menus.header.items}}
              <a href="{{this.url}}" class="nav-link" target="{{this.target}}">{{this.label}}</a>
            {{/each}}
          {{else}}
            <a href="/" class="nav-link">Home</a>
            <a href="/shop" class="nav-link">Shop</a>
            <a href="/courses" class="nav-link">Courses</a>
            <a href="/blog" class="nav-link">Blog</a>
          {{/if}}
        </div>
        <div class="nav-actions">
          <a href="/cart" class="nav-icon cart-icon" title="Cart">
            <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="9" cy="21" r="1"></circle><circle cx="20" cy="21" r="1"></circle><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path></svg>
            <span class="cart-count" id="cartCount" style="display: none;">0</span>
          </a>
          {{#if user}}
          <div class="user-menu">
            <button class="user-menu-btn" id="userMenuBtn">
              <span class="user-avatar">{{substring user.name 0 1}}</span>
              <span class="user-name">{{user.name}}</span>
            </button>
            <div class="user-dropdown" id="userDropdown">
              <a href="/my-account" class="dropdown-item">My Account</a>
              <a href="/my-courses" class="dropdown-item">My Courses</a>
              <a href="/orders" class="dropdown-item">Orders</a>
              <div class="dropdown-divider"></div>
              <button class="dropdown-item" id="logoutBtn">Sign Out</button>
            </div>
          </div>
          {{else}}
          <a href="/login" class="nav-link nav-auth-link">Sign In</a>
          <a href="/register" class="btn btn-primary btn-sm">Get Started</a>
          {{/if}}
        </div>
      </div>
    </div>
  </nav>
  <main class="main-content">
`;
        const footer = `  </main>
  <footer class="site-footer">
    <div class="container">
      <p>&copy; {{year}} {{site.name}}. All rights reserved.</p>
    </div>
  </footer>
  <script src="/themes/${slug}/assets/js/main.js"></script>
</body>
</html>
`;
        const homePage = pages.find((p) => p.isHomePage || p.slug === '/');
        const homePageBlocks = homePage?.blocks || [];
        const renderedHomeBlocks = this.renderPageBlocks(homePageBlocks, settings);
        const home = renderedHomeBlocks
            ? `{{> header}}
${renderedHomeBlocks}

<!-- Dynamic content sections -->
{{#if featuredProducts.length}}
<section class="posts-section">
  <div class="container">
    <h2>Featured Products</h2>
    <div class="posts-grid">
      {{#each featuredProducts}}
      <article class="post-card">
        {{#if images.[0]}}<img src="{{images.[0]}}" alt="{{name}}" class="post-image">{{/if}}
        <div class="post-content">
          <h3><a href="/shop/product/{{slug}}">{{name}}</a></h3>
          <p style="color: var(--color-primary); font-weight: 600;">{{#if salePrice}}<s style="color: var(--color-text-muted);">${'$'}{{price}}</s> ${'$'}{{salePrice}}{{else}}${'$'}{{price}}{{/if}}</p>
        </div>
      </article>
      {{/each}}
    </div>
  </div>
</section>
{{/if}}

<section class="posts-section">
  <div class="container">
    <h2>Latest Posts</h2>
    <div class="posts-grid">
      {{#each posts}}
      <article class="post-card">
        {{#if this.featuredImage}}<img src="{{this.featuredImage}}" alt="{{this.title}}" class="post-image">{{/if}}
        <div class="post-content">
          <h3><a href="/post/{{this.slug}}">{{this.title}}</a></h3>
          <p>{{this.excerpt}}</p>
        </div>
      </article>
      {{/each}}
    </div>
  </div>
</section>
{{> footer}}`
            : `{{> header}}
<section class="hero">
  <div class="container">
    <h1>Welcome to {{site.name}}</h1>
    <p>{{site.description}}</p>
    <div style="margin-top: 2rem; display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap;">
      <a href="/shop" class="btn btn-primary">Browse Shop</a>
      <a href="/courses" class="btn btn-outline">View Courses</a>
    </div>
  </div>
</section>

{{#if featuredProducts.length}}
<section class="posts-section">
  <div class="container">
    <h2>Featured Products</h2>
    <div class="posts-grid">
      {{#each featuredProducts}}
      <article class="post-card">
        {{#if images.[0]}}<img src="{{images.[0]}}" alt="{{name}}" class="post-image">{{/if}}
        <div class="post-content">
          <h3><a href="/shop/product/{{slug}}">{{name}}</a></h3>
          <p style="color: var(--color-primary); font-weight: 600;">{{#if salePrice}}<s style="color: var(--color-text-muted);">${'$'}{{price}}</s> ${'$'}{{salePrice}}{{else}}${'$'}{{price}}{{/if}}</p>
        </div>
      </article>
      {{/each}}
    </div>
  </div>
</section>
{{/if}}

<section class="posts-section">
  <div class="container">
    <h2>Latest Posts</h2>
    <div class="posts-grid">
      {{#each posts}}
      <article class="post-card">
        {{#if this.featuredImage}}<img src="{{this.featuredImage}}" alt="{{this.title}}" class="post-image">{{/if}}
        <div class="post-content">
          <h3><a href="/post/{{this.slug}}">{{this.title}}</a></h3>
          <p>{{this.excerpt}}</p>
        </div>
      </article>
      {{/each}}
    </div>
  </div>
</section>
{{> footer}}`;
        const singlePost = `{{> header}}
<article class="single-post">
  <div class="container">
    {{#if post.featuredImage}}
    <img src="{{post.featuredImage}}" alt="{{post.title}}" class="featured-image">
    {{/if}}
    <h1>{{post.title}}</h1>
    <div class="post-meta">
      {{#if post.author}}<span>By {{post.author.name}}</span> &bull; {{/if}}
      <span>{{formatDate post.createdAt}}</span>
      {{#if post.category}} &bull; <a href="/category/{{post.category.slug}}">{{post.category.name}}</a>{{/if}}
    </div>
    <div class="post-body">
      {{{post.content}}}
    </div>
  </div>
</article>
{{> footer}}
`;
        const singlePage = `{{> header}}
<div class="page-content">
  <div class="container">
    <h1>{{page.title}}</h1>
    <div class="post-body">
      {{{page.content}}}
    </div>
  </div>
</div>
{{> footer}}
`;
        const archive = `{{> header}}
<section class="posts-section">
  <div class="container">
    <h1>Blog</h1>
    <div class="posts-grid">
      {{#each posts}}
      <article class="post-card">
        {{#if this.featuredImage}}
        <img src="{{this.featuredImage}}" alt="{{this.title}}" class="post-image">
        {{/if}}
        <div class="post-content">
          <h3><a href="/post/{{this.slug}}">{{this.title}}</a></h3>
          <p>{{this.excerpt}}</p>
        </div>
      </article>
      {{/each}}
    </div>
  </div>
</section>
{{> footer}}
`;
        const shop = `{{> header}}
<section class="posts-section">
  <div class="container">
    <h1>Shop</h1>
    <div class="posts-grid">
      {{#each products}}
      <article class="post-card">
        {{#if images.[0]}}
        <img src="{{images.[0]}}" alt="{{name}}" class="post-image">
        {{/if}}
        <div class="post-content">
          <h3><a href="/shop/product/{{slug}}">{{name}}</a></h3>
          <p style="color: var(--color-primary); font-weight: 600;">
            {{#if salePrice}}<s style="color: var(--color-text-muted);">\${{price}}</s> \${{salePrice}}{{else}}\${{price}}{{/if}}
          </p>
          <a href="/shop/product/{{slug}}" class="btn btn-sm btn-primary">View Product</a>
        </div>
      </article>
      {{/each}}
    </div>
  </div>
</section>
{{> footer}}
`;
        const singleProduct = `{{> header}}
<div class="page-content">
  <div class="container">
    <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 2rem;">
      <div>
        {{#if product.images.[0]}}
        <img src="{{product.images.[0]}}" alt="{{product.name}}" style="width: 100%; border-radius: var(--border-radius);">
        {{/if}}
      </div>
      <div>
        <h1>{{product.name}}</h1>
        <p style="font-size: 1.5rem; color: var(--color-primary); font-weight: 600; margin-bottom: 1rem;">
          {{#if product.salePrice}}<s style="color: var(--color-text-muted);">\${{product.price}}</s> \${{product.salePrice}}{{else}}\${{product.price}}{{/if}}
        </p>
        <div class="post-body">{{{product.description}}}</div>
        <button class="btn btn-primary" data-add-product="{{product.id}}" style="margin-top: 1rem;">Add to Cart</button>
      </div>
    </div>
  </div>
</div>
{{> footer}}
`;
        const courses = `{{> header}}
<section class="posts-section">
  <div class="container">
    <h1>Courses</h1>
    <div class="posts-grid">
      {{#each courses}}
      <article class="post-card">
        {{#if thumbnail}}
        <img src="{{thumbnail}}" alt="{{title}}" class="post-image">
        {{/if}}
        <div class="post-content">
          <h3><a href="/courses/{{slug}}">{{title}}</a></h3>
          <p>{{shortDescription}}</p>
          <p style="color: var(--color-primary); font-weight: 600;">
            {{#if (eq priceType 'FREE')}}Free{{else}}\${{price}}{{/if}}
          </p>
          <a href="/courses/{{slug}}" class="btn btn-sm btn-primary">Learn More</a>
        </div>
      </article>
      {{/each}}
    </div>
  </div>
</section>
{{> footer}}
`;
        const singleCourse = `{{> header}}
<div class="page-content">
  <div class="container">
    {{#if course.thumbnail}}
    <img src="{{course.thumbnail}}" alt="{{course.title}}" class="featured-image">
    {{/if}}
    <h1>{{course.title}}</h1>
    <div class="post-meta">
      <span>Level: {{course.level}}</span>
      {{#if course.estimatedHours}} &bull; <span>{{course.estimatedHours}} hours</span>{{/if}}
    </div>
    <div class="post-body">
      {{{course.description}}}
    </div>
    <div style="margin-top: 2rem;">
      <p style="font-size: 1.5rem; color: var(--color-primary); font-weight: 600;">
        {{#if (eq course.priceType 'FREE')}}Free{{else}}\${{course.priceAmount}}{{/if}}
      </p>
      {{#if (eq course.priceType 'FREE')}}
      <button class="btn btn-primary btn-lg" data-enroll-course="{{course.id}}" style="margin-top: 1rem;">Enroll Now - Free</button>
      {{else}}
      <button class="btn btn-primary btn-lg" data-add-course="{{course.id}}" style="margin-top: 1rem;">Add to Cart</button>
      {{/if}}
    </div>
  </div>
</div>
{{> footer}}
`;
        const login = `{{> header}}
<section class="auth-section" style="display: flex; align-items: center; justify-content: center; min-height: calc(100vh - 200px); padding: var(--section-padding) 0;">
  <div class="container" style="max-width: 420px;">
    <div class="auth-card" style="background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--border-radius); padding: 2.5rem;">
      <div style="text-align: center; margin-bottom: 2rem;">
        <h1 style="margin-bottom: 0.5rem;">Welcome Back</h1>
        <p style="color: var(--color-text-muted); margin: 0;">Sign in to your account</p>
      </div>
      {{#if error}}<div class="alert alert-error" style="padding: 1rem; background: rgba(239,68,68,0.1); border: 1px solid var(--color-error); color: var(--color-error); border-radius: 8px; margin-bottom: 1.5rem;">{{error}}</div>{{/if}}
      <form id="loginForm" method="POST" action="/login{{#if redirect}}?redirect={{redirect}}{{/if}}">
        <div style="margin-bottom: 1.25rem;">
          <label style="display: block; font-weight: 500; margin-bottom: 0.5rem;">Email</label>
          <input type="email" name="email" required placeholder="you@example.com" style="width: 100%; padding: 0.75rem 1rem; background: var(--color-background); border: 1px solid var(--color-border); border-radius: 8px; color: var(--color-text);">
        </div>
        <div style="margin-bottom: 1.25rem;">
          <label style="display: block; font-weight: 500; margin-bottom: 0.5rem;">Password</label>
          <input type="password" name="password" required placeholder="••••••••" style="width: 100%; padding: 0.75rem 1rem; background: var(--color-background); border: 1px solid var(--color-border); border-radius: 8px; color: var(--color-text);">
        </div>
        <button type="submit" class="btn btn-primary" style="width: 100%; justify-content: center;" id="submitBtn"><span class="btn-text">Sign In</span><span class="btn-loading" style="display: none;">Signing in...</span></button>
      </form>
      <div style="text-align: center; margin-top: 1.5rem; padding-top: 1.5rem; border-top: 1px solid var(--color-border);">
        <p style="margin: 0; color: var(--color-text-muted);">Don't have an account? <a href="/register">Create one</a></p>
      </div>
    </div>
  </div>
</section>
<script src="/themes/${slug}/assets/js/auth.js"></script>
{{> footer}}
`;
        const register = `{{> header}}
<section class="auth-section" style="display: flex; align-items: center; justify-content: center; min-height: calc(100vh - 200px); padding: var(--section-padding) 0;">
  <div class="container" style="max-width: 420px;">
    <div class="auth-card" style="background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--border-radius); padding: 2.5rem;">
      <div style="text-align: center; margin-bottom: 2rem;">
        <h1 style="margin-bottom: 0.5rem;">Create Account</h1>
        <p style="color: var(--color-text-muted); margin: 0;">Join us and start learning</p>
      </div>
      {{#if error}}<div class="alert alert-error" style="padding: 1rem; background: rgba(239,68,68,0.1); border: 1px solid var(--color-error); color: var(--color-error); border-radius: 8px; margin-bottom: 1.5rem;">{{error}}</div>{{/if}}
      <form id="registerForm" method="POST" action="/register">
        <div style="margin-bottom: 1.25rem;">
          <label style="display: block; font-weight: 500; margin-bottom: 0.5rem;">Full Name</label>
          <input type="text" name="name" required placeholder="John Doe" style="width: 100%; padding: 0.75rem 1rem; background: var(--color-background); border: 1px solid var(--color-border); border-radius: 8px; color: var(--color-text);">
        </div>
        <div style="margin-bottom: 1.25rem;">
          <label style="display: block; font-weight: 500; margin-bottom: 0.5rem;">Email</label>
          <input type="email" name="email" required placeholder="you@example.com" style="width: 100%; padding: 0.75rem 1rem; background: var(--color-background); border: 1px solid var(--color-border); border-radius: 8px; color: var(--color-text);">
        </div>
        <div style="margin-bottom: 1.25rem;">
          <label style="display: block; font-weight: 500; margin-bottom: 0.5rem;">Password</label>
          <input type="password" name="password" required placeholder="••••••••" minlength="8" style="width: 100%; padding: 0.75rem 1rem; background: var(--color-background); border: 1px solid var(--color-border); border-radius: 8px; color: var(--color-text);">
        </div>
        <div style="margin-bottom: 1.25rem;">
          <label style="display: block; font-weight: 500; margin-bottom: 0.5rem;">Confirm Password</label>
          <input type="password" name="confirmPassword" required placeholder="••••••••" style="width: 100%; padding: 0.75rem 1rem; background: var(--color-background); border: 1px solid var(--color-border); border-radius: 8px; color: var(--color-text);">
        </div>
        <button type="submit" class="btn btn-primary" style="width: 100%; justify-content: center;" id="submitBtn"><span class="btn-text">Create Account</span><span class="btn-loading" style="display: none;">Creating...</span></button>
      </form>
      <div style="text-align: center; margin-top: 1.5rem; padding-top: 1.5rem; border-top: 1px solid var(--color-border);">
        <p style="margin: 0; color: var(--color-text-muted);">Already have an account? <a href="/login">Sign in</a></p>
      </div>
    </div>
  </div>
</section>
<script src="/themes/${slug}/assets/js/auth.js"></script>
{{> footer}}
`;
        const cart = `{{> header}}
<section class="cart-section" style="padding: var(--section-padding) 0;">
  <div class="container">
    <h1>Shopping Cart</h1>
    <div class="cart-layout" id="cartContent" style="display: grid; grid-template-columns: 1fr 350px; gap: 2rem;">
      <div class="cart-items" id="cartItems" style="background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--border-radius); padding: 1.5rem;">
        <div class="loading-state" style="text-align: center; padding: 2rem; color: var(--color-text-muted);">Loading cart...</div>
      </div>
      <div class="cart-summary" id="cartSummary" style="background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--border-radius); padding: 1.5rem; height: fit-content;">
        <h3 style="margin-bottom: 1rem;">Order Summary</h3>
        <div style="display: flex; justify-content: space-between; padding: 0.75rem 0; border-bottom: 1px solid var(--color-border);"><span>Subtotal</span><span id="subtotal">$0.00</span></div>
        <div style="display: flex; justify-content: space-between; padding: 0.75rem 0; border-bottom: 1px solid var(--color-border);"><span>Tax</span><span id="tax">$0.00</span></div>
        <div style="display: flex; justify-content: space-between; padding: 0.75rem 0; font-weight: 600; font-size: 1.1rem;"><span>Total</span><span id="total">$0.00</span></div>
        <a href="/checkout" class="btn btn-primary" style="width: 100%; justify-content: center; margin-top: 1rem;">Proceed to Checkout</a>
        <a href="/shop" class="btn btn-outline" style="width: 100%; justify-content: center; margin-top: 0.5rem;">Continue Shopping</a>
      </div>
    </div>
    <div class="empty-cart" id="emptyCart" style="display: none; text-align: center; padding: 4rem 2rem;">
      <div style="font-size: 4rem; margin-bottom: 1rem;">🛒</div>
      <h2>Your cart is empty</h2>
      <p style="color: var(--color-text-muted); margin-bottom: 2rem;">Looks like you haven't added anything yet.</p>
      <div style="display: flex; gap: 1rem; justify-content: center;">
        <a href="/shop" class="btn btn-primary">Browse Products</a>
        <a href="/courses" class="btn btn-outline">Explore Courses</a>
      </div>
    </div>
  </div>
</section>
<script src="/themes/${slug}/assets/js/cart.js"></script>
{{> footer}}
`;
        const checkout = `{{> header}}
<section class="checkout-section" style="padding: var(--section-padding) 0;">
  <div class="container">
    <h1>Checkout</h1>
    <div class="checkout-layout" style="display: grid; grid-template-columns: 1fr 380px; gap: 2rem;">
      <div style="background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--border-radius); padding: 2rem;">
        <form id="checkoutForm">
          <div style="margin-bottom: 2rem; padding-bottom: 2rem; border-bottom: 1px solid var(--color-border);">
            <h3 style="margin-bottom: 1rem;">Contact Information</h3>
            {{#if user}}<p style="color: var(--color-text-muted); margin-bottom: 1rem;">Logged in as <strong>{{user.email}}</strong></p>{{/if}}
            <div style="margin-bottom: 1rem;"><label style="display: block; font-weight: 500; margin-bottom: 0.5rem;">Email *</label><input type="email" name="email" id="checkoutEmail" required value="{{#if user}}{{user.email}}{{/if}}" style="width: 100%; padding: 0.75rem; background: var(--color-background); border: 1px solid var(--color-border); border-radius: 8px; color: var(--color-text);"></div>
          </div>
          <div style="margin-bottom: 2rem; padding-bottom: 2rem; border-bottom: 1px solid var(--color-border);">
            <h3 style="margin-bottom: 1rem;">Billing Address</h3>
            <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-bottom: 1rem;">
              <div><label style="display: block; font-weight: 500; margin-bottom: 0.5rem;">First Name</label><input type="text" name="firstName" required style="width: 100%; padding: 0.75rem; background: var(--color-background); border: 1px solid var(--color-border); border-radius: 8px; color: var(--color-text);"></div>
              <div><label style="display: block; font-weight: 500; margin-bottom: 0.5rem;">Last Name</label><input type="text" name="lastName" required style="width: 100%; padding: 0.75rem; background: var(--color-background); border: 1px solid var(--color-border); border-radius: 8px; color: var(--color-text);"></div>
            </div>
            <div style="margin-bottom: 1rem;"><label style="display: block; font-weight: 500; margin-bottom: 0.5rem;">Address</label><input type="text" name="address" required style="width: 100%; padding: 0.75rem; background: var(--color-background); border: 1px solid var(--color-border); border-radius: 8px; color: var(--color-text);"></div>
            <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-bottom: 1rem;">
              <div><label style="display: block; font-weight: 500; margin-bottom: 0.5rem;">City</label><input type="text" name="city" required style="width: 100%; padding: 0.75rem; background: var(--color-background); border: 1px solid var(--color-border); border-radius: 8px; color: var(--color-text);"></div>
              <div><label style="display: block; font-weight: 500; margin-bottom: 0.5rem;">State</label><input type="text" name="state" required style="width: 100%; padding: 0.75rem; background: var(--color-background); border: 1px solid var(--color-border); border-radius: 8px; color: var(--color-text);"></div>
            </div>
            <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;">
              <div><label style="display: block; font-weight: 500; margin-bottom: 0.5rem;">Postal Code</label><input type="text" name="postalCode" required style="width: 100%; padding: 0.75rem; background: var(--color-background); border: 1px solid var(--color-border); border-radius: 8px; color: var(--color-text);"></div>
              <div><label style="display: block; font-weight: 500; margin-bottom: 0.5rem;">Country</label><select name="country" required style="width: 100%; padding: 0.75rem; background: var(--color-background); border: 1px solid var(--color-border); border-radius: 8px; color: var(--color-text);"><option value="">Select</option><option value="US">United States</option><option value="CA">Canada</option><option value="GB">United Kingdom</option></select></div>
            </div>
          </div>
          <button type="submit" class="btn btn-primary" style="width: 100%; padding: 1rem; font-size: 1.1rem;" id="placeOrderBtn"><span class="btn-text">Place Order</span><span class="btn-loading" style="display: none;">Processing...</span></button>
        </form>
      </div>
      <div style="background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--border-radius); padding: 1.5rem; height: fit-content;">
        <h3 style="margin-bottom: 1rem;">Order Summary</h3>
        <div id="orderItems" style="margin-bottom: 1rem; max-height: 300px; overflow-y: auto;"><div class="loading-state">Loading...</div></div>
        <div style="border-top: 1px solid var(--color-border); padding-top: 1rem;">
          <div style="display: flex; justify-content: space-between; padding: 0.5rem 0;"><span>Subtotal</span><span id="subtotal">$0.00</span></div>
          <div style="display: flex; justify-content: space-between; padding: 0.5rem 0;"><span>Tax</span><span id="tax">$0.00</span></div>
          <div style="display: flex; justify-content: space-between; padding: 0.75rem 0; font-weight: 600; font-size: 1.1rem;"><span>Total</span><span id="total">$0.00</span></div>
        </div>
      </div>
    </div>
  </div>
</section>
<script src="/themes/${slug}/assets/js/checkout.js"></script>
{{> footer}}
`;
        const result = {
            header,
            footer,
            home,
            'single-post': singlePost,
            'single-page': singlePage,
            archive,
            shop,
            'single-product': singleProduct,
            courses,
            'single-course': singleCourse,
            login,
            register,
            cart,
            checkout,
        };
        for (const page of pages) {
            if (page.isHomePage || page.slug === '/' || !page.blocks || page.blocks.length === 0) {
                continue;
            }
            const pageName = page.slug.replace(/^\//, '').replace(/\//g, '-') ||
                page.name.toLowerCase().replace(/\s+/g, '-');
            const pageBlocks = this.renderPageBlocks(page.blocks, settings);
            result[`page-${pageName}`] = `{{> header}}
${pageBlocks}
{{> footer}}`;
        }
        return result;
    }
    generateJavaScriptFiles() {
        const mainJs = `(function(){
  'use strict';
  document.addEventListener('DOMContentLoaded',function(){initUserMenu();updateCartCount();initAddToCart();});
  function initUserMenu(){var b=document.getElementById('userMenuBtn'),d=document.getElementById('userDropdown');if(b&&d){b.addEventListener('click',function(e){e.stopPropagation();d.classList.toggle('active');});document.addEventListener('click',function(){d.classList.remove('active');});}var l=document.getElementById('logoutBtn');if(l){l.addEventListener('click',function(){localStorage.removeItem('access_token');window.location.href='/logout';});}}
  async function updateCartCount(){var c=document.getElementById('cartCount');if(!c)return;try{var r=await fetch('/api/shop/cart',{credentials:'include',headers:getAuthHeaders()});if(!r.ok){c.style.display='none';return;}var cart=await r.json();var count=cart.items?.reduce((s,i)=>s+i.quantity,0)||0;if(count>0){c.textContent=count;c.style.display='flex';}else{c.style.display='none';}}catch(e){c.style.display='none';}}
  function initAddToCart(){document.querySelectorAll('[data-add-product]').forEach(b=>{b.addEventListener('click',async function(){await addToCart('product',this.dataset.addProduct);});});document.querySelectorAll('[data-add-course]').forEach(b=>{b.addEventListener('click',async function(){await addToCart('course',this.dataset.addCourse);});});document.querySelectorAll('[data-enroll-course]').forEach(b=>{b.addEventListener('click',async function(){await enrollFreeCourse(this.dataset.enrollCourse);});});}
  async function addToCart(type,id){try{var endpoint=type==='course'?'/api/shop/cart/add-course':'/api/shop/cart/add';var body=type==='course'?{courseId:id}:{productId:id,quantity:1};var r=await fetch(endpoint,{method:'POST',headers:{'Content-Type':'application/json',...getAuthHeaders()},body:JSON.stringify(body),credentials:'include'});if(r.ok){updateCartCount();showNotification('Added to cart!','success');}else{var e=await r.json();showNotification(e.message||'Failed to add to cart','error');}}catch(e){showNotification('Failed to add to cart','error');}}
  async function enrollFreeCourse(courseId){try{var r=await fetch('/api/lms/courses/'+courseId+'/enroll',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({}),credentials:'include'});if(r.ok){showNotification('Successfully enrolled!','success');setTimeout(function(){window.location.href='/learn/'+courseId;},1500);}else if(r.status===401){showNotification('Please log in to enroll','error');setTimeout(function(){window.location.href='/login?redirect='+encodeURIComponent(window.location.pathname);},1500);}else{var e=await r.json();showNotification(e.message||'Failed to enroll','error');}}catch(e){showNotification('Failed to enroll','error');}}
  function showNotification(msg,type){var n=document.createElement('div');n.className='notification notification-'+type;n.textContent=msg;n.style.cssText='position:fixed;top:80px;right:20px;padding:1rem 1.5rem;background:'+(type==='success'?'var(--color-success)':type==='error'?'var(--color-error)':'var(--color-primary)')+';color:white;border-radius:8px;z-index:9999;';document.body.appendChild(n);setTimeout(()=>n.remove(),3000);}
  function getAuthHeaders(){var t=localStorage.getItem('access_token');return t?{'Authorization':'Bearer '+t}:{};}
  window.addToCart=addToCart;window.updateCartCount=updateCartCount;window.enrollFreeCourse=enrollFreeCourse;
})();`;
        const authJs = `(function(){
  'use strict';
  var loginForm=document.getElementById('loginForm');
  if(loginForm){loginForm.addEventListener('submit',function(e){var btn=document.getElementById('submitBtn'),txt=btn.querySelector('.btn-text'),load=btn.querySelector('.btn-loading');var email=loginForm.querySelector('[name="email"]').value,pass=loginForm.querySelector('[name="password"]').value;if(!email||!pass){e.preventDefault();showError(loginForm,'Please fill in all fields');return;}txt.style.display='none';load.style.display='inline';btn.disabled=true;});}
  var regForm=document.getElementById('registerForm');
  if(regForm){regForm.addEventListener('submit',function(e){var btn=document.getElementById('submitBtn'),txt=btn.querySelector('.btn-text'),load=btn.querySelector('.btn-loading');var pass=regForm.querySelector('[name="password"]').value,conf=regForm.querySelector('[name="confirmPassword"]').value;if(pass!==conf){e.preventDefault();showError(regForm,'Passwords do not match');return;}txt.style.display='none';load.style.display='inline';btn.disabled=true;});}
  function showError(f,m){var a=f.querySelector('.alert-error');if(!a){a=document.createElement('div');a.className='alert alert-error';f.insertBefore(a,f.firstChild);}a.textContent=m;}
})();`;
        const cartJs = `(function(){
  'use strict';
  var API='/api/shop/cart';
  document.addEventListener('DOMContentLoaded',function(){setupEventListeners();loadCart();});
  async function loadCart(){var items=document.getElementById('cartItems'),empty=document.getElementById('emptyCart'),content=document.getElementById('cartContent');if(!items)return;try{var r=await fetch(API,{credentials:'include',headers:getAuthHeaders()});if(!r.ok)throw new Error();var cart=await r.json();if(!cart.items||cart.items.length===0){if(content)content.style.display='none';if(empty)empty.style.display='block';return;}if(content)content.style.display='grid';if(empty)empty.style.display='none';renderItems(cart.items);updateSummary(cart);}catch(e){items.innerHTML='<p>Failed to load cart</p>';}}
  function renderItems(items){var el=document.getElementById('cartItems');if(!el)return;el.innerHTML=items.map(i=>{var isCourse=i.type==='COURSE';var img=i.product?.images?.[0]||i.course?.thumbnail||'/placeholder.jpg';var title=i.product?.name||i.course?.title||'Item';var price=i.product?.price||i.course?.price||0;return '<div class="cart-item" data-item-id="'+i.id+'"><img src="'+img+'" alt="'+title+'" style="width:100px;height:100px;object-fit:cover;border-radius:8px;"><div style="flex:1;"><div style="font-weight:600;">'+title+'</div><div style="font-size:0.8rem;color:var(--color-primary);">'+(isCourse?'Course':'Product')+'</div><div style="color:var(--color-text-muted);">$'+parseFloat(price).toFixed(2)+'</div></div><div style="display:flex;flex-direction:column;align-items:flex-end;gap:0.5rem;">'+(isCourse?'':'<div style="display:flex;align-items:center;gap:0.5rem;"><button class="qty-btn" data-item-id="'+i.id+'" data-qty="'+(i.quantity-1)+'" style="width:32px;height:32px;border:1px solid var(--color-border);background:var(--color-background);border-radius:4px;cursor:pointer;">-</button><span>'+i.quantity+'</span><button class="qty-btn" data-item-id="'+i.id+'" data-qty="'+(i.quantity+1)+'" style="width:32px;height:32px;border:1px solid var(--color-border);background:var(--color-background);border-radius:4px;cursor:pointer;">+</button></div>')+'<button class="remove-btn" data-item-id="'+i.id+'" style="background:none;border:none;color:var(--color-error);cursor:pointer;">Remove</button></div></div>';}).join('');}
  function updateSummary(cart){var sub=cart.items.reduce((s,i)=>{var p=i.product?.price||i.course?.price||0;return s+(parseFloat(p)*i.quantity);},0);var tax=sub*0.1;document.getElementById('subtotal').textContent='$'+sub.toFixed(2);document.getElementById('tax').textContent='$'+tax.toFixed(2);document.getElementById('total').textContent='$'+(sub+tax).toFixed(2);}
  async function updateQuantity(id,qty){if(qty<1){removeItem(id);return;}try{await fetch(API+'/item/'+id,{method:'PUT',headers:{'Content-Type':'application/json',...getAuthHeaders()},body:JSON.stringify({quantity:qty}),credentials:'include'});loadCart();if(window.updateCartCount)window.updateCartCount();}catch(e){}}
  async function removeItem(id){try{await fetch(API+'/item/'+id,{method:'DELETE',headers:getAuthHeaders(),credentials:'include'});loadCart();if(window.updateCartCount)window.updateCartCount();}catch(e){}}
  function setupEventListeners(){var el=document.getElementById('cartItems');if(!el)return;el.addEventListener('click',function(e){var t=e.target;if(t.classList.contains('remove-btn')){var id=t.getAttribute('data-item-id');if(id)removeItem(id);return;}if(t.classList.contains('qty-btn')){var id=t.getAttribute('data-item-id'),qty=parseInt(t.getAttribute('data-qty'),10);if(id&&!isNaN(qty))updateQuantity(id,qty);}});}
  function getAuthHeaders(){var t=localStorage.getItem('access_token');return t?{'Authorization':'Bearer '+t}:{};}
})();`;
        const checkoutJs = `(function(){
  'use strict';
  var API='/api/shop';
  document.addEventListener('DOMContentLoaded',function(){loadOrderSummary();setupForm();});
  async function loadOrderSummary(){var el=document.getElementById('orderItems');if(!el)return;try{var r=await fetch(API+'/cart',{credentials:'include',headers:getAuthHeaders()});if(!r.ok)throw new Error();var cart=await r.json();if(!cart.items||cart.items.length===0){window.location.href='/cart';return;}renderItems(cart.items);updateTotals(cart);}catch(e){el.innerHTML='<p>Failed to load</p>';}}
  function renderItems(items){var el=document.getElementById('orderItems');if(!el)return;el.innerHTML=items.map(i=>{var isCourse=i.type==='COURSE';var img=i.product?.images?.[0]||i.course?.thumbnail||'/placeholder.jpg';var title=i.product?.name||i.course?.title||'Item';var price=i.product?.price||i.course?.price||0;return '<div style="display:flex;gap:0.75rem;padding:0.75rem 0;border-bottom:1px solid var(--color-border);font-size:0.9rem;"><img src="'+img+'" style="width:50px;height:50px;object-fit:cover;border-radius:4px;"><div style="flex:1;"><div style="font-weight:500;">'+title+'</div><div style="color:var(--color-text-muted);font-size:0.85rem;">'+(isCourse?'Course':'Qty: '+i.quantity)+'</div></div><div style="font-weight:500;">$'+(parseFloat(price)*i.quantity).toFixed(2)+'</div></div>';}).join('');}
  function updateTotals(cart){var sub=cart.items.reduce((s,i)=>{var p=i.product?.price||i.course?.price||0;return s+(parseFloat(p)*i.quantity);},0);var tax=sub*0.1;document.getElementById('subtotal').textContent='$'+sub.toFixed(2);document.getElementById('tax').textContent='$'+tax.toFixed(2);document.getElementById('total').textContent='$'+(sub+tax).toFixed(2);}
  function setupForm(){var form=document.getElementById('checkoutForm');if(!form)return;form.addEventListener('submit',async function(e){e.preventDefault();var btn=document.getElementById('placeOrderBtn'),txt=btn.querySelector('.btn-text'),load=btn.querySelector('.btn-loading');txt.style.display='none';load.style.display='inline';btn.disabled=true;var fd=new FormData(form);try{var r=await fetch(API+'/orders',{method:'POST',headers:{'Content-Type':'application/json',...getAuthHeaders()},body:JSON.stringify({email:fd.get('email'),billingAddress:{firstName:fd.get('firstName'),lastName:fd.get('lastName'),address1:fd.get('address'),city:fd.get('city'),state:fd.get('state'),postalCode:fd.get('postalCode'),country:fd.get('country')}}),credentials:'include'});if(r.ok){var o=await r.json();alert('Order placed! ID: '+o.id);window.location.href='/';}else{var e=await r.json();alert(e.message||'Failed');resetBtn(btn,txt,load);}}catch(e){alert('Error');resetBtn(btn,txt,load);}});}
  function resetBtn(b,t,l){t.style.display='inline';l.style.display='none';b.disabled=false;}
  function getAuthHeaders(){var t=localStorage.getItem('access_token');return t?{'Authorization':'Bearer '+t}:{};}
})();`;
        return {
            main: mainJs,
            auth: authJs,
            cart: cartJs,
            checkout: checkoutJs,
        };
    }
    async generateScreenshot(themePath, settings) {
        const svg = this.generateScreenshotSVG(settings);
        await fs.writeFile(path.join(themePath, 'screenshot.svg'), svg);
        await fs.writeFile(path.join(themePath, 'screenshot.png'), Buffer.from(''));
    }
    generateScreenshotSVG(settings) {
        const { colors } = settings;
        return `<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="900" viewBox="0 0 1200 900">
  <rect width="1200" height="900" fill="${colors.background}"/>
  <rect y="0" width="1200" height="60" fill="${colors.surface}"/>
  <text x="30" y="40" font-family="system-ui" font-size="24" font-weight="bold" fill="${colors.primary}">Theme Preview</text>
  <rect x="100" y="150" width="1000" height="400" rx="8" fill="${colors.surface}" stroke="${colors.border}"/>
  <text x="600" y="350" text-anchor="middle" font-family="system-ui" font-size="48" font-weight="bold" fill="${colors.heading}">Custom Theme</text>
  <text x="600" y="420" text-anchor="middle" font-family="system-ui" font-size="24" fill="${colors.textMuted}">Created with Theme Designer</text>
  <rect x="500" y="480" width="200" height="50" rx="8" fill="${colors.primary}"/>
  <text x="600" y="512" text-anchor="middle" font-family="system-ui" font-size="18" fill="#ffffff">Get Started</text>
</svg>`;
    }
};
exports.CustomThemesService = CustomThemesService;
exports.CustomThemesService = CustomThemesService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], CustomThemesService);


/***/ }),
/* 140 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e, _f, _g;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CustomThemesController = void 0;
const common_1 = __webpack_require__(2);
const express_1 = __webpack_require__(57);
const jwt_1 = __webpack_require__(43);
const custom_themes_service_1 = __webpack_require__(139);
const create_custom_theme_dto_1 = __webpack_require__(141);
const update_custom_theme_dto_1 = __webpack_require__(142);
const generate_ai_theme_dto_1 = __webpack_require__(143);
const ai_theme_generator_service_1 = __webpack_require__(144);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const client_1 = __webpack_require__(17);
let CustomThemesController = class CustomThemesController {
    constructor(customThemesService, aiThemeGeneratorService, jwtService) {
        this.customThemesService = customThemesService;
        this.aiThemeGeneratorService = aiThemeGeneratorService;
        this.jwtService = jwtService;
    }
    findAll() {
        return this.customThemesService.findAll();
    }
    getActive() {
        return this.customThemesService.getActiveTheme();
    }
    findOne(id) {
        return this.customThemesService.findById(id);
    }
    create(dto, req) {
        return this.customThemesService.create(dto, req.user.id);
    }
    update(id, dto) {
        return this.customThemesService.update(id, dto);
    }
    delete(id) {
        return this.customThemesService.delete(id);
    }
    duplicate(id, body, req) {
        return this.customThemesService.duplicate(id, req.user.id, body.name);
    }
    activate(id) {
        return this.customThemesService.activate(id);
    }
    exportTheme(id) {
        return this.customThemesService.exportTheme(id);
    }
    async exportAsZip(id, res) {
        const theme = await this.customThemesService.findById(id);
        const buffer = await this.customThemesService.exportAsZip(id);
        const slug = theme.name
            .toLowerCase()
            .replace(/[^a-z0-9]+/g, '-')
            .replace(/^-|-$/g, '');
        res.set({
            'Content-Type': 'application/zip',
            'Content-Disposition': `attachment; filename="${slug}.zip"`,
            'Content-Length': buffer.length,
        });
        res.end(buffer);
    }
    installTheme(id) {
        return this.customThemesService.installTheme(id);
    }
    importTheme(data, req) {
        return this.customThemesService.importTheme(data, req.user.id);
    }
    generateCSS(body) {
        return { css: this.customThemesService.generateCSS(body.settings, body.customCSS) };
    }
    async generateAiTheme(dto, req) {
        return this.aiThemeGeneratorService.generateTheme(dto, req.user.id);
    }
    generatePreviewToken(req) {
        const token = this.jwtService.sign({
            sub: req.user.id,
            preview: true,
            purpose: 'theme-customizer-preview',
        }, { expiresIn: '15m' });
        return {
            token,
            expiresIn: 900,
        };
    }
};
exports.CustomThemesController = CustomThemesController;
__decorate([
    (0, common_1.Get)(),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], CustomThemesController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)('active'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], CustomThemesController.prototype, "getActive", null);
__decorate([
    (0, common_1.Get)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], CustomThemesController.prototype, "findOne", null);
__decorate([
    (0, common_1.Post)(),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_d = typeof create_custom_theme_dto_1.CreateCustomThemeDto !== "undefined" && create_custom_theme_dto_1.CreateCustomThemeDto) === "function" ? _d : Object, Object]),
    __metadata("design:returntype", void 0)
], CustomThemesController.prototype, "create", null);
__decorate([
    (0, common_1.Put)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_e = typeof update_custom_theme_dto_1.UpdateCustomThemeDto !== "undefined" && update_custom_theme_dto_1.UpdateCustomThemeDto) === "function" ? _e : Object]),
    __metadata("design:returntype", void 0)
], CustomThemesController.prototype, "update", null);
__decorate([
    (0, common_1.Delete)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], CustomThemesController.prototype, "delete", null);
__decorate([
    (0, common_1.Post)(':id/duplicate'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __param(2, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object, Object]),
    __metadata("design:returntype", void 0)
], CustomThemesController.prototype, "duplicate", null);
__decorate([
    (0, common_1.Post)(':id/activate'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], CustomThemesController.prototype, "activate", null);
__decorate([
    (0, common_1.Get)(':id/export'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], CustomThemesController.prototype, "exportTheme", null);
__decorate([
    (0, common_1.Get)(':id/export-zip'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_f = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _f : Object]),
    __metadata("design:returntype", Promise)
], CustomThemesController.prototype, "exportAsZip", null);
__decorate([
    (0, common_1.Post)(':id/install'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], CustomThemesController.prototype, "installTheme", null);
__decorate([
    (0, common_1.Post)('import'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Object]),
    __metadata("design:returntype", void 0)
], CustomThemesController.prototype, "importTheme", null);
__decorate([
    (0, common_1.Post)('generate-css'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], CustomThemesController.prototype, "generateCSS", null);
__decorate([
    (0, common_1.Post)('generate-ai'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_g = typeof generate_ai_theme_dto_1.GenerateAiThemeDto !== "undefined" && generate_ai_theme_dto_1.GenerateAiThemeDto) === "function" ? _g : Object, Object]),
    __metadata("design:returntype", Promise)
], CustomThemesController.prototype, "generateAiTheme", null);
__decorate([
    (0, common_1.Post)('preview-token'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], CustomThemesController.prototype, "generatePreviewToken", null);
exports.CustomThemesController = CustomThemesController = __decorate([
    (0, common_1.Controller)('api/custom-themes'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof custom_themes_service_1.CustomThemesService !== "undefined" && custom_themes_service_1.CustomThemesService) === "function" ? _a : Object, typeof (_b = typeof ai_theme_generator_service_1.AiThemeGeneratorService !== "undefined" && ai_theme_generator_service_1.AiThemeGeneratorService) === "function" ? _b : Object, typeof (_c = typeof jwt_1.JwtService !== "undefined" && jwt_1.JwtService) === "function" ? _c : Object])
], CustomThemesController);


/***/ }),
/* 141 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CreateCustomThemeDto = void 0;
const class_validator_1 = __webpack_require__(59);
const class_transformer_1 = __webpack_require__(95);
class ContentBlockDataDto {
}
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], ContentBlockDataDto.prototype, "id", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], ContentBlockDataDto.prototype, "type", void 0);
__decorate([
    (0, class_validator_1.IsObject)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", typeof (_a = typeof Record !== "undefined" && Record) === "function" ? _a : Object)
], ContentBlockDataDto.prototype, "props", void 0);
__decorate([
    (0, class_validator_1.IsObject)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Object)
], ContentBlockDataDto.prototype, "link", void 0);
__decorate([
    (0, class_validator_1.IsObject)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Object)
], ContentBlockDataDto.prototype, "visibility", void 0);
__decorate([
    (0, class_validator_1.IsObject)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Object)
], ContentBlockDataDto.prototype, "animation", void 0);
class ThemePageDataDto {
}
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], ThemePageDataDto.prototype, "id", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], ThemePageDataDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], ThemePageDataDto.prototype, "slug", void 0);
__decorate([
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.ValidateNested)({ each: true }),
    (0, class_transformer_1.Type)(() => ContentBlockDataDto),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", Array)
], ThemePageDataDto.prototype, "blocks", void 0);
__decorate([
    (0, class_validator_1.IsBoolean)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Boolean)
], ThemePageDataDto.prototype, "isHomePage", void 0);
class CreateCustomThemeDto {
}
exports.CreateCustomThemeDto = CreateCustomThemeDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], CreateCustomThemeDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateCustomThemeDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsObject)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", typeof (_b = typeof Record !== "undefined" && Record) === "function" ? _b : Object)
], CreateCustomThemeDto.prototype, "settings", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateCustomThemeDto.prototype, "customCSS", void 0);
__decorate([
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.ValidateNested)({ each: true }),
    (0, class_transformer_1.Type)(() => ThemePageDataDto),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], CreateCustomThemeDto.prototype, "pages", void 0);
__decorate([
    (0, class_validator_1.IsBoolean)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Boolean)
], CreateCustomThemeDto.prototype, "isDefault", void 0);


/***/ }),
/* 142 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UpdateCustomThemeDto = void 0;
const class_validator_1 = __webpack_require__(59);
const class_transformer_1 = __webpack_require__(95);
class ContentBlockDataDto {
}
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], ContentBlockDataDto.prototype, "id", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], ContentBlockDataDto.prototype, "type", void 0);
__decorate([
    (0, class_validator_1.IsObject)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_a = typeof Record !== "undefined" && Record) === "function" ? _a : Object)
], ContentBlockDataDto.prototype, "props", void 0);
__decorate([
    (0, class_validator_1.IsObject)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Object)
], ContentBlockDataDto.prototype, "link", void 0);
__decorate([
    (0, class_validator_1.IsObject)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Object)
], ContentBlockDataDto.prototype, "visibility", void 0);
__decorate([
    (0, class_validator_1.IsObject)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Object)
], ContentBlockDataDto.prototype, "animation", void 0);
class ThemePageDataDto {
}
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], ThemePageDataDto.prototype, "id", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], ThemePageDataDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], ThemePageDataDto.prototype, "slug", void 0);
__decorate([
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.ValidateNested)({ each: true }),
    (0, class_transformer_1.Type)(() => ContentBlockDataDto),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], ThemePageDataDto.prototype, "blocks", void 0);
__decorate([
    (0, class_validator_1.IsBoolean)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Boolean)
], ThemePageDataDto.prototype, "isHomePage", void 0);
class UpdateCustomThemeDto {
}
exports.UpdateCustomThemeDto = UpdateCustomThemeDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateCustomThemeDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateCustomThemeDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsObject)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_b = typeof Record !== "undefined" && Record) === "function" ? _b : Object)
], UpdateCustomThemeDto.prototype, "settings", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateCustomThemeDto.prototype, "customCSS", void 0);
__decorate([
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.ValidateNested)({ each: true }),
    (0, class_transformer_1.Type)(() => ThemePageDataDto),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], UpdateCustomThemeDto.prototype, "pages", void 0);
__decorate([
    (0, class_validator_1.IsBoolean)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Boolean)
], UpdateCustomThemeDto.prototype, "isDefault", void 0);


/***/ }),
/* 143 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.GenerateAiThemeDto = void 0;
const class_validator_1 = __webpack_require__(59);
class GenerateAiThemeDto {
}
exports.GenerateAiThemeDto = GenerateAiThemeDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], GenerateAiThemeDto.prototype, "prompt", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], GenerateAiThemeDto.prototype, "themeName", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], GenerateAiThemeDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.Min)(1),
    (0, class_validator_1.Max)(5),
    __metadata("design:type", Number)
], GenerateAiThemeDto.prototype, "numberOfPages", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], GenerateAiThemeDto.prototype, "style", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], GenerateAiThemeDto.prototype, "colorScheme", void 0);


/***/ }),
/* 144 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.AiThemeGeneratorService = void 0;
const common_1 = __webpack_require__(2);
const config_1 = __webpack_require__(13);
const uuid_1 = __webpack_require__(25);
let AiThemeGeneratorService = class AiThemeGeneratorService {
    constructor(configService) {
        this.configService = configService;
        this.rateLimitMap = new Map();
        this.isConfigured = false;
        this.aiProvider = (this.configService.get('AI_PROVIDER') || 'openai');
        this.openaiApiKey = this.configService.get('OPENAI_API_KEY') || '';
        this.anthropicApiKey = this.configService.get('ANTHROPIC_API_KEY') || '';
        if (!this.openaiApiKey && !this.anthropicApiKey) {
            console.warn('AI Theme Generator: No API keys configured. AI features will be disabled.');
            this.isConfigured = false;
        }
        else {
            this.isConfigured = true;
        }
    }
    isAvailable() {
        return this.isConfigured;
    }
    checkRateLimit(userId) {
        const limit = parseInt(this.configService.get('AI_RATE_LIMIT') || '10');
        const window = parseInt(this.configService.get('AI_RATE_LIMIT_WINDOW') || '3600') * 1000;
        const now = Date.now();
        if (!this.rateLimitMap.has(userId)) {
            this.rateLimitMap.set(userId, []);
        }
        const timestamps = this.rateLimitMap.get(userId);
        const recentRequests = timestamps.filter((t) => now - t < window);
        if (recentRequests.length >= limit) {
            return false;
        }
        recentRequests.push(now);
        this.rateLimitMap.set(userId, recentRequests);
        return true;
    }
    async generateTheme(dto, userId) {
        if (!this.isConfigured) {
            throw new common_1.ServiceUnavailableException('AI Theme Generator is not configured. Please set OPENAI_API_KEY or ANTHROPIC_API_KEY in .env');
        }
        if (!this.checkRateLimit(userId)) {
            throw new common_1.BadRequestException('Rate limit exceeded. Please try again later.');
        }
        try {
            if (this.aiProvider === 'openai' && this.openaiApiKey) {
                return await this.generateWithOpenAI(dto);
            }
            else if (this.aiProvider === 'anthropic' && this.anthropicApiKey) {
                return await this.generateWithAnthropic(dto);
            }
            else {
                throw new common_1.ServiceUnavailableException('No AI provider configured');
            }
        }
        catch (error) {
            throw new common_1.ServiceUnavailableException(`AI generation failed: ${error.message || 'Unknown error'}`);
        }
    }
    async generateWithOpenAI(dto) {
        const response = await fetch('https://api.openai.com/v1/chat/completions', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                Authorization: `Bearer ${this.openaiApiKey}`,
            },
            body: JSON.stringify({
                model: 'gpt-4-turbo-preview',
                messages: [
                    {
                        role: 'system',
                        content: this.getSystemPrompt(),
                    },
                    {
                        role: 'user',
                        content: this.buildUserPrompt(dto),
                    },
                ],
                temperature: 0.7,
                max_tokens: 4000,
            }),
        });
        if (!response.ok) {
            const error = await response.json();
            throw new Error(`OpenAI API error: ${error.error?.message || 'Unknown error'}`);
        }
        const data = await response.json();
        const content = data.choices[0].message.content;
        return this.parseAiResponse(content, dto);
    }
    async generateWithAnthropic(dto) {
        const response = await fetch('https://api.anthropic.com/v1/messages', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'x-api-key': this.anthropicApiKey,
                'anthropic-version': '2023-06-01',
            },
            body: JSON.stringify({
                model: 'claude-3-opus-20240229',
                max_tokens: 4000,
                system: this.getSystemPrompt(),
                messages: [
                    {
                        role: 'user',
                        content: this.buildUserPrompt(dto),
                    },
                ],
            }),
        });
        if (!response.ok) {
            const error = await response.json();
            throw new Error(`Anthropic API error: ${error.error?.message || 'Unknown error'}`);
        }
        const data = await response.json();
        const content = data.content[0].text;
        return this.parseAiResponse(content, dto);
    }
    getSystemPrompt() {
        return `You are an expert web designer and theme creator. Generate professional, modern theme configurations based on user descriptions.

Return ONLY valid JSON (no markdown, no code blocks) with this exact structure:
{
  "settings": {
    "colors": {
      "primary": "#hex",
      "secondary": "#hex",
      "accent": "#hex",
      "background": "#hex",
      "surface": "#hex",
      "text": "#hex",
      "textMuted": "#hex",
      "heading": "#hex",
      "link": "#hex",
      "linkHover": "#hex",
      "border": "#hex"
    },
    "typography": {
      "headingFont": "font-name",
      "bodyFont": "font-name",
      "baseFontSize": 16,
      "lineHeight": 1.6,
      "headingWeight": 600
    },
    "layout": {
      "sidebarPosition": "none|left|right",
      "contentWidth": 1200,
      "headerStyle": "default|sticky|minimal|centered",
      "footerStyle": "default|minimal|centered"
    },
    "spacing": {
      "sectionPadding": 32,
      "elementSpacing": 16,
      "containerPadding": 24
    },
    "borders": {
      "radius": 8,
      "width": 1
    }
  },
  "pages": [
    {
      "id": "uuid",
      "name": "Home",
      "slug": "home",
      "isHomePage": true,
      "blocks": []
    }
  ]
}

Ensure all colors are valid hex codes, fonts are web-safe, and values are reasonable.`;
    }
    buildUserPrompt(dto) {
        let prompt = `Create a theme with the following requirements:\n\n`;
        prompt += `Description: ${dto.prompt}\n`;
        if (dto.style) {
            prompt += `Style: ${dto.style}\n`;
        }
        if (dto.colorScheme) {
            prompt += `Color Scheme: ${dto.colorScheme}\n`;
        }
        const pages = dto.numberOfPages || 1;
        prompt += `Number of pages: ${pages}\n`;
        prompt += `\nGenerate a complete, production-ready theme configuration.`;
        return prompt;
    }
    parseAiResponse(content, dto) {
        try {
            let jsonStr = content;
            const jsonMatch = content.match(/```(?:json)?\s*([\s\S]*?)\s*```/);
            if (jsonMatch) {
                jsonStr = jsonMatch[1];
            }
            const parsed = JSON.parse(jsonStr);
            const settings = this.validateSettings(parsed.settings);
            const pages = this.generatePages(parsed.pages || [], dto.numberOfPages || 1);
            return {
                settings,
                pages,
                name: dto.themeName || `AI Theme ${new Date().toLocaleDateString()}`,
                description: dto.description || `Generated with AI: ${dto.prompt.substring(0, 100)}...`,
            };
        }
        catch (_error) {
            throw new common_1.BadRequestException('Failed to parse AI response. Please try again.');
        }
    }
    validateSettings(settings) {
        const defaults = {
            colors: {
                primary: '#3b82f6',
                secondary: '#1d4ed8',
                accent: '#3b82f6',
                background: '#ffffff',
                surface: '#f8fafc',
                text: '#334155',
                textMuted: '#64748b',
                heading: '#0f172a',
                link: '#3b82f6',
                linkHover: '#1d4ed8',
                border: '#e2e8f0',
            },
            typography: {
                headingFont: 'Inter',
                bodyFont: 'Inter',
                baseFontSize: 16,
                lineHeight: 1.6,
                headingWeight: 600,
            },
            layout: {
                sidebarPosition: 'none',
                contentWidth: 1200,
                headerStyle: 'default',
                footerStyle: 'default',
            },
            spacing: {
                sectionPadding: 32,
                elementSpacing: 16,
                containerPadding: 24,
            },
            borders: {
                radius: 8,
                width: 1,
            },
        };
        return { ...defaults, ...settings };
    }
    generatePages(pages, count) {
        const generatedPages = [];
        for (let i = 0; i < count; i++) {
            const isHome = i === 0;
            generatedPages.push({
                id: (0, uuid_1.v4)(),
                name: isHome ? 'Home' : `Page ${i}`,
                slug: isHome ? 'home' : `page-${i}`,
                isHomePage: isHome,
                blocks: this.generateDefaultBlocks(isHome),
            });
        }
        return generatedPages;
    }
    generateDefaultBlocks(isHomePage) {
        const blocks = [];
        if (isHomePage) {
            blocks.push({
                id: (0, uuid_1.v4)(),
                type: 'hero',
                props: {
                    title: 'Welcome to Your Site',
                    subtitle: 'Created with AI Theme Designer',
                    backgroundImage: null,
                    ctaText: 'Get Started',
                    ctaUrl: '#',
                },
            });
            blocks.push({
                id: (0, uuid_1.v4)(),
                type: 'features',
                props: {
                    title: 'Key Features',
                    features: [
                        { title: 'Feature 1', description: 'Description here' },
                        { title: 'Feature 2', description: 'Description here' },
                        { title: 'Feature 3', description: 'Description here' },
                    ],
                },
            });
        }
        return blocks;
    }
};
exports.AiThemeGeneratorService = AiThemeGeneratorService;
exports.AiThemeGeneratorService = AiThemeGeneratorService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof config_1.ConfigService !== "undefined" && config_1.ConfigService) === "function" ? _a : Object])
], AiThemeGeneratorService);


/***/ }),
/* 145 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ThemeCustomizationService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let ThemeCustomizationService = class ThemeCustomizationService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async createImage(themeId, dto) {
        const theme = await this.prisma.theme.findUnique({ where: { id: themeId } });
        if (!theme) {
            throw new common_1.NotFoundException('Theme not found');
        }
        return this.prisma.themeCustomizationImage.create({
            data: {
                themeId,
                ...dto,
            },
        });
    }
    async getImages(themeId, type) {
        const where = { themeId };
        if (type)
            where.type = type;
        return this.prisma.themeCustomizationImage.findMany({
            where,
            orderBy: { position: 'asc' },
        });
    }
    async getImage(id) {
        const image = await this.prisma.themeCustomizationImage.findUnique({ where: { id } });
        if (!image)
            throw new common_1.NotFoundException('Image not found');
        return image;
    }
    async updateImage(id, dto) {
        await this.getImage(id);
        return this.prisma.themeCustomizationImage.update({
            where: { id },
            data: dto,
        });
    }
    async deleteImage(id) {
        await this.getImage(id);
        return this.prisma.themeCustomizationImage.delete({ where: { id } });
    }
    async reorderImages(themeId, imageIds) {
        const updates = imageIds.map((id, index) => this.prisma.themeCustomizationImage.update({
            where: { id },
            data: { position: index },
        }));
        return Promise.all(updates);
    }
    async createBlock(themeId, dto) {
        const theme = await this.prisma.theme.findUnique({ where: { id: themeId } });
        if (!theme)
            throw new common_1.NotFoundException('Theme not found');
        return this.prisma.themeCustomizationBlock.create({
            data: {
                themeId,
                ...dto,
            },
        });
    }
    async getBlocks(themeId, type) {
        const where = { themeId };
        if (type)
            where.type = type;
        return this.prisma.themeCustomizationBlock.findMany({
            where,
            orderBy: { position: 'asc' },
        });
    }
    async getBlock(id) {
        const block = await this.prisma.themeCustomizationBlock.findUnique({ where: { id } });
        if (!block)
            throw new common_1.NotFoundException('Block not found');
        return block;
    }
    async updateBlock(id, dto) {
        await this.getBlock(id);
        return this.prisma.themeCustomizationBlock.update({
            where: { id },
            data: dto,
        });
    }
    async deleteBlock(id) {
        await this.getBlock(id);
        return this.prisma.themeCustomizationBlock.delete({ where: { id } });
    }
    async reorderBlocks(themeId, blockIds) {
        const updates = blockIds.map((id, index) => this.prisma.themeCustomizationBlock.update({
            where: { id },
            data: { position: index },
        }));
        return Promise.all(updates);
    }
    async createLink(themeId, dto) {
        const theme = await this.prisma.theme.findUnique({ where: { id: themeId } });
        if (!theme)
            throw new common_1.NotFoundException('Theme not found');
        return this.prisma.themeCustomizationLink.create({
            data: {
                themeId,
                ...dto,
            },
        });
    }
    async getLinks(themeId, type, group) {
        const where = { themeId };
        if (type)
            where.type = type;
        if (group)
            where.group = group;
        return this.prisma.themeCustomizationLink.findMany({
            where,
            orderBy: { position: 'asc' },
        });
    }
    async getLink(id) {
        const link = await this.prisma.themeCustomizationLink.findUnique({ where: { id } });
        if (!link)
            throw new common_1.NotFoundException('Link not found');
        return link;
    }
    async updateLink(id, dto) {
        await this.getLink(id);
        return this.prisma.themeCustomizationLink.update({
            where: { id },
            data: dto,
        });
    }
    async deleteLink(id) {
        await this.getLink(id);
        return this.prisma.themeCustomizationLink.delete({ where: { id } });
    }
    async reorderLinks(themeId, linkIds) {
        const updates = linkIds.map((id, index) => this.prisma.themeCustomizationLink.update({
            where: { id },
            data: { position: index },
        }));
        return Promise.all(updates);
    }
};
exports.ThemeCustomizationService = ThemeCustomizationService;
exports.ThemeCustomizationService = ThemeCustomizationService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], ThemeCustomizationService);


/***/ }),
/* 146 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e, _f, _g;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ThemeCustomizationController = void 0;
const common_1 = __webpack_require__(2);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const theme_customization_service_1 = __webpack_require__(145);
const create_theme_customization_image_dto_1 = __webpack_require__(147);
const create_theme_customization_block_dto_1 = __webpack_require__(148);
const create_theme_customization_link_dto_1 = __webpack_require__(149);
let ThemeCustomizationController = class ThemeCustomizationController {
    constructor(service) {
        this.service = service;
    }
    createImage(themeId, dto) {
        return this.service.createImage(themeId, dto);
    }
    getImages(themeId, type) {
        return this.service.getImages(themeId, type);
    }
    getImage(id) {
        return this.service.getImage(id);
    }
    updateImage(id, dto) {
        return this.service.updateImage(id, dto);
    }
    deleteImage(id) {
        return this.service.deleteImage(id);
    }
    reorderImages(themeId, body) {
        return this.service.reorderImages(themeId, body.imageIds);
    }
    createBlock(themeId, dto) {
        return this.service.createBlock(themeId, dto);
    }
    getBlocks(themeId, type) {
        return this.service.getBlocks(themeId, type);
    }
    getBlock(id) {
        return this.service.getBlock(id);
    }
    updateBlock(id, dto) {
        return this.service.updateBlock(id, dto);
    }
    deleteBlock(id) {
        return this.service.deleteBlock(id);
    }
    reorderBlocks(themeId, body) {
        return this.service.reorderBlocks(themeId, body.blockIds);
    }
    createLink(themeId, dto) {
        return this.service.createLink(themeId, dto);
    }
    getLinks(themeId, type, group) {
        return this.service.getLinks(themeId, type, group);
    }
    getLink(id) {
        return this.service.getLink(id);
    }
    updateLink(id, dto) {
        return this.service.updateLink(id, dto);
    }
    deleteLink(id) {
        return this.service.deleteLink(id);
    }
    reorderLinks(themeId, body) {
        return this.service.reorderLinks(themeId, body.linkIds);
    }
};
exports.ThemeCustomizationController = ThemeCustomizationController;
__decorate([
    (0, common_1.Post)('images/:themeId'),
    (0, roles_decorator_1.Roles)('ADMIN', 'EDITOR'),
    __param(0, (0, common_1.Param)('themeId')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_b = typeof create_theme_customization_image_dto_1.CreateThemeCustomizationImageDto !== "undefined" && create_theme_customization_image_dto_1.CreateThemeCustomizationImageDto) === "function" ? _b : Object]),
    __metadata("design:returntype", void 0)
], ThemeCustomizationController.prototype, "createImage", null);
__decorate([
    (0, common_1.Get)('images/:themeId'),
    __param(0, (0, common_1.Param)('themeId')),
    __param(1, (0, common_1.Query)('type')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", void 0)
], ThemeCustomizationController.prototype, "getImages", null);
__decorate([
    (0, common_1.Get)('images/detail/:id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], ThemeCustomizationController.prototype, "getImage", null);
__decorate([
    (0, common_1.Put)('images/:id'),
    (0, roles_decorator_1.Roles)('ADMIN', 'EDITOR'),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_c = typeof create_theme_customization_image_dto_1.UpdateThemeCustomizationImageDto !== "undefined" && create_theme_customization_image_dto_1.UpdateThemeCustomizationImageDto) === "function" ? _c : Object]),
    __metadata("design:returntype", void 0)
], ThemeCustomizationController.prototype, "updateImage", null);
__decorate([
    (0, common_1.Delete)('images/:id'),
    (0, roles_decorator_1.Roles)('ADMIN', 'EDITOR'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], ThemeCustomizationController.prototype, "deleteImage", null);
__decorate([
    (0, common_1.Post)('images/:themeId/reorder'),
    (0, roles_decorator_1.Roles)('ADMIN', 'EDITOR'),
    __param(0, (0, common_1.Param)('themeId')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", void 0)
], ThemeCustomizationController.prototype, "reorderImages", null);
__decorate([
    (0, common_1.Post)('blocks/:themeId'),
    (0, roles_decorator_1.Roles)('ADMIN', 'EDITOR'),
    __param(0, (0, common_1.Param)('themeId')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_d = typeof create_theme_customization_block_dto_1.CreateThemeCustomizationBlockDto !== "undefined" && create_theme_customization_block_dto_1.CreateThemeCustomizationBlockDto) === "function" ? _d : Object]),
    __metadata("design:returntype", void 0)
], ThemeCustomizationController.prototype, "createBlock", null);
__decorate([
    (0, common_1.Get)('blocks/:themeId'),
    __param(0, (0, common_1.Param)('themeId')),
    __param(1, (0, common_1.Query)('type')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", void 0)
], ThemeCustomizationController.prototype, "getBlocks", null);
__decorate([
    (0, common_1.Get)('blocks/detail/:id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], ThemeCustomizationController.prototype, "getBlock", null);
__decorate([
    (0, common_1.Put)('blocks/:id'),
    (0, roles_decorator_1.Roles)('ADMIN', 'EDITOR'),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_e = typeof create_theme_customization_block_dto_1.UpdateThemeCustomizationBlockDto !== "undefined" && create_theme_customization_block_dto_1.UpdateThemeCustomizationBlockDto) === "function" ? _e : Object]),
    __metadata("design:returntype", void 0)
], ThemeCustomizationController.prototype, "updateBlock", null);
__decorate([
    (0, common_1.Delete)('blocks/:id'),
    (0, roles_decorator_1.Roles)('ADMIN', 'EDITOR'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], ThemeCustomizationController.prototype, "deleteBlock", null);
__decorate([
    (0, common_1.Post)('blocks/:themeId/reorder'),
    (0, roles_decorator_1.Roles)('ADMIN', 'EDITOR'),
    __param(0, (0, common_1.Param)('themeId')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", void 0)
], ThemeCustomizationController.prototype, "reorderBlocks", null);
__decorate([
    (0, common_1.Post)('links/:themeId'),
    (0, roles_decorator_1.Roles)('ADMIN', 'EDITOR'),
    __param(0, (0, common_1.Param)('themeId')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_f = typeof create_theme_customization_link_dto_1.CreateThemeCustomizationLinkDto !== "undefined" && create_theme_customization_link_dto_1.CreateThemeCustomizationLinkDto) === "function" ? _f : Object]),
    __metadata("design:returntype", void 0)
], ThemeCustomizationController.prototype, "createLink", null);
__decorate([
    (0, common_1.Get)('links/:themeId'),
    __param(0, (0, common_1.Param)('themeId')),
    __param(1, (0, common_1.Query)('type')),
    __param(2, (0, common_1.Query)('group')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, String]),
    __metadata("design:returntype", void 0)
], ThemeCustomizationController.prototype, "getLinks", null);
__decorate([
    (0, common_1.Get)('links/detail/:id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], ThemeCustomizationController.prototype, "getLink", null);
__decorate([
    (0, common_1.Put)('links/:id'),
    (0, roles_decorator_1.Roles)('ADMIN', 'EDITOR'),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_g = typeof create_theme_customization_link_dto_1.UpdateThemeCustomizationLinkDto !== "undefined" && create_theme_customization_link_dto_1.UpdateThemeCustomizationLinkDto) === "function" ? _g : Object]),
    __metadata("design:returntype", void 0)
], ThemeCustomizationController.prototype, "updateLink", null);
__decorate([
    (0, common_1.Delete)('links/:id'),
    (0, roles_decorator_1.Roles)('ADMIN', 'EDITOR'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], ThemeCustomizationController.prototype, "deleteLink", null);
__decorate([
    (0, common_1.Post)('links/:themeId/reorder'),
    (0, roles_decorator_1.Roles)('ADMIN', 'EDITOR'),
    __param(0, (0, common_1.Param)('themeId')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", void 0)
], ThemeCustomizationController.prototype, "reorderLinks", null);
exports.ThemeCustomizationController = ThemeCustomizationController = __decorate([
    (0, common_1.Controller)('api/theme-customization'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof theme_customization_service_1.ThemeCustomizationService !== "undefined" && theme_customization_service_1.ThemeCustomizationService) === "function" ? _a : Object])
], ThemeCustomizationController);


/***/ }),
/* 147 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UpdateThemeCustomizationImageDto = exports.CreateThemeCustomizationImageDto = void 0;
const class_validator_1 = __webpack_require__(59);
class CreateThemeCustomizationImageDto {
}
exports.CreateThemeCustomizationImageDto = CreateThemeCustomizationImageDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], CreateThemeCustomizationImageDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], CreateThemeCustomizationImageDto.prototype, "type", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], CreateThemeCustomizationImageDto.prototype, "url", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationImageDto.prototype, "altText", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationImageDto.prototype, "title", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationImageDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Number)
], CreateThemeCustomizationImageDto.prototype, "width", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Number)
], CreateThemeCustomizationImageDto.prototype, "height", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationImageDto.prototype, "mimeType", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Number)
], CreateThemeCustomizationImageDto.prototype, "fileSize", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationImageDto.prototype, "section", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Number)
], CreateThemeCustomizationImageDto.prototype, "position", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_a = typeof Record !== "undefined" && Record) === "function" ? _a : Object)
], CreateThemeCustomizationImageDto.prototype, "customData", void 0);
class UpdateThemeCustomizationImageDto {
}
exports.UpdateThemeCustomizationImageDto = UpdateThemeCustomizationImageDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationImageDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationImageDto.prototype, "type", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationImageDto.prototype, "url", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationImageDto.prototype, "altText", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationImageDto.prototype, "title", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationImageDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Number)
], UpdateThemeCustomizationImageDto.prototype, "width", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Number)
], UpdateThemeCustomizationImageDto.prototype, "height", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationImageDto.prototype, "mimeType", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Number)
], UpdateThemeCustomizationImageDto.prototype, "fileSize", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationImageDto.prototype, "section", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Number)
], UpdateThemeCustomizationImageDto.prototype, "position", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_b = typeof Record !== "undefined" && Record) === "function" ? _b : Object)
], UpdateThemeCustomizationImageDto.prototype, "customData", void 0);


/***/ }),
/* 148 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b, _c, _d;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UpdateThemeCustomizationBlockDto = exports.CreateThemeCustomizationBlockDto = void 0;
const class_validator_1 = __webpack_require__(59);
class CreateThemeCustomizationBlockDto {
}
exports.CreateThemeCustomizationBlockDto = CreateThemeCustomizationBlockDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], CreateThemeCustomizationBlockDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], CreateThemeCustomizationBlockDto.prototype, "type", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationBlockDto.prototype, "title", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationBlockDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationBlockDto.prototype, "content", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_a = typeof Record !== "undefined" && Record) === "function" ? _a : Object)
], CreateThemeCustomizationBlockDto.prototype, "richContent", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationBlockDto.prototype, "backgroundColor", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationBlockDto.prototype, "textColor", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationBlockDto.prototype, "customCSS", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationBlockDto.prototype, "layout", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Number)
], CreateThemeCustomizationBlockDto.prototype, "columns", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationBlockDto.prototype, "padding", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationBlockDto.prototype, "margin", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationBlockDto.prototype, "backgroundImage", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationBlockDto.prototype, "featuredImage", void 0);
__decorate([
    (0, class_validator_1.IsBoolean)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Boolean)
], CreateThemeCustomizationBlockDto.prototype, "isVisible", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Number)
], CreateThemeCustomizationBlockDto.prototype, "position", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_b = typeof Record !== "undefined" && Record) === "function" ? _b : Object)
], CreateThemeCustomizationBlockDto.prototype, "customData", void 0);
class UpdateThemeCustomizationBlockDto {
}
exports.UpdateThemeCustomizationBlockDto = UpdateThemeCustomizationBlockDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationBlockDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationBlockDto.prototype, "type", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationBlockDto.prototype, "title", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationBlockDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationBlockDto.prototype, "content", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_c = typeof Record !== "undefined" && Record) === "function" ? _c : Object)
], UpdateThemeCustomizationBlockDto.prototype, "richContent", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationBlockDto.prototype, "backgroundColor", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationBlockDto.prototype, "textColor", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationBlockDto.prototype, "customCSS", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationBlockDto.prototype, "layout", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Number)
], UpdateThemeCustomizationBlockDto.prototype, "columns", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationBlockDto.prototype, "padding", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationBlockDto.prototype, "margin", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationBlockDto.prototype, "backgroundImage", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationBlockDto.prototype, "featuredImage", void 0);
__decorate([
    (0, class_validator_1.IsBoolean)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Boolean)
], UpdateThemeCustomizationBlockDto.prototype, "isVisible", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Number)
], UpdateThemeCustomizationBlockDto.prototype, "position", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_d = typeof Record !== "undefined" && Record) === "function" ? _d : Object)
], UpdateThemeCustomizationBlockDto.prototype, "customData", void 0);


/***/ }),
/* 149 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UpdateThemeCustomizationLinkDto = exports.CreateThemeCustomizationLinkDto = void 0;
const class_validator_1 = __webpack_require__(59);
class CreateThemeCustomizationLinkDto {
}
exports.CreateThemeCustomizationLinkDto = CreateThemeCustomizationLinkDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], CreateThemeCustomizationLinkDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], CreateThemeCustomizationLinkDto.prototype, "type", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], CreateThemeCustomizationLinkDto.prototype, "label", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], CreateThemeCustomizationLinkDto.prototype, "url", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationLinkDto.prototype, "icon", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationLinkDto.prototype, "target", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationLinkDto.prototype, "rel", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationLinkDto.prototype, "title", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationLinkDto.prototype, "className", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationLinkDto.prototype, "customCSS", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateThemeCustomizationLinkDto.prototype, "group", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Number)
], CreateThemeCustomizationLinkDto.prototype, "position", void 0);
__decorate([
    (0, class_validator_1.IsBoolean)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Boolean)
], CreateThemeCustomizationLinkDto.prototype, "isVisible", void 0);
__decorate([
    (0, class_validator_1.IsBoolean)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Boolean)
], CreateThemeCustomizationLinkDto.prototype, "isActive", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_a = typeof Record !== "undefined" && Record) === "function" ? _a : Object)
], CreateThemeCustomizationLinkDto.prototype, "customData", void 0);
class UpdateThemeCustomizationLinkDto {
}
exports.UpdateThemeCustomizationLinkDto = UpdateThemeCustomizationLinkDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationLinkDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationLinkDto.prototype, "type", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationLinkDto.prototype, "label", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationLinkDto.prototype, "url", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationLinkDto.prototype, "icon", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationLinkDto.prototype, "target", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationLinkDto.prototype, "rel", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationLinkDto.prototype, "title", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationLinkDto.prototype, "className", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationLinkDto.prototype, "customCSS", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateThemeCustomizationLinkDto.prototype, "group", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Number)
], UpdateThemeCustomizationLinkDto.prototype, "position", void 0);
__decorate([
    (0, class_validator_1.IsBoolean)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Boolean)
], UpdateThemeCustomizationLinkDto.prototype, "isVisible", void 0);
__decorate([
    (0, class_validator_1.IsBoolean)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Boolean)
], UpdateThemeCustomizationLinkDto.prototype, "isActive", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_b = typeof Record !== "undefined" && Record) === "function" ? _b : Object)
], UpdateThemeCustomizationLinkDto.prototype, "customData", void 0);


/***/ }),
/* 150 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 MarketplaceService_1;
var _a, _b, _c;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.MarketplaceService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const themes_service_1 = __webpack_require__(129);
const email_service_1 = __webpack_require__(50);
const path = __webpack_require__(3);
const fs = __webpack_require__(24);
let MarketplaceService = MarketplaceService_1 = class MarketplaceService {
    constructor(prisma, themesService, emailService) {
        this.prisma = prisma;
        this.themesService = themesService;
        this.emailService = emailService;
        this.logger = new common_1.Logger(MarketplaceService_1.name);
        this.uploadsDir = path.join(process.cwd(), 'uploads', 'marketplace');
        this.thumbnailsDir = path.join(process.cwd(), 'uploads', 'marketplace', 'thumbnails');
        this.ensureUploadDir();
    }
    async ensureUploadDir() {
        try {
            await fs.mkdir(this.uploadsDir, { recursive: true });
            await fs.mkdir(this.thumbnailsDir, { recursive: true });
        }
        catch (error) {
            console.error('Failed to create marketplace uploads directory:', error);
        }
    }
    async findAll(query) {
        const { category, search, status = 'approved', featured, sortBy = 'downloads', page = 1, limit = 20, } = query;
        const where = {};
        if (status) {
            where.status = status;
        }
        if (category && category !== 'all') {
            where.category = category;
        }
        if (featured !== undefined) {
            where.isFeatured = featured;
        }
        if (search) {
            where.OR = [
                { name: { contains: search, mode: 'insensitive' } },
                { description: { contains: search, mode: 'insensitive' } },
                { author: { contains: search, mode: 'insensitive' } },
            ];
        }
        let orderBy = {};
        switch (sortBy) {
            case 'downloads':
                orderBy = { downloads: 'desc' };
                break;
            case 'rating':
                orderBy = { rating: 'desc' };
                break;
            case 'newest':
                orderBy = { createdAt: 'desc' };
                break;
            case 'name':
                orderBy = { name: 'asc' };
                break;
            default:
                orderBy = { downloads: 'desc' };
        }
        const [themes, total] = await Promise.all([
            this.prisma.marketplaceTheme.findMany({
                where,
                orderBy,
                skip: (page - 1) * limit,
                take: limit,
                include: {
                    submittedBy: { select: { id: true, name: true, avatar: true } },
                },
            }),
            this.prisma.marketplaceTheme.count({ where }),
        ]);
        return {
            themes,
            pagination: {
                page,
                limit,
                total,
                totalPages: Math.ceil(total / limit),
            },
        };
    }
    async getFeatured(limit = 6) {
        return this.prisma.marketplaceTheme.findMany({
            where: { status: 'approved', isFeatured: true },
            orderBy: { featuredOrder: 'asc' },
            take: limit,
            include: { submittedBy: { select: { id: true, name: true, avatar: true } } },
        });
    }
    async findById(id) {
        const theme = await this.prisma.marketplaceTheme.findUnique({
            where: { id },
            include: {
                submittedBy: { select: { id: true, name: true, avatar: true } },
                ratings: {
                    include: { user: { select: { id: true, name: true, avatar: true } } },
                    orderBy: { createdAt: 'desc' },
                    take: 10,
                },
            },
        });
        if (!theme)
            throw new common_1.NotFoundException('Theme not found');
        return theme;
    }
    async findBySlug(slug) {
        const theme = await this.prisma.marketplaceTheme.findUnique({
            where: { slug },
            include: {
                submittedBy: { select: { id: true, name: true, avatar: true } },
                ratings: {
                    include: { user: { select: { id: true, name: true, avatar: true } } },
                    orderBy: { createdAt: 'desc' },
                    take: 10,
                },
            },
        });
        if (!theme)
            throw new common_1.NotFoundException('Theme not found');
        return theme;
    }
    async submitTheme(dto, files, userId) {
        const { themeFile, thumbnailFile } = files;
        const slug = dto.name
            .toLowerCase()
            .replace(/[^a-z0-9]+/g, '-')
            .replace(/^-|-$/g, '');
        const existing = await this.prisma.marketplaceTheme.findUnique({ where: { slug } });
        if (existing) {
            throw new common_1.BadRequestException(`Theme "${dto.name}" already exists in marketplace`);
        }
        const validation = await this.themesService.validateTheme(themeFile);
        if (!validation.valid) {
            throw new common_1.BadRequestException({
                message: 'Invalid theme package',
                errors: validation.errors,
            });
        }
        const fileName = `${slug}-${Date.now()}.zip`;
        const filePath = path.join(this.uploadsDir, fileName);
        await fs.writeFile(filePath, themeFile.buffer);
        const stats = await fs.stat(filePath);
        let thumbnailUrl = validation.themeConfig?.thumbnail || null;
        if (thumbnailFile) {
            const ext = path.extname(thumbnailFile.originalname) || '.jpg';
            const thumbnailName = `${slug}-${Date.now()}${ext}`;
            const thumbnailPath = path.join(this.thumbnailsDir, thumbnailName);
            await fs.writeFile(thumbnailPath, thumbnailFile.buffer);
            thumbnailUrl = `/uploads/marketplace/thumbnails/${thumbnailName}`;
        }
        const theme = await this.prisma.marketplaceTheme.create({
            data: {
                name: dto.name,
                slug,
                description: dto.description,
                longDescription: dto.longDescription,
                version: dto.version,
                author: dto.author,
                authorEmail: dto.authorEmail,
                authorUrl: dto.authorUrl,
                category: dto.category || 'blog',
                tags: dto.tags || [],
                features: dto.features || [],
                demoUrl: dto.demoUrl,
                repositoryUrl: dto.repositoryUrl,
                licenseType: dto.licenseType || 'GPL-2.0',
                downloadUrl: `/uploads/marketplace/${fileName}`,
                thumbnailUrl,
                fileSize: stats.size,
                status: 'pending',
                submittedById: userId,
            },
            include: { submittedBy: { select: { id: true, name: true } } },
        });
        return theme;
    }
    async installTheme(id) {
        const theme = await this.findById(id);
        if (theme.status !== 'approved') {
            throw new common_1.BadRequestException('This theme is not approved for installation');
        }
        if (!theme.downloadUrl) {
            throw new common_1.BadRequestException('Theme package not available');
        }
        const filePath = path.join(process.cwd(), theme.downloadUrl);
        const fileBuffer = await fs.readFile(filePath);
        const mockFile = {
            buffer: fileBuffer,
            originalname: `${theme.slug}.zip`,
            fieldname: 'file',
            encoding: '7bit',
            mimetype: 'application/zip',
            size: fileBuffer.length,
            destination: '',
            filename: '',
            path: '',
            stream: null,
        };
        const installed = await this.themesService.uploadTheme(mockFile);
        await this.prisma.marketplaceTheme.update({
            where: { id },
            data: { downloads: { increment: 1 } },
        });
        return installed;
    }
    async rateTheme(themeId, userId, rating, review) {
        if (rating < 1 || rating > 5) {
            throw new common_1.BadRequestException('Rating must be between 1 and 5');
        }
        const ratingRecord = await this.prisma.marketplaceThemeRating.upsert({
            where: { themeId_userId: { themeId, userId } },
            update: { rating, review },
            create: { themeId, userId, rating, review },
        });
        const stats = await this.prisma.marketplaceThemeRating.aggregate({
            where: { themeId },
            _avg: { rating: true },
            _count: { rating: true },
        });
        await this.prisma.marketplaceTheme.update({
            where: { id: themeId },
            data: { rating: stats._avg.rating || 0, ratingCount: stats._count.rating },
        });
        return ratingRecord;
    }
    async approveTheme(id, approverId) {
        const theme = await this.prisma.marketplaceTheme.update({
            where: { id },
            data: { status: 'approved', approvedById: approverId, approvedAt: new Date() },
            include: { submittedBy: { select: { id: true, name: true, email: true } } },
        });
        await this.sendApprovalEmail(theme);
        return theme;
    }
    async rejectTheme(id, approverId, reason) {
        const theme = await this.prisma.marketplaceTheme.update({
            where: { id },
            data: { status: 'rejected', approvedById: approverId, rejectionReason: reason },
            include: { submittedBy: { select: { id: true, name: true, email: true } } },
        });
        await this.sendRejectionEmail(theme, reason);
        return theme;
    }
    async bulkApprove(ids, approverId) {
        const results = await Promise.allSettled(ids.map((id) => this.approveTheme(id, approverId)));
        const succeeded = results.filter((r) => r.status === 'fulfilled').length;
        const failed = results.filter((r) => r.status === 'rejected').length;
        return { succeeded, failed, total: ids.length };
    }
    async bulkReject(ids, approverId, reason) {
        const results = await Promise.allSettled(ids.map((id) => this.rejectTheme(id, approverId, reason)));
        const succeeded = results.filter((r) => r.status === 'fulfilled').length;
        const failed = results.filter((r) => r.status === 'rejected').length;
        return { succeeded, failed, total: ids.length };
    }
    async bulkDelete(ids) {
        const results = await Promise.allSettled(ids.map((id) => this.deleteTheme(id)));
        const succeeded = results.filter((r) => r.status === 'fulfilled').length;
        const failed = results.filter((r) => r.status === 'rejected').length;
        return { succeeded, failed, total: ids.length };
    }
    async sendApprovalEmail(theme) {
        if (!theme.submittedBy?.email)
            return;
        const html = `
      <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
        <div style="background: linear-gradient(135deg, #10b981 0%, #059669 100%); padding: 30px; border-radius: 12px 12px 0 0;">
          <h1 style="color: white; margin: 0; font-size: 24px;">🎉 Theme Approved!</h1>
        </div>
        <div style="background: #f8fafc; padding: 30px; border-radius: 0 0 12px 12px;">
          <p style="color: #334155; font-size: 16px; line-height: 1.6;">
            Hi ${theme.submittedBy.name || 'Developer'},
          </p>
          <p style="color: #334155; font-size: 16px; line-height: 1.6;">
            Great news! Your theme <strong>"${theme.name}"</strong> has been approved and is now live on the marketplace!
          </p>
          <div style="background: white; padding: 20px; border-radius: 8px; margin: 20px 0; border: 1px solid #e2e8f0;">
            <p style="margin: 0 0 10px 0;"><strong>Theme:</strong> ${theme.name}</p>
            <p style="margin: 0 0 10px 0;"><strong>Version:</strong> ${theme.version}</p>
            <p style="margin: 0;"><strong>Category:</strong> ${theme.category}</p>
          </div>
          <p style="color: #64748b; font-size: 14px;">
            Users can now discover, install, and rate your theme. Thank you for contributing to our marketplace!
          </p>
        </div>
      </div>
    `;
        try {
            await this.emailService.send({
                to: theme.submittedBy.email,
                toName: theme.submittedBy.name,
                subject: `🎉 Your theme "${theme.name}" has been approved!`,
                html,
                recipientId: theme.submittedBy.id,
                metadata: { type: 'theme_approved', themeId: theme.id },
            });
            this.logger.log(`Approval email sent to ${theme.submittedBy.email} for theme ${theme.name}`);
        }
        catch (error) {
            this.logger.error(`Failed to send approval email: ${error.message}`);
        }
    }
    async sendRejectionEmail(theme, reason) {
        if (!theme.submittedBy?.email)
            return;
        const html = `
      <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
        <div style="background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); padding: 30px; border-radius: 12px 12px 0 0;">
          <h1 style="color: white; margin: 0; font-size: 24px;">Theme Review Update</h1>
        </div>
        <div style="background: #f8fafc; padding: 30px; border-radius: 0 0 12px 12px;">
          <p style="color: #334155; font-size: 16px; line-height: 1.6;">
            Hi ${theme.submittedBy.name || 'Developer'},
          </p>
          <p style="color: #334155; font-size: 16px; line-height: 1.6;">
            We've reviewed your theme <strong>"${theme.name}"</strong> and unfortunately, it wasn't approved at this time.
          </p>
          <div style="background: #fef3c7; padding: 20px; border-radius: 8px; margin: 20px 0; border: 1px solid #fcd34d;">
            <p style="margin: 0 0 10px 0; color: #92400e;"><strong>Reason:</strong></p>
            <p style="margin: 0; color: #92400e;">${reason}</p>
          </div>
          <p style="color: #334155; font-size: 16px; line-height: 1.6;">
            Please review the feedback and feel free to submit an updated version addressing the issues mentioned.
          </p>
          <p style="color: #64748b; font-size: 14px;">
            If you have questions, please reach out to our support team.
          </p>
        </div>
      </div>
    `;
        try {
            await this.emailService.send({
                to: theme.submittedBy.email,
                toName: theme.submittedBy.name,
                subject: `Theme "${theme.name}" - Review Update`,
                html,
                recipientId: theme.submittedBy.id,
                metadata: { type: 'theme_rejected', themeId: theme.id },
            });
            this.logger.log(`Rejection email sent to ${theme.submittedBy.email} for theme ${theme.name}`);
        }
        catch (error) {
            this.logger.error(`Failed to send rejection email: ${error.message}`);
        }
    }
    async setFeatured(id, featured, order) {
        return this.prisma.marketplaceTheme.update({
            where: { id },
            data: { isFeatured: featured, featuredOrder: order },
        });
    }
    async deleteTheme(id) {
        const theme = await this.findById(id);
        if (theme.downloadUrl) {
            try {
                const filePath = path.join(process.cwd(), theme.downloadUrl);
                await fs.unlink(filePath);
            }
            catch { }
        }
        return this.prisma.marketplaceTheme.delete({ where: { id } });
    }
    async getStats() {
        const [total, approved, pending, featured, totalDownloads] = await Promise.all([
            this.prisma.marketplaceTheme.count(),
            this.prisma.marketplaceTheme.count({ where: { status: 'approved' } }),
            this.prisma.marketplaceTheme.count({ where: { status: 'pending' } }),
            this.prisma.marketplaceTheme.count({ where: { isFeatured: true } }),
            this.prisma.marketplaceTheme.aggregate({ _sum: { downloads: true } }),
        ]);
        return {
            total,
            approved,
            pending,
            featured,
            totalDownloads: totalDownloads._sum.downloads || 0,
        };
    }
    async getCategories() {
        const categories = await this.prisma.marketplaceTheme.groupBy({
            by: ['category'],
            where: { status: 'approved' },
            _count: { id: true },
        });
        return categories.map((c) => ({ category: c.category, count: c._count.id }));
    }
};
exports.MarketplaceService = MarketplaceService;
exports.MarketplaceService = MarketplaceService = MarketplaceService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof themes_service_1.ThemesService !== "undefined" && themes_service_1.ThemesService) === "function" ? _b : Object, typeof (_c = typeof email_service_1.EmailService !== "undefined" && email_service_1.EmailService) === "function" ? _c : Object])
], MarketplaceService);


/***/ }),
/* 151 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.MarketplaceController = void 0;
const common_1 = __webpack_require__(2);
const platform_express_1 = __webpack_require__(124);
const marketplace_service_1 = __webpack_require__(150);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const client_1 = __webpack_require__(17);
const optional_jwt_auth_guard_1 = __webpack_require__(76);
let MarketplaceController = class MarketplaceController {
    constructor(marketplaceService) {
        this.marketplaceService = marketplaceService;
    }
    findAll(category, search, sortBy, page, limit) {
        return this.marketplaceService.findAll({
            category,
            search,
            status: 'approved',
            sortBy,
            page: page ? parseInt(page) : 1,
            limit: limit ? parseInt(limit) : 20,
        });
    }
    getFeatured(limit) {
        return this.marketplaceService.getFeatured(limit ? parseInt(limit) : 6);
    }
    getStats() {
        return this.marketplaceService.getStats();
    }
    getCategories() {
        return this.marketplaceService.getCategories();
    }
    findById(id) {
        return this.marketplaceService.findById(id);
    }
    findBySlug(slug) {
        return this.marketplaceService.findBySlug(slug);
    }
    submitTheme(files, body, req) {
        const dto = {
            name: body.name,
            description: body.description,
            longDescription: body.longDescription,
            version: body.version || '1.0.0',
            author: body.author || req.user.name,
            authorEmail: body.authorEmail || req.user.email,
            authorUrl: body.authorUrl,
            category: body.category || 'blog',
            tags: body.tags ? JSON.parse(body.tags) : [],
            features: body.features ? JSON.parse(body.features) : [],
            demoUrl: body.demoUrl,
            repositoryUrl: body.repositoryUrl,
            licenseType: body.licenseType,
        };
        if (!files.file?.[0]) {
            throw new Error('Theme file is required');
        }
        return this.marketplaceService.submitTheme(dto, {
            themeFile: files.file[0],
            thumbnailFile: files.thumbnail?.[0],
        }, req.user.id);
    }
    installTheme(id) {
        return this.marketplaceService.installTheme(id);
    }
    rateTheme(id, body, req) {
        return this.marketplaceService.rateTheme(id, req.user.id, body.rating, body.review);
    }
    findAllAdmin(category, search, status, sortBy, page, limit) {
        return this.marketplaceService.findAll({
            category,
            search,
            status: status || undefined,
            sortBy,
            page: page ? parseInt(page) : 1,
            limit: limit ? parseInt(limit) : 20,
        });
    }
    approveTheme(id, req) {
        return this.marketplaceService.approveTheme(id, req.user.id);
    }
    rejectTheme(id, body, req) {
        return this.marketplaceService.rejectTheme(id, req.user.id, body.reason);
    }
    setFeatured(id, body) {
        return this.marketplaceService.setFeatured(id, body.featured, body.order);
    }
    deleteTheme(id) {
        return this.marketplaceService.deleteTheme(id);
    }
    bulkApprove(body, req) {
        return this.marketplaceService.bulkApprove(body.ids, req.user.id);
    }
    bulkReject(body, req) {
        return this.marketplaceService.bulkReject(body.ids, req.user.id, body.reason);
    }
    bulkDelete(body) {
        return this.marketplaceService.bulkDelete(body.ids);
    }
};
exports.MarketplaceController = MarketplaceController;
__decorate([
    (0, common_1.Get)('themes'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Query)('category')),
    __param(1, (0, common_1.Query)('search')),
    __param(2, (0, common_1.Query)('sortBy')),
    __param(3, (0, common_1.Query)('page')),
    __param(4, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, String, String, String]),
    __metadata("design:returntype", void 0)
], MarketplaceController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)('featured'),
    __param(0, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], MarketplaceController.prototype, "getFeatured", null);
__decorate([
    (0, common_1.Get)('stats'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], MarketplaceController.prototype, "getStats", null);
__decorate([
    (0, common_1.Get)('categories'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], MarketplaceController.prototype, "getCategories", null);
__decorate([
    (0, common_1.Get)('themes/:id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], MarketplaceController.prototype, "findById", null);
__decorate([
    (0, common_1.Get)('themes/slug/:slug'),
    __param(0, (0, common_1.Param)('slug')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], MarketplaceController.prototype, "findBySlug", null);
__decorate([
    (0, common_1.Post)('submit'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    (0, common_1.UseInterceptors)((0, platform_express_1.FileFieldsInterceptor)([
        { name: 'file', maxCount: 1 },
        { name: 'thumbnail', maxCount: 1 },
    ])),
    __param(0, (0, common_1.UploadedFiles)()),
    __param(1, (0, common_1.Body)()),
    __param(2, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Object, Object]),
    __metadata("design:returntype", void 0)
], MarketplaceController.prototype, "submitTheme", null);
__decorate([
    (0, common_1.Post)('themes/:id/install'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], MarketplaceController.prototype, "installTheme", null);
__decorate([
    (0, common_1.Post)('themes/:id/rate'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __param(2, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object, Object]),
    __metadata("design:returntype", void 0)
], MarketplaceController.prototype, "rateTheme", null);
__decorate([
    (0, common_1.Get)('admin/themes'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Query)('category')),
    __param(1, (0, common_1.Query)('search')),
    __param(2, (0, common_1.Query)('status')),
    __param(3, (0, common_1.Query)('sortBy')),
    __param(4, (0, common_1.Query)('page')),
    __param(5, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, String, String, String, String]),
    __metadata("design:returntype", void 0)
], MarketplaceController.prototype, "findAllAdmin", null);
__decorate([
    (0, common_1.Post)('admin/themes/:id/approve'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", void 0)
], MarketplaceController.prototype, "approveTheme", null);
__decorate([
    (0, common_1.Post)('admin/themes/:id/reject'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __param(2, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object, Object]),
    __metadata("design:returntype", void 0)
], MarketplaceController.prototype, "rejectTheme", null);
__decorate([
    (0, common_1.Post)('admin/themes/:id/feature'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", void 0)
], MarketplaceController.prototype, "setFeatured", null);
__decorate([
    (0, common_1.Delete)('admin/themes/:id'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], MarketplaceController.prototype, "deleteTheme", null);
__decorate([
    (0, common_1.Post)('admin/bulk/approve'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Object]),
    __metadata("design:returntype", void 0)
], MarketplaceController.prototype, "bulkApprove", null);
__decorate([
    (0, common_1.Post)('admin/bulk/reject'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Object]),
    __metadata("design:returntype", void 0)
], MarketplaceController.prototype, "bulkReject", null);
__decorate([
    (0, common_1.Post)('admin/bulk/delete'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], MarketplaceController.prototype, "bulkDelete", null);
exports.MarketplaceController = MarketplaceController = __decorate([
    (0, common_1.Controller)('api/marketplace'),
    __metadata("design:paramtypes", [typeof (_a = typeof marketplace_service_1.MarketplaceService !== "undefined" && marketplace_service_1.MarketplaceService) === "function" ? _a : Object])
], MarketplaceController);


/***/ }),
/* 152 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.MenusModule = void 0;
const common_1 = __webpack_require__(2);
const prisma_module_1 = __webpack_require__(15);
const menus_controller_1 = __webpack_require__(153);
const menus_service_1 = __webpack_require__(133);
let MenusModule = class MenusModule {
};
exports.MenusModule = MenusModule;
exports.MenusModule = MenusModule = __decorate([
    (0, common_1.Module)({
        imports: [prisma_module_1.PrismaModule],
        controllers: [menus_controller_1.MenusController],
        providers: [menus_service_1.MenusService],
        exports: [menus_service_1.MenusService],
    })
], MenusModule);


/***/ }),
/* 153 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.MenusController = void 0;
const common_1 = __webpack_require__(2);
const menus_service_1 = __webpack_require__(133);
const create_menu_dto_1 = __webpack_require__(154);
const update_menu_dto_1 = __webpack_require__(155);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const client_1 = __webpack_require__(17);
const public_decorator_1 = __webpack_require__(62);
let MenusController = class MenusController {
    constructor(menusService) {
        this.menusService = menusService;
    }
    create(createMenuDto) {
        return this.menusService.create(createMenuDto);
    }
    findAll() {
        return this.menusService.findAll();
    }
    getAvailableLinks() {
        return this.menusService.getAvailableLinks();
    }
    findByLocation(location) {
        return this.menusService.findByLocation(location);
    }
    findOne(id) {
        return this.menusService.findOne(id);
    }
    update(id, updateMenuDto) {
        return this.menusService.update(id, updateMenuDto);
    }
    remove(id) {
        return this.menusService.remove(id);
    }
};
exports.MenusController = MenusController;
__decorate([
    (0, common_1.Post)(),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_b = typeof create_menu_dto_1.CreateMenuDto !== "undefined" && create_menu_dto_1.CreateMenuDto) === "function" ? _b : Object]),
    __metadata("design:returntype", void 0)
], MenusController.prototype, "create", null);
__decorate([
    (0, common_1.Get)(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], MenusController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)('available-links'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], MenusController.prototype, "getAvailableLinks", null);
__decorate([
    (0, public_decorator_1.Public)(),
    (0, common_1.Get)('location/:location'),
    __param(0, (0, common_1.Param)('location')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], MenusController.prototype, "findByLocation", null);
__decorate([
    (0, common_1.Get)(':id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], MenusController.prototype, "findOne", null);
__decorate([
    (0, common_1.Put)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_c = typeof update_menu_dto_1.UpdateMenuDto !== "undefined" && update_menu_dto_1.UpdateMenuDto) === "function" ? _c : Object]),
    __metadata("design:returntype", void 0)
], MenusController.prototype, "update", null);
__decorate([
    (0, common_1.Delete)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], MenusController.prototype, "remove", null);
exports.MenusController = MenusController = __decorate([
    (0, common_1.Controller)('api/menus'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof menus_service_1.MenusService !== "undefined" && menus_service_1.MenusService) === "function" ? _a : Object])
], MenusController);


/***/ }),
/* 154 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CreateMenuDto = exports.CreateMenuItemDto = void 0;
const class_validator_1 = __webpack_require__(59);
const class_transformer_1 = __webpack_require__(95);
class CreateMenuItemDto {
    constructor() {
        this.target = '_self';
        this.type = 'CUSTOM';
        this.order = 0;
    }
}
exports.CreateMenuItemDto = CreateMenuItemDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], CreateMenuItemDto.prototype, "label", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateMenuItemDto.prototype, "url", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateMenuItemDto.prototype, "target", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateMenuItemDto.prototype, "type", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateMenuItemDto.prototype, "pageId", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateMenuItemDto.prototype, "postId", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Number)
], CreateMenuItemDto.prototype, "order", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateMenuItemDto.prototype, "cssClass", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateMenuItemDto.prototype, "icon", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateMenuItemDto.prototype, "parentId", void 0);
class CreateMenuDto {
}
exports.CreateMenuDto = CreateMenuDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], CreateMenuDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], CreateMenuDto.prototype, "location", void 0);
__decorate([
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.ValidateNested)({ each: true }),
    (0, class_transformer_1.Type)(() => CreateMenuItemDto),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], CreateMenuDto.prototype, "items", void 0);


/***/ }),
/* 155 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UpdateMenuDto = exports.UpdateMenuItemDto = void 0;
const class_validator_1 = __webpack_require__(59);
const class_transformer_1 = __webpack_require__(95);
class UpdateMenuItemDto {
}
exports.UpdateMenuItemDto = UpdateMenuItemDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateMenuItemDto.prototype, "id", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateMenuItemDto.prototype, "label", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateMenuItemDto.prototype, "url", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateMenuItemDto.prototype, "target", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateMenuItemDto.prototype, "type", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateMenuItemDto.prototype, "pageId", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateMenuItemDto.prototype, "postId", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Number)
], UpdateMenuItemDto.prototype, "order", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateMenuItemDto.prototype, "cssClass", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateMenuItemDto.prototype, "icon", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateMenuItemDto.prototype, "parentId", void 0);
class UpdateMenuDto {
}
exports.UpdateMenuDto = UpdateMenuDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateMenuDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateMenuDto.prototype, "location", void 0);
__decorate([
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.ValidateNested)({ each: true }),
    (0, class_transformer_1.Type)(() => UpdateMenuItemDto),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], UpdateMenuDto.prototype, "items", void 0);


/***/ }),
/* 156 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 SubscriptionsModule_1;
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SubscriptionsModule = void 0;
const common_1 = __webpack_require__(2);
const subscriptions_controller_1 = __webpack_require__(157);
const subscriptions_service_1 = __webpack_require__(135);
const prisma_module_1 = __webpack_require__(15);
const system_config_service_1 = __webpack_require__(52);
const encryption_service_1 = __webpack_require__(53);
const guards_1 = __webpack_require__(159);
let SubscriptionsModule = SubscriptionsModule_1 = class SubscriptionsModule {
    constructor(subscriptionsService) {
        this.subscriptionsService = subscriptionsService;
        this.logger = new common_1.Logger(SubscriptionsModule_1.name);
    }
    async onModuleInit() {
        try {
            const result = await this.subscriptionsService.seedDefaultPlans();
            if (result.count) {
                this.logger.log(`Seeded ${result.count} default subscription plans`);
            }
        }
        catch (error) {
            this.logger.warn('Could not seed subscription plans:', error.message);
        }
    }
};
exports.SubscriptionsModule = SubscriptionsModule;
exports.SubscriptionsModule = SubscriptionsModule = SubscriptionsModule_1 = __decorate([
    (0, common_1.Module)({
        imports: [prisma_module_1.PrismaModule],
        controllers: [subscriptions_controller_1.SubscriptionsController],
        providers: [
            subscriptions_service_1.SubscriptionsService,
            system_config_service_1.SystemConfigService,
            encryption_service_1.EncryptionService,
            guards_1.SubscriptionGuard,
            guards_1.FeatureGuard,
            guards_1.PlanGuard,
        ],
        exports: [subscriptions_service_1.SubscriptionsService, guards_1.SubscriptionGuard, guards_1.FeatureGuard, guards_1.PlanGuard],
    }),
    __metadata("design:paramtypes", [typeof (_a = typeof subscriptions_service_1.SubscriptionsService !== "undefined" && subscriptions_service_1.SubscriptionsService) === "function" ? _a : Object])
], SubscriptionsModule);


/***/ }),
/* 157 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SubscriptionsController = void 0;
const common_1 = __webpack_require__(2);
const express_1 = __webpack_require__(57);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const client_1 = __webpack_require__(17);
const subscriptions_service_1 = __webpack_require__(135);
const subscription_dto_1 = __webpack_require__(158);
let SubscriptionsController = class SubscriptionsController {
    constructor(subscriptionsService) {
        this.subscriptionsService = subscriptionsService;
    }
    async getPlans() {
        return this.subscriptionsService.getPlans(false);
    }
    async getPlanBySlug(slug) {
        return this.subscriptionsService.getPlanBySlug(slug);
    }
    async handleWebhook(req, signature) {
        if (!req.rawBody) {
            throw new Error('Raw body not available. Ensure rawBody is enabled for this route.');
        }
        return this.subscriptionsService.handleWebhook(req.rawBody, signature);
    }
    async getCurrentSubscription(req) {
        const userId = req.user.id;
        return this.subscriptionsService.getUserSubscription(userId);
    }
    async createCheckout(req, dto) {
        const userId = req.user.id;
        return this.subscriptionsService.createCheckoutSession(userId, dto);
    }
    async getBillingPortal(req) {
        const userId = req.user.id;
        return this.subscriptionsService.createBillingPortalSession(userId);
    }
    async cancelSubscription(req) {
        const userId = req.user.id;
        return this.subscriptionsService.cancelSubscription(userId);
    }
    async hasFeature(req, feature) {
        const userId = req.user.id;
        const hasIt = await this.subscriptionsService.hasFeature(userId, feature);
        return { feature, hasAccess: hasIt };
    }
    async getAdminPlans(includeInactive) {
        return this.subscriptionsService.getPlans(includeInactive === 'true');
    }
    async createPlan(dto) {
        return this.subscriptionsService.createPlan(dto);
    }
    async updatePlan(id, dto) {
        return this.subscriptionsService.updatePlan(id, dto);
    }
    async deletePlan(id) {
        return this.subscriptionsService.deletePlan(id);
    }
    async seedDefaultPlans() {
        return this.subscriptionsService.seedDefaultPlans();
    }
    async activateAllPlans() {
        return this.subscriptionsService.activateAllPlans();
    }
};
exports.SubscriptionsController = SubscriptionsController;
__decorate([
    (0, common_1.Get)('plans'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SubscriptionsController.prototype, "getPlans", null);
__decorate([
    (0, common_1.Get)('plans/:slug'),
    __param(0, (0, common_1.Param)('slug')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], SubscriptionsController.prototype, "getPlanBySlug", null);
__decorate([
    (0, common_1.Post)('webhook'),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Headers)('stripe-signature')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_b = typeof common_1.RawBodyRequest !== "undefined" && common_1.RawBodyRequest) === "function" ? _b : Object, String]),
    __metadata("design:returntype", Promise)
], SubscriptionsController.prototype, "handleWebhook", null);
__decorate([
    (0, common_1.Get)('current'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_c = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _c : Object]),
    __metadata("design:returntype", Promise)
], SubscriptionsController.prototype, "getCurrentSubscription", null);
__decorate([
    (0, common_1.Post)('checkout'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_d = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _d : Object, typeof (_e = typeof subscription_dto_1.CreateCheckoutDto !== "undefined" && subscription_dto_1.CreateCheckoutDto) === "function" ? _e : Object]),
    __metadata("design:returntype", Promise)
], SubscriptionsController.prototype, "createCheckout", null);
__decorate([
    (0, common_1.Post)('portal'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_f = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _f : Object]),
    __metadata("design:returntype", Promise)
], SubscriptionsController.prototype, "getBillingPortal", null);
__decorate([
    (0, common_1.Post)('cancel'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_g = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _g : Object]),
    __metadata("design:returntype", Promise)
], SubscriptionsController.prototype, "cancelSubscription", null);
__decorate([
    (0, common_1.Get)('has-feature/:feature'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Param)('feature')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_h = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _h : Object, String]),
    __metadata("design:returntype", Promise)
], SubscriptionsController.prototype, "hasFeature", null);
__decorate([
    (0, common_1.Get)('admin/plans'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Query)('includeInactive')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], SubscriptionsController.prototype, "getAdminPlans", null);
__decorate([
    (0, common_1.Post)('admin/plans'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_j = typeof subscription_dto_1.CreatePlanDto !== "undefined" && subscription_dto_1.CreatePlanDto) === "function" ? _j : Object]),
    __metadata("design:returntype", Promise)
], SubscriptionsController.prototype, "createPlan", null);
__decorate([
    (0, common_1.Put)('admin/plans/:id'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_k = typeof subscription_dto_1.UpdatePlanDto !== "undefined" && subscription_dto_1.UpdatePlanDto) === "function" ? _k : Object]),
    __metadata("design:returntype", Promise)
], SubscriptionsController.prototype, "updatePlan", null);
__decorate([
    (0, common_1.Delete)('admin/plans/:id'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], SubscriptionsController.prototype, "deletePlan", null);
__decorate([
    (0, common_1.Post)('admin/seed-plans'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SubscriptionsController.prototype, "seedDefaultPlans", null);
__decorate([
    (0, common_1.Post)('admin/activate-all-plans'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SubscriptionsController.prototype, "activateAllPlans", null);
exports.SubscriptionsController = SubscriptionsController = __decorate([
    (0, common_1.Controller)('api/subscriptions'),
    __metadata("design:paramtypes", [typeof (_a = typeof subscriptions_service_1.SubscriptionsService !== "undefined" && subscriptions_service_1.SubscriptionsService) === "function" ? _a : Object])
], SubscriptionsController);


/***/ }),
/* 158 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CreateCheckoutDto = exports.UpdatePlanDto = exports.CreatePlanDto = void 0;
const class_validator_1 = __webpack_require__(59);
class CreatePlanDto {
}
exports.CreatePlanDto = CreatePlanDto;
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreatePlanDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreatePlanDto.prototype, "slug", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreatePlanDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], CreatePlanDto.prototype, "monthlyPrice", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], CreatePlanDto.prototype, "yearlyPrice", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreatePlanDto.prototype, "stripePriceIdMonthly", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreatePlanDto.prototype, "stripePriceIdYearly", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], CreatePlanDto.prototype, "maxUsers", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], CreatePlanDto.prototype, "maxStorageMb", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], CreatePlanDto.prototype, "maxProjects", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], CreatePlanDto.prototype, "maxCourses", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], CreatePlanDto.prototype, "maxProducts", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsArray)(),
    __metadata("design:type", Array)
], CreatePlanDto.prototype, "features", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsBoolean)(),
    __metadata("design:type", Boolean)
], CreatePlanDto.prototype, "isFeatured", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], CreatePlanDto.prototype, "displayOrder", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreatePlanDto.prototype, "badgeText", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], CreatePlanDto.prototype, "trialDays", void 0);
class UpdatePlanDto {
}
exports.UpdatePlanDto = UpdatePlanDto;
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], UpdatePlanDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], UpdatePlanDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], UpdatePlanDto.prototype, "monthlyPrice", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], UpdatePlanDto.prototype, "yearlyPrice", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], UpdatePlanDto.prototype, "stripePriceIdMonthly", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], UpdatePlanDto.prototype, "stripePriceIdYearly", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], UpdatePlanDto.prototype, "maxUsers", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], UpdatePlanDto.prototype, "maxStorageMb", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsArray)(),
    __metadata("design:type", Array)
], UpdatePlanDto.prototype, "features", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsBoolean)(),
    __metadata("design:type", Boolean)
], UpdatePlanDto.prototype, "isActive", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsBoolean)(),
    __metadata("design:type", Boolean)
], UpdatePlanDto.prototype, "isFeatured", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], UpdatePlanDto.prototype, "displayOrder", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], UpdatePlanDto.prototype, "badgeText", void 0);
class CreateCheckoutDto {
}
exports.CreateCheckoutDto = CreateCheckoutDto;
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateCheckoutDto.prototype, "planId", void 0);
__decorate([
    (0, class_validator_1.IsEnum)(['monthly', 'yearly']),
    __metadata("design:type", String)
], CreateCheckoutDto.prototype, "billingCycle", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateCheckoutDto.prototype, "successUrl", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateCheckoutDto.prototype, "cancelUrl", void 0);


/***/ }),
/* 159 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
__exportStar(__webpack_require__(72), exports);
__exportStar(__webpack_require__(160), exports);
__exportStar(__webpack_require__(162), exports);
__exportStar(__webpack_require__(163), exports);


/***/ }),
/* 160 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 SubscriptionGuard_1;
var _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SubscriptionGuard = void 0;
const common_1 = __webpack_require__(2);
const core_1 = __webpack_require__(1);
const prisma_service_1 = __webpack_require__(16);
const subscription_decorator_1 = __webpack_require__(161);
const client_1 = __webpack_require__(17);
let SubscriptionGuard = SubscriptionGuard_1 = class SubscriptionGuard {
    constructor(reflector, prisma) {
        this.reflector = reflector;
        this.prisma = prisma;
        this.logger = new common_1.Logger(SubscriptionGuard_1.name);
    }
    async canActivate(context) {
        const requiresSubscription = this.reflector.getAllAndOverride(subscription_decorator_1.REQUIRES_SUBSCRIPTION_KEY, [context.getHandler(), context.getClass()]);
        if (!requiresSubscription) {
            return true;
        }
        const request = context.switchToHttp().getRequest();
        const user = request.user;
        if (!user) {
            this.logger.warn('SubscriptionGuard: No user found in request');
            throw new common_1.ForbiddenException('Authentication required');
        }
        if (user.role === client_1.UserRole.ADMIN) {
            return true;
        }
        const subscription = await this.prisma.subscription.findUnique({
            where: { userId: user.id },
            include: { plan: true },
        });
        if (!subscription) {
            this.logger.debug(`SubscriptionGuard: No subscription for user ${user.id}`);
            throw new common_1.ForbiddenException('A paid subscription is required to access this feature. Please upgrade your plan.');
        }
        const activeStatuses = ['ACTIVE', 'TRIALING'];
        if (!activeStatuses.includes(subscription.status)) {
            this.logger.debug(`SubscriptionGuard: Inactive subscription status ${subscription.status}`);
            throw new common_1.ForbiddenException(`Your subscription is ${subscription.status.toLowerCase()}. Please update your payment method.`);
        }
        if (Number(subscription.plan.monthlyPrice) === 0) {
            throw new common_1.ForbiddenException('A paid subscription is required to access this feature. Please upgrade your plan.');
        }
        request.subscription = subscription;
        return true;
    }
};
exports.SubscriptionGuard = SubscriptionGuard;
exports.SubscriptionGuard = SubscriptionGuard = SubscriptionGuard_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof core_1.Reflector !== "undefined" && core_1.Reflector) === "function" ? _a : Object, typeof (_b = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _b : Object])
], SubscriptionGuard);


/***/ }),
/* 161 */
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PLAN_SLUGS = exports.SUBSCRIPTION_FEATURES = exports.RequiresSubscription = exports.REQUIRES_SUBSCRIPTION_KEY = exports.RequiresPlan = exports.REQUIRED_PLAN_KEY = exports.RequiresFeature = exports.REQUIRED_FEATURES_KEY = void 0;
const common_1 = __webpack_require__(2);
exports.REQUIRED_FEATURES_KEY = 'requiredFeatures';
const RequiresFeature = (...features) => (0, common_1.SetMetadata)(exports.REQUIRED_FEATURES_KEY, features);
exports.RequiresFeature = RequiresFeature;
exports.REQUIRED_PLAN_KEY = 'requiredPlan';
const RequiresPlan = (...planSlugs) => (0, common_1.SetMetadata)(exports.REQUIRED_PLAN_KEY, planSlugs);
exports.RequiresPlan = RequiresPlan;
exports.REQUIRES_SUBSCRIPTION_KEY = 'requiresSubscription';
const RequiresSubscription = () => (0, common_1.SetMetadata)(exports.REQUIRES_SUBSCRIPTION_KEY, true);
exports.RequiresSubscription = RequiresSubscription;
exports.SUBSCRIPTION_FEATURES = {
    BASIC_CMS: 'basic_cms',
    MEDIA_LIBRARY: 'media_library',
    VIDEO_CALLS: 'video_calls',
    LMS: 'lms',
    ECOMMERCE: 'ecommerce',
    ANALYTICS: 'analytics',
    API_ACCESS: 'api_access',
    PRIORITY_SUPPORT: 'priority_support',
    CUSTOM_DOMAIN: 'custom_domain',
    SLA: 'sla',
    DEDICATED_SUPPORT: 'dedicated_support',
    CUSTOM_INTEGRATIONS: 'custom_integrations',
};
exports.PLAN_SLUGS = {
    FREE: 'free',
    PRO: 'pro',
    BUSINESS: 'business',
    ENTERPRISE: 'enterprise',
};


/***/ }),
/* 162 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 FeatureGuard_1;
var _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.FeatureGuard = void 0;
const common_1 = __webpack_require__(2);
const core_1 = __webpack_require__(1);
const prisma_service_1 = __webpack_require__(16);
const subscription_decorator_1 = __webpack_require__(161);
const client_1 = __webpack_require__(17);
let FeatureGuard = FeatureGuard_1 = class FeatureGuard {
    constructor(reflector, prisma) {
        this.reflector = reflector;
        this.prisma = prisma;
        this.logger = new common_1.Logger(FeatureGuard_1.name);
    }
    async canActivate(context) {
        const requiredFeatures = this.reflector.getAllAndOverride(subscription_decorator_1.REQUIRED_FEATURES_KEY, [
            context.getHandler(),
            context.getClass(),
        ]);
        if (!requiredFeatures || requiredFeatures.length === 0) {
            return true;
        }
        const request = context.switchToHttp().getRequest();
        const user = request.user;
        if (!user) {
            this.logger.warn('FeatureGuard: No user found in request');
            throw new common_1.ForbiddenException('Authentication required');
        }
        if (user.role === client_1.UserRole.ADMIN) {
            return true;
        }
        const subscription = await this.prisma.subscription.findUnique({
            where: { userId: user.id },
            include: { plan: true },
        });
        if (!subscription) {
            this.logger.debug(`FeatureGuard: No subscription for user ${user.id}`);
            throw new common_1.ForbiddenException(`This feature requires a subscription with: ${requiredFeatures.join(', ')}. Please upgrade your plan.`);
        }
        const activeStatuses = ['ACTIVE', 'TRIALING'];
        if (!activeStatuses.includes(subscription.status)) {
            throw new common_1.ForbiddenException(`Your subscription is ${subscription.status.toLowerCase()}. Please update your payment method.`);
        }
        const planFeatures = subscription.plan.features || [];
        const missingFeatures = requiredFeatures.filter((f) => !planFeatures.includes(f));
        if (missingFeatures.length > 0) {
            this.logger.debug(`FeatureGuard: User ${user.id} missing features: ${missingFeatures.join(', ')}`);
            throw new common_1.ForbiddenException(`Your plan does not include: ${missingFeatures.join(', ')}. Please upgrade to access this feature.`);
        }
        request.subscription = subscription;
        return true;
    }
};
exports.FeatureGuard = FeatureGuard;
exports.FeatureGuard = FeatureGuard = FeatureGuard_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof core_1.Reflector !== "undefined" && core_1.Reflector) === "function" ? _a : Object, typeof (_b = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _b : Object])
], FeatureGuard);


/***/ }),
/* 163 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 PlanGuard_1;
var _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PlanGuard = void 0;
const common_1 = __webpack_require__(2);
const core_1 = __webpack_require__(1);
const prisma_service_1 = __webpack_require__(16);
const subscription_decorator_1 = __webpack_require__(161);
const client_1 = __webpack_require__(17);
const PLAN_HIERARCHY = {
    free: 0,
    pro: 1,
    business: 2,
    enterprise: 3,
};
let PlanGuard = PlanGuard_1 = class PlanGuard {
    constructor(reflector, prisma) {
        this.reflector = reflector;
        this.prisma = prisma;
        this.logger = new common_1.Logger(PlanGuard_1.name);
    }
    async canActivate(context) {
        const requiredPlans = this.reflector.getAllAndOverride(subscription_decorator_1.REQUIRED_PLAN_KEY, [
            context.getHandler(),
            context.getClass(),
        ]);
        if (!requiredPlans || requiredPlans.length === 0) {
            return true;
        }
        const request = context.switchToHttp().getRequest();
        const user = request.user;
        if (!user) {
            this.logger.warn('PlanGuard: No user found in request');
            throw new common_1.ForbiddenException('Authentication required');
        }
        if (user.role === client_1.UserRole.ADMIN) {
            return true;
        }
        const subscription = await this.prisma.subscription.findUnique({
            where: { userId: user.id },
            include: { plan: true },
        });
        const userPlan = subscription?.plan?.slug || 'free';
        const userPlanLevel = PLAN_HIERARCHY[userPlan] ?? 0;
        if (subscription) {
            const activeStatuses = ['ACTIVE', 'TRIALING'];
            if (!activeStatuses.includes(subscription.status)) {
                throw new common_1.ForbiddenException(`Your subscription is ${subscription.status.toLowerCase()}. Please update your payment method.`);
            }
        }
        const minRequiredLevel = Math.min(...requiredPlans.map((p) => PLAN_HIERARCHY[p] ?? 999));
        if (userPlanLevel < minRequiredLevel) {
            const requiredPlanNames = requiredPlans.join(' or ');
            this.logger.debug(`PlanGuard: User ${user.id} on ${userPlan} plan, requires ${requiredPlanNames}`);
            throw new common_1.ForbiddenException(`This feature requires a ${requiredPlanNames} plan or higher. Your current plan: ${userPlan}.`);
        }
        if (subscription) {
            request.subscription = subscription;
        }
        return true;
    }
};
exports.PlanGuard = PlanGuard;
exports.PlanGuard = PlanGuard = PlanGuard_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof core_1.Reflector !== "undefined" && core_1.Reflector) === "function" ? _a : Object, typeof (_b = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _b : Object])
], PlanGuard);


/***/ }),
/* 164 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PluginsModule = void 0;
const common_1 = __webpack_require__(2);
const prisma_module_1 = __webpack_require__(15);
const plugins_service_1 = __webpack_require__(165);
const plugins_controller_1 = __webpack_require__(166);
const plugin_loader_service_1 = __webpack_require__(167);
const plugin_marketplace_service_1 = __webpack_require__(168);
const plugin_marketplace_controller_1 = __webpack_require__(169);
const email_module_1 = __webpack_require__(77);
let PluginsModule = class PluginsModule {
};
exports.PluginsModule = PluginsModule;
exports.PluginsModule = PluginsModule = __decorate([
    (0, common_1.Module)({
        imports: [prisma_module_1.PrismaModule, (0, common_1.forwardRef)(() => email_module_1.EmailModule)],
        providers: [plugins_service_1.PluginsService, plugin_loader_service_1.PluginLoaderService, plugin_marketplace_service_1.PluginMarketplaceService],
        controllers: [plugins_controller_1.PluginsController, plugin_marketplace_controller_1.PluginMarketplaceController],
        exports: [plugins_service_1.PluginsService, plugin_loader_service_1.PluginLoaderService, plugin_marketplace_service_1.PluginMarketplaceService],
    })
], PluginsModule);


/***/ }),
/* 165 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PluginsService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const fs = __webpack_require__(24);
const path = __webpack_require__(3);
const AdmZip = __webpack_require__(130);
const REQUIRED_PLUGIN_JSON_FIELDS = ['name', 'version'];
const MAX_PLUGIN_SIZE = 10 * 1024 * 1024;
let PluginsService = class PluginsService {
    constructor(prisma) {
        this.prisma = prisma;
        this.pluginsDir = path.join(process.cwd(), 'plugins');
    }
    async scanPlugins() {
        try {
            const dirs = await fs.readdir(this.pluginsDir);
            const plugins = [];
            for (const dir of dirs) {
                const pluginPath = path.join(this.pluginsDir, dir);
                const stat = await fs.stat(pluginPath);
                if (stat.isDirectory()) {
                    const configPath = path.join(pluginPath, 'plugin.json');
                    try {
                        const configContent = await fs.readFile(configPath, 'utf-8');
                        const config = JSON.parse(configContent);
                        const plugin = await this.prisma.plugin.upsert({
                            where: { slug: dir },
                            update: {
                                name: config.name,
                                version: config.version,
                                author: config.author,
                                description: config.description,
                                config,
                            },
                            create: {
                                name: config.name,
                                slug: dir,
                                version: config.version,
                                author: config.author,
                                description: config.description,
                                path: `/plugins/${dir}`,
                                config,
                            },
                        });
                        plugins.push(plugin);
                    }
                    catch (error) {
                        console.error(`Error loading plugin ${dir}:`, error.message);
                    }
                }
            }
            return plugins;
        }
        catch (error) {
            console.error('Error scanning plugins:', error);
            return [];
        }
    }
    async findAll() {
        return this.prisma.plugin.findMany({
            orderBy: { name: 'asc' },
        });
    }
    async findActive() {
        return this.prisma.plugin.findMany({
            where: { isActive: true },
            orderBy: { name: 'asc' },
        });
    }
    async findById(id) {
        const plugin = await this.prisma.plugin.findUnique({
            where: { id },
        });
        if (!plugin) {
            throw new common_1.NotFoundException('Plugin not found');
        }
        return plugin;
    }
    async activate(id) {
        return this.prisma.plugin.update({
            where: { id },
            data: { isActive: true },
        });
    }
    async deactivate(id) {
        return this.prisma.plugin.update({
            where: { id },
            data: { isActive: false },
        });
    }
    async updateSettings(id, settings) {
        return this.prisma.plugin.update({
            where: { id },
            data: { settings },
        });
    }
    getPluginPath(pluginSlug) {
        return path.join(this.pluginsDir, pluginSlug);
    }
    validatePluginZip(file) {
        const errors = [];
        const warnings = [];
        if (!file.originalname.endsWith('.zip')) {
            errors.push('Only ZIP files are allowed');
            return { valid: false, errors, warnings };
        }
        if (file.size > MAX_PLUGIN_SIZE) {
            errors.push(`File size exceeds maximum allowed size of ${MAX_PLUGIN_SIZE / 1024 / 1024}MB`);
            return { valid: false, errors, warnings };
        }
        try {
            const zip = new AdmZip(file.buffer);
            const zipEntries = zip.getEntries();
            const entryNames = zipEntries
                .filter((e) => !e.entryName.includes('__MACOSX'))
                .map((e) => e.entryName);
            let rootFolder;
            const dirs = entryNames.filter((name) => name.endsWith('/') && !name.includes('/', 0));
            if (dirs.length === 1) {
                rootFolder = dirs[0].replace('/', '');
            }
            const pluginJsonPath = rootFolder
                ? entryNames.find((name) => name === `${rootFolder}/plugin.json`)
                : entryNames.find((name) => name === 'plugin.json');
            if (!pluginJsonPath) {
                errors.push('plugin.json not found in the archive');
                return { valid: false, errors, warnings };
            }
            const pluginJsonEntry = zip.getEntry(pluginJsonPath);
            if (!pluginJsonEntry) {
                errors.push('Could not read plugin.json');
                return { valid: false, errors, warnings };
            }
            let pluginConfig;
            try {
                pluginConfig = JSON.parse(pluginJsonEntry.getData().toString('utf8'));
            }
            catch (_e) {
                errors.push('plugin.json is not valid JSON');
                return { valid: false, errors, warnings };
            }
            for (const field of REQUIRED_PLUGIN_JSON_FIELDS) {
                if (!pluginConfig[field]) {
                    errors.push(`plugin.json missing required field: ${field}`);
                }
            }
            const pluginSlug = rootFolder ||
                path
                    .basename(file.originalname, '.zip')
                    .toLowerCase()
                    .replace(/[^a-z0-9-]/g, '-');
            const entryFile = pluginConfig.entry || 'index.js';
            const entryPath = rootFolder ? `${rootFolder}/${entryFile}` : entryFile;
            if (!entryNames.some((name) => name === entryPath)) {
                warnings.push(`Entry file "${entryFile}" not found - plugin may not load correctly`);
            }
            if (!pluginConfig.hooks || pluginConfig.hooks.length === 0) {
                warnings.push('No hooks defined - plugin may not do anything');
            }
            return {
                valid: errors.length === 0,
                errors,
                warnings,
                pluginConfig,
                pluginSlug,
                rootFolder,
            };
        }
        catch (error) {
            errors.push('Failed to read ZIP file: ' + error.message);
            return { valid: false, errors, warnings };
        }
    }
    async validatePlugin(file) {
        const validation = this.validatePluginZip(file);
        if (validation.valid && validation.pluginSlug) {
            const existingPlugin = await this.prisma.plugin.findUnique({
                where: { slug: validation.pluginSlug },
            });
            if (existingPlugin) {
                validation.errors.push(`Plugin "${validation.pluginSlug}" already exists. Please delete it first or use a different folder name.`);
                validation.valid = false;
                return { ...validation, exists: true };
            }
        }
        return validation;
    }
    async uploadPlugin(file) {
        const validation = await this.validatePlugin(file);
        if (!validation.valid) {
            throw new common_1.BadRequestException({
                message: 'Plugin validation failed',
                errors: validation.errors,
                warnings: validation.warnings,
            });
        }
        const { pluginConfig, pluginSlug, rootFolder } = validation;
        try {
            const zip = new AdmZip(file.buffer);
            const extractPath = path.join(this.pluginsDir, pluginSlug);
            await fs.mkdir(extractPath, { recursive: true });
            if (rootFolder) {
                const entries = zip
                    .getEntries()
                    .filter((e) => !e.entryName.includes('__MACOSX') && e.entryName.startsWith(rootFolder + '/'));
                for (const entry of entries) {
                    const relativePath = entry.entryName.substring(rootFolder.length + 1);
                    if (!relativePath)
                        continue;
                    const targetPath = path.join(extractPath, relativePath);
                    if (entry.isDirectory) {
                        await fs.mkdir(targetPath, { recursive: true });
                    }
                    else {
                        await fs.mkdir(path.dirname(targetPath), { recursive: true });
                        await fs.writeFile(targetPath, entry.getData());
                    }
                }
            }
            else {
                zip.extractAllTo(extractPath, true);
            }
            const plugin = await this.prisma.plugin.create({
                data: {
                    name: pluginConfig.name,
                    slug: pluginSlug,
                    version: pluginConfig.version,
                    author: pluginConfig.author || 'Unknown',
                    description: pluginConfig.description || '',
                    path: `/plugins/${pluginSlug}`,
                    config: pluginConfig,
                },
            });
            return {
                ...plugin,
                warnings: validation.warnings,
            };
        }
        catch (error) {
            try {
                const pluginPath = path.join(this.pluginsDir, pluginSlug);
                await fs.rm(pluginPath, { recursive: true, force: true });
            }
            catch { }
            if (error instanceof common_1.BadRequestException) {
                throw error;
            }
            console.error('Error uploading plugin:', error);
            throw new common_1.BadRequestException('Failed to upload plugin: ' + error.message);
        }
    }
    async deletePlugin(id) {
        const plugin = await this.findById(id);
        if (plugin.isActive) {
            throw new common_1.BadRequestException('Cannot delete an active plugin. Deactivate it first.');
        }
        try {
            const pluginPath = path.join(this.pluginsDir, plugin.slug);
            await fs.rm(pluginPath, { recursive: true, force: true });
        }
        catch (error) {
            console.error(`Error deleting plugin files for ${plugin.slug}:`, error);
        }
        return this.prisma.plugin.delete({
            where: { id },
        });
    }
};
exports.PluginsService = PluginsService;
exports.PluginsService = PluginsService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], PluginsService);


/***/ }),
/* 166 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e, _f;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PluginsController = void 0;
const common_1 = __webpack_require__(2);
const platform_express_1 = __webpack_require__(124);
const plugins_service_1 = __webpack_require__(165);
const plugin_loader_service_1 = __webpack_require__(167);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const client_1 = __webpack_require__(17);
let PluginsController = class PluginsController {
    constructor(pluginsService, pluginLoader) {
        this.pluginsService = pluginsService;
        this.pluginLoader = pluginLoader;
    }
    scan() {
        return this.pluginsService.scanPlugins();
    }
    validate(file) {
        return this.pluginsService.validatePlugin(file);
    }
    upload(file) {
        return this.pluginsService.uploadPlugin(file);
    }
    findActive() {
        return this.pluginsService.findActive();
    }
    findAll() {
        return this.pluginsService.findAll();
    }
    findOne(id) {
        return this.pluginsService.findById(id);
    }
    async activate(id) {
        const plugin = await this.pluginsService.activate(id);
        await this.pluginLoader.loadPlugin(plugin.slug);
        return plugin;
    }
    async deactivate(id) {
        const plugin = await this.pluginsService.findById(id);
        await this.pluginLoader.unloadPlugin(plugin.slug);
        return this.pluginsService.deactivate(id);
    }
    async delete(id) {
        const plugin = await this.pluginsService.findById(id);
        if (plugin.isActive) {
            await this.pluginLoader.unloadPlugin(plugin.slug);
        }
        return this.pluginsService.deletePlugin(id);
    }
    updateSettings(id, settings) {
        return this.pluginsService.updateSettings(id, settings);
    }
};
exports.PluginsController = PluginsController;
__decorate([
    (0, common_1.Post)('scan'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], PluginsController.prototype, "scan", null);
__decorate([
    (0, common_1.Post)('validate'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    (0, common_1.UseInterceptors)((0, platform_express_1.FileInterceptor)('file')),
    __param(0, (0, common_1.UploadedFile)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_d = typeof Express !== "undefined" && (_c = Express.Multer) !== void 0 && _c.File) === "function" ? _d : Object]),
    __metadata("design:returntype", void 0)
], PluginsController.prototype, "validate", null);
__decorate([
    (0, common_1.Post)('upload'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    (0, common_1.UseInterceptors)((0, platform_express_1.FileInterceptor)('file')),
    __param(0, (0, common_1.UploadedFile)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_f = typeof Express !== "undefined" && (_e = Express.Multer) !== void 0 && _e.File) === "function" ? _f : Object]),
    __metadata("design:returntype", void 0)
], PluginsController.prototype, "upload", null);
__decorate([
    (0, common_1.Get)('active'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], PluginsController.prototype, "findActive", null);
__decorate([
    (0, common_1.Get)(),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], PluginsController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], PluginsController.prototype, "findOne", null);
__decorate([
    (0, common_1.Post)(':id/activate'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], PluginsController.prototype, "activate", null);
__decorate([
    (0, common_1.Post)(':id/deactivate'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], PluginsController.prototype, "deactivate", null);
__decorate([
    (0, common_1.Delete)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], PluginsController.prototype, "delete", null);
__decorate([
    (0, common_1.Patch)(':id/settings'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", void 0)
], PluginsController.prototype, "updateSettings", null);
exports.PluginsController = PluginsController = __decorate([
    (0, common_1.Controller)('api/plugins'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof plugins_service_1.PluginsService !== "undefined" && plugins_service_1.PluginsService) === "function" ? _a : Object, typeof (_b = typeof plugin_loader_service_1.PluginLoaderService !== "undefined" && plugin_loader_service_1.PluginLoaderService) === "function" ? _b : Object])
], PluginsController);


/***/ }),
/* 167 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PluginLoaderService = void 0;
const common_1 = __webpack_require__(2);
const plugins_service_1 = __webpack_require__(165);
const path = __webpack_require__(3);
const fs = __webpack_require__(4);
const dynamicRequire = eval('require');
let PluginLoaderService = class PluginLoaderService {
    constructor(pluginsService) {
        this.pluginsService = pluginsService;
        this.loadedPlugins = new Map();
        this.expressApp = null;
    }
    async onModuleInit() {
        await this.loadActivePlugins();
    }
    setExpressApp(app) {
        this.expressApp = app;
        for (const [slug, plugin] of this.loadedPlugins.entries()) {
            if (plugin.registerRoutes && this.expressApp) {
                try {
                    plugin.registerRoutes(this.expressApp);
                    console.log(`✅ Plugin routes registered: ${slug}`);
                }
                catch (error) {
                    console.error(`Error registering routes for plugin ${slug}:`, error);
                }
            }
        }
    }
    async loadActivePlugins() {
        const activePlugins = await this.pluginsService.findActive();
        for (const plugin of activePlugins) {
            try {
                await this.loadPlugin(plugin.slug);
            }
            catch (error) {
                console.error(`Error loading plugin ${plugin.slug}:`, error);
            }
        }
    }
    async loadPlugin(slug) {
        try {
            const pluginPath = this.pluginsService.getPluginPath(slug);
            const entryFile = path.join(pluginPath, 'index.js');
            if (!fs.existsSync(entryFile)) {
                console.warn(`⚠️ Plugin file not found: ${entryFile}`);
                return;
            }
            delete dynamicRequire.cache[dynamicRequire.resolve(entryFile)];
            const pluginModule = dynamicRequire(entryFile);
            const pluginInstance = pluginModule.default || pluginModule;
            this.loadedPlugins.set(slug, pluginInstance);
            if (pluginInstance.onActivate) {
                await pluginInstance.onActivate();
            }
            if (pluginInstance.registerRoutes && this.expressApp) {
                try {
                    pluginInstance.registerRoutes(this.expressApp);
                    console.log(`✅ Plugin routes registered: ${slug}`);
                }
                catch (error) {
                    console.error(`Error registering routes for plugin ${slug}:`, error);
                }
            }
            console.log(`✅ Plugin loaded: ${slug}`);
        }
        catch (error) {
            console.error(`Error loading plugin ${slug}:`, error);
            throw error;
        }
    }
    async unloadPlugin(slug) {
        const plugin = this.loadedPlugins.get(slug);
        if (plugin && plugin.onDeactivate) {
            await plugin.onDeactivate();
        }
        this.loadedPlugins.delete(slug);
        console.log(`Plugin unloaded: ${slug}`);
    }
    async executeHook(hookName, ...args) {
        const results = [];
        for (const [slug, plugin] of this.loadedPlugins.entries()) {
            const hook = plugin[hookName];
            if (typeof hook === 'function') {
                try {
                    const result = await hook(...args);
                    results.push({ slug, result });
                }
                catch (error) {
                    console.error(`Error executing ${hookName} hook in plugin ${slug}:`, error);
                }
            }
        }
        return results;
    }
    getLoadedPlugins() {
        return Array.from(this.loadedPlugins.keys());
    }
    isPluginLoaded(slug) {
        return this.loadedPlugins.has(slug);
    }
};
exports.PluginLoaderService = PluginLoaderService;
exports.PluginLoaderService = PluginLoaderService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof plugins_service_1.PluginsService !== "undefined" && plugins_service_1.PluginsService) === "function" ? _a : Object])
], PluginLoaderService);


/***/ }),
/* 168 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 PluginMarketplaceService_1;
var _a, _b, _c;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PluginMarketplaceService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const plugins_service_1 = __webpack_require__(165);
const email_service_1 = __webpack_require__(50);
const path = __webpack_require__(3);
const fs = __webpack_require__(24);
let PluginMarketplaceService = PluginMarketplaceService_1 = class PluginMarketplaceService {
    constructor(prisma, pluginsService, emailService) {
        this.prisma = prisma;
        this.pluginsService = pluginsService;
        this.emailService = emailService;
        this.logger = new common_1.Logger(PluginMarketplaceService_1.name);
        this.uploadsDir = path.join(process.cwd(), 'uploads', 'plugin-marketplace');
        this.iconsDir = path.join(process.cwd(), 'uploads', 'plugin-marketplace', 'icons');
        this.ensureUploadDir();
    }
    async ensureUploadDir() {
        try {
            await fs.mkdir(this.uploadsDir, { recursive: true });
            await fs.mkdir(this.iconsDir, { recursive: true });
        }
        catch (error) {
            console.error('Failed to create plugin marketplace uploads directory:', error);
        }
    }
    async findAll(query) {
        const { category, search, status = 'approved', featured, sortBy = 'downloads', page = 1, limit = 20, } = query;
        const where = {};
        if (status) {
            where.status = status;
        }
        if (category && category !== 'all') {
            where.category = category;
        }
        if (featured !== undefined) {
            where.isFeatured = featured;
        }
        if (search) {
            where.OR = [
                { name: { contains: search, mode: 'insensitive' } },
                { description: { contains: search, mode: 'insensitive' } },
                { author: { contains: search, mode: 'insensitive' } },
            ];
        }
        let orderBy = {};
        switch (sortBy) {
            case 'downloads':
                orderBy = { downloads: 'desc' };
                break;
            case 'activeInstalls':
                orderBy = { activeInstalls: 'desc' };
                break;
            case 'rating':
                orderBy = { rating: 'desc' };
                break;
            case 'newest':
                orderBy = { createdAt: 'desc' };
                break;
            case 'name':
                orderBy = { name: 'asc' };
                break;
            default:
                orderBy = { downloads: 'desc' };
        }
        const [plugins, total] = await Promise.all([
            this.prisma.marketplacePlugin.findMany({
                where,
                orderBy,
                skip: (page - 1) * limit,
                take: limit,
                include: {
                    submittedBy: { select: { id: true, name: true, avatar: true } },
                },
            }),
            this.prisma.marketplacePlugin.count({ where }),
        ]);
        return {
            plugins,
            pagination: {
                page,
                limit,
                total,
                totalPages: Math.ceil(total / limit),
            },
        };
    }
    async getFeatured(limit = 6) {
        return this.prisma.marketplacePlugin.findMany({
            where: { status: 'approved', isFeatured: true },
            orderBy: { featuredOrder: 'asc' },
            take: limit,
            include: { submittedBy: { select: { id: true, name: true, avatar: true } } },
        });
    }
    async findById(id) {
        const plugin = await this.prisma.marketplacePlugin.findUnique({
            where: { id },
            include: {
                submittedBy: { select: { id: true, name: true, avatar: true } },
                ratings: {
                    include: { user: { select: { id: true, name: true, avatar: true } } },
                    orderBy: { createdAt: 'desc' },
                    take: 10,
                },
            },
        });
        if (!plugin)
            throw new common_1.NotFoundException('Plugin not found');
        return plugin;
    }
    async findBySlug(slug) {
        const plugin = await this.prisma.marketplacePlugin.findUnique({
            where: { slug },
            include: {
                submittedBy: { select: { id: true, name: true, avatar: true } },
                ratings: {
                    include: { user: { select: { id: true, name: true, avatar: true } } },
                    orderBy: { createdAt: 'desc' },
                    take: 10,
                },
            },
        });
        if (!plugin)
            throw new common_1.NotFoundException('Plugin not found');
        return plugin;
    }
    async submitPlugin(dto, files, userId) {
        const { pluginFile, iconFile } = files;
        const slug = dto.name
            .toLowerCase()
            .replace(/[^a-z0-9]+/g, '-')
            .replace(/^-|-$/g, '');
        const existing = await this.prisma.marketplacePlugin.findUnique({ where: { slug } });
        if (existing) {
            throw new common_1.BadRequestException(`Plugin "${dto.name}" already exists in marketplace`);
        }
        const validation = await this.pluginsService.validatePlugin(pluginFile);
        if (!validation.valid) {
            throw new common_1.BadRequestException({
                message: 'Invalid plugin package',
                errors: validation.errors,
            });
        }
        const fileName = `${slug}-${Date.now()}.zip`;
        const filePath = path.join(this.uploadsDir, fileName);
        await fs.writeFile(filePath, pluginFile.buffer);
        const stats = await fs.stat(filePath);
        let iconUrl = validation.pluginConfig?.icon || null;
        if (iconFile) {
            const ext = path.extname(iconFile.originalname) || '.png';
            const iconName = `${slug}-${Date.now()}${ext}`;
            const iconPath = path.join(this.iconsDir, iconName);
            await fs.writeFile(iconPath, iconFile.buffer);
            iconUrl = `/uploads/plugin-marketplace/icons/${iconName}`;
        }
        const plugin = await this.prisma.marketplacePlugin.create({
            data: {
                name: dto.name,
                slug,
                description: dto.description,
                longDescription: dto.longDescription,
                version: dto.version,
                author: dto.author,
                authorEmail: dto.authorEmail,
                authorUrl: dto.authorUrl,
                category: dto.category || 'utility',
                tags: dto.tags || [],
                features: dto.features || [],
                repositoryUrl: dto.repositoryUrl,
                licenseType: dto.licenseType || 'MIT',
                downloadUrl: `/uploads/plugin-marketplace/${fileName}`,
                iconUrl,
                fileSize: stats.size,
                status: 'pending',
                submittedById: userId,
            },
            include: { submittedBy: { select: { id: true, name: true } } },
        });
        return plugin;
    }
    async installPlugin(id) {
        const plugin = await this.findById(id);
        if (plugin.status !== 'approved') {
            throw new common_1.BadRequestException('This plugin is not approved for installation');
        }
        if (!plugin.downloadUrl) {
            throw new common_1.BadRequestException('Plugin package not available');
        }
        const filePath = path.join(process.cwd(), plugin.downloadUrl);
        const fileBuffer = await fs.readFile(filePath);
        const mockFile = {
            buffer: fileBuffer,
            originalname: `${plugin.slug}.zip`,
            fieldname: 'file',
            encoding: '7bit',
            mimetype: 'application/zip',
            size: fileBuffer.length,
            destination: '',
            filename: '',
            path: '',
            stream: null,
        };
        const installed = await this.pluginsService.uploadPlugin(mockFile);
        await this.prisma.marketplacePlugin.update({
            where: { id },
            data: {
                downloads: { increment: 1 },
                activeInstalls: { increment: 1 },
            },
        });
        return installed;
    }
    async ratePlugin(pluginId, userId, rating, review) {
        if (rating < 1 || rating > 5) {
            throw new common_1.BadRequestException('Rating must be between 1 and 5');
        }
        const ratingRecord = await this.prisma.marketplacePluginRating.upsert({
            where: { pluginId_userId: { pluginId, userId } },
            update: { rating, review },
            create: { pluginId, userId, rating, review },
        });
        const stats = await this.prisma.marketplacePluginRating.aggregate({
            where: { pluginId },
            _avg: { rating: true },
            _count: { rating: true },
        });
        await this.prisma.marketplacePlugin.update({
            where: { id: pluginId },
            data: { rating: stats._avg.rating || 0, ratingCount: stats._count.rating },
        });
        return ratingRecord;
    }
    async approvePlugin(id, approverId) {
        const plugin = await this.prisma.marketplacePlugin.update({
            where: { id },
            data: { status: 'approved', approvedById: approverId, approvedAt: new Date() },
            include: { submittedBy: { select: { id: true, name: true, email: true } } },
        });
        await this.sendApprovalEmail(plugin);
        return plugin;
    }
    async rejectPlugin(id, approverId, reason) {
        const plugin = await this.prisma.marketplacePlugin.update({
            where: { id },
            data: { status: 'rejected', approvedById: approverId, rejectionReason: reason },
            include: { submittedBy: { select: { id: true, name: true, email: true } } },
        });
        await this.sendRejectionEmail(plugin, reason);
        return plugin;
    }
    async bulkApprove(ids, approverId) {
        const results = await Promise.allSettled(ids.map((id) => this.approvePlugin(id, approverId)));
        const succeeded = results.filter((r) => r.status === 'fulfilled').length;
        const failed = results.filter((r) => r.status === 'rejected').length;
        return { succeeded, failed, total: ids.length };
    }
    async bulkReject(ids, approverId, reason) {
        const results = await Promise.allSettled(ids.map((id) => this.rejectPlugin(id, approverId, reason)));
        const succeeded = results.filter((r) => r.status === 'fulfilled').length;
        const failed = results.filter((r) => r.status === 'rejected').length;
        return { succeeded, failed, total: ids.length };
    }
    async bulkDelete(ids) {
        const results = await Promise.allSettled(ids.map((id) => this.deletePlugin(id)));
        const succeeded = results.filter((r) => r.status === 'fulfilled').length;
        const failed = results.filter((r) => r.status === 'rejected').length;
        return { succeeded, failed, total: ids.length };
    }
    async setFeatured(id, featured, order) {
        return this.prisma.marketplacePlugin.update({
            where: { id },
            data: { isFeatured: featured, featuredOrder: order },
        });
    }
    async deletePlugin(id) {
        const plugin = await this.findById(id);
        if (plugin.downloadUrl) {
            try {
                const filePath = path.join(process.cwd(), plugin.downloadUrl);
                await fs.unlink(filePath);
            }
            catch { }
        }
        return this.prisma.marketplacePlugin.delete({ where: { id } });
    }
    async getStats() {
        const [total, approved, pending, featured, totalDownloads, totalActiveInstalls] = await Promise.all([
            this.prisma.marketplacePlugin.count(),
            this.prisma.marketplacePlugin.count({ where: { status: 'approved' } }),
            this.prisma.marketplacePlugin.count({ where: { status: 'pending' } }),
            this.prisma.marketplacePlugin.count({ where: { isFeatured: true } }),
            this.prisma.marketplacePlugin.aggregate({ _sum: { downloads: true } }),
            this.prisma.marketplacePlugin.aggregate({ _sum: { activeInstalls: true } }),
        ]);
        return {
            total,
            approved,
            pending,
            featured,
            totalDownloads: totalDownloads._sum.downloads || 0,
            totalActiveInstalls: totalActiveInstalls._sum.activeInstalls || 0,
        };
    }
    async getCategories() {
        const categories = await this.prisma.marketplacePlugin.groupBy({
            by: ['category'],
            where: { status: 'approved' },
            _count: { id: true },
        });
        return categories.map((c) => ({ category: c.category, count: c._count.id }));
    }
    async sendApprovalEmail(plugin) {
        if (!plugin.submittedBy?.email)
            return;
        const html = `
      <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
        <div style="background: linear-gradient(135deg, #10b981 0%, #059669 100%); padding: 30px; border-radius: 12px 12px 0 0;">
          <h1 style="color: white; margin: 0; font-size: 24px;">🎉 Plugin Approved!</h1>
        </div>
        <div style="background: #f8fafc; padding: 30px; border-radius: 0 0 12px 12px;">
          <p style="color: #334155; font-size: 16px; line-height: 1.6;">
            Hi ${plugin.submittedBy.name || 'Developer'},
          </p>
          <p style="color: #334155; font-size: 16px; line-height: 1.6;">
            Great news! Your plugin <strong>"${plugin.name}"</strong> has been approved and is now live on the marketplace!
          </p>
          <div style="background: white; padding: 20px; border-radius: 8px; margin: 20px 0; border: 1px solid #e2e8f0;">
            <p style="margin: 0 0 10px 0;"><strong>Plugin:</strong> ${plugin.name}</p>
            <p style="margin: 0 0 10px 0;"><strong>Version:</strong> ${plugin.version}</p>
            <p style="margin: 0;"><strong>Category:</strong> ${plugin.category}</p>
          </div>
          <p style="color: #64748b; font-size: 14px;">
            Users can now discover, install, and rate your plugin. Thank you for contributing to our marketplace!
          </p>
        </div>
      </div>
    `;
        try {
            await this.emailService.send({
                to: plugin.submittedBy.email,
                toName: plugin.submittedBy.name,
                subject: `🎉 Your plugin "${plugin.name}" has been approved!`,
                html,
                recipientId: plugin.submittedBy.id,
                metadata: { type: 'plugin_approved', pluginId: plugin.id },
            });
            this.logger.log(`Approval email sent to ${plugin.submittedBy.email} for plugin ${plugin.name}`);
        }
        catch (error) {
            this.logger.error(`Failed to send approval email: ${error.message}`);
        }
    }
    async sendRejectionEmail(plugin, reason) {
        if (!plugin.submittedBy?.email)
            return;
        const html = `
      <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
        <div style="background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); padding: 30px; border-radius: 12px 12px 0 0;">
          <h1 style="color: white; margin: 0; font-size: 24px;">Plugin Review Update</h1>
        </div>
        <div style="background: #f8fafc; padding: 30px; border-radius: 0 0 12px 12px;">
          <p style="color: #334155; font-size: 16px; line-height: 1.6;">
            Hi ${plugin.submittedBy.name || 'Developer'},
          </p>
          <p style="color: #334155; font-size: 16px; line-height: 1.6;">
            We've reviewed your plugin <strong>"${plugin.name}"</strong> and unfortunately, it wasn't approved at this time.
          </p>
          <div style="background: #fef3c7; padding: 20px; border-radius: 8px; margin: 20px 0; border: 1px solid #fcd34d;">
            <p style="margin: 0 0 10px 0; color: #92400e;"><strong>Reason:</strong></p>
            <p style="margin: 0; color: #92400e;">${reason}</p>
          </div>
          <p style="color: #334155; font-size: 16px; line-height: 1.6;">
            Please review the feedback and feel free to submit an updated version addressing the issues mentioned.
          </p>
        </div>
      </div>
    `;
        try {
            await this.emailService.send({
                to: plugin.submittedBy.email,
                toName: plugin.submittedBy.name,
                subject: `Plugin "${plugin.name}" - Review Update`,
                html,
                recipientId: plugin.submittedBy.id,
                metadata: { type: 'plugin_rejected', pluginId: plugin.id },
            });
            this.logger.log(`Rejection email sent to ${plugin.submittedBy.email} for plugin ${plugin.name}`);
        }
        catch (error) {
            this.logger.error(`Failed to send rejection email: ${error.message}`);
        }
    }
};
exports.PluginMarketplaceService = PluginMarketplaceService;
exports.PluginMarketplaceService = PluginMarketplaceService = PluginMarketplaceService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof plugins_service_1.PluginsService !== "undefined" && plugins_service_1.PluginsService) === "function" ? _b : Object, typeof (_c = typeof email_service_1.EmailService !== "undefined" && email_service_1.EmailService) === "function" ? _c : Object])
], PluginMarketplaceService);


/***/ }),
/* 169 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PluginMarketplaceController = void 0;
const common_1 = __webpack_require__(2);
const platform_express_1 = __webpack_require__(124);
const plugin_marketplace_service_1 = __webpack_require__(168);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const client_1 = __webpack_require__(17);
const optional_jwt_auth_guard_1 = __webpack_require__(76);
let PluginMarketplaceController = class PluginMarketplaceController {
    constructor(marketplaceService) {
        this.marketplaceService = marketplaceService;
    }
    findAll(category, search, sortBy, page, limit) {
        return this.marketplaceService.findAll({
            category,
            search,
            status: 'approved',
            sortBy,
            page: page ? parseInt(page) : 1,
            limit: limit ? parseInt(limit) : 20,
        });
    }
    getFeatured(limit) {
        return this.marketplaceService.getFeatured(limit ? parseInt(limit) : 6);
    }
    getStats() {
        return this.marketplaceService.getStats();
    }
    getCategories() {
        return this.marketplaceService.getCategories();
    }
    findById(id) {
        return this.marketplaceService.findById(id);
    }
    findBySlug(slug) {
        return this.marketplaceService.findBySlug(slug);
    }
    submitPlugin(files, body, req) {
        const dto = {
            name: body.name,
            description: body.description,
            longDescription: body.longDescription,
            version: body.version || '1.0.0',
            author: body.author || req.user.name,
            authorEmail: body.authorEmail || req.user.email,
            authorUrl: body.authorUrl,
            category: body.category || 'utility',
            tags: body.tags ? JSON.parse(body.tags) : [],
            features: body.features ? JSON.parse(body.features) : [],
            repositoryUrl: body.repositoryUrl,
            licenseType: body.licenseType,
        };
        if (!files.file?.[0]) {
            throw new Error('Plugin file is required');
        }
        return this.marketplaceService.submitPlugin(dto, {
            pluginFile: files.file[0],
            iconFile: files.icon?.[0],
        }, req.user.id);
    }
    installPlugin(id) {
        return this.marketplaceService.installPlugin(id);
    }
    ratePlugin(id, body, req) {
        return this.marketplaceService.ratePlugin(id, req.user.id, body.rating, body.review);
    }
    findAllAdmin(category, search, status, sortBy, page, limit) {
        return this.marketplaceService.findAll({
            category,
            search,
            status: status || undefined,
            sortBy,
            page: page ? parseInt(page) : 1,
            limit: limit ? parseInt(limit) : 20,
        });
    }
    approvePlugin(id, req) {
        return this.marketplaceService.approvePlugin(id, req.user.id);
    }
    rejectPlugin(id, body, req) {
        return this.marketplaceService.rejectPlugin(id, req.user.id, body.reason);
    }
    setFeatured(id, body) {
        return this.marketplaceService.setFeatured(id, body.featured, body.order);
    }
    deletePlugin(id) {
        return this.marketplaceService.deletePlugin(id);
    }
    bulkApprove(body, req) {
        return this.marketplaceService.bulkApprove(body.ids, req.user.id);
    }
    bulkReject(body, req) {
        return this.marketplaceService.bulkReject(body.ids, req.user.id, body.reason);
    }
    bulkDelete(body) {
        return this.marketplaceService.bulkDelete(body.ids);
    }
};
exports.PluginMarketplaceController = PluginMarketplaceController;
__decorate([
    (0, common_1.Get)('plugins'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Query)('category')),
    __param(1, (0, common_1.Query)('search')),
    __param(2, (0, common_1.Query)('sortBy')),
    __param(3, (0, common_1.Query)('page')),
    __param(4, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, String, String, String]),
    __metadata("design:returntype", void 0)
], PluginMarketplaceController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)('featured'),
    __param(0, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], PluginMarketplaceController.prototype, "getFeatured", null);
__decorate([
    (0, common_1.Get)('stats'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], PluginMarketplaceController.prototype, "getStats", null);
__decorate([
    (0, common_1.Get)('categories'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], PluginMarketplaceController.prototype, "getCategories", null);
__decorate([
    (0, common_1.Get)('plugins/:id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], PluginMarketplaceController.prototype, "findById", null);
__decorate([
    (0, common_1.Get)('plugins/slug/:slug'),
    __param(0, (0, common_1.Param)('slug')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], PluginMarketplaceController.prototype, "findBySlug", null);
__decorate([
    (0, common_1.Post)('submit'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    (0, common_1.UseInterceptors)((0, platform_express_1.FileFieldsInterceptor)([
        { name: 'file', maxCount: 1 },
        { name: 'icon', maxCount: 1 },
    ])),
    __param(0, (0, common_1.UploadedFiles)()),
    __param(1, (0, common_1.Body)()),
    __param(2, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Object, Object]),
    __metadata("design:returntype", void 0)
], PluginMarketplaceController.prototype, "submitPlugin", null);
__decorate([
    (0, common_1.Post)('plugins/:id/install'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], PluginMarketplaceController.prototype, "installPlugin", null);
__decorate([
    (0, common_1.Post)('plugins/:id/rate'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __param(2, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object, Object]),
    __metadata("design:returntype", void 0)
], PluginMarketplaceController.prototype, "ratePlugin", null);
__decorate([
    (0, common_1.Get)('admin/plugins'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Query)('category')),
    __param(1, (0, common_1.Query)('search')),
    __param(2, (0, common_1.Query)('status')),
    __param(3, (0, common_1.Query)('sortBy')),
    __param(4, (0, common_1.Query)('page')),
    __param(5, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, String, String, String, String]),
    __metadata("design:returntype", void 0)
], PluginMarketplaceController.prototype, "findAllAdmin", null);
__decorate([
    (0, common_1.Post)('admin/plugins/:id/approve'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", void 0)
], PluginMarketplaceController.prototype, "approvePlugin", null);
__decorate([
    (0, common_1.Post)('admin/plugins/:id/reject'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __param(2, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object, Object]),
    __metadata("design:returntype", void 0)
], PluginMarketplaceController.prototype, "rejectPlugin", null);
__decorate([
    (0, common_1.Post)('admin/plugins/:id/feature'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", void 0)
], PluginMarketplaceController.prototype, "setFeatured", null);
__decorate([
    (0, common_1.Delete)('admin/plugins/:id'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], PluginMarketplaceController.prototype, "deletePlugin", null);
__decorate([
    (0, common_1.Post)('admin/bulk/approve'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Object]),
    __metadata("design:returntype", void 0)
], PluginMarketplaceController.prototype, "bulkApprove", null);
__decorate([
    (0, common_1.Post)('admin/bulk/reject'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Object]),
    __metadata("design:returntype", void 0)
], PluginMarketplaceController.prototype, "bulkReject", null);
__decorate([
    (0, common_1.Post)('admin/bulk/delete'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], PluginMarketplaceController.prototype, "bulkDelete", null);
exports.PluginMarketplaceController = PluginMarketplaceController = __decorate([
    (0, common_1.Controller)('api/plugin-marketplace'),
    __metadata("design:paramtypes", [typeof (_a = typeof plugin_marketplace_service_1.PluginMarketplaceService !== "undefined" && plugin_marketplace_service_1.PluginMarketplaceService) === "function" ? _a : Object])
], PluginMarketplaceController);


/***/ }),
/* 170 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PublicModule = void 0;
const common_1 = __webpack_require__(2);
const public_controller_1 = __webpack_require__(171);
const content_module_1 = __webpack_require__(97);
const themes_module_1 = __webpack_require__(128);
const shop_module_1 = __webpack_require__(183);
const lms_module_1 = __webpack_require__(198);
const users_module_1 = __webpack_require__(68);
const auth_module_1 = __webpack_require__(42);
const recommendations_module_1 = __webpack_require__(218);
const marketplace_module_1 = __webpack_require__(223);
const plugins_module_1 = __webpack_require__(164);
const subscriptions_module_1 = __webpack_require__(156);
let PublicModule = class PublicModule {
};
exports.PublicModule = PublicModule;
exports.PublicModule = PublicModule = __decorate([
    (0, common_1.Module)({
        imports: [
            content_module_1.ContentModule,
            themes_module_1.ThemesModule,
            shop_module_1.ShopModule,
            lms_module_1.LmsModule,
            users_module_1.UsersModule,
            auth_module_1.AuthModule,
            (0, common_1.forwardRef)(() => recommendations_module_1.RecommendationsModule),
            (0, common_1.forwardRef)(() => marketplace_module_1.MarketplaceModule),
            (0, common_1.forwardRef)(() => plugins_module_1.PluginsModule),
            (0, common_1.forwardRef)(() => subscriptions_module_1.SubscriptionsModule),
        ],
        controllers: [public_controller_1.PublicController],
    })
], PublicModule);


/***/ }),
/* 171 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PublicController = void 0;
const common_1 = __webpack_require__(2);
const express_1 = __webpack_require__(57);
const path_1 = __webpack_require__(3);
const posts_service_1 = __webpack_require__(98);
const pages_service_1 = __webpack_require__(100);
const theme_renderer_service_1 = __webpack_require__(132);
const products_service_1 = __webpack_require__(172);
const categories_service_1 = __webpack_require__(173);
const courses_service_1 = __webpack_require__(174);
const certificates_service_1 = __webpack_require__(175);
const profiles_service_1 = __webpack_require__(74);
const auth_service_1 = __webpack_require__(45);
const recommendations_service_1 = __webpack_require__(179);
const recommendation_tracking_service_1 = __webpack_require__(181);
const prisma_service_1 = __webpack_require__(16);
const developers_service_1 = __webpack_require__(182);
const marketplace_service_1 = __webpack_require__(150);
const plugin_marketplace_service_1 = __webpack_require__(168);
const subscriptions_service_1 = __webpack_require__(135);
const client_1 = __webpack_require__(17);
const optional_jwt_auth_guard_1 = __webpack_require__(76);
let PublicController = class PublicController {
    constructor(postsService, pagesService, themeRenderer, productsService, categoriesService, coursesService, certificatesService, profilesService, authService, recommendationsService, trackingService, prisma, developersService, themeMarketplaceService, pluginMarketplaceService, subscriptionsService) {
        this.postsService = postsService;
        this.pagesService = pagesService;
        this.themeRenderer = themeRenderer;
        this.productsService = productsService;
        this.categoriesService = categoriesService;
        this.coursesService = coursesService;
        this.certificatesService = certificatesService;
        this.profilesService = profilesService;
        this.authService = authService;
        this.recommendationsService = recommendationsService;
        this.trackingService = trackingService;
        this.prisma = prisma;
        this.developersService = developersService;
        this.themeMarketplaceService = themeMarketplaceService;
        this.pluginMarketplaceService = pluginMarketplaceService;
        this.subscriptionsService = subscriptionsService;
    }
    async adminSpaRoot(res) {
        const adminIndexPath = (0, path_1.join)(process.cwd(), 'admin', 'dist', 'index.html');
        const { existsSync } = await Promise.resolve().then(() => __webpack_require__(4));
        if (!existsSync(adminIndexPath)) {
            return res.status(503).send(this.getAdminNotBuiltMessage());
        }
        res.sendFile(adminIndexPath);
    }
    async adminSpaFallback(res) {
        const adminIndexPath = (0, path_1.join)(process.cwd(), 'admin', 'dist', 'index.html');
        const { existsSync } = await Promise.resolve().then(() => __webpack_require__(4));
        if (!existsSync(adminIndexPath)) {
            return res.status(503).send(this.getAdminNotBuiltMessage());
        }
        res.sendFile(adminIndexPath);
    }
    getAdminNotBuiltMessage() {
        return `
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Admin Panel Not Built - WordPress Node CMS</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body {
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      min-height: 100vh;
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 20px;
    }
    .container {
      background: white;
      border-radius: 16px;
      padding: 40px;
      max-width: 600px;
      box-shadow: 0 20px 60px rgba(0,0,0,0.3);
    }
    h1 { color: #e53e3e; margin-bottom: 16px; font-size: 24px; }
    p { color: #4a5568; line-height: 1.6; margin-bottom: 16px; }
    .code {
      background: #1a202c;
      color: #68d391;
      padding: 16px;
      border-radius: 8px;
      font-family: 'Consolas', monospace;
      margin: 20px 0;
      overflow-x: auto;
    }
    .code div { margin: 4px 0; }
    .comment { color: #718096; }
    .steps { margin: 20px 0; }
    .steps li { margin: 8px 0; color: #4a5568; }
    .tip {
      background: #ebf8ff;
      border-left: 4px solid #4299e1;
      padding: 12px 16px;
      margin-top: 20px;
      border-radius: 4px;
    }
    .tip strong { color: #2b6cb0; }
  </style>
</head>
<body>
  <div class="container">
    <h1>⚠️ Admin Panel Not Built</h1>
    <p>The admin panel files are missing. This usually happens on a fresh installation.</p>

    <div class="steps">
      <strong>To fix this, run these commands:</strong>
      <div class="code">
        <div><span class="comment"># Navigate to the admin directory</span></div>
        <div>cd admin</div>
        <div></div>
        <div><span class="comment"># Install dependencies</span></div>
        <div>npm install</div>
        <div></div>
        <div><span class="comment"># Build the admin panel</span></div>
        <div>npm run build</div>
        <div></div>
        <div><span class="comment"># Restart the server</span></div>
        <div>cd .. && node dist/main.js</div>
      </div>
    </div>

    <div class="tip">
      <strong>💡 Tip:</strong> If you're using the setup script, make sure it completed without errors.
      Check the console output for any build failures.
    </div>

    <p style="margin-top: 20px; font-size: 14px; color: #718096;">
      After building, refresh this page to access the admin panel.
    </p>
  </div>
</body>
</html>
`;
    }
    async home(req, res) {
        try {
            const user = req.user;
            const [postsResult, productsResult, categories, coursesResult] = await Promise.all([
                this.postsService.findAll(1, 6, client_1.PostStatus.PUBLISHED),
                this.productsService.getActiveProducts({ limit: 8 }),
                this.categoriesService.findAll().catch(() => []),
                this.coursesService.findPublished({ limit: 6 }).catch(() => ({ courses: [] })),
            ]);
            const html = await this.themeRenderer.renderHome(postsResult.data, {
                featuredProducts: productsResult.products || [],
                categories: categories || [],
                featuredCourses: coursesResult.courses || [],
            }, user);
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering home page:', error);
            res.status(500).send(`Error rendering home page: ${error.message}`);
        }
    }
    async lmsRoot(res) {
        res.redirect('http://localhost:5173/admin/lms');
    }
    async lmsFallback(res) {
        const originalUrl = res.req?.originalUrl || '/lms';
        res.redirect(`http://localhost:5173/admin${originalUrl}`);
    }
    async learnCourse(req, courseId, res) {
        try {
            const user = req.user;
            const html = await this.themeRenderer.renderLearn(courseId, user);
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering learn page:', error);
            res.status(500).send(`Error rendering learn page: ${error.message}`);
        }
    }
    async myCourses(req, res) {
        try {
            const user = req.user;
            const html = await this.themeRenderer.renderMyCourses(user);
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering my courses page:', error);
            res.status(500).send(`Error rendering my courses page: ${error.message}`);
        }
    }
    async myAccount(req, res) {
        try {
            const user = req.user;
            const html = await this.themeRenderer.renderMyAccount(user);
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering my account page:', error);
            res.status(500).send(`Error rendering my account page: ${error.message}`);
        }
    }
    async ordersPage(res) {
        res.redirect('/my-account#orders');
    }
    async themeDesigner(req, res) {
        try {
            const user = req.user;
            if (!user || user.role !== 'ADMIN') {
                return res.redirect('/login?redirect=/theme-designer');
            }
            const html = await this.themeRenderer.renderThemeDesigner(user);
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering theme designer:', error);
            res.status(500).send(`Error rendering theme designer: ${error.message}`);
        }
    }
    async loginPage(req, redirect, res) {
        try {
            const user = req.user;
            if (user) {
                return res.redirect(redirect || '/');
            }
            const html = await this.themeRenderer.renderLogin(redirect);
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering login page:', error);
            res.status(500).send(`Error rendering login page: ${error.message}`);
        }
    }
    async loginSubmit(body, redirect, res) {
        try {
            const result = await this.authService.login({ email: body.email, password: body.password });
            res.cookie('access_token', result.access_token, {
                httpOnly: true,
                secure: process.env.NODE_ENV === 'production',
                sameSite: 'lax',
                maxAge: 7 * 24 * 60 * 60 * 1000,
            });
            res.redirect(redirect || '/');
        }
        catch (_error) {
            const html = await this.themeRenderer.renderLogin(redirect, 'Invalid email or password');
            res.send(html);
        }
    }
    async registerPage(req, res) {
        try {
            const user = req.user;
            if (user) {
                return res.redirect('/');
            }
            const html = await this.themeRenderer.renderRegister();
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering register page:', error);
            res.status(500).send(`Error rendering register page: ${error.message}`);
        }
    }
    async registerSubmit(body, res) {
        try {
            await this.authService.register({
                name: body.name,
                email: body.email,
                password: body.password,
            });
            const result = await this.authService.login({ email: body.email, password: body.password });
            res.cookie('access_token', result.access_token, {
                httpOnly: true,
                secure: process.env.NODE_ENV === 'production',
                sameSite: 'lax',
                maxAge: 7 * 24 * 60 * 60 * 1000,
            });
            res.redirect('/');
        }
        catch (error) {
            const html = await this.themeRenderer.renderRegister(error.message || 'Registration failed');
            res.send(html);
        }
    }
    async logout(res) {
        res.clearCookie('access_token');
        res.redirect('/');
    }
    async cartPage(req, res) {
        try {
            const user = req.user;
            const html = await this.themeRenderer.renderCart(user);
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering cart page:', error);
            res.status(500).send(`Error rendering cart page: ${error.message}`);
        }
    }
    async checkoutPage(req, res) {
        try {
            const user = req.user;
            const html = await this.themeRenderer.renderCheckout(user);
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering checkout page:', error);
            res.status(500).send(`Error rendering checkout page: ${error.message}`);
        }
    }
    async orderSuccessPage(req, orderId, res) {
        try {
            const user = req.user;
            let order = null;
            if (orderId) {
                order = await this.prisma.order.findUnique({
                    where: { id: orderId },
                    include: { items: true },
                });
            }
            const html = await this.themeRenderer.renderOrderSuccess(order, user);
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering order success page:', error);
            res.status(500).send(`Error rendering order success page: ${error.message}`);
        }
    }
    async blog(req, page, res) {
        try {
            const user = req.user;
            const currentPage = page ? parseInt(page) : 1;
            const result = await this.postsService.findAll(currentPage, 10, client_1.PostStatus.PUBLISHED);
            const pagination = {
                page: result.meta.page,
                totalPages: result.meta.totalPages,
                hasPrev: result.meta.page > 1,
                hasNext: result.meta.page < result.meta.totalPages,
                prevPage: result.meta.page - 1,
                nextPage: result.meta.page + 1,
            };
            const html = await this.themeRenderer.renderArchive(result.data, pagination, user);
            res.send(html);
        }
        catch (_error) {
            res.status(500).send('Error rendering blog archive');
        }
    }
    async shop(req, page, category, res) {
        try {
            const user = req.user;
            const currentPage = page ? parseInt(page) : 1;
            const limit = 12;
            const categories = await this.categoriesService.findAll().catch(() => []);
            let categoryId;
            if (category) {
                const foundCategory = categories.find((c) => c.slug === category);
                categoryId = foundCategory?.id;
            }
            const productsResult = await this.productsService.getActiveProducts({
                page: currentPage,
                limit,
                categoryId,
            });
            const pagination = {
                page: currentPage,
                totalPages: productsResult.pagination?.pages || 1,
                hasPrev: currentPage > 1,
                hasNext: currentPage < (productsResult.pagination?.pages || 1),
                prevPage: currentPage - 1,
                nextPage: currentPage + 1,
            };
            const html = await this.themeRenderer.renderShop(productsResult.products || [], categories || [], pagination, category || null, user);
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering shop page:', error);
            res.status(500).send(`Error rendering shop page: ${error.message}`);
        }
    }
    async product(req, slug, res) {
        try {
            const user = req.user;
            const product = await this.productsService.findBySlug(slug);
            if (!product || product.status !== 'ACTIVE') {
                res.status(404).send('Product not found');
                return;
            }
            await this.trackingService.trackInteraction({
                contentType: 'product',
                contentId: product.id,
                interactionType: 'view',
                userId: user?.id,
                sessionId: req.sessionID,
            });
            const relatedProducts = await this.recommendationsService.getRelatedProducts(product.id, 4, user?.id);
            const productWithRecommendations = {
                ...product,
                relatedProducts: relatedProducts.items,
            };
            const html = await this.themeRenderer.renderProduct(productWithRecommendations, user);
            res.send(html);
        }
        catch (_error) {
            res.status(404).send('Product not found');
        }
    }
    async courses(req, page, category, level, priceType, res) {
        try {
            const user = req.user;
            const currentPage = page ? parseInt(page) : 1;
            const limit = 12;
            const coursesResult = await this.coursesService.findPublished({
                page: currentPage,
                limit,
                category: category || undefined,
                level: level ? level : undefined,
                priceType: priceType ? priceType : undefined,
            });
            const categoriesList = await this.coursesService.getCategories();
            const pagination = {
                page: currentPage,
                pages: coursesResult.pagination?.pages || 1,
                hasPrev: currentPage > 1,
                hasNext: currentPage < (coursesResult.pagination?.pages || 1),
            };
            const html = await this.themeRenderer.renderCourses(coursesResult.courses || [], categoriesList.filter((c) => c !== null), pagination, { category, level, priceType }, user);
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering courses page:', error);
            res.status(500).send(`Error rendering courses page: ${error.message}`);
        }
    }
    async course(req, slug, res) {
        try {
            const user = req.user;
            const course = await this.coursesService.findBySlug(slug);
            if (!course || course.status !== 'PUBLISHED') {
                res.status(404).send('Course not found');
                return;
            }
            const html = await this.themeRenderer.renderCourse(course, false, user);
            res.send(html);
        }
        catch (_error) {
            res.status(404).send('Course not found');
        }
    }
    async enrollCourse(slug, res) {
        try {
            const course = await this.coursesService.findBySlug(slug);
            if (!course || course.status !== 'PUBLISHED') {
                res.status(404).send('Course not found');
                return;
            }
            res.redirect(`http://localhost:5173/admin/lms/course/${slug}?enroll=true`);
        }
        catch (_error) {
            res.status(404).send('Course not found');
        }
    }
    async verifyCertificate(hash, res) {
        try {
            const result = await this.certificatesService.verify(hash);
            const html = await this.themeRenderer.renderCertificateVerify(result);
            res.send(html);
        }
        catch (_error) {
            res.status(500).send('Error verifying certificate');
        }
    }
    async post(req, slug, res) {
        try {
            const user = req.user;
            const post = await this.postsService.findBySlug(slug);
            if (post.status !== client_1.PostStatus.PUBLISHED) {
                res.status(404).send('Post not found');
                return;
            }
            await this.trackingService.trackInteraction({
                contentType: 'post',
                contentId: post.id,
                interactionType: 'view',
                userId: user?.id,
                sessionId: req.sessionID,
            });
            const relatedPosts = await this.recommendationsService.getRelatedPosts(post.id, 4, user?.id);
            const postWithRecommendations = {
                ...post,
                relatedPosts: relatedPosts.items,
            };
            const html = await this.themeRenderer.renderPost(postWithRecommendations, user);
            res.send(html);
        }
        catch (_error) {
            res.status(404).send('Post not found');
        }
    }
    async userProfile(req, identifier, res) {
        try {
            const user = req.user;
            const profile = await this.profilesService.getPublicProfile(identifier);
            if (!profile || !profile.isPublic) {
                res.status(404).send('Profile not found');
                return;
            }
            const stats = await this.profilesService.getStats(profile.id);
            const html = await this.themeRenderer.renderProfile(profile, stats, user);
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering profile:', error);
            res.status(404).send('Profile not found');
        }
    }
    async hireDeveloper(req, res, category, skills, minRate, maxRate, search, page) {
        try {
            const user = req.user;
            const result = await this.developersService.findAll({
                status: 'ACTIVE',
                category: category,
                skills: skills ? skills.split(',') : undefined,
                minRate: minRate ? parseFloat(minRate) : undefined,
                maxRate: maxRate ? parseFloat(maxRate) : undefined,
                search,
                page: page ? parseInt(page) : 1,
                limit: 12,
            });
            const categories = [
                { value: 'FRONTEND', label: 'Frontend Developer' },
                { value: 'BACKEND', label: 'Backend Developer' },
                { value: 'FULLSTACK', label: 'Full-Stack Developer' },
                { value: 'WORDPRESS', label: 'WordPress Developer' },
                { value: 'MOBILE', label: 'Mobile Developer' },
                { value: 'DEVOPS', label: 'DevOps Engineer' },
                { value: 'DESIGN', label: 'UI/UX Designer' },
                { value: 'DATABASE', label: 'Database Expert' },
                { value: 'SECURITY', label: 'Security Specialist' },
            ];
            const html = await this.themeRenderer.render('hire-developer', {
                title: 'Hire a Developer',
                developers: result.developers,
                pagination: result.pagination,
                categories,
                filters: { category, skills, minRate, maxRate, search },
                user,
            });
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering hire-developer page:', error);
            res.status(500).send('Error loading page');
        }
    }
    async developerMarketplace(req, res) {
        try {
            const user = req.user;
            const featured = await this.developersService.findAll({
                status: 'ACTIVE',
                sortBy: 'rating',
                limit: 6,
            });
            const categories = ['FRONTEND', 'BACKEND', 'FULLSTACK', 'MOBILE', 'DEVOPS', 'DESIGN'];
            const byCategory = await Promise.all(categories.map(async (cat) => ({
                category: cat,
                label: cat.charAt(0) + cat.slice(1).toLowerCase().replace('_', ' '),
                developers: (await this.developersService.findAll({
                    status: 'ACTIVE',
                    category: cat,
                    limit: 4,
                })).developers,
            })));
            const html = await this.themeRenderer.render('developer-marketplace', {
                title: 'Developer Marketplace',
                featured: featured.developers,
                byCategory: byCategory.filter((c) => c.developers.length > 0),
                user,
            });
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering developer-marketplace:', error);
            res.status(500).send('Error loading page');
        }
    }
    async developerProfile(req, slug, res) {
        try {
            const user = req.user;
            const developer = await this.developersService.findBySlug(slug);
            const html = await this.themeRenderer.render('developer-profile', {
                title: developer.displayName,
                developer,
                user,
            });
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering developer profile:', error);
            res.status(404).send('Developer not found');
        }
    }
    async marketplace(req, res, tab) {
        try {
            const user = req.user;
            const activeTab = tab === 'plugins' ? 'plugins' : 'themes';
            const [featuredThemes, featuredPlugins, themeStats, pluginStats] = await Promise.all([
                this.themeMarketplaceService.getFeatured(6),
                this.pluginMarketplaceService.getFeatured(6),
                this.themeMarketplaceService.getStats(),
                this.pluginMarketplaceService.getStats(),
            ]);
            const html = await this.themeRenderer.render('marketplace', {
                title: 'Themes & Plugins Marketplace',
                activeTab,
                featuredThemes,
                featuredPlugins,
                stats: {
                    themes: themeStats,
                    plugins: pluginStats,
                },
                user,
            });
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering marketplace:', error);
            res.status(500).send('Error loading marketplace');
        }
    }
    async marketplaceThemes(req, res, category, search, sortBy, page) {
        try {
            const user = req.user;
            const [themes, categories] = await Promise.all([
                this.themeMarketplaceService.findAll({
                    category,
                    search,
                    status: 'approved',
                    sortBy: sortBy || 'downloads',
                    page: page ? parseInt(page) : 1,
                    limit: 12,
                }),
                this.themeMarketplaceService.getCategories(),
            ]);
            const html = await this.themeRenderer.render('marketplace-themes', {
                title: 'Browse Themes',
                themes: themes.themes,
                pagination: themes.pagination,
                categories,
                filters: { category, search, sortBy },
                user,
            });
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering themes marketplace:', error);
            res.status(500).send('Error loading themes');
        }
    }
    async marketplaceThemeDetail(req, slug, res) {
        try {
            const user = req.user;
            const theme = await this.themeMarketplaceService.findBySlug(slug);
            const html = await this.themeRenderer.render('marketplace-theme-detail', {
                title: theme.name,
                theme,
                user,
            });
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering theme detail:', error);
            res.status(404).send('Theme not found');
        }
    }
    async marketplacePlugins(req, res, category, search, sortBy, page) {
        try {
            const user = req.user;
            const [plugins, categories] = await Promise.all([
                this.pluginMarketplaceService.findAll({
                    category,
                    search,
                    status: 'approved',
                    sortBy: sortBy || 'downloads',
                    page: page ? parseInt(page) : 1,
                    limit: 12,
                }),
                this.pluginMarketplaceService.getCategories(),
            ]);
            const html = await this.themeRenderer.render('marketplace-plugins', {
                title: 'Browse Plugins',
                plugins: plugins.plugins,
                pagination: plugins.pagination,
                categories,
                filters: { category, search, sortBy },
                user,
            });
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering plugins marketplace:', error);
            res.status(500).send('Error loading plugins');
        }
    }
    async marketplacePluginDetail(req, slug, res) {
        try {
            const user = req.user;
            const plugin = await this.pluginMarketplaceService.findBySlug(slug);
            const html = await this.themeRenderer.render('marketplace-plugin-detail', {
                title: plugin.name,
                plugin,
                user,
            });
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering plugin detail:', error);
            res.status(404).send('Plugin not found');
        }
    }
    async developerGuidelines(req, res) {
        try {
            const user = req.user;
            const html = await this.themeRenderer.render('marketplace-guidelines', {
                title: 'Developer Requirements & Guidelines',
                user,
            });
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering developer guidelines:', error);
            res.status(500).send('Error loading guidelines');
        }
    }
    async pricing(req, res) {
        try {
            const user = req.user;
            const plans = await this.subscriptionsService.getPlans(false);
            console.log('[Pricing] Plans fetched:', plans?.length || 0, 'plans');
            if (plans?.length) {
                console.log('[Pricing] Plan names:', plans.map((p) => `${p.name} (active: ${p.isActive})`).join(', '));
            }
            const html = await this.themeRenderer.render('pricing', {
                title: 'Pricing Plans',
                description: 'Choose the perfect plan for your needs',
                plans,
                user,
            });
            res.send(html);
        }
        catch (error) {
            console.error('Error rendering pricing page:', error);
            res.status(500).send('Error loading pricing');
        }
    }
    async page(req, slug, res) {
        try {
            const user = req.user;
            const page = await this.pagesService.findBySlug(slug);
            if (page.status !== client_1.PostStatus.PUBLISHED) {
                res.status(404).send('Page not found');
                return;
            }
            const html = await this.themeRenderer.renderPage(page, user);
            res.send(html);
        }
        catch (_error) {
            res.status(404).send('Page not found');
        }
    }
};
exports.PublicController = PublicController;
__decorate([
    (0, common_1.Get)('admin'),
    __param(0, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_s = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _s : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "adminSpaRoot", null);
__decorate([
    (0, common_1.Get)('admin/*'),
    __param(0, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_t = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _t : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "adminSpaFallback", null);
__decorate([
    (0, common_1.Get)(),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_u = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _u : Object, typeof (_v = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _v : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "home", null);
__decorate([
    (0, common_1.Get)('lms'),
    __param(0, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_w = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _w : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "lmsRoot", null);
__decorate([
    (0, common_1.Get)('lms/*path'),
    __param(0, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_x = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _x : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "lmsFallback", null);
__decorate([
    (0, common_1.Get)('learn/:courseId'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Param)('courseId')),
    __param(2, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_y = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _y : Object, String, typeof (_z = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _z : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "learnCourse", null);
__decorate([
    (0, common_1.Get)('my-courses'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_0 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _0 : Object, typeof (_1 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _1 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "myCourses", null);
__decorate([
    (0, common_1.Get)('my-account'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_2 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _2 : Object, typeof (_3 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _3 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "myAccount", null);
__decorate([
    (0, common_1.Get)('orders'),
    __param(0, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_4 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _4 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "ordersPage", null);
__decorate([
    (0, common_1.Get)('theme-designer'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_5 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _5 : Object, typeof (_6 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _6 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "themeDesigner", null);
__decorate([
    (0, common_1.Get)('login'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Query)('redirect')),
    __param(2, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_7 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _7 : Object, String, typeof (_8 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _8 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "loginPage", null);
__decorate([
    (0, common_1.Post)('login'),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, common_1.Query)('redirect')),
    __param(2, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, typeof (_9 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _9 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "loginSubmit", null);
__decorate([
    (0, common_1.Get)('register'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_10 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _10 : Object, typeof (_11 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _11 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "registerPage", null);
__decorate([
    (0, common_1.Post)('register'),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, typeof (_12 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _12 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "registerSubmit", null);
__decorate([
    (0, common_1.Get)('logout'),
    __param(0, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_13 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _13 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "logout", null);
__decorate([
    (0, common_1.Get)('cart'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_14 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _14 : Object, typeof (_15 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _15 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "cartPage", null);
__decorate([
    (0, common_1.Get)('checkout'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_16 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _16 : Object, typeof (_17 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _17 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "checkoutPage", null);
__decorate([
    (0, common_1.Get)('order-success'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Query)('order')),
    __param(2, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_18 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _18 : Object, String, typeof (_19 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _19 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "orderSuccessPage", null);
__decorate([
    (0, common_1.Get)('blog'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Query)('page')),
    __param(2, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_20 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _20 : Object, String, typeof (_21 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _21 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "blog", null);
__decorate([
    (0, common_1.Get)('shop'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Query)('page')),
    __param(2, (0, common_1.Query)('category')),
    __param(3, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_22 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _22 : Object, String, String, typeof (_23 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _23 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "shop", null);
__decorate([
    (0, common_1.Get)('shop/product/:slug'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Param)('slug')),
    __param(2, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_24 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _24 : Object, String, typeof (_25 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _25 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "product", null);
__decorate([
    (0, common_1.Get)('courses'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Query)('page')),
    __param(2, (0, common_1.Query)('category')),
    __param(3, (0, common_1.Query)('level')),
    __param(4, (0, common_1.Query)('priceType')),
    __param(5, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_26 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _26 : Object, String, String, String, String, typeof (_27 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _27 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "courses", null);
__decorate([
    (0, common_1.Get)('courses/:slug'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Param)('slug')),
    __param(2, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_28 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _28 : Object, String, typeof (_29 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _29 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "course", null);
__decorate([
    (0, common_1.Get)('courses/:slug/enroll'),
    __param(0, (0, common_1.Param)('slug')),
    __param(1, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_30 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _30 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "enrollCourse", null);
__decorate([
    (0, common_1.Get)('verify/:hash'),
    __param(0, (0, common_1.Param)('hash')),
    __param(1, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_31 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _31 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "verifyCertificate", null);
__decorate([
    (0, common_1.Get)('post/:slug'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Param)('slug')),
    __param(2, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_32 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _32 : Object, String, typeof (_33 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _33 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "post", null);
__decorate([
    (0, common_1.Get)('u/:identifier'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Param)('identifier')),
    __param(2, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_34 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _34 : Object, String, typeof (_35 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _35 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "userProfile", null);
__decorate([
    (0, common_1.Get)('hire-developer'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Res)()),
    __param(2, (0, common_1.Query)('category')),
    __param(3, (0, common_1.Query)('skills')),
    __param(4, (0, common_1.Query)('minRate')),
    __param(5, (0, common_1.Query)('maxRate')),
    __param(6, (0, common_1.Query)('search')),
    __param(7, (0, common_1.Query)('page')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_36 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _36 : Object, typeof (_37 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _37 : Object, String, String, String, String, String, String]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "hireDeveloper", null);
__decorate([
    (0, common_1.Get)('developer-marketplace'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_38 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _38 : Object, typeof (_39 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _39 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "developerMarketplace", null);
__decorate([
    (0, common_1.Get)('developer/:slug'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Param)('slug')),
    __param(2, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_40 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _40 : Object, String, typeof (_41 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _41 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "developerProfile", null);
__decorate([
    (0, common_1.Get)('marketplace'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Res)()),
    __param(2, (0, common_1.Query)('tab')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_42 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _42 : Object, typeof (_43 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _43 : Object, String]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "marketplace", null);
__decorate([
    (0, common_1.Get)('marketplace/themes'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Res)()),
    __param(2, (0, common_1.Query)('category')),
    __param(3, (0, common_1.Query)('search')),
    __param(4, (0, common_1.Query)('sortBy')),
    __param(5, (0, common_1.Query)('page')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_44 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _44 : Object, typeof (_45 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _45 : Object, String, String, String, String]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "marketplaceThemes", null);
__decorate([
    (0, common_1.Get)('marketplace/themes/:slug'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Param)('slug')),
    __param(2, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_46 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _46 : Object, String, typeof (_47 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _47 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "marketplaceThemeDetail", null);
__decorate([
    (0, common_1.Get)('marketplace/plugins'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Res)()),
    __param(2, (0, common_1.Query)('category')),
    __param(3, (0, common_1.Query)('search')),
    __param(4, (0, common_1.Query)('sortBy')),
    __param(5, (0, common_1.Query)('page')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_48 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _48 : Object, typeof (_49 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _49 : Object, String, String, String, String]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "marketplacePlugins", null);
__decorate([
    (0, common_1.Get)('marketplace/plugins/:slug'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Param)('slug')),
    __param(2, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_50 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _50 : Object, String, typeof (_51 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _51 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "marketplacePluginDetail", null);
__decorate([
    (0, common_1.Get)('marketplace/developer-guidelines'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_52 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _52 : Object, typeof (_53 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _53 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "developerGuidelines", null);
__decorate([
    (0, common_1.Get)('pricing'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_54 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _54 : Object, typeof (_55 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _55 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "pricing", null);
__decorate([
    (0, common_1.Get)(':slug'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Param)('slug')),
    __param(2, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_56 = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _56 : Object, String, typeof (_57 = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _57 : Object]),
    __metadata("design:returntype", Promise)
], PublicController.prototype, "page", null);
exports.PublicController = PublicController = __decorate([
    (0, common_1.Controller)(),
    __param(9, (0, common_1.Inject)((0, common_1.forwardRef)(() => recommendations_service_1.RecommendationsService))),
    __param(10, (0, common_1.Inject)((0, common_1.forwardRef)(() => recommendation_tracking_service_1.RecommendationTrackingService))),
    __param(12, (0, common_1.Inject)((0, common_1.forwardRef)(() => developers_service_1.DevelopersService))),
    __param(13, (0, common_1.Inject)((0, common_1.forwardRef)(() => marketplace_service_1.MarketplaceService))),
    __param(14, (0, common_1.Inject)((0, common_1.forwardRef)(() => plugin_marketplace_service_1.PluginMarketplaceService))),
    __param(15, (0, common_1.Inject)((0, common_1.forwardRef)(() => subscriptions_service_1.SubscriptionsService))),
    __metadata("design:paramtypes", [typeof (_a = typeof posts_service_1.PostsService !== "undefined" && posts_service_1.PostsService) === "function" ? _a : Object, typeof (_b = typeof pages_service_1.PagesService !== "undefined" && pages_service_1.PagesService) === "function" ? _b : Object, typeof (_c = typeof theme_renderer_service_1.ThemeRendererService !== "undefined" && theme_renderer_service_1.ThemeRendererService) === "function" ? _c : Object, typeof (_d = typeof products_service_1.ProductsService !== "undefined" && products_service_1.ProductsService) === "function" ? _d : Object, typeof (_e = typeof categories_service_1.CategoriesService !== "undefined" && categories_service_1.CategoriesService) === "function" ? _e : Object, typeof (_f = typeof courses_service_1.CoursesService !== "undefined" && courses_service_1.CoursesService) === "function" ? _f : Object, typeof (_g = typeof certificates_service_1.CertificatesService !== "undefined" && certificates_service_1.CertificatesService) === "function" ? _g : Object, typeof (_h = typeof profiles_service_1.ProfilesService !== "undefined" && profiles_service_1.ProfilesService) === "function" ? _h : Object, typeof (_j = typeof auth_service_1.AuthService !== "undefined" && auth_service_1.AuthService) === "function" ? _j : Object, typeof (_k = typeof recommendations_service_1.RecommendationsService !== "undefined" && recommendations_service_1.RecommendationsService) === "function" ? _k : Object, typeof (_l = typeof recommendation_tracking_service_1.RecommendationTrackingService !== "undefined" && recommendation_tracking_service_1.RecommendationTrackingService) === "function" ? _l : Object, typeof (_m = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _m : Object, typeof (_o = typeof developers_service_1.DevelopersService !== "undefined" && developers_service_1.DevelopersService) === "function" ? _o : Object, typeof (_p = typeof marketplace_service_1.MarketplaceService !== "undefined" && marketplace_service_1.MarketplaceService) === "function" ? _p : Object, typeof (_q = typeof plugin_marketplace_service_1.PluginMarketplaceService !== "undefined" && plugin_marketplace_service_1.PluginMarketplaceService) === "function" ? _q : Object, typeof (_r = typeof subscriptions_service_1.SubscriptionsService !== "undefined" && subscriptions_service_1.SubscriptionsService) === "function" ? _r : Object])
], PublicController);


/***/ }),
/* 172 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ProductsService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let ProductsService = class ProductsService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    generateSlug(name) {
        return name
            .toLowerCase()
            .replace(/[^a-z0-9]+/g, '-')
            .replace(/^-|-$/g, '');
    }
    async create(dto) {
        const slug = this.generateSlug(dto.name);
        const existing = await this.prisma.product.findUnique({ where: { slug } });
        if (existing) {
            throw new common_1.ConflictException('Product with this name already exists');
        }
        if (dto.sku) {
            const existingSku = await this.prisma.product.findUnique({ where: { sku: dto.sku } });
            if (existingSku) {
                throw new common_1.ConflictException('SKU already exists');
            }
        }
        const { variants, tags, ...productData } = dto;
        const product = await this.prisma.product.create({
            data: {
                ...productData,
                slug,
                price: dto.price,
                salePrice: dto.salePrice,
                costPrice: dto.costPrice,
                weight: dto.weight,
                variants: variants
                    ? {
                        create: variants.map((v) => ({
                            ...v,
                            price: v.price,
                            salePrice: v.salePrice,
                            options: v.options || {},
                        })),
                    }
                    : undefined,
                tags: tags
                    ? {
                        connectOrCreate: tags.map((tag) => ({
                            where: { slug: this.generateSlug(tag) },
                            create: { name: tag, slug: this.generateSlug(tag) },
                        })),
                    }
                    : undefined,
            },
            include: {
                category: true,
                variants: true,
                tags: true,
            },
        });
        return product;
    }
    async findAll(query) {
        const { search, status, categoryId, page = 1, limit = 20 } = query;
        const skip = (page - 1) * limit;
        const where = {};
        if (search) {
            where.OR = [
                { name: { contains: search, mode: 'insensitive' } },
                { sku: { contains: search, mode: 'insensitive' } },
                { description: { contains: search, mode: 'insensitive' } },
            ];
        }
        if (status)
            where.status = status;
        if (categoryId)
            where.categoryId = categoryId;
        const [products, total] = await Promise.all([
            this.prisma.product.findMany({
                where,
                skip,
                take: limit,
                orderBy: { createdAt: 'desc' },
                include: {
                    category: true,
                    variants: true,
                    tags: true,
                    _count: { select: { reviews: true } },
                },
            }),
            this.prisma.product.count({ where }),
        ]);
        return {
            products,
            pagination: {
                page,
                limit,
                total,
                pages: Math.ceil(total / limit),
            },
        };
    }
    async findOne(id) {
        const product = await this.prisma.product.findUnique({
            where: { id },
            include: {
                category: true,
                variants: true,
                tags: true,
                reviews: { where: { isApproved: true }, orderBy: { createdAt: 'desc' } },
            },
        });
        if (!product)
            throw new common_1.NotFoundException('Product not found');
        return product;
    }
    async findBySlug(slug) {
        const product = await this.prisma.product.findUnique({
            where: { slug },
            include: {
                category: true,
                variants: true,
                tags: true,
                reviews: { where: { isApproved: true }, orderBy: { createdAt: 'desc' } },
            },
        });
        if (!product)
            throw new common_1.NotFoundException('Product not found');
        return product;
    }
    async update(id, dto) {
        const existing = await this.prisma.product.findUnique({ where: { id } });
        if (!existing)
            throw new common_1.NotFoundException('Product not found');
        const { variants, tags, slug: dtoSlug, ...productData } = dto;
        let slug = existing.slug;
        if (dtoSlug && dtoSlug !== existing.slug) {
            const slugExists = await this.prisma.product.findFirst({
                where: {
                    slug: dtoSlug,
                    id: { not: id },
                },
            });
            if (slugExists) {
                throw new common_1.ConflictException(`Slug "${dtoSlug}" is already in use`);
            }
            slug = dtoSlug;
        }
        else if (dto.name && dto.name !== existing.name && !dtoSlug) {
            slug = this.generateSlug(dto.name);
        }
        if (variants) {
            await this.prisma.productVariant.deleteMany({ where: { productId: id } });
        }
        const product = await this.prisma.product.update({
            where: { id },
            data: {
                ...productData,
                slug,
                variants: variants
                    ? {
                        create: variants.map((v) => ({ ...v, options: v.options || {} })),
                    }
                    : undefined,
                tags: tags
                    ? {
                        set: [],
                        connectOrCreate: tags.map((tag) => ({
                            where: { slug: this.generateSlug(tag) },
                            create: { name: tag, slug: this.generateSlug(tag) },
                        })),
                    }
                    : undefined,
            },
            include: { category: true, variants: true, tags: true },
        });
        return product;
    }
    async delete(id) {
        const existing = await this.prisma.product.findUnique({ where: { id } });
        if (!existing)
            throw new common_1.NotFoundException('Product not found');
        await this.prisma.product.delete({ where: { id } });
        return { message: 'Product deleted successfully' };
    }
    async getActiveProducts(query) {
        return this.findAll({ ...query, status: 'ACTIVE' });
    }
    async updateStock(id, quantity, variantId) {
        if (variantId) {
            await this.prisma.productVariant.update({
                where: { id: variantId },
                data: { stock: { increment: quantity } },
            });
        }
        else {
            await this.prisma.product.update({
                where: { id },
                data: { stock: { increment: quantity } },
            });
        }
    }
};
exports.ProductsService = ProductsService;
exports.ProductsService = ProductsService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], ProductsService);


/***/ }),
/* 173 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CategoriesService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let CategoriesService = class CategoriesService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    generateSlug(name) {
        return name
            .toLowerCase()
            .replace(/[^a-z0-9]+/g, '-')
            .replace(/^-|-$/g, '');
    }
    async create(dto) {
        const slug = this.generateSlug(dto.name);
        const existing = await this.prisma.productCategory.findUnique({ where: { slug } });
        if (existing) {
            throw new common_1.ConflictException('Category with this name already exists');
        }
        return this.prisma.productCategory.create({
            data: { ...dto, slug },
            include: { parent: true, children: true },
        });
    }
    async findAll() {
        return this.prisma.productCategory.findMany({
            include: {
                parent: true,
                children: true,
                _count: { select: { products: true } },
            },
            orderBy: { name: 'asc' },
        });
    }
    async findTree() {
        const categories = await this.prisma.productCategory.findMany({
            where: { parentId: null },
            include: {
                children: {
                    include: {
                        children: true,
                        _count: { select: { products: true } },
                    },
                },
                _count: { select: { products: true } },
            },
            orderBy: { name: 'asc' },
        });
        return categories;
    }
    async findOne(id) {
        const category = await this.prisma.productCategory.findUnique({
            where: { id },
            include: {
                parent: true,
                children: true,
                products: { where: { status: 'ACTIVE' }, take: 10 },
            },
        });
        if (!category)
            throw new common_1.NotFoundException('Category not found');
        return category;
    }
    async findBySlug(slug) {
        const category = await this.prisma.productCategory.findUnique({
            where: { slug },
            include: {
                parent: true,
                children: true,
                products: { where: { status: 'ACTIVE' } },
            },
        });
        if (!category)
            throw new common_1.NotFoundException('Category not found');
        return category;
    }
    async update(id, dto) {
        const existing = await this.prisma.productCategory.findUnique({ where: { id } });
        if (!existing)
            throw new common_1.NotFoundException('Category not found');
        let slug = existing.slug;
        if (dto.name && dto.name !== existing.name) {
            slug = this.generateSlug(dto.name);
        }
        return this.prisma.productCategory.update({
            where: { id },
            data: { ...dto, slug },
            include: { parent: true, children: true },
        });
    }
    async delete(id) {
        const existing = await this.prisma.productCategory.findUnique({
            where: { id },
            include: { children: true, products: true },
        });
        if (!existing)
            throw new common_1.NotFoundException('Category not found');
        if (existing.children.length > 0) {
            await this.prisma.productCategory.updateMany({
                where: { parentId: id },
                data: { parentId: existing.parentId },
            });
        }
        await this.prisma.product.updateMany({
            where: { categoryId: id },
            data: { categoryId: null },
        });
        await this.prisma.productCategory.delete({ where: { id } });
        return { message: 'Category deleted successfully' };
    }
};
exports.CategoriesService = CategoriesService;
exports.CategoriesService = CategoriesService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], CategoriesService);


/***/ }),
/* 174 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CoursesService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let CoursesService = class CoursesService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    generateSlug(title) {
        return title
            .toLowerCase()
            .replace(/[^a-z0-9]+/g, '-')
            .replace(/(^-|-$)/g, '');
    }
    async create(dto, instructorId) {
        const slug = this.generateSlug(dto.title);
        let finalSlug = slug;
        let counter = 1;
        while (await this.prisma.course.findUnique({ where: { slug: finalSlug } })) {
            finalSlug = `${slug}-${counter++}`;
        }
        return this.prisma.course.create({
            data: {
                ...dto,
                slug: finalSlug,
                instructorId,
                priceAmount: dto.priceAmount ? dto.priceAmount : null,
                whatYouLearn: dto.whatYouLearn || [],
                requirements: dto.requirements || [],
            },
            include: {
                instructor: { select: { id: true, name: true, avatar: true } },
                _count: { select: { lessons: true, enrollments: true } },
            },
        });
    }
    async findAll(query) {
        const { search, category, level, priceType, status, instructorId, page = 1, limit = 12, } = query;
        const skip = (page - 1) * limit;
        const where = {};
        if (search) {
            where.OR = [
                { title: { contains: search, mode: 'insensitive' } },
                { description: { contains: search, mode: 'insensitive' } },
            ];
        }
        if (category)
            where.category = category;
        if (level)
            where.level = level;
        if (priceType)
            where.priceType = priceType;
        if (status)
            where.status = status;
        if (instructorId)
            where.instructorId = instructorId;
        const [courses, total] = await Promise.all([
            this.prisma.course.findMany({
                where,
                skip,
                take: limit,
                orderBy: { createdAt: 'desc' },
                include: {
                    instructor: { select: { id: true, name: true, avatar: true } },
                    _count: { select: { lessons: true, enrollments: true } },
                },
            }),
            this.prisma.course.count({ where }),
        ]);
        return {
            courses,
            pagination: {
                page,
                limit,
                total,
                pages: Math.ceil(total / limit),
            },
        };
    }
    async findPublished(query) {
        return this.findAll({ ...query, status: 'PUBLISHED' });
    }
    async findOne(id) {
        const course = await this.prisma.course.findUnique({
            where: { id },
            include: {
                instructor: { select: { id: true, name: true, avatar: true, bio: true } },
                modules: {
                    orderBy: { orderIndex: 'asc' },
                    include: {
                        lessons: { orderBy: { orderIndex: 'asc' }, include: { videoAsset: true, quiz: true } },
                        _count: { select: { lessons: true } },
                    },
                },
                lessons: { orderBy: { orderIndex: 'asc' }, include: { videoAsset: true, quiz: true } },
                quizzes: { include: { _count: { select: { questions: true } } } },
                _count: { select: { lessons: true, enrollments: true, quizzes: true, modules: true } },
            },
        });
        if (!course)
            throw new common_1.NotFoundException('Course not found');
        return course;
    }
    async findBySlug(slug) {
        const course = await this.prisma.course.findUnique({
            where: { slug },
            include: {
                instructor: { select: { id: true, name: true, avatar: true, bio: true } },
                modules: {
                    orderBy: { orderIndex: 'asc' },
                    where: { isPublished: true },
                    include: {
                        lessons: {
                            orderBy: { orderIndex: 'asc' },
                            select: {
                                id: true,
                                title: true,
                                type: true,
                                estimatedMinutes: true,
                                isPreview: true,
                                orderIndex: true,
                            },
                        },
                    },
                },
                lessons: {
                    orderBy: { orderIndex: 'asc' },
                    where: { moduleId: null },
                    select: {
                        id: true,
                        title: true,
                        type: true,
                        estimatedMinutes: true,
                        isPreview: true,
                        orderIndex: true,
                    },
                },
                _count: { select: { lessons: true, enrollments: true } },
            },
        });
        if (!course)
            throw new common_1.NotFoundException('Course not found');
        return course;
    }
    async update(id, dto, userId, isAdmin) {
        const course = await this.findOne(id);
        if (!isAdmin && course.instructorId !== userId) {
            throw new common_1.ForbiddenException('Not authorized to update this course');
        }
        let slug = course.slug;
        if (dto.slug && dto.slug !== course.slug) {
            const slugExists = await this.prisma.course.findFirst({
                where: {
                    slug: dto.slug,
                    id: { not: id },
                },
            });
            if (slugExists) {
                throw new common_1.ConflictException(`Slug "${dto.slug}" is already in use`);
            }
            slug = dto.slug;
        }
        else if (dto.title && dto.title !== course.title && !dto.slug) {
            slug = this.generateSlug(dto.title);
            let finalSlug = slug;
            let counter = 1;
            while (await this.prisma.course.findFirst({ where: { slug: finalSlug, id: { not: id } } })) {
                finalSlug = `${slug}-${counter}`;
                counter++;
            }
            slug = finalSlug;
        }
        const { slug: _slugFromDto, ...restDto } = dto;
        return this.prisma.course.update({
            where: { id },
            data: {
                ...restDto,
                slug,
                priceAmount: dto.priceAmount !== undefined ? dto.priceAmount : undefined,
                whatYouLearn: dto.whatYouLearn || undefined,
                requirements: dto.requirements || undefined,
            },
            include: {
                instructor: { select: { id: true, name: true, avatar: true } },
                _count: { select: { lessons: true, enrollments: true } },
            },
        });
    }
    async delete(id, userId, isAdmin) {
        const course = await this.findOne(id);
        if (!isAdmin && course.instructorId !== userId) {
            throw new common_1.ForbiddenException('Not authorized to delete this course');
        }
        await this.prisma.course.delete({ where: { id } });
        return { message: 'Course deleted successfully' };
    }
    async getCategories() {
        const courses = await this.prisma.course.findMany({
            where: { status: 'PUBLISHED', category: { not: null } },
            select: { category: true },
            distinct: ['category'],
        });
        return courses.map((c) => c.category).filter(Boolean);
    }
    async getAdminDashboardStats(instructorId) {
        const courseWhere = instructorId ? { instructorId } : {};
        const enrollmentWhere = instructorId ? { course: { instructorId } } : {};
        const [totalCourses, publishedCourses, draftCourses, totalEnrollments, activeEnrollments, completedEnrollments, totalRevenue, recentEnrollments, topCourses,] = await Promise.all([
            this.prisma.course.count({ where: courseWhere }),
            this.prisma.course.count({ where: { ...courseWhere, status: 'PUBLISHED' } }),
            this.prisma.course.count({ where: { ...courseWhere, status: 'DRAFT' } }),
            this.prisma.enrollment.count({ where: enrollmentWhere }),
            this.prisma.enrollment.count({ where: { ...enrollmentWhere, status: 'ACTIVE' } }),
            this.prisma.enrollment.count({ where: { ...enrollmentWhere, status: 'COMPLETED' } }),
            this.prisma.enrollment.aggregate({
                where: enrollmentWhere,
                _sum: { pricePaid: true },
            }),
            this.prisma.enrollment.findMany({
                where: enrollmentWhere,
                orderBy: { enrolledAt: 'desc' },
                take: 10,
                include: {
                    user: { select: { id: true, name: true, email: true, avatar: true } },
                    course: { select: { id: true, title: true, slug: true } },
                },
            }),
            this.prisma.course.findMany({
                where: { ...courseWhere, status: 'PUBLISHED' },
                orderBy: { enrollments: { _count: 'desc' } },
                take: 5,
                include: {
                    _count: { select: { enrollments: true, lessons: true } },
                },
            }),
        ]);
        return {
            courses: { total: totalCourses, published: publishedCourses, draft: draftCourses },
            enrollments: {
                total: totalEnrollments,
                active: activeEnrollments,
                completed: completedEnrollments,
            },
            revenue: totalRevenue._sum.pricePaid || 0,
            recentEnrollments,
            topCourses,
        };
    }
};
exports.CoursesService = CoursesService;
exports.CoursesService = CoursesService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], CoursesService);


/***/ }),
/* 175 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b, _c;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CertificatesService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const progress_service_1 = __webpack_require__(176);
const certificate_generator_service_1 = __webpack_require__(177);
const crypto = __webpack_require__(48);
let CertificatesService = class CertificatesService {
    constructor(prisma, progressService, certificateGenerator) {
        this.prisma = prisma;
        this.progressService = progressService;
        this.certificateGenerator = certificateGenerator;
    }
    generateCertificateNumber() {
        const timestamp = Date.now().toString(36).toUpperCase();
        const random = crypto.randomBytes(4).toString('hex').toUpperCase();
        return `CERT-${timestamp}-${random}`;
    }
    generateVerificationHash() {
        return crypto.randomBytes(16).toString('hex');
    }
    async issueCertificate(courseId, userId) {
        const course = await this.prisma.course.findUnique({
            where: { id: courseId },
            include: { instructor: { select: { name: true } } },
        });
        if (!course)
            throw new common_1.NotFoundException('Course not found');
        if (!course.certificateEnabled) {
            throw new common_1.BadRequestException('This course does not offer certificates');
        }
        const enrollment = await this.prisma.enrollment.findUnique({
            where: { courseId_userId: { courseId, userId } },
        });
        if (!enrollment)
            throw new common_1.ForbiddenException('Not enrolled in this course');
        const existing = await this.prisma.certificate.findFirst({
            where: { courseId, userId, revokedAt: null },
            include: {
                course: { select: { title: true, instructor: { select: { name: true } } } },
                user: { select: { name: true } },
            },
        });
        if (existing)
            return existing;
        const progress = await this.progressService.getCourseProgress(courseId, userId);
        if (!progress.isComplete) {
            throw new common_1.BadRequestException('Course not completed yet');
        }
        const user = await this.prisma.user.findUnique({
            where: { id: userId },
            select: { name: true, email: true },
        });
        const certificateNumber = this.generateCertificateNumber();
        const verificationHash = this.generateVerificationHash();
        const { pdfUrl } = await this.certificateGenerator.generateCertificatePDF({
            certificateNumber,
            studentName: user?.name || 'Student',
            courseName: course.title,
            instructorName: course.instructor.name || 'Instructor',
            issuedAt: new Date(),
            verificationHash,
        });
        const certificate = await this.prisma.certificate.create({
            data: {
                certificateNumber,
                courseId,
                userId,
                verificationHash,
                pdfUrl,
                metadata: {
                    courseTitleAtIssue: course.title,
                    instructorName: course.instructor.name,
                    studentName: user?.name,
                    issuedDate: new Date().toISOString(),
                },
            },
            include: {
                course: { select: { title: true, instructor: { select: { name: true } } } },
                user: { select: { name: true } },
            },
        });
        await this.prisma.enrollment.update({
            where: { courseId_userId: { courseId, userId } },
            data: { status: 'COMPLETED', completedAt: new Date() },
        });
        return certificate;
    }
    async findByUser(userId) {
        return this.prisma.certificate.findMany({
            where: { userId, revokedAt: null },
            include: {
                course: { select: { title: true, slug: true, featuredImage: true } },
            },
            orderBy: { issuedAt: 'desc' },
        });
    }
    async findOne(id) {
        const certificate = await this.prisma.certificate.findUnique({
            where: { id },
            include: {
                course: { select: { title: true, instructor: { select: { name: true } } } },
                user: { select: { name: true } },
            },
        });
        if (!certificate)
            throw new common_1.NotFoundException('Certificate not found');
        return certificate;
    }
    async verify(hash) {
        const certificate = await this.prisma.certificate.findUnique({
            where: { verificationHash: hash },
            include: {
                course: { select: { title: true } },
                user: { select: { name: true } },
            },
        });
        if (!certificate) {
            return { valid: false, message: 'Certificate not found' };
        }
        if (certificate.revokedAt) {
            return {
                valid: false,
                message: 'This certificate has been revoked',
                revokedAt: certificate.revokedAt,
                revokedReason: certificate.revokedReason,
            };
        }
        return {
            valid: true,
            certificate: {
                certificateNumber: certificate.certificateNumber,
                courseName: certificate.course.title,
                studentName: certificate.user.name,
                issuedAt: certificate.issuedAt,
            },
        };
    }
    async revoke(id, reason) {
        const certificate = await this.findOne(id);
        if (certificate.revokedAt) {
            throw new common_1.BadRequestException('Certificate already revoked');
        }
        return this.prisma.certificate.update({
            where: { id },
            data: { revokedAt: new Date(), revokedReason: reason },
        });
    }
    async checkAndIssueCertificate(courseId, userId) {
        const course = await this.prisma.course.findUnique({ where: { id: courseId } });
        if (!course?.certificateEnabled)
            return null;
        const progress = await this.progressService.getCourseProgress(courseId, userId);
        if (!progress.isComplete)
            return null;
        const existing = await this.prisma.certificate.findFirst({
            where: { courseId, userId, revokedAt: null },
        });
        if (existing)
            return existing;
        return this.issueCertificate(courseId, userId);
    }
};
exports.CertificatesService = CertificatesService;
exports.CertificatesService = CertificatesService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof progress_service_1.ProgressService !== "undefined" && progress_service_1.ProgressService) === "function" ? _b : Object, typeof (_c = typeof certificate_generator_service_1.CertificateGeneratorService !== "undefined" && certificate_generator_service_1.CertificateGeneratorService) === "function" ? _c : Object])
], CertificatesService);


/***/ }),
/* 176 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ProgressService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let ProgressService = class ProgressService {
    constructor(prisma) {
        this.prisma = prisma;
        this.VIDEO_COMPLETION_THRESHOLD = 90;
    }
    async updateProgress(lessonId, userId, dto) {
        const lesson = await this.prisma.lesson.findUnique({
            where: { id: lessonId },
            include: { videoAsset: true, course: true },
        });
        if (!lesson)
            throw new common_1.NotFoundException('Lesson not found');
        const enrollment = await this.prisma.enrollment.findUnique({
            where: { courseId_userId: { courseId: lesson.courseId, userId } },
        });
        if (!enrollment)
            throw new common_1.ForbiddenException('You must be enrolled to track progress');
        let lessonCompleted = dto.lessonCompleted;
        if (!lessonCompleted && dto.videoWatchedSeconds && lesson.videoAsset?.durationSeconds) {
            const watchedPercent = (dto.videoWatchedSeconds / lesson.videoAsset.durationSeconds) * 100;
            if (watchedPercent >= this.VIDEO_COMPLETION_THRESHOLD) {
                lessonCompleted = true;
            }
        }
        const progress = await this.prisma.lessonProgress.upsert({
            where: {
                courseId_lessonId_userId: {
                    courseId: lesson.courseId,
                    lessonId,
                    userId,
                },
            },
            update: {
                videoWatchedSeconds: dto.videoWatchedSeconds ?? undefined,
                lessonCompleted: lessonCompleted ?? undefined,
                completedAt: lessonCompleted ? new Date() : undefined,
                lastAccessedAt: new Date(),
            },
            create: {
                courseId: lesson.courseId,
                lessonId,
                userId,
                videoWatchedSeconds: dto.videoWatchedSeconds ?? 0,
                lessonCompleted: lessonCompleted ?? false,
                completedAt: lessonCompleted ? new Date() : null,
            },
        });
        return progress;
    }
    async markComplete(lessonId, userId) {
        return this.updateProgress(lessonId, userId, { lessonCompleted: true });
    }
    async getCourseProgress(courseId, userId) {
        const [lessons, progressRecords, quizAttempts] = await Promise.all([
            this.prisma.lesson.findMany({
                where: { courseId },
                orderBy: { orderIndex: 'asc' },
                select: { id: true, title: true, type: true, isRequired: true },
            }),
            this.prisma.lessonProgress.findMany({
                where: { courseId, userId },
            }),
            this.prisma.quizAttempt.findMany({
                where: { courseId, userId, passed: true },
                distinct: ['quizId'],
                select: { quizId: true },
            }),
        ]);
        const progressMap = new Map(progressRecords.map((p) => [p.lessonId, p]));
        const passedQuizIds = new Set(quizAttempts.map((a) => a.quizId));
        const lessonProgress = lessons.map((lesson) => ({
            ...lesson,
            progress: progressMap.get(lesson.id) || null,
            completed: progressMap.get(lesson.id)?.lessonCompleted || false,
        }));
        const completedCount = lessonProgress.filter((l) => l.completed).length;
        const totalCount = lessons.length;
        const nextLesson = lessonProgress.find((l) => !l.completed);
        const requiredQuizzes = await this.prisma.quiz.findMany({
            where: { courseId, isRequired: true },
            select: { id: true, title: true },
        });
        const allRequiredQuizzesPassed = requiredQuizzes.every((q) => passedQuizIds.has(q.id));
        return {
            lessons: lessonProgress,
            completedLessons: completedCount,
            totalLessons: totalCount,
            percentComplete: totalCount > 0 ? Math.round((completedCount / totalCount) * 100) : 0,
            nextLesson,
            requiredQuizzes: requiredQuizzes.map((q) => ({
                ...q,
                passed: passedQuizIds.has(q.id),
            })),
            allRequiredQuizzesPassed,
            isComplete: completedCount === totalCount && allRequiredQuizzesPassed,
        };
    }
    async getNextLesson(courseId, userId) {
        const progress = await this.getCourseProgress(courseId, userId);
        return progress.nextLesson;
    }
    async getUserDashboard(userId) {
        const enrollments = await this.prisma.enrollment.findMany({
            where: { userId, status: { in: ['ACTIVE', 'COMPLETED'] } },
            include: {
                course: {
                    select: { id: true, title: true, slug: true, featuredImage: true },
                },
            },
            orderBy: { updatedAt: 'desc' },
        });
        const coursesWithProgress = await Promise.all(enrollments.map(async (enrollment) => {
            const progress = await this.getCourseProgress(enrollment.courseId, userId);
            return {
                ...enrollment,
                progress,
            };
        }));
        const certificates = await this.prisma.certificate.findMany({
            where: { userId, revokedAt: null },
            include: { course: { select: { title: true } } },
            orderBy: { issuedAt: 'desc' },
        });
        return {
            enrollments: coursesWithProgress,
            certificates,
            stats: {
                totalCourses: enrollments.length,
                completedCourses: enrollments.filter((e) => e.status === 'COMPLETED').length,
                totalCertificates: certificates.length,
            },
        };
    }
};
exports.ProgressService = ProgressService;
exports.ProgressService = ProgressService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], ProgressService);


/***/ }),
/* 177 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CertificateGeneratorService = void 0;
const common_1 = __webpack_require__(2);
const config_1 = __webpack_require__(13);
const fs = __webpack_require__(4);
const path = __webpack_require__(3);
const pdfkit_1 = __webpack_require__(178);
let CertificateGeneratorService = class CertificateGeneratorService {
    constructor(configService) {
        this.configService = configService;
        this.uploadsDir = path.join(process.cwd(), 'uploads', 'certificates');
        this.baseUrl = this.configService.get('BASE_URL') || 'http://localhost:3000';
        if (!fs.existsSync(this.uploadsDir)) {
            fs.mkdirSync(this.uploadsDir, { recursive: true });
        }
    }
    async generateCertificatePDF(data) {
        const fileName = `certificate-${data.certificateNumber}.pdf`;
        const filePath = path.join(this.uploadsDir, fileName);
        const verifyUrl = `${this.baseUrl}/lms/certificates/verify/${data.verificationHash}`;
        await this.createPDF(data, filePath, verifyUrl);
        return {
            filePath: `/uploads/certificates/${fileName}`,
            pdfUrl: `/uploads/certificates/${fileName}`,
        };
    }
    createPDF(data, filePath, verifyUrl) {
        return new Promise((resolve, reject) => {
            const doc = new pdfkit_1.default({
                size: 'A4',
                layout: 'landscape',
                margins: { top: 50, bottom: 50, left: 50, right: 50 },
            });
            const stream = fs.createWriteStream(filePath);
            doc.pipe(stream);
            const pageWidth = doc.page.width;
            const pageHeight = doc.page.height;
            doc.rect(0, 0, pageWidth, pageHeight).fill('#f8fafc');
            doc
                .lineWidth(3)
                .strokeColor('#6366f1')
                .rect(30, 30, pageWidth - 60, pageHeight - 60)
                .stroke();
            doc
                .lineWidth(1)
                .strokeColor('#a5b4fc')
                .rect(40, 40, pageWidth - 80, pageHeight - 80)
                .stroke();
            doc
                .lineWidth(4)
                .strokeColor('#6366f1')
                .moveTo(50, 50)
                .lineTo(pageWidth - 50, 50)
                .stroke();
            doc
                .fontSize(42)
                .fillColor('#1e293b')
                .font('Helvetica-Bold')
                .text('Certificate of Completion', 0, 80, { align: 'center' });
            doc
                .fontSize(14)
                .fillColor('#64748b')
                .font('Helvetica')
                .text('This is to certify that', 0, 140, { align: 'center' });
            doc
                .fontSize(36)
                .fillColor('#6366f1')
                .font('Helvetica-Bold')
                .text(data.studentName, 0, 170, { align: 'center' });
            const nameWidth = doc.widthOfString(data.studentName);
            const nameX = (pageWidth - nameWidth) / 2;
            doc
                .lineWidth(2)
                .strokeColor('#6366f1')
                .moveTo(nameX, 215)
                .lineTo(nameX + nameWidth, 215)
                .stroke();
            doc
                .fontSize(14)
                .fillColor('#64748b')
                .font('Helvetica')
                .text('has successfully completed the course', 0, 235, { align: 'center' });
            doc
                .fontSize(28)
                .fillColor('#1e293b')
                .font('Helvetica-Bold')
                .text(data.courseName, 50, 265, { align: 'center', width: pageWidth - 100 });
            const footerY = pageHeight - 120;
            doc.lineWidth(1).strokeColor('#334155').moveTo(100, footerY).lineTo(280, footerY).stroke();
            doc
                .fontSize(12)
                .fillColor('#1e293b')
                .font('Helvetica-Bold')
                .text(data.instructorName, 100, footerY + 10, { width: 180, align: 'center' });
            doc
                .fontSize(10)
                .fillColor('#64748b')
                .font('Helvetica')
                .text('Course Instructor', 100, footerY + 28, { width: 180, align: 'center' });
            const formattedDate = data.issuedAt.toLocaleDateString('en-US', {
                year: 'numeric',
                month: 'long',
                day: 'numeric',
            });
            doc
                .fontSize(11)
                .fillColor('#64748b')
                .font('Helvetica')
                .text(`Date: ${formattedDate}`, pageWidth - 300, footerY + 5, {
                width: 200,
                align: 'right',
            });
            doc
                .fontSize(10)
                .text(`Certificate #: ${data.certificateNumber}`, pageWidth - 300, footerY + 22, {
                width: 200,
                align: 'right',
            });
            doc
                .fontSize(9)
                .fillColor('#6366f1')
                .text(`Verify: ${verifyUrl}`, pageWidth - 300, footerY + 39, {
                width: 200,
                align: 'right',
            });
            doc
                .fontSize(10)
                .fillColor('#94a3b8')
                .text('WordPress Node LMS', 0, pageHeight - 60, { align: 'center' });
            doc.end();
            stream.on('finish', () => resolve());
            stream.on('error', reject);
        });
    }
};
exports.CertificateGeneratorService = CertificateGeneratorService;
exports.CertificateGeneratorService = CertificateGeneratorService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof config_1.ConfigService !== "undefined" && config_1.ConfigService) === "function" ? _a : Object])
], CertificateGeneratorService);


/***/ }),
/* 178 */
/***/ ((module) => {

module.exports = require("pdfkit");

/***/ }),
/* 179 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 RecommendationsService_1;
var _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.RecommendationsService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const recommendation_engine_service_1 = __webpack_require__(180);
let RecommendationsService = RecommendationsService_1 = class RecommendationsService {
    constructor(prisma, engine) {
        this.prisma = prisma;
        this.engine = engine;
        this.logger = new common_1.Logger(RecommendationsService_1.name);
    }
    async getRelatedPosts(postId, limit = 6, userId) {
        try {
            if (!userId) {
                const cached = await this.getCachedRecommendations('post', postId, 'post', 'related');
                if (cached) {
                    return { ...cached, cached: true };
                }
            }
            const post = await this.prisma.post.findUnique({
                where: { id: postId },
                select: { id: true, title: true, authorId: true, customFields: true },
            });
            if (!post) {
                return this.emptyResult('post', postId, 'related');
            }
            const requestLimit = userId ? limit + 10 : limit;
            let items = await this.engine.getRelatedPosts(post, requestLimit);
            if (userId && items.length > 0) {
                const viewedPosts = await this.prisma.userInteraction.findMany({
                    where: {
                        userId,
                        contentType: 'post',
                        interactionType: 'view',
                    },
                    select: { contentId: true },
                    take: 100,
                });
                const viewedIds = new Set(viewedPosts.map((v) => v.contentId));
                items = items.filter((item) => !viewedIds.has(item.id)).slice(0, limit);
            }
            if (!userId) {
                await this.cacheRecommendations('post', postId, 'post', 'related', items);
            }
            return {
                items,
                algorithm: 'related',
                sourceType: 'post',
                sourceId: postId,
                cached: false,
            };
        }
        catch (error) {
            this.logger.error(`Failed to get related posts for ${postId}:`, error);
            return this.emptyResult('post', postId, 'related');
        }
    }
    async getRelatedPages(pageId, limit = 6) {
        try {
            const cached = await this.getCachedRecommendations('page', pageId, 'page', 'related');
            if (cached) {
                return { ...cached, cached: true };
            }
            const page = await this.prisma.page.findUnique({
                where: { id: pageId },
                select: { id: true, title: true, template: true },
            });
            if (!page) {
                return this.emptyResult('page', pageId, 'related');
            }
            const items = await this.engine.getRelatedPages(page, limit);
            await this.cacheRecommendations('page', pageId, 'page', 'related', items);
            return {
                items,
                algorithm: 'related',
                sourceType: 'page',
                sourceId: pageId,
                cached: false,
            };
        }
        catch (error) {
            this.logger.error(`Failed to get related pages for ${pageId}:`, error);
            return this.emptyResult('page', pageId, 'related');
        }
    }
    async getRelatedProducts(productId, limit = 6, userId) {
        try {
            if (!userId) {
                const cached = await this.getCachedRecommendations('product', productId, 'product', 'related');
                if (cached) {
                    return { ...cached, cached: true };
                }
            }
            const product = await this.prisma.product.findUnique({
                where: { id: productId },
                select: { id: true, name: true, categoryId: true, tags: true },
            });
            if (!product) {
                return this.emptyResult('product', productId, 'related');
            }
            const requestLimit = userId ? limit + 10 : limit;
            let items = await this.engine.getRelatedProducts(product, requestLimit);
            if (userId && items.length > 0) {
                const viewedProducts = await this.prisma.userInteraction.findMany({
                    where: {
                        userId,
                        contentType: 'product',
                        interactionType: { in: ['view', 'purchase'] },
                    },
                    select: { contentId: true },
                    take: 100,
                });
                const viewedIds = new Set(viewedProducts.map((v) => v.contentId));
                items = items.filter((item) => !viewedIds.has(item.id)).slice(0, limit);
            }
            if (!userId) {
                await this.cacheRecommendations('product', productId, 'product', 'related', items);
            }
            return {
                items,
                algorithm: 'related',
                sourceType: 'product',
                sourceId: productId,
                cached: false,
            };
        }
        catch (error) {
            this.logger.error(`Failed to get related products for ${productId}:`, error);
            return this.emptyResult('product', productId, 'related');
        }
    }
    async getRelatedCourses(courseId, limit = 6) {
        try {
            const cached = await this.getCachedRecommendations('course', courseId, 'course', 'related');
            if (cached) {
                return { ...cached, cached: true };
            }
            const course = await this.prisma.course.findUnique({
                where: { id: courseId },
                select: { id: true, title: true, category: true, level: true },
            });
            if (!course) {
                return this.emptyResult('course', courseId, 'related');
            }
            const items = await this.engine.getRelatedCourses(course, limit);
            await this.cacheRecommendations('course', courseId, 'course', 'related', items);
            return {
                items,
                algorithm: 'related',
                sourceType: 'course',
                sourceId: courseId,
                cached: false,
            };
        }
        catch (error) {
            this.logger.error(`Failed to get related courses for ${courseId}:`, error);
            return this.emptyResult('course', courseId, 'related');
        }
    }
    async getTrending(contentType, limit = 6, timeframeDays = 7) {
        try {
            const cacheKey = `trending_${timeframeDays}`;
            const cached = await this.getCachedRecommendations('global', cacheKey, contentType, 'trending');
            if (cached) {
                return { ...cached, cached: true };
            }
            const items = await this.engine.getTrending(contentType, limit, timeframeDays);
            await this.cacheRecommendations('global', cacheKey, contentType, 'trending', items, 60);
            return {
                items,
                algorithm: 'trending',
                sourceType: 'global',
                sourceId: cacheKey,
                cached: false,
            };
        }
        catch (error) {
            this.logger.error(`Failed to get trending ${contentType}:`, error);
            return this.emptyResult('global', 'trending', 'trending');
        }
    }
    async getPopular(contentType, limit = 6) {
        try {
            const cached = await this.getCachedRecommendations('global', 'popular', contentType, 'popular');
            if (cached) {
                return { ...cached, cached: true };
            }
            const items = await this.engine.getPopular(contentType, limit);
            await this.cacheRecommendations('global', 'popular', contentType, 'popular', items, 120);
            return {
                items,
                algorithm: 'popular',
                sourceType: 'global',
                sourceId: 'popular',
                cached: false,
            };
        }
        catch (error) {
            this.logger.error(`Failed to get popular ${contentType}:`, error);
            return this.emptyResult('global', 'popular', 'popular');
        }
    }
    async getPersonalized(userId, contentType, limit = 6) {
        try {
            const items = await this.engine.getPersonalized(userId, contentType, limit);
            return {
                items,
                algorithm: 'personalized',
                sourceType: 'user',
                sourceId: userId,
                cached: false,
            };
        }
        catch (error) {
            this.logger.error(`Failed to get personalized ${contentType} for user ${userId}:`, error);
            return this.getPopular(contentType, limit);
        }
    }
    async getCachedRecommendations(sourceType, sourceId, targetType, algorithm) {
        try {
            const cached = await this.prisma.recommendationCache.findUnique({
                where: {
                    sourceType_sourceId_targetType_algorithm: {
                        sourceType,
                        sourceId,
                        targetType,
                        algorithm,
                    },
                },
            });
            if (cached && cached.expiresAt > new Date()) {
                return {
                    items: cached.recommendations,
                    algorithm,
                    sourceType,
                    sourceId,
                    cached: true,
                };
            }
            return null;
        }
        catch {
            return null;
        }
    }
    async cacheRecommendations(sourceType, sourceId, targetType, algorithm, items, durationMinutes = 30) {
        try {
            const expiresAt = new Date(Date.now() + durationMinutes * 60 * 1000);
            await this.prisma.recommendationCache.upsert({
                where: {
                    sourceType_sourceId_targetType_algorithm: {
                        sourceType,
                        sourceId,
                        targetType,
                        algorithm,
                    },
                },
                update: {
                    recommendations: items,
                    expiresAt,
                },
                create: {
                    sourceType,
                    sourceId,
                    targetType,
                    algorithm,
                    recommendations: items,
                    expiresAt,
                },
            });
        }
        catch (error) {
            this.logger.warn('Failed to cache recommendations:', error);
        }
    }
    emptyResult(sourceType, sourceId, algorithm) {
        return {
            items: [],
            algorithm,
            sourceType,
            sourceId,
            cached: false,
        };
    }
    async clearCache(sourceType, sourceId) {
        const where = {};
        if (sourceType)
            where.sourceType = sourceType;
        if (sourceId)
            where.sourceId = sourceId;
        const result = await this.prisma.recommendationCache.deleteMany({ where });
        return result.count;
    }
    async clearExpiredCache() {
        const result = await this.prisma.recommendationCache.deleteMany({
            where: { expiresAt: { lt: new Date() } },
        });
        return result.count;
    }
    async getCollaborativeRecommendations(contentId, contentType, limit = 6) {
        try {
            const cached = await this.getCachedRecommendations(contentType, contentId, contentType, 'collaborative');
            if (cached) {
                return { ...cached, cached: true };
            }
            const items = await this.engine.getCollaborativeRecommendations(contentId, contentType, limit);
            await this.cacheRecommendations(contentType, contentId, contentType, 'collaborative', items, 30);
            return {
                items,
                algorithm: 'collaborative',
                sourceType: contentType,
                sourceId: contentId,
                cached: false,
            };
        }
        catch (error) {
            this.logger.error(`Failed to get collaborative recommendations: ${error.message}`);
            return this.emptyResult(contentType, contentId, 'collaborative');
        }
    }
    async getFrequentlyBoughtTogether(productId, limit = 4) {
        try {
            const cached = await this.getCachedRecommendations('product', productId, 'product', 'bought_together');
            if (cached) {
                return { ...cached, cached: true };
            }
            const items = await this.engine.getFrequentlyBoughtTogether(productId, limit);
            await this.cacheRecommendations('product', productId, 'product', 'bought_together', items, 60);
            return {
                items,
                algorithm: 'bought_together',
                sourceType: 'product',
                sourceId: productId,
                cached: false,
            };
        }
        catch (error) {
            this.logger.error(`Failed to get frequently bought together: ${error.message}`);
            return this.emptyResult('product', productId, 'bought_together');
        }
    }
    async getSimilarUsersRecommendations(userId, contentType, limit = 6) {
        try {
            const cached = await this.getCachedRecommendations('user', userId, contentType, 'similar_users');
            if (cached) {
                return { ...cached, cached: true };
            }
            const items = await this.engine.getSimilarUserRecommendations(userId, contentType, limit);
            await this.cacheRecommendations('user', userId, contentType, 'similar_users', items, 15);
            return {
                items,
                algorithm: 'similar_users',
                sourceType: 'user',
                sourceId: userId,
                cached: false,
            };
        }
        catch (error) {
            this.logger.error(`Failed to get similar users recommendations: ${error.message}`);
            return this.emptyResult('user', userId, 'similar_users');
        }
    }
};
exports.RecommendationsService = RecommendationsService;
exports.RecommendationsService = RecommendationsService = RecommendationsService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof recommendation_engine_service_1.RecommendationEngineService !== "undefined" && recommendation_engine_service_1.RecommendationEngineService) === "function" ? _b : Object])
], RecommendationsService);


/***/ }),
/* 180 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 RecommendationEngineService_1;
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.RecommendationEngineService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let RecommendationEngineService = RecommendationEngineService_1 = class RecommendationEngineService {
    constructor(prisma) {
        this.prisma = prisma;
        this.logger = new common_1.Logger(RecommendationEngineService_1.name);
    }
    async getRelatedPosts(post, limit) {
        const relatedPosts = await this.prisma.post.findMany({
            where: {
                id: { not: post.id },
                status: 'PUBLISHED',
                OR: [
                    { authorId: post.authorId },
                ],
            },
            select: {
                id: true,
                title: true,
                slug: true,
                excerpt: true,
                featuredImage: true,
                publishedAt: true,
                author: { select: { name: true } },
            },
            orderBy: { publishedAt: 'desc' },
            take: limit,
        });
        if (relatedPosts.length < limit) {
            const additionalPosts = await this.prisma.post.findMany({
                where: {
                    id: { notIn: [post.id, ...relatedPosts.map((p) => p.id)] },
                    status: 'PUBLISHED',
                },
                select: {
                    id: true,
                    title: true,
                    slug: true,
                    excerpt: true,
                    featuredImage: true,
                    publishedAt: true,
                    author: { select: { name: true } },
                },
                orderBy: { publishedAt: 'desc' },
                take: limit - relatedPosts.length,
            });
            relatedPosts.push(...additionalPosts);
        }
        return relatedPosts.map((p, idx) => ({
            id: p.id,
            type: 'post',
            title: p.title,
            slug: p.slug,
            excerpt: p.excerpt || undefined,
            image: p.featuredImage || undefined,
            score: 1 - idx * 0.1,
            metadata: { author: p.author?.name },
        }));
    }
    async getRelatedPages(page, limit) {
        const relatedPages = await this.prisma.page.findMany({
            where: {
                id: { not: page.id },
                status: 'PUBLISHED',
                ...(page.template ? { template: page.template } : {}),
            },
            select: {
                id: true,
                title: true,
                slug: true,
                featuredImage: true,
            },
            orderBy: { updatedAt: 'desc' },
            take: limit,
        });
        if (relatedPages.length < limit) {
            const additionalPages = await this.prisma.page.findMany({
                where: {
                    id: { notIn: [page.id, ...relatedPages.map((p) => p.id)] },
                    status: 'PUBLISHED',
                },
                select: {
                    id: true,
                    title: true,
                    slug: true,
                    featuredImage: true,
                },
                orderBy: { updatedAt: 'desc' },
                take: limit - relatedPages.length,
            });
            relatedPages.push(...additionalPages);
        }
        return relatedPages.map((p, idx) => ({
            id: p.id,
            type: 'page',
            title: p.title,
            slug: p.slug,
            image: p.featuredImage || undefined,
            score: 1 - idx * 0.1,
        }));
    }
    async getRelatedProducts(product, limit) {
        const conditions = [];
        if (product.categoryId) {
            conditions.push({ categoryId: product.categoryId });
        }
        const relatedProducts = await this.prisma.product.findMany({
            where: {
                id: { not: product.id },
                status: 'ACTIVE',
                ...(conditions.length > 0 ? { OR: conditions } : {}),
            },
            select: {
                id: true,
                name: true,
                slug: true,
                description: true,
                images: true,
                price: true,
                salePrice: true,
                category: { select: { name: true } },
            },
            orderBy: { createdAt: 'desc' },
            take: limit,
        });
        if (relatedProducts.length < limit) {
            const additionalProducts = await this.prisma.product.findMany({
                where: {
                    id: { notIn: [product.id, ...relatedProducts.map((p) => p.id)] },
                    status: 'ACTIVE',
                },
                select: {
                    id: true,
                    name: true,
                    slug: true,
                    description: true,
                    images: true,
                    price: true,
                    salePrice: true,
                    category: { select: { name: true } },
                },
                orderBy: { createdAt: 'desc' },
                take: limit - relatedProducts.length,
            });
            relatedProducts.push(...additionalProducts);
        }
        return relatedProducts.map((p, idx) => ({
            id: p.id,
            type: 'product',
            title: p.name,
            slug: p.slug,
            excerpt: p.description ? p.description.substring(0, 150) : undefined,
            image: Array.isArray(p.images) && p.images.length > 0 ? String(p.images[0]) : undefined,
            score: 1 - idx * 0.1,
            metadata: {
                price: p.price,
                salePrice: p.salePrice,
                category: p.category?.name,
            },
        }));
    }
    async getRelatedCourses(course, limit) {
        const conditions = [];
        if (course.category) {
            conditions.push({ category: course.category });
        }
        if (course.level) {
            conditions.push({ level: course.level });
        }
        const relatedCourses = await this.prisma.course.findMany({
            where: {
                id: { not: course.id },
                status: 'PUBLISHED',
                ...(conditions.length > 0 ? { OR: conditions } : {}),
            },
            select: {
                id: true,
                title: true,
                slug: true,
                description: true,
                featuredImage: true,
                priceAmount: true,
                category: true,
                level: true,
                instructor: { select: { name: true } },
            },
            orderBy: { createdAt: 'desc' },
            take: limit,
        });
        if (relatedCourses.length < limit) {
            const additionalCourses = await this.prisma.course.findMany({
                where: {
                    id: { notIn: [course.id, ...relatedCourses.map((c) => c.id)] },
                    status: 'PUBLISHED',
                },
                select: {
                    id: true,
                    title: true,
                    slug: true,
                    description: true,
                    featuredImage: true,
                    priceAmount: true,
                    category: true,
                    level: true,
                    instructor: { select: { name: true } },
                },
                orderBy: { createdAt: 'desc' },
                take: limit - relatedCourses.length,
            });
            relatedCourses.push(...additionalCourses);
        }
        return relatedCourses.map((c, idx) => ({
            id: c.id,
            type: 'course',
            title: c.title,
            slug: c.slug,
            excerpt: c.description ? c.description.substring(0, 150) : undefined,
            image: c.featuredImage || undefined,
            score: 1 - idx * 0.1,
            metadata: {
                price: c.priceAmount,
                category: c.category,
                level: c.level,
                instructor: c.instructor?.name,
            },
        }));
    }
    async getTrending(contentType, limit, timeframeDays) {
        const startDate = new Date();
        startDate.setDate(startDate.getDate() - timeframeDays);
        const interactions = await this.prisma.userInteraction.groupBy({
            by: ['contentId'],
            where: {
                contentType,
                createdAt: { gte: startDate },
            },
            _count: { contentId: true },
            orderBy: { _count: { contentId: 'desc' } },
            take: limit,
        });
        if (interactions.length === 0) {
            return this.getRecent(contentType, limit);
        }
        const contentIds = interactions.map((i) => i.contentId);
        return this.fetchContentByIds(contentType, contentIds, interactions);
    }
    async getPopular(contentType, limit) {
        const interactions = await this.prisma.userInteraction.groupBy({
            by: ['contentId'],
            where: { contentType },
            _count: { contentId: true },
            orderBy: { _count: { contentId: 'desc' } },
            take: limit,
        });
        if (interactions.length === 0) {
            return this.getRecent(contentType, limit);
        }
        const contentIds = interactions.map((i) => i.contentId);
        return this.fetchContentByIds(contentType, contentIds, interactions);
    }
    async getPersonalized(userId, contentType, limit) {
        const userInteractions = await this.prisma.userInteraction.findMany({
            where: { userId, contentType },
            orderBy: { createdAt: 'desc' },
            take: 20,
            select: { contentId: true },
        });
        if (userInteractions.length === 0) {
            return this.getTrending(contentType, limit, 7);
        }
        const viewedIds = userInteractions.map((i) => i.contentId);
        return this.getContentNotViewed(contentType, viewedIds, limit);
    }
    async getRecent(contentType, limit) {
        switch (contentType) {
            case 'post':
                const posts = await this.prisma.post.findMany({
                    where: { status: 'PUBLISHED' },
                    select: { id: true, title: true, slug: true, excerpt: true, featuredImage: true },
                    orderBy: { publishedAt: 'desc' },
                    take: limit,
                });
                return posts.map((p, idx) => ({
                    id: p.id,
                    type: 'post',
                    title: p.title,
                    slug: p.slug,
                    excerpt: p.excerpt || undefined,
                    image: p.featuredImage || undefined,
                    score: 1 - idx * 0.1,
                }));
            case 'product':
                const products = await this.prisma.product.findMany({
                    where: { status: 'ACTIVE' },
                    select: {
                        id: true,
                        name: true,
                        slug: true,
                        description: true,
                        images: true,
                        price: true,
                    },
                    orderBy: { createdAt: 'desc' },
                    take: limit,
                });
                return products.map((p, idx) => ({
                    id: p.id,
                    type: 'product',
                    title: p.name,
                    slug: p.slug,
                    excerpt: p.description ? p.description.substring(0, 150) : undefined,
                    image: Array.isArray(p.images) && p.images.length > 0 ? String(p.images[0]) : undefined,
                    score: 1 - idx * 0.1,
                    metadata: { price: p.price },
                }));
            case 'course':
                const courses = await this.prisma.course.findMany({
                    where: { status: 'PUBLISHED' },
                    select: {
                        id: true,
                        title: true,
                        slug: true,
                        description: true,
                        featuredImage: true,
                        priceAmount: true,
                    },
                    orderBy: { createdAt: 'desc' },
                    take: limit,
                });
                return courses.map((c, idx) => ({
                    id: c.id,
                    type: 'course',
                    title: c.title,
                    slug: c.slug,
                    excerpt: c.description ? c.description.substring(0, 150) : undefined,
                    image: c.featuredImage || undefined,
                    score: 1 - idx * 0.1,
                    metadata: { price: c.priceAmount },
                }));
            default:
                return [];
        }
    }
    async fetchContentByIds(contentType, contentIds, interactions) {
        const scoreMap = new Map(interactions.map((i) => [i.contentId, i._count.contentId]));
        const maxScore = Math.max(...interactions.map((i) => i._count.contentId));
        switch (contentType) {
            case 'post':
                const posts = await this.prisma.post.findMany({
                    where: { id: { in: contentIds }, status: 'PUBLISHED' },
                    select: { id: true, title: true, slug: true, excerpt: true, featuredImage: true },
                });
                return posts
                    .map((p) => ({
                    id: p.id,
                    type: 'post',
                    title: p.title,
                    slug: p.slug,
                    excerpt: p.excerpt || undefined,
                    image: p.featuredImage || undefined,
                    score: (scoreMap.get(p.id) || 0) / maxScore,
                }))
                    .sort((a, b) => (b.score || 0) - (a.score || 0));
            case 'product':
                const products = await this.prisma.product.findMany({
                    where: { id: { in: contentIds }, status: 'ACTIVE' },
                    select: {
                        id: true,
                        name: true,
                        slug: true,
                        description: true,
                        images: true,
                        price: true,
                    },
                });
                return products
                    .map((p) => ({
                    id: p.id,
                    type: 'product',
                    title: p.name,
                    slug: p.slug,
                    excerpt: p.description ? p.description.substring(0, 150) : undefined,
                    image: Array.isArray(p.images) && p.images.length > 0 ? String(p.images[0]) : undefined,
                    score: (scoreMap.get(p.id) || 0) / maxScore,
                    metadata: { price: p.price },
                }))
                    .sort((a, b) => (b.score || 0) - (a.score || 0));
            case 'course':
                const courses2 = await this.prisma.course.findMany({
                    where: { id: { in: contentIds }, status: 'PUBLISHED' },
                    select: {
                        id: true,
                        title: true,
                        slug: true,
                        description: true,
                        featuredImage: true,
                        priceAmount: true,
                    },
                });
                return courses2
                    .map((c) => ({
                    id: c.id,
                    type: 'course',
                    title: c.title,
                    slug: c.slug,
                    excerpt: c.description ? c.description.substring(0, 150) : undefined,
                    image: c.featuredImage || undefined,
                    score: (scoreMap.get(c.id) || 0) / maxScore,
                    metadata: { price: c.priceAmount },
                }))
                    .sort((a, b) => (b.score || 0) - (a.score || 0));
            default:
                return [];
        }
    }
    async fetchContentByIdsSimple(contentType, contentIds) {
        switch (contentType) {
            case 'post':
                const posts = await this.prisma.post.findMany({
                    where: { id: { in: contentIds }, status: 'PUBLISHED' },
                    select: { id: true, title: true, slug: true, excerpt: true, featuredImage: true },
                });
                return posts.map((p, idx) => ({
                    id: p.id,
                    type: 'post',
                    title: p.title,
                    slug: p.slug,
                    excerpt: p.excerpt || undefined,
                    image: p.featuredImage || undefined,
                    score: 1 - idx * 0.05,
                }));
            case 'product':
                const products = await this.prisma.product.findMany({
                    where: { id: { in: contentIds }, status: 'ACTIVE' },
                    select: {
                        id: true,
                        name: true,
                        slug: true,
                        description: true,
                        images: true,
                        price: true,
                    },
                });
                return products.map((p, idx) => ({
                    id: p.id,
                    type: 'product',
                    title: p.name,
                    slug: p.slug,
                    excerpt: p.description ? p.description.substring(0, 150) : undefined,
                    image: Array.isArray(p.images) && p.images.length > 0 ? String(p.images[0]) : undefined,
                    score: 1 - idx * 0.05,
                    metadata: { price: p.price },
                }));
            case 'course':
                const courses = await this.prisma.course.findMany({
                    where: { id: { in: contentIds }, status: 'PUBLISHED' },
                    select: {
                        id: true,
                        title: true,
                        slug: true,
                        description: true,
                        featuredImage: true,
                        priceAmount: true,
                    },
                });
                return courses.map((c, idx) => ({
                    id: c.id,
                    type: 'course',
                    title: c.title,
                    slug: c.slug,
                    excerpt: c.description ? c.description.substring(0, 150) : undefined,
                    image: c.featuredImage || undefined,
                    score: 1 - idx * 0.05,
                    metadata: { price: c.priceAmount },
                }));
            default:
                return [];
        }
    }
    async getContentNotViewed(contentType, viewedIds, limit) {
        switch (contentType) {
            case 'post':
                const posts = await this.prisma.post.findMany({
                    where: { id: { notIn: viewedIds }, status: 'PUBLISHED' },
                    select: { id: true, title: true, slug: true, excerpt: true, featuredImage: true },
                    orderBy: { publishedAt: 'desc' },
                    take: limit,
                });
                return posts.map((p, idx) => ({
                    id: p.id,
                    type: 'post',
                    title: p.title,
                    slug: p.slug,
                    excerpt: p.excerpt || undefined,
                    image: p.featuredImage || undefined,
                    score: 1 - idx * 0.1,
                }));
            case 'product':
                const products = await this.prisma.product.findMany({
                    where: { id: { notIn: viewedIds }, status: 'ACTIVE' },
                    select: {
                        id: true,
                        name: true,
                        slug: true,
                        description: true,
                        images: true,
                        price: true,
                    },
                    orderBy: { createdAt: 'desc' },
                    take: limit,
                });
                return products.map((p, idx) => ({
                    id: p.id,
                    type: 'product',
                    title: p.name,
                    slug: p.slug,
                    excerpt: p.description ? p.description.substring(0, 150) : undefined,
                    image: Array.isArray(p.images) && p.images.length > 0 ? String(p.images[0]) : undefined,
                    score: 1 - idx * 0.1,
                    metadata: { price: p.price },
                }));
            case 'course':
                const courses3 = await this.prisma.course.findMany({
                    where: { id: { notIn: viewedIds }, status: 'PUBLISHED' },
                    select: {
                        id: true,
                        title: true,
                        slug: true,
                        description: true,
                        featuredImage: true,
                        priceAmount: true,
                    },
                    orderBy: { createdAt: 'desc' },
                    take: limit,
                });
                return courses3.map((c, idx) => ({
                    id: c.id,
                    type: 'course',
                    title: c.title,
                    slug: c.slug,
                    excerpt: c.description ? c.description.substring(0, 150) : undefined,
                    image: c.featuredImage || undefined,
                    score: 1 - idx * 0.1,
                    metadata: { price: c.priceAmount },
                }));
            default:
                return [];
        }
    }
    async getCollaborativeRecommendations(contentId, contentType, limit) {
        try {
            const usersWhoViewed = await this.prisma.userInteraction.findMany({
                where: {
                    contentId,
                    contentType,
                    interactionType: { in: ['view', 'click'] },
                    userId: { not: null },
                },
                select: { userId: true },
                distinct: ['userId'],
                take: 100,
            });
            const userIds = usersWhoViewed.map((u) => u.userId).filter((id) => id !== null);
            if (userIds.length === 0) {
                return this.getPopular(contentType, limit);
            }
            const otherInteractions = await this.prisma.userInteraction.groupBy({
                by: ['contentId'],
                where: {
                    userId: { in: userIds },
                    contentType,
                    contentId: { not: contentId },
                    interactionType: { in: ['view', 'click', 'purchase'] },
                },
                _count: { id: true },
                orderBy: { _count: { id: 'desc' } },
                take: limit * 2,
            });
            if (otherInteractions.length === 0) {
                return this.getPopular(contentType, limit);
            }
            const contentIds = otherInteractions.map((i) => i.contentId);
            const items = await this.fetchContentByIdsSimple(contentType, contentIds);
            const maxCount = otherInteractions[0]?._count?.id || 1;
            return items.slice(0, limit).map((item) => {
                const interaction = otherInteractions.find((i) => i.contentId === item.id);
                const score = interaction ? interaction._count.id / maxCount : 0.5;
                return { ...item, score: Math.max(0.1, score) };
            });
        }
        catch (error) {
            this.logger.error(`Collaborative filtering failed: ${error.message}`);
            return [];
        }
    }
    async getFrequentlyBoughtTogether(productId, limit) {
        try {
            const purchasers = await this.prisma.userInteraction.findMany({
                where: {
                    contentId: productId,
                    contentType: 'product',
                    interactionType: 'purchase',
                    userId: { not: null },
                },
                select: { userId: true, sessionId: true, createdAt: true },
                take: 500,
            });
            if (purchasers.length === 0) {
                return this.getRelatedProductsById(productId, limit);
            }
            const purchaseKeys = purchasers.map((p) => ({
                userId: p.userId,
                sessionId: p.sessionId,
                date: p.createdAt,
            }));
            const coPurchasePromises = purchaseKeys.map(async (pk) => {
                const windowStart = new Date(pk.date.getTime() - 30 * 60 * 1000);
                const windowEnd = new Date(pk.date.getTime() + 30 * 60 * 1000);
                const orConditions = [];
                if (pk.userId) {
                    orConditions.push({ userId: pk.userId });
                }
                if (pk.sessionId) {
                    orConditions.push({ sessionId: pk.sessionId });
                }
                if (orConditions.length === 0)
                    return [];
                return this.prisma.userInteraction.findMany({
                    where: {
                        OR: orConditions,
                        contentType: 'product',
                        contentId: { not: productId },
                        interactionType: 'purchase',
                        createdAt: { gte: windowStart, lte: windowEnd },
                    },
                    select: { contentId: true },
                });
            });
            const allCoPurchases = await Promise.all(coPurchasePromises);
            const flatCoPurchases = allCoPurchases.flat();
            if (flatCoPurchases.length === 0) {
                return this.getRelatedProductsById(productId, limit);
            }
            const countMap = new Map();
            flatCoPurchases.forEach((p) => {
                countMap.set(p.contentId, (countMap.get(p.contentId) || 0) + 1);
            });
            const sortedIds = Array.from(countMap.entries())
                .sort((a, b) => b[1] - a[1])
                .slice(0, limit)
                .map(([id]) => id);
            const products = await this.prisma.product.findMany({
                where: { id: { in: sortedIds }, status: 'ACTIVE' },
                select: {
                    id: true,
                    name: true,
                    slug: true,
                    description: true,
                    price: true,
                    images: true,
                },
            });
            const maxCount = Math.max(...countMap.values()) || 1;
            return sortedIds
                .map((id) => products.find((p) => p.id === id))
                .filter((p) => p !== undefined)
                .map((p) => ({
                id: p.id,
                type: 'product',
                title: p.name,
                slug: p.slug,
                excerpt: p.description ? p.description.substring(0, 150) : undefined,
                image: p.images?.[0] || undefined,
                score: (countMap.get(p.id) || 0) / maxCount,
                metadata: { price: p.price, algorithm: 'frequently_bought_together' },
            }));
        }
        catch (error) {
            this.logger.error(`Frequently bought together failed: ${error.message}`);
            return [];
        }
    }
    async getRelatedProductsById(productId, limit) {
        const product = await this.prisma.product.findUnique({
            where: { id: productId },
            select: { categoryId: true },
        });
        const related = await this.prisma.product.findMany({
            where: {
                id: { not: productId },
                status: 'ACTIVE',
                ...(product?.categoryId ? { categoryId: product.categoryId } : {}),
            },
            select: {
                id: true,
                name: true,
                slug: true,
                description: true,
                price: true,
                images: true,
            },
            take: limit,
            orderBy: { createdAt: 'desc' },
        });
        return related.map((p, idx) => ({
            id: p.id,
            type: 'product',
            title: p.name,
            slug: p.slug,
            excerpt: p.description ? p.description.substring(0, 150) : undefined,
            image: p.images?.[0] || undefined,
            score: 1 - idx * 0.1,
            metadata: { price: p.price },
        }));
    }
    async getSimilarUserRecommendations(userId, contentType, limit) {
        try {
            const userHistory = await this.prisma.userInteraction.findMany({
                where: { userId, contentType },
                select: { contentId: true },
                take: 50,
            });
            if (userHistory.length === 0) {
                return this.getPopular(contentType, limit);
            }
            const userContentIds = userHistory.map((h) => h.contentId);
            const similarUsers = await this.prisma.userInteraction.groupBy({
                by: ['userId'],
                where: {
                    contentId: { in: userContentIds },
                    userId: { not: userId },
                    NOT: { userId: null },
                },
                _count: { id: true },
                orderBy: { _count: { id: 'desc' } },
                take: 20,
            });
            const similarUserIds = similarUsers
                .map((u) => u.userId)
                .filter((id) => id !== null);
            if (similarUserIds.length === 0) {
                return this.getPopular(contentType, limit);
            }
            const recommendations = await this.prisma.userInteraction.groupBy({
                by: ['contentId'],
                where: {
                    userId: { in: similarUserIds },
                    contentType,
                    contentId: { notIn: userContentIds },
                },
                _count: { id: true },
                orderBy: { _count: { id: 'desc' } },
                take: limit * 2,
            });
            const contentIds = recommendations.map((r) => r.contentId);
            const items = await this.fetchContentByIdsSimple(contentType, contentIds);
            const maxCount = recommendations[0]?._count?.id || 1;
            return items.slice(0, limit).map((item) => {
                const rec = recommendations.find((r) => r.contentId === item.id);
                return {
                    ...item,
                    score: rec ? rec._count.id / maxCount : 0.5,
                    metadata: { ...item.metadata, algorithm: 'similar_users' },
                };
            });
        }
        catch (error) {
            this.logger.error(`Similar users recommendation failed: ${error.message}`);
            return [];
        }
    }
};
exports.RecommendationEngineService = RecommendationEngineService;
exports.RecommendationEngineService = RecommendationEngineService = RecommendationEngineService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], RecommendationEngineService);


/***/ }),
/* 181 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 RecommendationTrackingService_1;
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.RecommendationTrackingService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let RecommendationTrackingService = RecommendationTrackingService_1 = class RecommendationTrackingService {
    constructor(prisma) {
        this.prisma = prisma;
        this.logger = new common_1.Logger(RecommendationTrackingService_1.name);
    }
    async trackInteraction(dto) {
        try {
            await this.prisma.userInteraction.create({
                data: {
                    contentType: dto.contentType,
                    contentId: dto.contentId,
                    interactionType: dto.interactionType,
                    userId: dto.userId,
                    sessionId: dto.sessionId,
                    metadata: dto.metadata || {},
                },
            });
            return { success: true };
        }
        catch (error) {
            this.logger.error('Failed to track interaction:', error);
            return { success: false };
        }
    }
    async trackRecommendationClick(dto) {
        try {
            await this.prisma.recommendationClick.create({
                data: {
                    sourceType: dto.sourceType,
                    sourceId: dto.sourceId,
                    recommendationType: dto.recommendationType,
                    clickedType: dto.clickedType,
                    clickedId: dto.clickedId,
                    position: dto.position,
                    userId: dto.userId,
                    sessionId: dto.sessionId,
                },
            });
            await this.trackInteraction({
                contentType: dto.clickedType,
                contentId: dto.clickedId,
                interactionType: 'recommendation_click',
                userId: dto.userId,
                sessionId: dto.sessionId,
                metadata: {
                    sourceType: dto.sourceType,
                    sourceId: dto.sourceId,
                    recommendationType: dto.recommendationType,
                    position: dto.position,
                },
            });
            return { success: true };
        }
        catch (error) {
            this.logger.error('Failed to track recommendation click:', error);
            return { success: false };
        }
    }
    async getUserInteractions(userId, contentType, limit = 50) {
        const where = { userId };
        if (contentType) {
            where.contentType = contentType;
        }
        return this.prisma.userInteraction.findMany({
            where,
            orderBy: { createdAt: 'desc' },
            take: limit,
        });
    }
    async getInteractionCount(contentType, contentId) {
        return this.prisma.userInteraction.count({
            where: { contentType, contentId },
        });
    }
    async getInteractionBreakdown(contentType, contentId) {
        const interactions = await this.prisma.userInteraction.groupBy({
            by: ['interactionType'],
            where: { contentType, contentId },
            _count: { interactionType: true },
        });
        const breakdown = {};
        interactions.forEach((i) => {
            breakdown[i.interactionType] = i._count.interactionType;
        });
        return breakdown;
    }
    async cleanupOldInteractions(daysToKeep = 90) {
        const cutoffDate = new Date();
        cutoffDate.setDate(cutoffDate.getDate() - daysToKeep);
        const result = await this.prisma.userInteraction.deleteMany({
            where: {
                createdAt: { lt: cutoffDate },
                interactionType: { notIn: ['purchase', 'enroll'] },
            },
        });
        this.logger.log(`Cleaned up ${result.count} old interactions`);
        return result.count;
    }
    async cleanupOldClicks(daysToKeep = 30) {
        const cutoffDate = new Date();
        cutoffDate.setDate(cutoffDate.getDate() - daysToKeep);
        const result = await this.prisma.recommendationClick.deleteMany({
            where: { createdAt: { lt: cutoffDate } },
        });
        this.logger.log(`Cleaned up ${result.count} old recommendation clicks`);
        return result.count;
    }
};
exports.RecommendationTrackingService = RecommendationTrackingService;
exports.RecommendationTrackingService = RecommendationTrackingService = RecommendationTrackingService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], RecommendationTrackingService);


/***/ }),
/* 182 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.DevelopersService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const USER_SELECT = {
    id: true,
    name: true,
    email: true,
    avatar: true,
    role: true,
    createdAt: true,
    accountLockedUntil: true,
    lastLoginAt: true,
    username: true,
};
let DevelopersService = class DevelopersService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async create(userId, dto) {
        const existing = await this.prisma.developer.findUnique({
            where: { userId },
        });
        if (existing) {
            throw new common_1.BadRequestException('Developer profile already exists');
        }
        const baseSlug = dto.displayName
            .toLowerCase()
            .replace(/[^a-z0-9]+/g, '-')
            .replace(/^-|-$/g, '');
        let slug = baseSlug;
        let counter = 1;
        while (await this.prisma.developer.findUnique({ where: { slug } })) {
            slug = `${baseSlug}-${counter}`;
            counter++;
        }
        return this.prisma.developer.create({
            data: {
                userId,
                displayName: dto.displayName,
                slug,
                headline: dto.headline,
                bio: dto.bio,
                category: dto.category || 'FULLSTACK',
                skills: dto.skills || [],
                languages: dto.languages || [],
                frameworks: dto.frameworks || [],
                hourlyRate: dto.hourlyRate,
                minimumBudget: dto.minimumBudget,
                yearsOfExperience: dto.yearsOfExperience || 0,
                applicationNote: dto.applicationNote,
                websiteUrl: dto.websiteUrl,
                githubUrl: dto.githubUrl,
                linkedinUrl: dto.linkedinUrl,
                status: 'PENDING',
            },
            include: { user: { select: USER_SELECT } },
        });
    }
    async update(developerId, userId, dto, isAdmin = false) {
        const developer = await this.prisma.developer.findUnique({ where: { id: developerId } });
        if (!developer)
            throw new common_1.NotFoundException('Developer not found');
        if (!isAdmin && developer.userId !== userId)
            throw new common_1.ForbiddenException('Not authorized');
        return this.prisma.developer.update({
            where: { id: developerId },
            data: {
                ...dto,
                category: dto.category,
                portfolio: dto.portfolio ? JSON.parse(JSON.stringify(dto.portfolio)) : undefined,
                education: dto.education ? JSON.parse(JSON.stringify(dto.education)) : undefined,
                certifications: dto.certifications
                    ? JSON.parse(JSON.stringify(dto.certifications))
                    : undefined,
            },
            include: { user: { select: USER_SELECT } },
        });
    }
    async findById(id) {
        const developer = await this.prisma.developer.findUnique({
            where: { id },
            include: {
                user: { select: USER_SELECT },
                reviews: { where: { isApproved: true }, orderBy: { createdAt: 'desc' }, take: 10 },
            },
        });
        if (!developer)
            throw new common_1.NotFoundException('Developer not found');
        return developer;
    }
    async findBySlug(slug) {
        const developer = await this.prisma.developer.findUnique({
            where: { slug, status: 'ACTIVE' },
            include: {
                user: { select: { id: true, name: true, avatar: true } },
                reviews: {
                    where: { isApproved: true },
                    orderBy: { createdAt: 'desc' },
                    take: 10,
                    include: { reviewer: { select: { id: true, name: true, avatar: true } } },
                },
            },
        });
        if (!developer)
            throw new common_1.NotFoundException('Developer not found');
        return developer;
    }
    async findByUserId(userId) {
        return this.prisma.developer.findUnique({
            where: { userId },
            include: { user: { select: USER_SELECT } },
        });
    }
    async findAll(filters) {
        const { status, category, skills, minRate, maxRate, minRating, availability, search, sortBy = 'rating', page = 1, limit = 12, } = filters;
        const where = {};
        if (status)
            where.status = status;
        if (category)
            where.category = category;
        if (availability)
            where.availability = availability;
        if (minRating)
            where.rating = { gte: minRating };
        if (minRate || maxRate) {
            where.hourlyRate = {};
            if (minRate)
                where.hourlyRate.gte = minRate;
            if (maxRate)
                where.hourlyRate.lte = maxRate;
        }
        if (skills?.length)
            where.skills = { hasSome: skills };
        if (search) {
            where.OR = [
                { displayName: { contains: search, mode: 'insensitive' } },
                { headline: { contains: search, mode: 'insensitive' } },
                { bio: { contains: search, mode: 'insensitive' } },
            ];
        }
        const orderBy = {};
        if (sortBy === 'rating')
            orderBy.rating = 'desc';
        else if (sortBy === 'price_low')
            orderBy.hourlyRate = 'asc';
        else if (sortBy === 'price_high')
            orderBy.hourlyRate = 'desc';
        else if (sortBy === 'experience')
            orderBy.yearsOfExperience = 'desc';
        else if (sortBy === 'projects')
            orderBy.projectsCompleted = 'desc';
        else
            orderBy.createdAt = 'desc';
        const [developers, total] = await Promise.all([
            this.prisma.developer.findMany({
                where,
                orderBy,
                skip: (page - 1) * limit,
                take: limit,
                include: { user: { select: USER_SELECT } },
            }),
            this.prisma.developer.count({ where }),
        ]);
        return { developers, pagination: { page, limit, total, pages: Math.ceil(total / limit) } };
    }
    async approve(developerId) {
        const developer = await this.prisma.developer.findUnique({ where: { id: developerId } });
        if (!developer)
            throw new common_1.NotFoundException('Developer not found');
        if (developer.status !== 'PENDING')
            throw new common_1.BadRequestException('Developer is not pending approval');
        return this.prisma.developer.update({
            where: { id: developerId },
            data: { status: 'ACTIVE', isVerified: true, verifiedAt: new Date() },
        });
    }
    async reject(developerId, reason) {
        const developer = await this.prisma.developer.findUnique({ where: { id: developerId } });
        if (!developer)
            throw new common_1.NotFoundException('Developer not found');
        return this.prisma.developer.update({
            where: { id: developerId },
            data: { status: 'REJECTED', rejectionReason: reason },
        });
    }
    async suspend(developerId, reason) {
        return this.prisma.developer.update({
            where: { id: developerId },
            data: { status: 'SUSPENDED', suspensionReason: reason },
        });
    }
    async reactivate(developerId) {
        return this.prisma.developer.update({
            where: { id: developerId },
            data: { status: 'ACTIVE', suspensionReason: null },
        });
    }
    async setFeatured(developerId, featured, daysUntil = 30) {
        return this.prisma.developer.update({
            where: { id: developerId },
            data: {
                isFeatured: featured,
                featuredUntil: featured ? new Date(Date.now() + daysUntil * 24 * 60 * 60 * 1000) : null,
            },
        });
    }
    async getStatistics() {
        const [total, pending, active, suspended, byCategory, topRated] = await Promise.all([
            this.prisma.developer.count(),
            this.prisma.developer.count({ where: { status: 'PENDING' } }),
            this.prisma.developer.count({ where: { status: 'ACTIVE' } }),
            this.prisma.developer.count({ where: { status: 'SUSPENDED' } }),
            this.prisma.developer.groupBy({ by: ['category'], _count: true }),
            this.prisma.developer.findMany({
                where: { status: 'ACTIVE' },
                orderBy: { rating: 'desc' },
                take: 5,
                include: { user: { select: USER_SELECT } },
            }),
        ]);
        return { total, pending, active, suspended, byCategory, topRated };
    }
    async updateStats(developerId, projectRating, earnings) {
        const developer = await this.prisma.developer.findUnique({ where: { id: developerId } });
        if (!developer)
            return;
        const newReviewCount = developer.reviewCount + 1;
        const newRating = (developer.rating * developer.reviewCount + projectRating) / newReviewCount;
        await this.prisma.developer.update({
            where: { id: developerId },
            data: {
                rating: newRating,
                reviewCount: newReviewCount,
                projectsCompleted: developer.projectsCompleted + 1,
                totalEarnings: { increment: earnings },
            },
        });
    }
    async matchDevelopers(requirements, limit = 10) {
        const where = { status: 'ACTIVE', availability: 'available' };
        if (requirements.category)
            where.category = requirements.category;
        if (requirements.skills?.length)
            where.skills = { hasSome: requirements.skills };
        if (requirements.budget && requirements.budgetType === 'hourly') {
            where.hourlyRate = { lte: requirements.budget };
        }
        const developers = await this.prisma.developer.findMany({
            where,
            orderBy: [{ rating: 'desc' }, { projectsCompleted: 'desc' }],
            take: limit,
            include: { user: { select: USER_SELECT } },
        });
        return developers
            .map((dev) => {
            let score = dev.rating * 20;
            if (requirements.skills?.length) {
                const matchedSkills = requirements.skills.filter((s) => dev.skills.includes(s));
                score += (matchedSkills.length / requirements.skills.length) * 30;
            }
            score += Math.min(dev.projectsCompleted, 10) * 2;
            return { ...dev, matchScore: Math.round(score) };
        })
            .sort((a, b) => b.matchScore - a.matchScore);
    }
};
exports.DevelopersService = DevelopersService;
exports.DevelopersService = DevelopersService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], DevelopersService);


/***/ }),
/* 183 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ShopModule = void 0;
const common_1 = __webpack_require__(2);
const config_1 = __webpack_require__(13);
const prisma_module_1 = __webpack_require__(15);
const products_service_1 = __webpack_require__(172);
const categories_service_1 = __webpack_require__(173);
const cart_service_1 = __webpack_require__(184);
const orders_service_1 = __webpack_require__(186);
const stripe_service_1 = __webpack_require__(187);
const products_controller_1 = __webpack_require__(188);
const categories_controller_1 = __webpack_require__(190);
const cart_controller_1 = __webpack_require__(192);
const orders_controller_1 = __webpack_require__(194);
const checkout_controller_1 = __webpack_require__(196);
const storefront_controller_1 = __webpack_require__(197);
const feature_guard_1 = __webpack_require__(162);
let ShopModule = class ShopModule {
};
exports.ShopModule = ShopModule;
exports.ShopModule = ShopModule = __decorate([
    (0, common_1.Module)({
        imports: [prisma_module_1.PrismaModule, config_1.ConfigModule],
        controllers: [
            products_controller_1.ProductsController,
            categories_controller_1.CategoriesController,
            orders_controller_1.AdminOrdersController,
            checkout_controller_1.RefundsController,
            cart_controller_1.CartController,
            orders_controller_1.OrdersController,
            orders_controller_1.UserOrdersController,
            checkout_controller_1.CheckoutController,
            storefront_controller_1.StorefrontController,
        ],
        providers: [
            products_service_1.ProductsService,
            categories_service_1.CategoriesService,
            cart_service_1.CartService,
            orders_service_1.OrdersService,
            stripe_service_1.StripeService,
            feature_guard_1.FeatureGuard,
        ],
        exports: [products_service_1.ProductsService, categories_service_1.CategoriesService, cart_service_1.CartService, orders_service_1.OrdersService, stripe_service_1.StripeService],
    })
], ShopModule);


/***/ }),
/* 184 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CartService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const library_1 = __webpack_require__(185);
let CartService = class CartService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async getOrCreateCart(userId, sessionId) {
        if (!userId && !sessionId) {
            throw new common_1.BadRequestException('User ID or Session ID is required');
        }
        const cartInclude = {
            items: {
                include: {
                    product: { include: { category: true } },
                    variant: true,
                    course: {
                        select: {
                            id: true,
                            title: true,
                            slug: true,
                            featuredImage: true,
                            priceAmount: true,
                            priceType: true,
                            instructor: { select: { id: true, name: true } },
                        },
                    },
                },
            },
        };
        let cart = userId
            ? await this.prisma.cart.findFirst({ where: { userId }, include: cartInclude })
            : null;
        if (userId && sessionId) {
            const sessionCart = await this.prisma.cart.findFirst({
                where: { sessionId },
                include: cartInclude,
            });
            if (sessionCart && sessionCart.items.length > 0) {
                if (!cart) {
                    cart = await this.prisma.cart.update({
                        where: { id: sessionCart.id },
                        data: { userId, sessionId: null },
                        include: cartInclude,
                    });
                }
                else {
                    for (const item of sessionCart.items) {
                        const existingItem = cart.items.find((ci) => ci.productId === item.productId &&
                            ci.variantId === item.variantId &&
                            ci.courseId === item.courseId);
                        if (existingItem) {
                            await this.prisma.cartItem.update({
                                where: { id: existingItem.id },
                                data: { quantity: existingItem.quantity + item.quantity },
                            });
                        }
                        else {
                            await this.prisma.cartItem.update({
                                where: { id: item.id },
                                data: { cartId: cart.id },
                            });
                        }
                    }
                    await this.prisma.cart.delete({ where: { id: sessionCart.id } });
                    cart = await this.prisma.cart.findFirst({ where: { userId }, include: cartInclude });
                }
            }
        }
        if (!cart && sessionId) {
            cart = await this.prisma.cart.findFirst({
                where: { sessionId },
                include: cartInclude,
            });
        }
        if (!cart) {
            cart = await this.prisma.cart.create({
                data: userId ? { userId } : { sessionId },
                include: cartInclude,
            });
        }
        return this.calculateCartTotals(cart);
    }
    async addToCart(dto, userId, sessionId) {
        const cart = await this.getOrCreateCart(userId, sessionId);
        const product = await this.prisma.product.findUnique({
            where: { id: dto.productId },
            include: { variants: true },
        });
        if (!product || product.status !== 'ACTIVE') {
            throw new common_1.NotFoundException('Product not found or not available');
        }
        if (dto.variantId) {
            const variant = product.variants.find((v) => v.id === dto.variantId);
            if (!variant) {
                throw new common_1.NotFoundException('Variant not found');
            }
        }
        const existingItem = await this.prisma.cartItem.findFirst({
            where: {
                cartId: cart.id,
                productId: dto.productId,
                variantId: dto.variantId || null,
            },
        });
        if (existingItem) {
            await this.prisma.cartItem.update({
                where: { id: existingItem.id },
                data: { quantity: existingItem.quantity + dto.quantity },
            });
        }
        else {
            await this.prisma.cartItem.create({
                data: {
                    cartId: cart.id,
                    productId: dto.productId,
                    variantId: dto.variantId,
                    quantity: dto.quantity,
                },
            });
        }
        return this.getOrCreateCart(userId, sessionId);
    }
    async addCourseToCart(courseId, userId, sessionId) {
        const cart = await this.getOrCreateCart(userId, sessionId);
        const course = await this.prisma.course.findUnique({
            where: { id: courseId },
        });
        if (!course || course.status !== 'PUBLISHED') {
            throw new common_1.NotFoundException('Course not found or not available');
        }
        if (course.priceType === 'FREE') {
            throw new common_1.BadRequestException('Free courses cannot be added to cart. Enroll directly.');
        }
        if (userId) {
            const existingEnrollment = await this.prisma.enrollment.findUnique({
                where: { courseId_userId: { courseId, userId } },
            });
            if (existingEnrollment) {
                throw new common_1.BadRequestException('You are already enrolled in this course');
            }
        }
        const existingItem = await this.prisma.cartItem.findFirst({
            where: { cartId: cart.id, courseId },
        });
        if (existingItem) {
            throw new common_1.BadRequestException('Course is already in your cart');
        }
        await this.prisma.cartItem.create({
            data: {
                cartId: cart.id,
                courseId,
                itemType: 'COURSE',
                quantity: 1,
            },
        });
        return this.getOrCreateCart(userId, sessionId);
    }
    async updateCartItem(itemId, dto, userId, sessionId) {
        const cart = await this.getOrCreateCart(userId, sessionId);
        const item = await this.prisma.cartItem.findFirst({
            where: { id: itemId, cartId: cart.id },
        });
        if (!item) {
            throw new common_1.NotFoundException('Cart item not found');
        }
        if (dto.quantity === 0) {
            await this.prisma.cartItem.delete({ where: { id: itemId } });
        }
        else {
            await this.prisma.cartItem.update({
                where: { id: itemId },
                data: { quantity: dto.quantity },
            });
        }
        return this.getOrCreateCart(userId, sessionId);
    }
    async removeFromCart(itemId, userId, sessionId) {
        const cart = await this.getOrCreateCart(userId, sessionId);
        const item = await this.prisma.cartItem.findFirst({
            where: { id: itemId, cartId: cart.id },
        });
        if (!item) {
            throw new common_1.NotFoundException('Cart item not found');
        }
        await this.prisma.cartItem.delete({ where: { id: itemId } });
        return this.getOrCreateCart(userId, sessionId);
    }
    async clearCart(userId, sessionId) {
        const cart = await this.getOrCreateCart(userId, sessionId);
        await this.prisma.cartItem.deleteMany({ where: { cartId: cart.id } });
        return this.getOrCreateCart(userId, sessionId);
    }
    calculateCartTotals(cart) {
        let subtotal = new library_1.Decimal(0);
        const itemsWithTotals = cart.items.map((item) => {
            let price;
            if (item.itemType === 'COURSE' && item.course) {
                price = item.course.priceAmount || new library_1.Decimal(0);
            }
            else if (item.product) {
                price = item.variant?.price || item.product.salePrice || item.product.price;
            }
            else {
                price = new library_1.Decimal(0);
            }
            const itemTotal = new library_1.Decimal(price).times(item.quantity);
            subtotal = subtotal.plus(itemTotal);
            return {
                ...item,
                price: new library_1.Decimal(price).toNumber(),
                itemTotal: itemTotal.toNumber(),
                name: item.course?.title || item.product?.name || 'Unknown Item',
                image: item.course?.featuredImage || item.product?.images?.[0] || null,
            };
        });
        return {
            ...cart,
            items: itemsWithTotals,
            subtotal: subtotal.toNumber(),
            itemCount: cart.items.reduce((sum, item) => sum + item.quantity, 0),
            hasCourses: cart.items.some((item) => item.itemType === 'COURSE'),
            hasProducts: cart.items.some((item) => item.itemType === 'PRODUCT'),
        };
    }
};
exports.CartService = CartService;
exports.CartService = CartService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], CartService);


/***/ }),
/* 185 */
/***/ ((module) => {

module.exports = require("@prisma/client/runtime/library");

/***/ }),
/* 186 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.OrdersService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const library_1 = __webpack_require__(185);
let OrdersService = class OrdersService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    generateOrderNumber() {
        const date = new Date();
        const year = date.getFullYear().toString().slice(-2);
        const month = (date.getMonth() + 1).toString().padStart(2, '0');
        const random = Math.random().toString(36).substring(2, 8).toUpperCase();
        return `ORD-${year}${month}-${random}`;
    }
    async createFromCart(dto, userId, sessionId) {
        const cartInclude = {
            items: {
                include: {
                    product: true,
                    variant: true,
                    course: true,
                },
            },
        };
        let cart = userId
            ? await this.prisma.cart.findFirst({ where: { userId }, include: cartInclude })
            : null;
        if (userId && sessionId && (!cart || cart.items.length === 0)) {
            const sessionCart = await this.prisma.cart.findFirst({
                where: { sessionId },
                include: cartInclude,
            });
            if (sessionCart && sessionCart.items.length > 0) {
                if (!cart) {
                    cart = await this.prisma.cart.update({
                        where: { id: sessionCart.id },
                        data: { userId, sessionId: null },
                        include: cartInclude,
                    });
                }
                else {
                    for (const item of sessionCart.items) {
                        await this.prisma.cartItem.update({
                            where: { id: item.id },
                            data: { cartId: cart.id },
                        });
                    }
                    await this.prisma.cart.delete({ where: { id: sessionCart.id } });
                    cart = await this.prisma.cart.findFirst({ where: { userId }, include: cartInclude });
                }
            }
        }
        if (!cart && sessionId) {
            cart = await this.prisma.cart.findFirst({
                where: { sessionId },
                include: cartInclude,
            });
        }
        if (!cart || cart.items.length === 0) {
            throw new common_1.BadRequestException('Cart is empty');
        }
        const productItems = cart.items.filter((item) => item.itemType === 'PRODUCT' && item.product);
        const courseItems = cart.items.filter((item) => item.itemType === 'COURSE' && item.course);
        let subtotal = new library_1.Decimal(0);
        const orderItems = productItems.map((item) => {
            const price = item.variant?.price || item.product.salePrice || item.product.price;
            const total = new library_1.Decimal(price).times(item.quantity);
            subtotal = subtotal.plus(total);
            return {
                product: { connect: { id: item.productId } },
                variant: item.variantId ? { connect: { id: item.variantId } } : undefined,
                name: item.product.name + (item.variant ? ` - ${item.variant.name}` : ''),
                sku: item.variant?.sku || item.product.sku,
                price,
                quantity: item.quantity,
                total,
                options: item.variant?.options ?? undefined,
            };
        });
        for (const item of courseItems) {
            if (item.course?.priceAmount) {
                subtotal = subtotal.plus(item.course.priceAmount);
            }
        }
        let shipping = new library_1.Decimal(0);
        if (dto.shippingMethod) {
            const shippingMethod = await this.prisma.shippingMethod.findUnique({
                where: { id: dto.shippingMethod },
            });
            if (shippingMethod) {
                shipping =
                    shippingMethod.freeAbove && subtotal.gte(shippingMethod.freeAbove)
                        ? new library_1.Decimal(0)
                        : shippingMethod.cost;
            }
        }
        let discount = new library_1.Decimal(0);
        let couponCode = null;
        if (dto.couponCode) {
            const coupon = await this.prisma.coupon.findUnique({
                where: { code: dto.couponCode.toUpperCase() },
            });
            if (coupon && coupon.isActive) {
                if (coupon.type === 'PERCENTAGE') {
                    discount = subtotal.times(coupon.value).dividedBy(100);
                }
                else if (coupon.type === 'FIXED') {
                    discount = coupon.value;
                }
                else if (coupon.type === 'FREE_SHIPPING') {
                    shipping = new library_1.Decimal(0);
                }
                if (coupon.maxDiscount && discount.gt(coupon.maxDiscount)) {
                    discount = new library_1.Decimal(coupon.maxDiscount.toString());
                }
                couponCode = coupon.code;
                await this.prisma.coupon.update({
                    where: { id: coupon.id },
                    data: { usageCount: { increment: 1 } },
                });
            }
        }
        const taxRate = new library_1.Decimal(0.1);
        const tax = subtotal.minus(discount).times(taxRate);
        const total = subtotal.plus(shipping).plus(tax).minus(discount);
        const defaultAddress = {
            firstName: '',
            lastName: '',
            address1: '',
            city: '',
            postalCode: '',
            country: '',
        };
        if (!dto.email) {
            throw new common_1.BadRequestException('Email is required for checkout');
        }
        const order = await this.prisma.order.create({
            data: {
                orderNumber: this.generateOrderNumber(),
                userId: userId || null,
                email: dto.email,
                subtotal,
                tax,
                shipping,
                discount,
                total,
                couponCode,
                couponDiscount: discount.gt(0) ? discount : null,
                billingAddress: (dto.billingAddress || defaultAddress),
                shippingAddress: dto.shippingAddress,
                shippingMethod: dto.shippingMethod,
                customerNote: dto.customerNote,
                items: {
                    create: orderItems,
                },
            },
            include: { items: true },
        });
        for (const item of productItems) {
            if (item.product?.trackStock) {
                if (item.variantId) {
                    await this.prisma.productVariant.update({
                        where: { id: item.variantId },
                        data: { stock: { decrement: item.quantity } },
                    });
                }
                else if (item.productId) {
                    await this.prisma.product.update({
                        where: { id: item.productId },
                        data: { stock: { decrement: item.quantity } },
                    });
                }
            }
        }
        if (userId && courseItems.length > 0) {
            for (const item of courseItems) {
                if (item.courseId) {
                    const existingEnrollment = await this.prisma.enrollment.findUnique({
                        where: { courseId_userId: { courseId: item.courseId, userId } },
                    });
                    if (!existingEnrollment) {
                        await this.prisma.enrollment.create({
                            data: {
                                courseId: item.courseId,
                                userId,
                                status: 'ACTIVE',
                                paymentId: order.id,
                            },
                        });
                    }
                }
            }
        }
        await this.prisma.cartItem.deleteMany({ where: { cartId: cart.id } });
        return {
            ...order,
            coursesEnrolled: courseItems.map((item) => item.course?.title).filter(Boolean),
        };
    }
    async findAll(query) {
        const { status, paymentStatus, search, page = 1, limit = 20 } = query;
        const skip = (page - 1) * limit;
        const where = {};
        if (status)
            where.status = status;
        if (paymentStatus)
            where.paymentStatus = paymentStatus;
        if (search) {
            where.OR = [
                { orderNumber: { contains: search, mode: 'insensitive' } },
                { email: { contains: search, mode: 'insensitive' } },
            ];
        }
        const [orders, total] = await Promise.all([
            this.prisma.order.findMany({
                where,
                skip,
                take: limit,
                orderBy: { createdAt: 'desc' },
                include: { items: true, payments: true },
            }),
            this.prisma.order.count({ where }),
        ]);
        return {
            orders,
            pagination: { page, limit, total, pages: Math.ceil(total / limit) },
        };
    }
    async findOne(id) {
        const order = await this.prisma.order.findUnique({
            where: { id },
            include: { items: { include: { product: true } }, payments: true },
        });
        if (!order)
            throw new common_1.NotFoundException('Order not found');
        return order;
    }
    async findByOrderNumber(orderNumber) {
        const order = await this.prisma.order.findUnique({
            where: { orderNumber },
            include: { items: { include: { product: true } }, payments: true },
        });
        if (!order)
            throw new common_1.NotFoundException('Order not found');
        return order;
    }
    async findByUser(userId, query) {
        return this.findAll({ ...query, search: undefined });
    }
    async updateStatus(id, dto) {
        const order = await this.prisma.order.findUnique({ where: { id } });
        if (!order)
            throw new common_1.NotFoundException('Order not found');
        const updateData = { status: dto.status };
        if (dto.trackingNumber)
            updateData.trackingNumber = dto.trackingNumber;
        if (dto.adminNote)
            updateData.adminNote = dto.adminNote;
        if (dto.status === 'SHIPPED')
            updateData.shippedAt = new Date();
        if (dto.status === 'DELIVERED')
            updateData.deliveredAt = new Date();
        return this.prisma.order.update({
            where: { id },
            data: updateData,
            include: { items: true, payments: true },
        });
    }
    async cancel(id) {
        const order = await this.prisma.order.findUnique({
            where: { id },
            include: { items: true },
        });
        if (!order)
            throw new common_1.NotFoundException('Order not found');
        if (order.status !== 'PENDING' && order.status !== 'CONFIRMED') {
            throw new common_1.BadRequestException('Cannot cancel order in current status');
        }
        for (const item of order.items) {
            if (item.variantId) {
                await this.prisma.productVariant.update({
                    where: { id: item.variantId },
                    data: { stock: { increment: item.quantity } },
                });
            }
            else {
                await this.prisma.product.update({
                    where: { id: item.productId },
                    data: { stock: { increment: item.quantity } },
                });
            }
        }
        return this.prisma.order.update({
            where: { id },
            data: { status: 'CANCELLED' },
            include: { items: true, payments: true },
        });
    }
    async getStats() {
        const [totalOrders, totalRevenue, pendingOrders, todayOrders] = await Promise.all([
            this.prisma.order.count(),
            this.prisma.order.aggregate({ _sum: { total: true }, where: { paymentStatus: 'PAID' } }),
            this.prisma.order.count({ where: { status: 'PENDING' } }),
            this.prisma.order.count({
                where: { createdAt: { gte: new Date(new Date().setHours(0, 0, 0, 0)) } },
            }),
        ]);
        return {
            totalOrders,
            totalRevenue: totalRevenue._sum.total || 0,
            pendingOrders,
            todayOrders,
        };
    }
};
exports.OrdersService = OrdersService;
exports.OrdersService = OrdersService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], OrdersService);


/***/ }),
/* 187 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 StripeService_1;
var _a, _b, _c;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.StripeService = void 0;
const common_1 = __webpack_require__(2);
const config_1 = __webpack_require__(13);
const prisma_service_1 = __webpack_require__(16);
const system_config_service_1 = __webpack_require__(52);
const stripe_1 = __webpack_require__(82);
let StripeService = StripeService_1 = class StripeService {
    constructor(prisma, configService, systemConfig) {
        this.prisma = prisma;
        this.configService = configService;
        this.systemConfig = systemConfig;
        this.stripe = null;
        this.logger = new common_1.Logger(StripeService_1.name);
    }
    async onModuleInit() {
        await this.initializeStripe();
    }
    async initializeStripe() {
        try {
            const config = await this.systemConfig.getStripeConfig();
            const secretKey = config.secretKey;
            if (secretKey) {
                this.stripe = new stripe_1.default(secretKey);
                this.logger.log(`Stripe initialized: ${secretKey.substring(0, 10)}... (${config.isLiveMode ? 'LIVE' : 'TEST'} mode)`);
            }
            else {
                this.logger.warn('Stripe secret key not configured');
            }
        }
        catch (_error) {
            const secretKey = this.configService.get('STRIPE_SECRET_KEY');
            if (secretKey) {
                this.stripe = new stripe_1.default(secretKey);
                this.logger.log(`Stripe initialized from env: ${secretKey.substring(0, 10)}...`);
            }
            else {
                this.logger.warn('Stripe not configured (no DB or env config)');
            }
        }
    }
    async reloadConfig() {
        this.stripe = null;
        await this.initializeStripe();
    }
    async createPaymentIntent(orderId) {
        if (!this.stripe) {
            throw new common_1.BadRequestException('Stripe is not configured');
        }
        const order = await this.prisma.order.findUnique({
            where: { id: orderId },
            include: { items: true },
        });
        if (!order) {
            throw new common_1.NotFoundException('Order not found');
        }
        if (order.paymentStatus === 'PAID') {
            throw new common_1.BadRequestException('Order is already paid');
        }
        try {
            let stripeCustomerId;
            try {
                if (order.email) {
                    const customer = await this.stripe.customers.create({
                        email: order.email,
                        metadata: { orderId: order.id, userId: order.userId || 'guest' },
                    });
                    stripeCustomerId = customer.id;
                }
            }
            catch (customerError) {
                console.warn('Could not create Stripe customer:', customerError.message);
            }
            const paymentIntent = await this.stripe.paymentIntents.create({
                amount: Math.round(Number(order.total) * 100),
                currency: order.currency.toLowerCase(),
                customer: stripeCustomerId,
                metadata: {
                    orderId: order.id,
                    orderNumber: order.orderNumber,
                },
                automatic_payment_methods: {
                    enabled: true,
                },
            });
            await this.prisma.payment.create({
                data: {
                    orderId: order.id,
                    amount: order.total,
                    currency: order.currency,
                    stripePaymentIntentId: paymentIntent.id,
                    stripeCustomerId,
                },
            });
            return {
                clientSecret: paymentIntent.client_secret,
                paymentIntentId: paymentIntent.id,
            };
        }
        catch (error) {
            console.error('Stripe error:', error.message);
            throw new common_1.BadRequestException(`Stripe error: ${error.message}`);
        }
    }
    async handleWebhook(payload, signature) {
        if (!this.stripe) {
            throw new common_1.BadRequestException('Stripe is not configured');
        }
        let webhookSecret;
        try {
            const config = await this.systemConfig.getStripeConfig();
            webhookSecret = config.webhookSecret;
        }
        catch {
            webhookSecret = this.configService.get('STRIPE_WEBHOOK_SECRET') || '';
        }
        if (!webhookSecret) {
            throw new common_1.BadRequestException('Webhook secret not configured');
        }
        let event;
        try {
            event = this.stripe.webhooks.constructEvent(payload, signature, webhookSecret);
        }
        catch (_err) {
            throw new common_1.BadRequestException(`Webhook signature verification failed`);
        }
        switch (event.type) {
            case 'payment_intent.succeeded':
                await this.handlePaymentSuccess(event.data.object);
                break;
            case 'payment_intent.payment_failed':
                await this.handlePaymentFailed(event.data.object);
                break;
            case 'charge.refunded':
                await this.handleRefund(event.data.object);
                break;
        }
        return { received: true };
    }
    async handlePaymentSuccess(paymentIntent) {
        const payment = await this.prisma.payment.findUnique({
            where: { stripePaymentIntentId: paymentIntent.id },
        });
        if (!payment)
            return;
        await this.prisma.payment.update({
            where: { id: payment.id },
            data: {
                status: 'PAID',
                stripeChargeId: paymentIntent.latest_charge,
            },
        });
        await this.prisma.order.update({
            where: { id: payment.orderId },
            data: {
                paymentStatus: 'PAID',
                status: 'CONFIRMED',
            },
        });
    }
    async handlePaymentFailed(paymentIntent) {
        const payment = await this.prisma.payment.findUnique({
            where: { stripePaymentIntentId: paymentIntent.id },
        });
        if (!payment)
            return;
        await this.prisma.payment.update({
            where: { id: payment.id },
            data: { status: 'FAILED' },
        });
        await this.prisma.order.update({
            where: { id: payment.orderId },
            data: { paymentStatus: 'FAILED' },
        });
    }
    async handleRefund(charge) {
        const payment = await this.prisma.payment.findFirst({
            where: { stripeChargeId: charge.id },
        });
        if (!payment)
            return;
        const refundedAmount = charge.amount_refunded / 100;
        const isFullRefund = charge.refunded;
        await this.prisma.payment.update({
            where: { id: payment.id },
            data: {
                status: isFullRefund ? 'REFUNDED' : 'PARTIALLY_REFUNDED',
                refundedAmount,
                refundedAt: new Date(),
            },
        });
        await this.prisma.order.update({
            where: { id: payment.orderId },
            data: {
                paymentStatus: isFullRefund ? 'REFUNDED' : 'PARTIALLY_REFUNDED',
                status: isFullRefund ? 'REFUNDED' : undefined,
            },
        });
    }
    async createRefund(orderId, amount, reason) {
        if (!this.stripe) {
            throw new common_1.BadRequestException('Stripe is not configured');
        }
        const payment = await this.prisma.payment.findFirst({
            where: { orderId, status: 'PAID' },
        });
        if (!payment || !payment.stripePaymentIntentId) {
            throw new common_1.NotFoundException('No paid payment found for this order');
        }
        const refundParams = {
            payment_intent: payment.stripePaymentIntentId,
        };
        if (amount) {
            refundParams.amount = Math.round(amount * 100);
        }
        if (reason) {
            refundParams.reason = 'requested_by_customer';
            refundParams.metadata = { reason };
        }
        const refund = await this.stripe.refunds.create(refundParams);
        const refundedAmount = refund.amount / 100;
        const isFullRefund = refundedAmount >= Number(payment.amount);
        await this.prisma.payment.update({
            where: { id: payment.id },
            data: {
                status: isFullRefund ? 'REFUNDED' : 'PARTIALLY_REFUNDED',
                refundedAmount,
                refundReason: reason,
                refundedAt: new Date(),
            },
        });
        await this.prisma.order.update({
            where: { id: orderId },
            data: {
                paymentStatus: isFullRefund ? 'REFUNDED' : 'PARTIALLY_REFUNDED',
                status: isFullRefund ? 'REFUNDED' : undefined,
            },
        });
        return { success: true, refundId: refund.id, amount: refundedAmount };
    }
    async getPublishableKey() {
        try {
            const config = await this.systemConfig.getStripeConfig();
            return config.publishableKey;
        }
        catch {
            return this.configService.get('STRIPE_PUBLISHABLE_KEY') || '';
        }
    }
    isConfigured() {
        return this.stripe !== null;
    }
};
exports.StripeService = StripeService;
exports.StripeService = StripeService = StripeService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof config_1.ConfigService !== "undefined" && config_1.ConfigService) === "function" ? _b : Object, typeof (_c = typeof system_config_service_1.SystemConfigService !== "undefined" && system_config_service_1.SystemConfigService) === "function" ? _c : Object])
], StripeService);


/***/ }),
/* 188 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ProductsController = void 0;
const common_1 = __webpack_require__(2);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const feature_guard_1 = __webpack_require__(162);
const roles_decorator_1 = __webpack_require__(73);
const subscription_decorator_1 = __webpack_require__(161);
const client_1 = __webpack_require__(17);
const products_service_1 = __webpack_require__(172);
const product_dto_1 = __webpack_require__(189);
let ProductsController = class ProductsController {
    constructor(productsService) {
        this.productsService = productsService;
    }
    create(dto) {
        return this.productsService.create(dto);
    }
    findAll(query) {
        return this.productsService.findAll(query);
    }
    findOne(id) {
        return this.productsService.findOne(id);
    }
    update(id, dto) {
        return this.productsService.update(id, dto);
    }
    delete(id) {
        return this.productsService.delete(id);
    }
};
exports.ProductsController = ProductsController;
__decorate([
    (0, common_1.Post)(),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR, client_1.UserRole.AUTHOR),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_b = typeof product_dto_1.CreateProductDto !== "undefined" && product_dto_1.CreateProductDto) === "function" ? _b : Object]),
    __metadata("design:returntype", void 0)
], ProductsController.prototype, "create", null);
__decorate([
    (0, common_1.Get)(),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR, client_1.UserRole.AUTHOR),
    __param(0, (0, common_1.Query)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_c = typeof product_dto_1.ProductQueryDto !== "undefined" && product_dto_1.ProductQueryDto) === "function" ? _c : Object]),
    __metadata("design:returntype", void 0)
], ProductsController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR, client_1.UserRole.AUTHOR),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], ProductsController.prototype, "findOne", null);
__decorate([
    (0, common_1.Put)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR, client_1.UserRole.AUTHOR),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_d = typeof product_dto_1.UpdateProductDto !== "undefined" && product_dto_1.UpdateProductDto) === "function" ? _d : Object]),
    __metadata("design:returntype", void 0)
], ProductsController.prototype, "update", null);
__decorate([
    (0, common_1.Delete)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], ProductsController.prototype, "delete", null);
exports.ProductsController = ProductsController = __decorate([
    (0, common_1.Controller)('api/shop/products'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard, feature_guard_1.FeatureGuard),
    (0, subscription_decorator_1.RequiresFeature)(subscription_decorator_1.SUBSCRIPTION_FEATURES.ECOMMERCE),
    __metadata("design:paramtypes", [typeof (_a = typeof products_service_1.ProductsService !== "undefined" && products_service_1.ProductsService) === "function" ? _a : Object])
], ProductsController);


/***/ }),
/* 189 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ProductQueryDto = exports.UpdateProductDto = exports.CreateProductDto = exports.CreateVariantDto = exports.ProductType = exports.ProductStatus = void 0;
const class_validator_1 = __webpack_require__(59);
const class_transformer_1 = __webpack_require__(95);
var ProductStatus;
(function (ProductStatus) {
    ProductStatus["DRAFT"] = "DRAFT";
    ProductStatus["ACTIVE"] = "ACTIVE";
    ProductStatus["ARCHIVED"] = "ARCHIVED";
})(ProductStatus || (exports.ProductStatus = ProductStatus = {}));
var ProductType;
(function (ProductType) {
    ProductType["PHYSICAL"] = "PHYSICAL";
    ProductType["DIGITAL"] = "DIGITAL";
    ProductType["SERVICE"] = "SERVICE";
})(ProductType || (exports.ProductType = ProductType = {}));
class CreateVariantDto {
}
exports.CreateVariantDto = CreateVariantDto;
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateVariantDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateVariantDto.prototype, "sku", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    __metadata("design:type", Number)
], CreateVariantDto.prototype, "price", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    __metadata("design:type", Number)
], CreateVariantDto.prototype, "salePrice", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    __metadata("design:type", Number)
], CreateVariantDto.prototype, "stock", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateVariantDto.prototype, "image", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_a = typeof Record !== "undefined" && Record) === "function" ? _a : Object)
], CreateVariantDto.prototype, "options", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsBoolean)(),
    __metadata("design:type", Boolean)
], CreateVariantDto.prototype, "isDefault", void 0);
class CreateProductDto {
}
exports.CreateProductDto = CreateProductDto;
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateProductDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateProductDto.prototype, "slug", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateProductDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateProductDto.prototype, "shortDescription", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateProductDto.prototype, "sku", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    __metadata("design:type", Number)
], CreateProductDto.prototype, "price", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    __metadata("design:type", Number)
], CreateProductDto.prototype, "salePrice", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    __metadata("design:type", Number)
], CreateProductDto.prototype, "costPrice", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    __metadata("design:type", Number)
], CreateProductDto.prototype, "stock", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    __metadata("design:type", Number)
], CreateProductDto.prototype, "lowStockThreshold", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsBoolean)(),
    __metadata("design:type", Boolean)
], CreateProductDto.prototype, "trackStock", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsEnum)(ProductStatus),
    __metadata("design:type", String)
], CreateProductDto.prototype, "status", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsEnum)(ProductType),
    __metadata("design:type", String)
], CreateProductDto.prototype, "type", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateProductDto.prototype, "featuredImage", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsArray)(),
    __metadata("design:type", Array)
], CreateProductDto.prototype, "images", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], CreateProductDto.prototype, "weight", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Object)
], CreateProductDto.prototype, "dimensions", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateProductDto.prototype, "downloadUrl", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], CreateProductDto.prototype, "downloadLimit", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], CreateProductDto.prototype, "downloadExpiry", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateProductDto.prototype, "metaTitle", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateProductDto.prototype, "metaDescription", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsUUID)(),
    __metadata("design:type", String)
], CreateProductDto.prototype, "categoryId", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.IsString)({ each: true }),
    __metadata("design:type", Array)
], CreateProductDto.prototype, "tags", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.ValidateNested)({ each: true }),
    (0, class_transformer_1.Type)(() => CreateVariantDto),
    __metadata("design:type", Array)
], CreateProductDto.prototype, "variants", void 0);
class UpdateProductDto extends CreateProductDto {
}
exports.UpdateProductDto = UpdateProductDto;
class ProductQueryDto {
    constructor() {
        this.page = 1;
        this.limit = 20;
    }
}
exports.ProductQueryDto = ProductQueryDto;
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], ProductQueryDto.prototype, "search", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsEnum)(ProductStatus),
    __metadata("design:type", String)
], ProductQueryDto.prototype, "status", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsUUID)(),
    __metadata("design:type", String)
], ProductQueryDto.prototype, "categoryId", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], ProductQueryDto.prototype, "page", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], ProductQueryDto.prototype, "limit", void 0);


/***/ }),
/* 190 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CategoriesController = void 0;
const common_1 = __webpack_require__(2);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const client_1 = __webpack_require__(17);
const categories_service_1 = __webpack_require__(173);
const category_dto_1 = __webpack_require__(191);
let CategoriesController = class CategoriesController {
    constructor(categoriesService) {
        this.categoriesService = categoriesService;
    }
    create(dto) {
        return this.categoriesService.create(dto);
    }
    findAll() {
        return this.categoriesService.findAll();
    }
    findTree() {
        return this.categoriesService.findTree();
    }
    findOne(id) {
        return this.categoriesService.findOne(id);
    }
    update(id, dto) {
        return this.categoriesService.update(id, dto);
    }
    delete(id) {
        return this.categoriesService.delete(id);
    }
};
exports.CategoriesController = CategoriesController;
__decorate([
    (0, common_1.Post)(),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR, client_1.UserRole.AUTHOR),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_b = typeof category_dto_1.CreateCategoryDto !== "undefined" && category_dto_1.CreateCategoryDto) === "function" ? _b : Object]),
    __metadata("design:returntype", void 0)
], CategoriesController.prototype, "create", null);
__decorate([
    (0, common_1.Get)(),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR, client_1.UserRole.AUTHOR),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], CategoriesController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)('tree'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR, client_1.UserRole.AUTHOR),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], CategoriesController.prototype, "findTree", null);
__decorate([
    (0, common_1.Get)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR, client_1.UserRole.AUTHOR),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], CategoriesController.prototype, "findOne", null);
__decorate([
    (0, common_1.Put)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR, client_1.UserRole.AUTHOR),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_c = typeof category_dto_1.UpdateCategoryDto !== "undefined" && category_dto_1.UpdateCategoryDto) === "function" ? _c : Object]),
    __metadata("design:returntype", void 0)
], CategoriesController.prototype, "update", null);
__decorate([
    (0, common_1.Delete)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], CategoriesController.prototype, "delete", null);
exports.CategoriesController = CategoriesController = __decorate([
    (0, common_1.Controller)('api/shop/categories'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof categories_service_1.CategoriesService !== "undefined" && categories_service_1.CategoriesService) === "function" ? _a : Object])
], CategoriesController);


/***/ }),
/* 191 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UpdateCategoryDto = exports.CreateCategoryDto = void 0;
const class_validator_1 = __webpack_require__(59);
class CreateCategoryDto {
}
exports.CreateCategoryDto = CreateCategoryDto;
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateCategoryDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateCategoryDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateCategoryDto.prototype, "image", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsUUID)(),
    __metadata("design:type", String)
], CreateCategoryDto.prototype, "parentId", void 0);
class UpdateCategoryDto extends CreateCategoryDto {
}
exports.UpdateCategoryDto = UpdateCategoryDto;


/***/ }),
/* 192 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CartController = void 0;
const common_1 = __webpack_require__(2);
const express_1 = __webpack_require__(57);
const cart_service_1 = __webpack_require__(184);
const cart_dto_1 = __webpack_require__(193);
const optional_jwt_auth_guard_1 = __webpack_require__(76);
const uuid_1 = __webpack_require__(25);
let CartController = class CartController {
    constructor(cartService) {
        this.cartService = cartService;
    }
    getCartIdentifiers(req, res) {
        const userId = req.user?.id;
        let sessionId = req.cookies?.cart_session;
        if (!userId && !sessionId) {
            sessionId = (0, uuid_1.v4)();
            res.cookie('cart_session', sessionId, {
                httpOnly: true,
                maxAge: 30 * 24 * 60 * 60 * 1000,
                sameSite: 'lax',
            });
        }
        return { userId, sessionId };
    }
    async getCart(req, res) {
        const { userId, sessionId } = this.getCartIdentifiers(req, res);
        return this.cartService.getOrCreateCart(userId, sessionId);
    }
    async addToCart(dto, req, res) {
        const { userId, sessionId } = this.getCartIdentifiers(req, res);
        return this.cartService.addToCart(dto, userId, sessionId);
    }
    async addCourseToCart(dto, req, res) {
        const { userId, sessionId } = this.getCartIdentifiers(req, res);
        return this.cartService.addCourseToCart(dto.courseId, userId, sessionId);
    }
    async updateItem(itemId, dto, req, res) {
        const { userId, sessionId } = this.getCartIdentifiers(req, res);
        return this.cartService.updateCartItem(itemId, dto, userId, sessionId);
    }
    async removeItem(itemId, req, res) {
        const { userId, sessionId } = this.getCartIdentifiers(req, res);
        return this.cartService.removeFromCart(itemId, userId, sessionId);
    }
    async clearCart(req, res) {
        const { userId, sessionId } = this.getCartIdentifiers(req, res);
        return this.cartService.clearCart(userId, sessionId);
    }
};
exports.CartController = CartController;
__decorate([
    (0, common_1.Get)(),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Res)({ passthrough: true })),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_b = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _b : Object, typeof (_c = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _c : Object]),
    __metadata("design:returntype", Promise)
], CartController.prototype, "getCart", null);
__decorate([
    (0, common_1.Post)('add'),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, common_1.Req)()),
    __param(2, (0, common_1.Res)({ passthrough: true })),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_d = typeof cart_dto_1.AddToCartDto !== "undefined" && cart_dto_1.AddToCartDto) === "function" ? _d : Object, typeof (_e = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _e : Object, typeof (_f = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _f : Object]),
    __metadata("design:returntype", Promise)
], CartController.prototype, "addToCart", null);
__decorate([
    (0, common_1.Post)('add-course'),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, common_1.Req)()),
    __param(2, (0, common_1.Res)({ passthrough: true })),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, typeof (_g = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _g : Object, typeof (_h = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _h : Object]),
    __metadata("design:returntype", Promise)
], CartController.prototype, "addCourseToCart", null);
__decorate([
    (0, common_1.Put)('item/:itemId'),
    __param(0, (0, common_1.Param)('itemId')),
    __param(1, (0, common_1.Body)()),
    __param(2, (0, common_1.Req)()),
    __param(3, (0, common_1.Res)({ passthrough: true })),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_j = typeof cart_dto_1.UpdateCartItemDto !== "undefined" && cart_dto_1.UpdateCartItemDto) === "function" ? _j : Object, typeof (_k = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _k : Object, typeof (_l = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _l : Object]),
    __metadata("design:returntype", Promise)
], CartController.prototype, "updateItem", null);
__decorate([
    (0, common_1.Delete)('item/:itemId'),
    __param(0, (0, common_1.Param)('itemId')),
    __param(1, (0, common_1.Req)()),
    __param(2, (0, common_1.Res)({ passthrough: true })),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_m = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _m : Object, typeof (_o = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _o : Object]),
    __metadata("design:returntype", Promise)
], CartController.prototype, "removeItem", null);
__decorate([
    (0, common_1.Delete)('clear'),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Res)({ passthrough: true })),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_p = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _p : Object, typeof (_q = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _q : Object]),
    __metadata("design:returntype", Promise)
], CartController.prototype, "clearCart", null);
exports.CartController = CartController = __decorate([
    (0, common_1.Controller)('api/shop/cart'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof cart_service_1.CartService !== "undefined" && cart_service_1.CartService) === "function" ? _a : Object])
], CartController);


/***/ }),
/* 193 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ApplyCouponDto = exports.UpdateCartItemDto = exports.AddToCartDto = void 0;
const class_validator_1 = __webpack_require__(59);
class AddToCartDto {
}
exports.AddToCartDto = AddToCartDto;
__decorate([
    (0, class_validator_1.IsUUID)(),
    __metadata("design:type", String)
], AddToCartDto.prototype, "productId", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsUUID)(),
    __metadata("design:type", String)
], AddToCartDto.prototype, "variantId", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(1),
    __metadata("design:type", Number)
], AddToCartDto.prototype, "quantity", void 0);
class UpdateCartItemDto {
}
exports.UpdateCartItemDto = UpdateCartItemDto;
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    __metadata("design:type", Number)
], UpdateCartItemDto.prototype, "quantity", void 0);
class ApplyCouponDto {
}
exports.ApplyCouponDto = ApplyCouponDto;
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], ApplyCouponDto.prototype, "code", void 0);


/***/ }),
/* 194 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UserOrdersController = exports.OrdersController = exports.AdminOrdersController = void 0;
const common_1 = __webpack_require__(2);
const express_1 = __webpack_require__(57);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const client_1 = __webpack_require__(17);
const optional_jwt_auth_guard_1 = __webpack_require__(76);
const orders_service_1 = __webpack_require__(186);
const order_dto_1 = __webpack_require__(195);
let AdminOrdersController = class AdminOrdersController {
    constructor(ordersService) {
        this.ordersService = ordersService;
    }
    findAll(query) {
        return this.ordersService.findAll(query);
    }
    getStats() {
        return this.ordersService.getStats();
    }
    findOne(id) {
        return this.ordersService.findOne(id);
    }
    updateStatus(id, dto) {
        return this.ordersService.updateStatus(id, dto);
    }
    cancel(id) {
        return this.ordersService.cancel(id);
    }
};
exports.AdminOrdersController = AdminOrdersController;
__decorate([
    (0, common_1.Get)(),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Query)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_b = typeof order_dto_1.OrderQueryDto !== "undefined" && order_dto_1.OrderQueryDto) === "function" ? _b : Object]),
    __metadata("design:returntype", void 0)
], AdminOrdersController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)('stats'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], AdminOrdersController.prototype, "getStats", null);
__decorate([
    (0, common_1.Get)(':id'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], AdminOrdersController.prototype, "findOne", null);
__decorate([
    (0, common_1.Put)(':id/status'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_c = typeof order_dto_1.UpdateOrderStatusDto !== "undefined" && order_dto_1.UpdateOrderStatusDto) === "function" ? _c : Object]),
    __metadata("design:returntype", void 0)
], AdminOrdersController.prototype, "updateStatus", null);
__decorate([
    (0, common_1.Post)(':id/cancel'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], AdminOrdersController.prototype, "cancel", null);
exports.AdminOrdersController = AdminOrdersController = __decorate([
    (0, common_1.Controller)('api/shop/admin/orders'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof orders_service_1.OrdersService !== "undefined" && orders_service_1.OrdersService) === "function" ? _a : Object])
], AdminOrdersController);
let OrdersController = class OrdersController {
    constructor(ordersService) {
        this.ordersService = ordersService;
    }
    async createOrder(dto, req, _res) {
        const userId = req.user?.id;
        const sessionId = req.cookies?.cart_session;
        return this.ordersService.createFromCart(dto, userId, sessionId);
    }
    findByOrderNumber(orderNumber) {
        return this.ordersService.findByOrderNumber(orderNumber);
    }
    findOne(id) {
        return this.ordersService.findOne(id);
    }
};
exports.OrdersController = OrdersController;
__decorate([
    (0, common_1.Post)(),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, common_1.Req)()),
    __param(2, (0, common_1.Res)({ passthrough: true })),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_e = typeof order_dto_1.CreateOrderDto !== "undefined" && order_dto_1.CreateOrderDto) === "function" ? _e : Object, typeof (_f = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _f : Object, typeof (_g = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _g : Object]),
    __metadata("design:returntype", Promise)
], OrdersController.prototype, "createOrder", null);
__decorate([
    (0, common_1.Get)('lookup/:orderNumber'),
    __param(0, (0, common_1.Param)('orderNumber')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], OrdersController.prototype, "findByOrderNumber", null);
__decorate([
    (0, common_1.Get)(':id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], OrdersController.prototype, "findOne", null);
exports.OrdersController = OrdersController = __decorate([
    (0, common_1.Controller)('api/shop/orders'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __metadata("design:paramtypes", [typeof (_d = typeof orders_service_1.OrdersService !== "undefined" && orders_service_1.OrdersService) === "function" ? _d : Object])
], OrdersController);
let UserOrdersController = class UserOrdersController {
    constructor(ordersService) {
        this.ordersService = ordersService;
    }
    findMyOrders(req, query) {
        const userId = req.user.id;
        return this.ordersService.findByUser(userId, query);
    }
    findOne(id) {
        return this.ordersService.findOne(id);
    }
};
exports.UserOrdersController = UserOrdersController;
__decorate([
    (0, common_1.Get)(),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Query)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_j = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _j : Object, typeof (_k = typeof order_dto_1.OrderQueryDto !== "undefined" && order_dto_1.OrderQueryDto) === "function" ? _k : Object]),
    __metadata("design:returntype", void 0)
], UserOrdersController.prototype, "findMyOrders", null);
__decorate([
    (0, common_1.Get)(':id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], UserOrdersController.prototype, "findOne", null);
exports.UserOrdersController = UserOrdersController = __decorate([
    (0, common_1.Controller)('api/shop/my-orders'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __metadata("design:paramtypes", [typeof (_h = typeof orders_service_1.OrdersService !== "undefined" && orders_service_1.OrdersService) === "function" ? _h : Object])
], UserOrdersController);


/***/ }),
/* 195 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.OrderQueryDto = exports.RefundOrderDto = exports.UpdateOrderStatusDto = exports.CreateOrderDto = exports.AddressDto = exports.PaymentStatus = exports.OrderStatus = void 0;
const class_validator_1 = __webpack_require__(59);
const class_transformer_1 = __webpack_require__(95);
var OrderStatus;
(function (OrderStatus) {
    OrderStatus["PENDING"] = "PENDING";
    OrderStatus["CONFIRMED"] = "CONFIRMED";
    OrderStatus["PROCESSING"] = "PROCESSING";
    OrderStatus["SHIPPED"] = "SHIPPED";
    OrderStatus["DELIVERED"] = "DELIVERED";
    OrderStatus["COMPLETED"] = "COMPLETED";
    OrderStatus["CANCELLED"] = "CANCELLED";
    OrderStatus["REFUNDED"] = "REFUNDED";
})(OrderStatus || (exports.OrderStatus = OrderStatus = {}));
var PaymentStatus;
(function (PaymentStatus) {
    PaymentStatus["UNPAID"] = "UNPAID";
    PaymentStatus["PAID"] = "PAID";
    PaymentStatus["PARTIALLY_REFUNDED"] = "PARTIALLY_REFUNDED";
    PaymentStatus["REFUNDED"] = "REFUNDED";
    PaymentStatus["FAILED"] = "FAILED";
})(PaymentStatus || (exports.PaymentStatus = PaymentStatus = {}));
class AddressDto {
}
exports.AddressDto = AddressDto;
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], AddressDto.prototype, "firstName", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], AddressDto.prototype, "lastName", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], AddressDto.prototype, "company", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], AddressDto.prototype, "address1", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], AddressDto.prototype, "address2", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], AddressDto.prototype, "city", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], AddressDto.prototype, "state", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], AddressDto.prototype, "postalCode", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], AddressDto.prototype, "country", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], AddressDto.prototype, "phone", void 0);
class CreateOrderDto {
}
exports.CreateOrderDto = CreateOrderDto;
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsEmail)(),
    __metadata("design:type", String)
], CreateOrderDto.prototype, "email", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.ValidateNested)(),
    (0, class_transformer_1.Type)(() => AddressDto),
    __metadata("design:type", AddressDto)
], CreateOrderDto.prototype, "billingAddress", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.ValidateNested)(),
    (0, class_transformer_1.Type)(() => AddressDto),
    __metadata("design:type", AddressDto)
], CreateOrderDto.prototype, "shippingAddress", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateOrderDto.prototype, "shippingMethod", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateOrderDto.prototype, "couponCode", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateOrderDto.prototype, "customerNote", void 0);
class UpdateOrderStatusDto {
}
exports.UpdateOrderStatusDto = UpdateOrderStatusDto;
__decorate([
    (0, class_validator_1.IsEnum)(OrderStatus),
    __metadata("design:type", String)
], UpdateOrderStatusDto.prototype, "status", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], UpdateOrderStatusDto.prototype, "trackingNumber", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], UpdateOrderStatusDto.prototype, "adminNote", void 0);
class RefundOrderDto {
}
exports.RefundOrderDto = RefundOrderDto;
__decorate([
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], RefundOrderDto.prototype, "amount", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], RefundOrderDto.prototype, "reason", void 0);
class OrderQueryDto {
    constructor() {
        this.page = 1;
        this.limit = 20;
    }
}
exports.OrderQueryDto = OrderQueryDto;
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsEnum)(OrderStatus),
    __metadata("design:type", String)
], OrderQueryDto.prototype, "status", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsEnum)(PaymentStatus),
    __metadata("design:type", String)
], OrderQueryDto.prototype, "paymentStatus", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], OrderQueryDto.prototype, "search", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], OrderQueryDto.prototype, "page", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], OrderQueryDto.prototype, "limit", void 0);


/***/ }),
/* 196 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e, _f, _g, _h;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.RefundsController = exports.CheckoutController = void 0;
const common_1 = __webpack_require__(2);
const express_1 = __webpack_require__(57);
const stripe_service_1 = __webpack_require__(187);
const orders_service_1 = __webpack_require__(186);
const optional_jwt_auth_guard_1 = __webpack_require__(76);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const client_1 = __webpack_require__(17);
const order_dto_1 = __webpack_require__(195);
let CheckoutController = class CheckoutController {
    constructor(stripeService, ordersService) {
        this.stripeService = stripeService;
        this.ordersService = ordersService;
    }
    getConfig() {
        return {
            publishableKey: this.stripeService.getPublishableKey(),
        };
    }
    async createOrderAndPayment(dto, req, _res) {
        const user = req.user;
        const userId = user?.id;
        const sessionId = req.cookies?.cart_session;
        if (!dto.email && user?.email) {
            dto.email = user.email;
        }
        if (!dto.email) {
            throw new Error('Email is required for checkout');
        }
        console.log('Creating order for session:', sessionId, 'user:', userId, 'email:', dto.email);
        try {
            const order = await this.ordersService.createFromCart(dto, userId, sessionId);
            console.log('Order created:', order.id);
            const paymentIntent = await this.stripeService.createPaymentIntent(order.id);
            console.log('Payment intent created:', paymentIntent.paymentIntentId);
            return {
                order,
                ...paymentIntent,
            };
        }
        catch (error) {
            console.error('Checkout error:', error.message, error.stack);
            throw error;
        }
    }
    async createPaymentIntent(orderId) {
        return this.stripeService.createPaymentIntent(orderId);
    }
    async handleWebhook(req, signature) {
        if (!req.rawBody) {
            throw new Error('Raw body is required for webhook verification');
        }
        return this.stripeService.handleWebhook(req.rawBody, signature);
    }
};
exports.CheckoutController = CheckoutController;
__decorate([
    (0, common_1.Get)('config'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], CheckoutController.prototype, "getConfig", null);
__decorate([
    (0, common_1.Post)('create-order'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, common_1.Req)()),
    __param(2, (0, common_1.Res)({ passthrough: true })),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_c = typeof order_dto_1.CreateOrderDto !== "undefined" && order_dto_1.CreateOrderDto) === "function" ? _c : Object, typeof (_d = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _d : Object, typeof (_e = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _e : Object]),
    __metadata("design:returntype", Promise)
], CheckoutController.prototype, "createOrderAndPayment", null);
__decorate([
    (0, common_1.Post)('payment-intent/:orderId'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Param)('orderId')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], CheckoutController.prototype, "createPaymentIntent", null);
__decorate([
    (0, common_1.Post)('webhook'),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Headers)('stripe-signature')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_f = typeof common_1.RawBodyRequest !== "undefined" && common_1.RawBodyRequest) === "function" ? _f : Object, String]),
    __metadata("design:returntype", Promise)
], CheckoutController.prototype, "handleWebhook", null);
exports.CheckoutController = CheckoutController = __decorate([
    (0, common_1.Controller)('api/shop/checkout'),
    __metadata("design:paramtypes", [typeof (_a = typeof stripe_service_1.StripeService !== "undefined" && stripe_service_1.StripeService) === "function" ? _a : Object, typeof (_b = typeof orders_service_1.OrdersService !== "undefined" && orders_service_1.OrdersService) === "function" ? _b : Object])
], CheckoutController);
let RefundsController = class RefundsController {
    constructor(stripeService) {
        this.stripeService = stripeService;
    }
    async createRefund(orderId, dto) {
        return this.stripeService.createRefund(orderId, dto.amount, dto.reason);
    }
};
exports.RefundsController = RefundsController;
__decorate([
    (0, common_1.Post)(':orderId'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('orderId')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_h = typeof order_dto_1.RefundOrderDto !== "undefined" && order_dto_1.RefundOrderDto) === "function" ? _h : Object]),
    __metadata("design:returntype", Promise)
], RefundsController.prototype, "createRefund", null);
exports.RefundsController = RefundsController = __decorate([
    (0, common_1.Controller)('api/shop/admin/refunds'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    __metadata("design:paramtypes", [typeof (_g = typeof stripe_service_1.StripeService !== "undefined" && stripe_service_1.StripeService) === "function" ? _g : Object])
], RefundsController);


/***/ }),
/* 197 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.StorefrontController = void 0;
const common_1 = __webpack_require__(2);
const products_service_1 = __webpack_require__(172);
const categories_service_1 = __webpack_require__(173);
const product_dto_1 = __webpack_require__(189);
let StorefrontController = class StorefrontController {
    constructor(productsService, categoriesService) {
        this.productsService = productsService;
        this.categoriesService = categoriesService;
    }
    getProducts(query) {
        return this.productsService.getActiveProducts(query);
    }
    getProductBySlug(slug) {
        return this.productsService.findBySlug(slug);
    }
    getCategories() {
        return this.categoriesService.findAll();
    }
    getCategoryTree() {
        return this.categoriesService.findTree();
    }
    getCategoryBySlug(slug) {
        return this.categoriesService.findBySlug(slug);
    }
    async getFeaturedProducts() {
        const result = await this.productsService.getActiveProducts({ limit: 8 });
        return result.products;
    }
    async getSaleProducts() {
        const result = await this.productsService.getActiveProducts({ limit: 12 });
        return result.products.filter((p) => p.salePrice);
    }
};
exports.StorefrontController = StorefrontController;
__decorate([
    (0, common_1.Get)('products'),
    __param(0, (0, common_1.Query)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_c = typeof product_dto_1.ProductQueryDto !== "undefined" && product_dto_1.ProductQueryDto) === "function" ? _c : Object]),
    __metadata("design:returntype", void 0)
], StorefrontController.prototype, "getProducts", null);
__decorate([
    (0, common_1.Get)('products/:slug'),
    __param(0, (0, common_1.Param)('slug')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], StorefrontController.prototype, "getProductBySlug", null);
__decorate([
    (0, common_1.Get)('categories'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], StorefrontController.prototype, "getCategories", null);
__decorate([
    (0, common_1.Get)('categories/tree'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], StorefrontController.prototype, "getCategoryTree", null);
__decorate([
    (0, common_1.Get)('categories/:slug'),
    __param(0, (0, common_1.Param)('slug')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], StorefrontController.prototype, "getCategoryBySlug", null);
__decorate([
    (0, common_1.Get)('featured'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], StorefrontController.prototype, "getFeaturedProducts", null);
__decorate([
    (0, common_1.Get)('sale'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], StorefrontController.prototype, "getSaleProducts", null);
exports.StorefrontController = StorefrontController = __decorate([
    (0, common_1.Controller)('api/shop/storefront'),
    __metadata("design:paramtypes", [typeof (_a = typeof products_service_1.ProductsService !== "undefined" && products_service_1.ProductsService) === "function" ? _a : Object, typeof (_b = typeof categories_service_1.CategoriesService !== "undefined" && categories_service_1.CategoriesService) === "function" ? _b : Object])
], StorefrontController);


/***/ }),
/* 198 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.LmsModule = void 0;
const common_1 = __webpack_require__(2);
const prisma_module_1 = __webpack_require__(15);
const config_1 = __webpack_require__(13);
const courses_service_1 = __webpack_require__(174);
const lessons_service_1 = __webpack_require__(199);
const modules_service_1 = __webpack_require__(200);
const quizzes_service_1 = __webpack_require__(201);
const enrollments_service_1 = __webpack_require__(202);
const progress_service_1 = __webpack_require__(176);
const certificates_service_1 = __webpack_require__(175);
const certificate_generator_service_1 = __webpack_require__(177);
const course_placeholder_service_1 = __webpack_require__(203);
const courses_controller_1 = __webpack_require__(205);
const lessons_controller_1 = __webpack_require__(207);
const modules_controller_1 = __webpack_require__(210);
const quizzes_controller_1 = __webpack_require__(212);
const enrollments_controller_1 = __webpack_require__(214);
const learning_controller_1 = __webpack_require__(216);
const certificates_controller_1 = __webpack_require__(217);
const course_ownership_guard_1 = __webpack_require__(208);
const feature_guard_1 = __webpack_require__(162);
let LmsModule = class LmsModule {
};
exports.LmsModule = LmsModule;
exports.LmsModule = LmsModule = __decorate([
    (0, common_1.Module)({
        imports: [prisma_module_1.PrismaModule, config_1.ConfigModule],
        controllers: [
            courses_controller_1.CoursesController,
            courses_controller_1.PublicCoursesController,
            lessons_controller_1.LessonsController,
            modules_controller_1.ModulesController,
            quizzes_controller_1.QuizzesController,
            enrollments_controller_1.EnrollmentsController,
            learning_controller_1.LearningController,
            certificates_controller_1.CertificatesController,
        ],
        providers: [
            courses_service_1.CoursesService,
            lessons_service_1.LessonsService,
            modules_service_1.ModulesService,
            quizzes_service_1.QuizzesService,
            enrollments_service_1.EnrollmentsService,
            progress_service_1.ProgressService,
            certificates_service_1.CertificatesService,
            certificate_generator_service_1.CertificateGeneratorService,
            course_placeholder_service_1.CoursePlaceholderService,
            course_ownership_guard_1.CourseOwnershipGuard,
            feature_guard_1.FeatureGuard,
        ],
        exports: [
            courses_service_1.CoursesService,
            lessons_service_1.LessonsService,
            modules_service_1.ModulesService,
            quizzes_service_1.QuizzesService,
            enrollments_service_1.EnrollmentsService,
            progress_service_1.ProgressService,
            certificates_service_1.CertificatesService,
            course_placeholder_service_1.CoursePlaceholderService,
        ],
    })
], LmsModule);


/***/ }),
/* 199 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.LessonsService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const fs = __webpack_require__(24);
const path = __webpack_require__(3);
let LessonsService = class LessonsService {
    constructor(prisma) {
        this.prisma = prisma;
        this.videoUploadDir = path.join(process.cwd(), 'uploads', 'videos');
        this.ensureVideoDir();
    }
    async ensureVideoDir() {
        try {
            await fs.access(this.videoUploadDir);
        }
        catch {
            await fs.mkdir(this.videoUploadDir, { recursive: true });
        }
    }
    async create(courseId, dto) {
        const maxOrder = await this.prisma.lesson.aggregate({
            where: { courseId },
            _max: { orderIndex: true },
        });
        const orderIndex = dto.orderIndex ?? (maxOrder._max.orderIndex ?? -1) + 1;
        const lesson = await this.prisma.lesson.create({
            data: {
                ...dto,
                courseId,
                orderIndex,
            },
            include: {
                videoAsset: true,
                quiz: true,
            },
        });
        if (dto.type === 'QUIZ' && !lesson.quiz) {
            const quiz = await this.prisma.quiz.create({
                data: {
                    courseId,
                    lessonId: lesson.id,
                    title: dto.title,
                    description: dto.content || '',
                    isRequired: dto.isRequired ?? true,
                },
            });
            return { ...lesson, quiz };
        }
        return lesson;
    }
    async findByCourse(courseId) {
        return this.prisma.lesson.findMany({
            where: { courseId },
            orderBy: { orderIndex: 'asc' },
            include: {
                videoAsset: true,
                quiz: { select: { id: true, title: true } },
                module: { select: { id: true, title: true } },
            },
        });
    }
    async findOne(id) {
        const lesson = await this.prisma.lesson.findUnique({
            where: { id },
            include: {
                course: {
                    select: { id: true, title: true, instructorId: true, status: true },
                },
                videoAsset: true,
                quiz: true,
            },
        });
        if (!lesson)
            throw new common_1.NotFoundException('Lesson not found');
        return lesson;
    }
    async update(id, dto) {
        await this.findOne(id);
        return this.prisma.lesson.update({
            where: { id },
            data: dto,
            include: {
                videoAsset: true,
            },
        });
    }
    async delete(id) {
        await this.findOne(id);
        await this.prisma.lesson.delete({ where: { id } });
        return { message: 'Lesson deleted successfully' };
    }
    async reorder(courseId, lessonIds) {
        const updates = lessonIds.map((id, index) => this.prisma.lesson.update({
            where: { id },
            data: { orderIndex: index },
        }));
        await this.prisma.$transaction(updates);
        return this.findByCourse(courseId);
    }
    async createVideoAsset(dto) {
        return this.prisma.videoAsset.create({
            data: {
                provider: dto.provider || 'UPLOAD',
                url: dto.url,
                playbackId: dto.playbackId,
                filePath: dto.filePath,
                durationSeconds: dto.durationSeconds,
                isProtected: dto.isProtected ?? true,
                thumbnailUrl: dto.thumbnailUrl,
            },
        });
    }
    async getVideoAsset(id) {
        const asset = await this.prisma.videoAsset.findUnique({ where: { id } });
        if (!asset)
            throw new common_1.NotFoundException('Video asset not found');
        return asset;
    }
    async deleteVideoAsset(id) {
        await this.getVideoAsset(id);
        await this.prisma.videoAsset.delete({ where: { id } });
        return { message: 'Video asset deleted successfully' };
    }
    async getLessonForLearning(lessonId, userId) {
        const lesson = await this.findOne(lessonId);
        const enrollment = await this.prisma.enrollment.findUnique({
            where: {
                courseId_userId: {
                    courseId: lesson.course.id,
                    userId,
                },
            },
        });
        if (!lesson.isPreview && !enrollment) {
            throw new common_1.ForbiddenException('You must be enrolled to access this lesson');
        }
        const progress = await this.prisma.lessonProgress.findUnique({
            where: {
                courseId_lessonId_userId: {
                    courseId: lesson.course.id,
                    lessonId,
                    userId,
                },
            },
        });
        return { lesson, progress, isEnrolled: !!enrollment };
    }
    async uploadVideo(courseId, lessonId, file, userId) {
        await this.findOne(lessonId);
        const course = await this.prisma.course.findUnique({ where: { id: courseId } });
        if (!course)
            throw new common_1.NotFoundException('Course not found');
        if (course.instructorId !== userId) {
            const user = await this.prisma.user.findUnique({ where: { id: userId } });
            if (user?.role !== 'ADMIN') {
                throw new common_1.ForbiddenException('Not authorized to upload videos to this course');
            }
        }
        const ext = path.extname(file.originalname);
        const filename = `${courseId}-${lessonId}-${Date.now()}${ext}`;
        const filepath = path.join(this.videoUploadDir, filename);
        await fs.writeFile(filepath, file.buffer);
        const videoAsset = await this.prisma.videoAsset.create({
            data: {
                provider: 'UPLOAD',
                url: `/uploads/videos/${filename}`,
                filePath: filepath,
                isProtected: true,
            },
        });
        const updatedLesson = await this.prisma.lesson.update({
            where: { id: lessonId },
            data: { videoAssetId: videoAsset.id },
            include: { videoAsset: true },
        });
        return updatedLesson;
    }
    async attachExternalVideo(lessonId, dto) {
        await this.findOne(lessonId);
        const videoAsset = await this.prisma.videoAsset.create({
            data: {
                provider: dto.provider.toUpperCase(),
                url: dto.url,
                playbackId: dto.playbackId,
                durationSeconds: dto.durationSeconds,
                isProtected: false,
            },
        });
        const updatedLesson = await this.prisma.lesson.update({
            where: { id: lessonId },
            data: { videoAssetId: videoAsset.id, type: 'VIDEO' },
            include: { videoAsset: true },
        });
        return updatedLesson;
    }
    async removeVideo(lessonId) {
        const lesson = await this.findOne(lessonId);
        if (lesson.videoAsset) {
            if (lesson.videoAsset.filePath) {
                try {
                    await fs.unlink(lesson.videoAsset.filePath);
                }
                catch (e) {
                    console.error('Failed to delete video file:', e);
                }
            }
            await this.prisma.videoAsset.delete({ where: { id: lesson.videoAsset.id } });
        }
        return this.prisma.lesson.update({
            where: { id: lessonId },
            data: { videoAssetId: null },
        });
    }
};
exports.LessonsService = LessonsService;
exports.LessonsService = LessonsService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], LessonsService);


/***/ }),
/* 200 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ModulesService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let ModulesService = class ModulesService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async create(courseId, dto) {
        const course = await this.prisma.course.findUnique({ where: { id: courseId } });
        if (!course)
            throw new common_1.NotFoundException('Course not found');
        const maxOrder = await this.prisma.courseModule.aggregate({
            where: { courseId },
            _max: { orderIndex: true },
        });
        const orderIndex = dto.orderIndex ?? (maxOrder._max.orderIndex ?? -1) + 1;
        return this.prisma.courseModule.create({
            data: {
                ...dto,
                courseId,
                orderIndex,
            },
            include: {
                lessons: {
                    orderBy: { orderIndex: 'asc' },
                    select: { id: true, title: true, type: true, orderIndex: true },
                },
                _count: { select: { lessons: true } },
            },
        });
    }
    async findByCourse(courseId) {
        return this.prisma.courseModule.findMany({
            where: { courseId },
            orderBy: { orderIndex: 'asc' },
            include: {
                lessons: {
                    orderBy: { orderIndex: 'asc' },
                    include: {
                        videoAsset: { select: { id: true, provider: true, url: true } },
                        quiz: { select: { id: true, title: true } },
                    },
                },
                _count: { select: { lessons: true } },
            },
        });
    }
    async findOne(id) {
        const module = await this.prisma.courseModule.findUnique({
            where: { id },
            include: {
                course: { select: { id: true, title: true, instructorId: true } },
                lessons: {
                    orderBy: { orderIndex: 'asc' },
                    include: {
                        videoAsset: true,
                        quiz: { select: { id: true, title: true } },
                    },
                },
                _count: { select: { lessons: true } },
            },
        });
        if (!module)
            throw new common_1.NotFoundException('Module not found');
        return module;
    }
    async update(id, dto) {
        await this.findOne(id);
        return this.prisma.courseModule.update({
            where: { id },
            data: dto,
            include: {
                lessons: {
                    orderBy: { orderIndex: 'asc' },
                    select: { id: true, title: true, type: true, orderIndex: true },
                },
                _count: { select: { lessons: true } },
            },
        });
    }
    async delete(id) {
        const module = await this.findOne(id);
        await this.prisma.lesson.updateMany({
            where: { moduleId: id },
            data: { moduleId: null },
        });
        await this.prisma.courseModule.delete({ where: { id } });
        return { message: 'Module deleted successfully', lessonsUnassigned: module._count.lessons };
    }
    async reorder(courseId, moduleIds) {
        const updates = moduleIds.map((id, index) => this.prisma.courseModule.update({
            where: { id },
            data: { orderIndex: index },
        }));
        await this.prisma.$transaction(updates);
        return this.findByCourse(courseId);
    }
    async moveLessonToModule(lessonId, moduleId, orderIndex) {
        const lesson = await this.prisma.lesson.findUnique({ where: { id: lessonId } });
        if (!lesson)
            throw new common_1.NotFoundException('Lesson not found');
        if (moduleId) {
            const module = await this.prisma.courseModule.findUnique({ where: { id: moduleId } });
            if (!module)
                throw new common_1.NotFoundException('Module not found');
            if (module.courseId !== lesson.courseId) {
                throw new common_1.NotFoundException('Module does not belong to the same course');
            }
        }
        let newOrderIndex = orderIndex;
        if (newOrderIndex === undefined) {
            const maxOrder = await this.prisma.lesson.aggregate({
                where: { courseId: lesson.courseId, moduleId: moduleId ?? null },
                _max: { orderIndex: true },
            });
            newOrderIndex = (maxOrder._max.orderIndex ?? -1) + 1;
        }
        return this.prisma.lesson.update({
            where: { id: lessonId },
            data: { moduleId, orderIndex: newOrderIndex },
            include: { module: { select: { id: true, title: true } } },
        });
    }
};
exports.ModulesService = ModulesService;
exports.ModulesService = ModulesService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], ModulesService);


/***/ }),
/* 201 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.QuizzesService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let QuizzesService = class QuizzesService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async create(courseId, dto) {
        const { questions, ...quizData } = dto;
        const quiz = await this.prisma.quiz.create({
            data: {
                ...quizData,
                courseId,
            },
            include: { questions: { orderBy: { orderIndex: 'asc' } } },
        });
        if (questions && questions.length > 0) {
            await this.prisma.question.createMany({
                data: questions.map((q, index) => ({
                    ...q,
                    quizId: quiz.id,
                    orderIndex: q.orderIndex ?? index,
                })),
            });
            return this.findOne(quiz.id);
        }
        return quiz;
    }
    async findByCourse(courseId) {
        return this.prisma.quiz.findMany({
            where: { courseId },
            orderBy: { orderIndex: 'asc' },
            include: {
                _count: { select: { questions: true, attempts: true } },
            },
        });
    }
    async findOne(id) {
        const quiz = await this.prisma.quiz.findUnique({
            where: { id },
            include: {
                course: { select: { id: true, title: true, passingScorePercent: true } },
                questions: { orderBy: { orderIndex: 'asc' } },
                _count: { select: { attempts: true } },
            },
        });
        if (!quiz)
            throw new common_1.NotFoundException('Quiz not found');
        return quiz;
    }
    async update(id, dto) {
        const { questions: _questions, ...quizData } = dto;
        void _questions;
        await this.findOne(id);
        return this.prisma.quiz.update({
            where: { id },
            data: quizData,
            include: {
                questions: { orderBy: { orderIndex: 'asc' } },
            },
        });
    }
    async delete(id) {
        await this.findOne(id);
        await this.prisma.quiz.delete({ where: { id } });
        return { message: 'Quiz deleted successfully' };
    }
    async addQuestion(quizId, dto) {
        const quiz = await this.findOne(quizId);
        const maxOrder = quiz.questions.length > 0 ? Math.max(...quiz.questions.map((q) => q.orderIndex)) + 1 : 0;
        return this.prisma.question.create({
            data: {
                ...dto,
                quizId,
                orderIndex: dto.orderIndex ?? maxOrder,
            },
        });
    }
    async updateQuestion(questionId, dto) {
        const question = await this.prisma.question.findUnique({ where: { id: questionId } });
        if (!question)
            throw new common_1.NotFoundException('Question not found');
        return this.prisma.question.update({
            where: { id: questionId },
            data: dto,
        });
    }
    async deleteQuestion(questionId) {
        const question = await this.prisma.question.findUnique({ where: { id: questionId } });
        if (!question)
            throw new common_1.NotFoundException('Question not found');
        await this.prisma.question.delete({ where: { id: questionId } });
        return { message: 'Question deleted successfully' };
    }
    async reorderQuestions(quizId, questionIds) {
        const updates = questionIds.map((id, index) => this.prisma.question.update({
            where: { id },
            data: { orderIndex: index },
        }));
        await this.prisma.$transaction(updates);
        return this.findOne(quizId);
    }
    async startAttempt(quizId, userId, courseId) {
        const quiz = await this.findOne(quizId);
        const enrollment = await this.prisma.enrollment.findUnique({
            where: { courseId_userId: { courseId, userId } },
        });
        if (!enrollment)
            throw new common_1.ForbiddenException('You must be enrolled to take this quiz');
        if (quiz.attemptsAllowed) {
            const attemptCount = await this.prisma.quizAttempt.count({
                where: { quizId, userId },
            });
            if (attemptCount >= quiz.attemptsAllowed) {
                throw new common_1.BadRequestException(`Maximum attempts (${quiz.attemptsAllowed}) reached`);
            }
        }
        const lastAttempt = await this.prisma.quizAttempt.findFirst({
            where: { quizId, userId },
            orderBy: { attemptNumber: 'desc' },
        });
        let questions = quiz.questions.map((q) => ({
            id: q.id,
            type: q.type,
            prompt: q.prompt,
            optionsJson: q.optionsJson,
            points: q.points,
        }));
        if (quiz.shuffleQuestions) {
            questions = questions.sort(() => Math.random() - 0.5);
        }
        const attempt = await this.prisma.quizAttempt.create({
            data: { quizId, courseId, userId, attemptNumber: (lastAttempt?.attemptNumber ?? 0) + 1 },
        });
        return {
            attempt,
            questions,
            timeLimitSeconds: quiz.timeLimitSeconds,
            attemptsRemaining: quiz.attemptsAllowed
                ? quiz.attemptsAllowed - (lastAttempt?.attemptNumber ?? 0) - 1
                : null,
        };
    }
    async submitAttempt(attemptId, dto, userId) {
        const attempt = await this.prisma.quizAttempt.findUnique({
            where: { id: attemptId },
            include: {
                quiz: {
                    include: {
                        questions: true,
                        course: { select: { passingScorePercent: true } },
                    },
                },
            },
        });
        if (!attempt)
            throw new common_1.NotFoundException('Quiz attempt not found');
        if (attempt.userId !== userId)
            throw new common_1.ForbiddenException('Not authorized');
        if (attempt.submittedAt)
            throw new common_1.BadRequestException('Quiz already submitted');
        if (attempt.quiz.timeLimitSeconds) {
            const elapsed = (Date.now() - attempt.startedAt.getTime()) / 1000;
            if (elapsed > attempt.quiz.timeLimitSeconds + 30) {
                throw new common_1.BadRequestException('Time limit exceeded');
            }
        }
        const { scorePercent, scorePoints, maxPoints, results } = this.scoreQuiz(attempt.quiz.questions, dto.answers);
        const passingScore = attempt.quiz.passingScorePercent ?? attempt.quiz.course.passingScorePercent;
        const passed = scorePercent >= passingScore;
        const timeSpent = Math.floor((Date.now() - attempt.startedAt.getTime()) / 1000);
        const updatedAttempt = await this.prisma.quizAttempt.update({
            where: { id: attemptId },
            data: {
                submittedAt: new Date(),
                scorePercent,
                scorePoints,
                maxPoints,
                passed,
                answersJson: JSON.parse(JSON.stringify(dto.answers)),
                timeSpentSeconds: timeSpent,
            },
        });
        return {
            attempt: updatedAttempt,
            scorePercent,
            scorePoints,
            maxPoints,
            passed,
            passingScore,
            results,
        };
    }
    scoreQuiz(questions, answers) {
        let scorePoints = 0;
        let maxPoints = 0;
        const results = [];
        for (const question of questions) {
            maxPoints += question.points;
            const userAnswer = answers.find((a) => a.questionId === question.id);
            const isCorrect = this.checkAnswer(question, userAnswer?.answer);
            if (isCorrect)
                scorePoints += question.points;
            results.push({
                questionId: question.id,
                correct: isCorrect,
                userAnswer: userAnswer?.answer,
                correctAnswer: question.correctAnswerJson,
                explanation: question.explanation,
                points: isCorrect ? question.points : 0,
            });
        }
        const scorePercent = maxPoints > 0 ? Math.round((scorePoints / maxPoints) * 100) : 0;
        return { scorePercent, scorePoints, maxPoints, results };
    }
    checkAnswer(question, userAnswer) {
        if (!userAnswer)
            return false;
        const correct = question.correctAnswerJson;
        switch (question.type) {
            case 'MCQ':
            case 'SHORT_ANSWER':
                return String(userAnswer).toLowerCase().trim() === String(correct).toLowerCase().trim();
            case 'TRUE_FALSE':
                return Boolean(userAnswer) === Boolean(correct);
            case 'MCQ_MULTI':
                if (!Array.isArray(userAnswer) || !Array.isArray(correct))
                    return false;
                const sortedUser = [...userAnswer].sort();
                const sortedCorrect = [...correct].sort();
                return JSON.stringify(sortedUser) === JSON.stringify(sortedCorrect);
            case 'ESSAY':
                return true;
            default:
                return false;
        }
    }
    async getAttemptHistory(quizId, userId) {
        return this.prisma.quizAttempt.findMany({
            where: { quizId, userId },
            orderBy: { attemptNumber: 'desc' },
        });
    }
    async getQuizForStudent(quizId, userId) {
        const quiz = await this.findOne(quizId);
        const questions = quiz.questions.map((q) => ({
            id: q.id,
            type: q.type,
            prompt: q.prompt,
            optionsJson: q.optionsJson,
            points: q.points,
        }));
        const attempts = await this.getAttemptHistory(quizId, userId);
        return {
            ...quiz,
            questions,
            attempts,
            attemptsUsed: attempts.length,
            attemptsRemaining: quiz.attemptsAllowed ? quiz.attemptsAllowed - attempts.length : null,
        };
    }
};
exports.QuizzesService = QuizzesService;
exports.QuizzesService = QuizzesService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], QuizzesService);


/***/ }),
/* 202 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.EnrollmentsService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let EnrollmentsService = class EnrollmentsService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async enroll(courseId, userId, dto) {
        const course = await this.prisma.course.findUnique({ where: { id: courseId } });
        if (!course)
            throw new common_1.NotFoundException('Course not found');
        if (course.status !== 'PUBLISHED')
            throw new common_1.BadRequestException('Course is not available for enrollment');
        const existing = await this.prisma.enrollment.findUnique({
            where: { courseId_userId: { courseId, userId } },
        });
        if (existing)
            throw new common_1.BadRequestException('Already enrolled in this course');
        if (course.priceType === 'PAID' && !dto.paymentId) {
            throw new common_1.BadRequestException('Payment required for this course');
        }
        return this.prisma.enrollment.create({
            data: {
                courseId,
                userId,
                status: 'ACTIVE',
                paymentId: dto.paymentId,
            },
            include: {
                course: { select: { id: true, title: true, slug: true, featuredImage: true } },
            },
        });
    }
    async findUserEnrollments(userId) {
        const enrollments = await this.prisma.enrollment.findMany({
            where: { userId },
            orderBy: { enrolledAt: 'desc' },
            include: {
                course: {
                    select: {
                        id: true,
                        title: true,
                        slug: true,
                        featuredImage: true,
                        _count: { select: { lessons: true } },
                    },
                },
            },
        });
        const enrollmentsWithProgress = await Promise.all(enrollments.map(async (enrollment) => {
            const [completedLessons, totalLessons] = await Promise.all([
                this.prisma.lessonProgress.count({
                    where: { courseId: enrollment.courseId, userId, lessonCompleted: true },
                }),
                this.prisma.lesson.count({ where: { courseId: enrollment.courseId } }),
            ]);
            return {
                ...enrollment,
                progress: {
                    completedLessons,
                    totalLessons,
                    percent: totalLessons > 0 ? Math.round((completedLessons / totalLessons) * 100) : 0,
                },
            };
        }));
        return enrollmentsWithProgress;
    }
    async findCourseEnrollments(courseId) {
        return this.prisma.enrollment.findMany({
            where: { courseId },
            orderBy: { enrolledAt: 'desc' },
            include: {
                user: { select: { id: true, name: true, email: true, avatar: true } },
            },
        });
    }
    async findOne(courseId, userId) {
        const enrollment = await this.prisma.enrollment.findUnique({
            where: { courseId_userId: { courseId, userId } },
            include: {
                course: true,
                user: { select: { id: true, name: true, email: true } },
            },
        });
        if (!enrollment)
            throw new common_1.NotFoundException('Enrollment not found');
        return enrollment;
    }
    async isEnrolled(courseId, userId) {
        const enrollment = await this.prisma.enrollment.findUnique({
            where: { courseId_userId: { courseId, userId } },
        });
        return !!enrollment && enrollment.status === 'ACTIVE';
    }
    async update(courseId, userId, dto) {
        await this.findOne(courseId, userId);
        return this.prisma.enrollment.update({
            where: { courseId_userId: { courseId, userId } },
            data: dto,
        });
    }
    async cancel(courseId, userId) {
        const enrollment = await this.findOne(courseId, userId);
        return this.prisma.enrollment.update({
            where: { id: enrollment.id },
            data: { status: 'CANCELLED' },
        });
    }
    async complete(courseId, userId) {
        const enrollment = await this.findOne(courseId, userId);
        return this.prisma.enrollment.update({
            where: { id: enrollment.id },
            data: { status: 'COMPLETED', completedAt: new Date() },
        });
    }
    async getEnrollmentStats(courseId) {
        const [total, active, completed] = await Promise.all([
            this.prisma.enrollment.count({ where: { courseId } }),
            this.prisma.enrollment.count({ where: { courseId, status: 'ACTIVE' } }),
            this.prisma.enrollment.count({ where: { courseId, status: 'COMPLETED' } }),
        ]);
        return { total, active, completed };
    }
};
exports.EnrollmentsService = EnrollmentsService;
exports.EnrollmentsService = EnrollmentsService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], EnrollmentsService);


/***/ }),
/* 203 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CoursePlaceholderService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const sharp = __webpack_require__(36);
const fs = __webpack_require__(4);
const path = __webpack_require__(3);
const node_fetch_1 = __webpack_require__(204);
let CoursePlaceholderService = class CoursePlaceholderService {
    constructor(prisma) {
        this.prisma = prisma;
        this.uploadsDir = path.join(process.cwd(), 'uploads');
        this.cacheDir = path.join(this.uploadsDir, 'placeholders');
        if (!fs.existsSync(this.cacheDir)) {
            fs.mkdirSync(this.cacheDir, { recursive: true });
        }
    }
    async getCoursePlaceholder() {
        const placeholderPath = path.join(this.cacheDir, 'course-default.png');
        if (fs.existsSync(placeholderPath)) {
            return '/uploads/placeholders/course-default.png';
        }
        await this.generatePlaceholder(placeholderPath);
        return '/uploads/placeholders/course-default.png';
    }
    async generatePlaceholder(outputPath) {
        const width = 800;
        const height = 450;
        const logoUrl = await this.getSiteLogo();
        const svgBackground = `
      <svg width="${width}" height="${height}">
        <defs>
          <linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
            <stop offset="0%" style="stop-color:#6366f1;stop-opacity:1" />
            <stop offset="50%" style="stop-color:#8b5cf6;stop-opacity:1" />
            <stop offset="100%" style="stop-color:#a855f7;stop-opacity:1" />
          </linearGradient>
        </defs>
        <rect width="${width}" height="${height}" fill="url(#grad)"/>
        <text x="${width / 2}" y="${height - 40}" text-anchor="middle" 
              font-family="Arial, sans-serif" font-size="24" fill="rgba(255,255,255,0.7)">
          WordPress Node LMS
        </text>
      </svg>
    `;
        let baseImage = sharp(Buffer.from(svgBackground));
        if (logoUrl) {
            try {
                const logoBuffer = await this.fetchImage(logoUrl);
                if (logoBuffer) {
                    const resizedLogo = await sharp(logoBuffer)
                        .resize(200, 150, { fit: 'inside', background: { r: 0, g: 0, b: 0, alpha: 0 } })
                        .png()
                        .toBuffer();
                    const logoMeta = await sharp(resizedLogo).metadata();
                    const logoWidth = logoMeta.width || 200;
                    const logoHeight = logoMeta.height || 150;
                    const left = Math.floor((width - logoWidth) / 2);
                    const top = Math.floor((height - logoHeight) / 2) - 20;
                    baseImage = baseImage.composite([{ input: resizedLogo, left, top }]);
                }
            }
            catch (error) {
                console.log('Could not overlay logo, using text fallback:', error.message);
                baseImage = await this.addFallbackText(width, height);
            }
        }
        else {
            baseImage = await this.addFallbackText(width, height);
        }
        await baseImage.png().toFile(outputPath);
    }
    async addFallbackText(width, height) {
        const svg = `
      <svg width="${width}" height="${height}">
        <defs>
          <linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
            <stop offset="0%" style="stop-color:#6366f1;stop-opacity:1" />
            <stop offset="50%" style="stop-color:#8b5cf6;stop-opacity:1" />
            <stop offset="100%" style="stop-color:#a855f7;stop-opacity:1" />
          </linearGradient>
        </defs>
        <rect width="${width}" height="${height}" fill="url(#grad)"/>
        <text x="${width / 2}" y="${height / 2 - 20}" text-anchor="middle" 
              font-family="Arial, sans-serif" font-size="72" fill="white">
          📚
        </text>
        <text x="${width / 2}" y="${height / 2 + 50}" text-anchor="middle" 
              font-family="Arial, sans-serif" font-size="28" fill="white" font-weight="bold">
          Course
        </text>
        <text x="${width / 2}" y="${height - 40}" text-anchor="middle" 
              font-family="Arial, sans-serif" font-size="20" fill="rgba(255,255,255,0.7)">
          WordPress Node LMS
        </text>
      </svg>
    `;
        return sharp(Buffer.from(svg));
    }
    async getSiteLogo() {
        const logoSetting = await this.prisma.setting.findFirst({
            where: { key: { in: ['site_logo', 'logo', 'logo_url'] } },
        });
        if (logoSetting?.value) {
            const value = logoSetting.value;
            return typeof value === 'string' ? value : value.url || null;
        }
        const activeTheme = await this.prisma.theme.findFirst({
            where: { isActive: true },
            include: { customizationImages: { where: { type: 'logo' } } },
        });
        if (activeTheme?.customizationImages?.[0]?.url) {
            return activeTheme.customizationImages[0].url;
        }
        return null;
    }
    async fetchImage(url) {
        try {
            if (url.startsWith('http://') || url.startsWith('https://')) {
                const response = await (0, node_fetch_1.default)(url);
                if (!response.ok)
                    return null;
                return Buffer.from(await response.arrayBuffer());
            }
            else {
                const localPath = path.join(process.cwd(), url.replace(/^\//, ''));
                if (fs.existsSync(localPath)) {
                    return fs.readFileSync(localPath);
                }
            }
        }
        catch (error) {
            console.log('Failed to fetch image:', error.message);
        }
        return null;
    }
    async regeneratePlaceholder() {
        const placeholderPath = path.join(this.cacheDir, 'course-default.png');
        if (fs.existsSync(placeholderPath)) {
            fs.unlinkSync(placeholderPath);
        }
        return this.getCoursePlaceholder();
    }
};
exports.CoursePlaceholderService = CoursePlaceholderService;
exports.CoursePlaceholderService = CoursePlaceholderService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], CoursePlaceholderService);


/***/ }),
/* 204 */
/***/ ((module) => {

module.exports = require("node-fetch");

/***/ }),
/* 205 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e, _f, _g;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PublicCoursesController = exports.CoursesController = void 0;
const common_1 = __webpack_require__(2);
const express_1 = __webpack_require__(57);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const feature_guard_1 = __webpack_require__(162);
const roles_decorator_1 = __webpack_require__(73);
const subscription_decorator_1 = __webpack_require__(161);
const client_1 = __webpack_require__(17);
const courses_service_1 = __webpack_require__(174);
const course_placeholder_service_1 = __webpack_require__(203);
const course_dto_1 = __webpack_require__(206);
const path = __webpack_require__(3);
const fs = __webpack_require__(4);
let CoursesController = class CoursesController {
    constructor(coursesService, placeholderService) {
        this.coursesService = coursesService;
        this.placeholderService = placeholderService;
    }
    async getCategories() {
        return this.coursesService.getCategories();
    }
    async getDashboardStats(req) {
        const isAdmin = req.user.role === 'ADMIN';
        return this.coursesService.getAdminDashboardStats(isAdmin ? undefined : req.user.id);
    }
    async create(dto, req) {
        return this.coursesService.create(dto, req.user.id);
    }
    async findAll(query, req) {
        const isAdmin = req.user.role === 'ADMIN';
        if (!isAdmin) {
            query.instructorId = req.user.id;
        }
        return this.coursesService.findAll(query);
    }
    async findOne(id) {
        return this.coursesService.findOne(id);
    }
    async update(id, dto, req) {
        const hasFullAccess = req.user.role === 'ADMIN' || req.user.role === 'EDITOR';
        return this.coursesService.update(id, dto, req.user.id, hasFullAccess);
    }
    async delete(id, req) {
        const hasFullAccess = req.user.role === 'ADMIN' || req.user.role === 'EDITOR';
        return this.coursesService.delete(id, req.user.id, hasFullAccess);
    }
    async regeneratePlaceholder() {
        const url = await this.placeholderService.regeneratePlaceholder();
        return { url };
    }
};
exports.CoursesController = CoursesController;
__decorate([
    (0, common_1.Get)('categories/list'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], CoursesController.prototype, "getCategories", null);
__decorate([
    (0, common_1.Get)('dashboard/stats'),
    __param(0, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], CoursesController.prototype, "getDashboardStats", null);
__decorate([
    (0, common_1.Post)(),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_c = typeof course_dto_1.CreateCourseDto !== "undefined" && course_dto_1.CreateCourseDto) === "function" ? _c : Object, Object]),
    __metadata("design:returntype", Promise)
], CoursesController.prototype, "create", null);
__decorate([
    (0, common_1.Get)(),
    __param(0, (0, common_1.Query)()),
    __param(1, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_d = typeof course_dto_1.CourseQueryDto !== "undefined" && course_dto_1.CourseQueryDto) === "function" ? _d : Object, Object]),
    __metadata("design:returntype", Promise)
], CoursesController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)(':id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], CoursesController.prototype, "findOne", null);
__decorate([
    (0, common_1.Put)(':id'),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __param(2, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_e = typeof course_dto_1.UpdateCourseDto !== "undefined" && course_dto_1.UpdateCourseDto) === "function" ? _e : Object, Object]),
    __metadata("design:returntype", Promise)
], CoursesController.prototype, "update", null);
__decorate([
    (0, common_1.Delete)(':id'),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", Promise)
], CoursesController.prototype, "delete", null);
__decorate([
    (0, common_1.Post)('placeholder/regenerate'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], CoursesController.prototype, "regeneratePlaceholder", null);
exports.CoursesController = CoursesController = __decorate([
    (0, common_1.Controller)('api/lms/admin/courses'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard, feature_guard_1.FeatureGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN, client_1.UserRole.EDITOR, client_1.UserRole.AUTHOR),
    (0, subscription_decorator_1.RequiresFeature)(subscription_decorator_1.SUBSCRIPTION_FEATURES.LMS),
    __metadata("design:paramtypes", [typeof (_a = typeof courses_service_1.CoursesService !== "undefined" && courses_service_1.CoursesService) === "function" ? _a : Object, typeof (_b = typeof course_placeholder_service_1.CoursePlaceholderService !== "undefined" && course_placeholder_service_1.CoursePlaceholderService) === "function" ? _b : Object])
], CoursesController);
let PublicCoursesController = class PublicCoursesController {
    constructor(placeholderService) {
        this.placeholderService = placeholderService;
    }
    async getPlaceholderImage(res) {
        const url = await this.placeholderService.getCoursePlaceholder();
        const filePath = path.join(process.cwd(), url);
        if (fs.existsSync(filePath)) {
            res.setHeader('Content-Type', 'image/png');
            res.setHeader('Cache-Control', 'public, max-age=86400');
            fs.createReadStream(filePath).pipe(res);
        }
        else {
            res.redirect(url);
        }
    }
};
exports.PublicCoursesController = PublicCoursesController;
__decorate([
    (0, common_1.Get)('placeholder-image'),
    __param(0, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_g = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _g : Object]),
    __metadata("design:returntype", Promise)
], PublicCoursesController.prototype, "getPlaceholderImage", null);
exports.PublicCoursesController = PublicCoursesController = __decorate([
    (0, common_1.Controller)('api/lms/courses'),
    __metadata("design:paramtypes", [typeof (_f = typeof course_placeholder_service_1.CoursePlaceholderService !== "undefined" && course_placeholder_service_1.CoursePlaceholderService) === "function" ? _f : Object])
], PublicCoursesController);


/***/ }),
/* 206 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CourseQueryDto = exports.UpdateCourseDto = exports.CreateCourseDto = exports.CourseStatus = exports.CoursePriceType = exports.CourseLevel = void 0;
const class_validator_1 = __webpack_require__(59);
const class_transformer_1 = __webpack_require__(95);
var CourseLevel;
(function (CourseLevel) {
    CourseLevel["BEGINNER"] = "BEGINNER";
    CourseLevel["INTERMEDIATE"] = "INTERMEDIATE";
    CourseLevel["ADVANCED"] = "ADVANCED";
    CourseLevel["ALL_LEVELS"] = "ALL_LEVELS";
})(CourseLevel || (exports.CourseLevel = CourseLevel = {}));
var CoursePriceType;
(function (CoursePriceType) {
    CoursePriceType["FREE"] = "FREE";
    CoursePriceType["PAID"] = "PAID";
})(CoursePriceType || (exports.CoursePriceType = CoursePriceType = {}));
var CourseStatus;
(function (CourseStatus) {
    CourseStatus["DRAFT"] = "DRAFT";
    CourseStatus["PUBLISHED"] = "PUBLISHED";
    CourseStatus["ARCHIVED"] = "ARCHIVED";
})(CourseStatus || (exports.CourseStatus = CourseStatus = {}));
class CreateCourseDto {
}
exports.CreateCourseDto = CreateCourseDto;
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateCourseDto.prototype, "title", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateCourseDto.prototype, "slug", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateCourseDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateCourseDto.prototype, "shortDescription", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateCourseDto.prototype, "category", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsEnum)(CourseLevel),
    __metadata("design:type", String)
], CreateCourseDto.prototype, "level", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateCourseDto.prototype, "featuredImage", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsEnum)(CoursePriceType),
    __metadata("design:type", String)
], CreateCourseDto.prototype, "priceType", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    __metadata("design:type", Number)
], CreateCourseDto.prototype, "priceAmount", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsEnum)(CourseStatus),
    __metadata("design:type", String)
], CreateCourseDto.prototype, "status", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    (0, class_validator_1.Max)(100),
    __metadata("design:type", Number)
], CreateCourseDto.prototype, "passingScorePercent", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsBoolean)(),
    __metadata("design:type", Boolean)
], CreateCourseDto.prototype, "certificateEnabled", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    __metadata("design:type", Number)
], CreateCourseDto.prototype, "estimatedHours", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.IsString)({ each: true }),
    __metadata("design:type", Array)
], CreateCourseDto.prototype, "whatYouLearn", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.IsString)({ each: true }),
    __metadata("design:type", Array)
], CreateCourseDto.prototype, "requirements", void 0);
class UpdateCourseDto extends CreateCourseDto {
}
exports.UpdateCourseDto = UpdateCourseDto;
class CourseQueryDto {
    constructor() {
        this.page = 1;
        this.limit = 12;
    }
}
exports.CourseQueryDto = CourseQueryDto;
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CourseQueryDto.prototype, "search", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CourseQueryDto.prototype, "category", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsEnum)(CourseLevel),
    __metadata("design:type", String)
], CourseQueryDto.prototype, "level", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsEnum)(CoursePriceType),
    __metadata("design:type", String)
], CourseQueryDto.prototype, "priceType", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsEnum)(CourseStatus),
    __metadata("design:type", String)
], CourseQueryDto.prototype, "status", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CourseQueryDto.prototype, "instructorId", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], CourseQueryDto.prototype, "page", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], CourseQueryDto.prototype, "limit", void 0);


/***/ }),
/* 207 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e, _f, _g;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.LessonsController = void 0;
const common_1 = __webpack_require__(2);
const platform_express_1 = __webpack_require__(124);
const jwt_auth_guard_1 = __webpack_require__(61);
const course_ownership_guard_1 = __webpack_require__(208);
const lessons_service_1 = __webpack_require__(199);
const lesson_dto_1 = __webpack_require__(209);
let LessonsController = class LessonsController {
    constructor(lessonsService) {
        this.lessonsService = lessonsService;
    }
    async create(courseId, dto) {
        return this.lessonsService.create(courseId, dto);
    }
    async findByCourse(courseId) {
        return this.lessonsService.findByCourse(courseId);
    }
    async findOne(id) {
        return this.lessonsService.findOne(id);
    }
    async update(id, dto) {
        return this.lessonsService.update(id, dto);
    }
    async delete(id) {
        return this.lessonsService.delete(id);
    }
    async reorder(courseId, dto) {
        return this.lessonsService.reorder(courseId, dto.lessonIds);
    }
    async createVideoAsset(dto) {
        return this.lessonsService.createVideoAsset(dto);
    }
    async getVideoAsset(id) {
        return this.lessonsService.getVideoAsset(id);
    }
    async deleteVideoAsset(id) {
        return this.lessonsService.deleteVideoAsset(id);
    }
    async uploadVideo(courseId, lessonId, file, req) {
        return this.lessonsService.uploadVideo(courseId, lessonId, file, req.user.id);
    }
    async attachExternalVideo(lessonId, dto) {
        return this.lessonsService.attachExternalVideo(lessonId, dto);
    }
};
exports.LessonsController = LessonsController;
__decorate([
    (0, common_1.Post)(),
    __param(0, (0, common_1.Param)('courseId')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_b = typeof lesson_dto_1.CreateLessonDto !== "undefined" && lesson_dto_1.CreateLessonDto) === "function" ? _b : Object]),
    __metadata("design:returntype", Promise)
], LessonsController.prototype, "create", null);
__decorate([
    (0, common_1.Get)(),
    __param(0, (0, common_1.Param)('courseId')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], LessonsController.prototype, "findByCourse", null);
__decorate([
    (0, common_1.Get)(':id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], LessonsController.prototype, "findOne", null);
__decorate([
    (0, common_1.Put)(':id'),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_c = typeof lesson_dto_1.UpdateLessonDto !== "undefined" && lesson_dto_1.UpdateLessonDto) === "function" ? _c : Object]),
    __metadata("design:returntype", Promise)
], LessonsController.prototype, "update", null);
__decorate([
    (0, common_1.Delete)(':id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], LessonsController.prototype, "delete", null);
__decorate([
    (0, common_1.Put)('reorder'),
    __param(0, (0, common_1.Param)('courseId')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_d = typeof lesson_dto_1.ReorderLessonsDto !== "undefined" && lesson_dto_1.ReorderLessonsDto) === "function" ? _d : Object]),
    __metadata("design:returntype", Promise)
], LessonsController.prototype, "reorder", null);
__decorate([
    (0, common_1.Post)('video-assets'),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_e = typeof lesson_dto_1.CreateVideoAssetDto !== "undefined" && lesson_dto_1.CreateVideoAssetDto) === "function" ? _e : Object]),
    __metadata("design:returntype", Promise)
], LessonsController.prototype, "createVideoAsset", null);
__decorate([
    (0, common_1.Get)('video-assets/:id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], LessonsController.prototype, "getVideoAsset", null);
__decorate([
    (0, common_1.Delete)('video-assets/:id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], LessonsController.prototype, "deleteVideoAsset", null);
__decorate([
    (0, common_1.Post)(':id/upload-video'),
    (0, common_1.UseInterceptors)((0, platform_express_1.FileInterceptor)('video', {
        limits: { fileSize: 500 * 1024 * 1024 },
        fileFilter: (req, file, cb) => {
            if (file.mimetype.startsWith('video/')) {
                cb(null, true);
            }
            else {
                cb(new Error('Only video files are allowed'), false);
            }
        },
    })),
    __param(0, (0, common_1.Param)('courseId')),
    __param(1, (0, common_1.Param)('id')),
    __param(2, (0, common_1.UploadedFile)()),
    __param(3, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, typeof (_g = typeof Express !== "undefined" && (_f = Express.Multer) !== void 0 && _f.File) === "function" ? _g : Object, Object]),
    __metadata("design:returntype", Promise)
], LessonsController.prototype, "uploadVideo", null);
__decorate([
    (0, common_1.Post)(':id/attach-video'),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", Promise)
], LessonsController.prototype, "attachExternalVideo", null);
exports.LessonsController = LessonsController = __decorate([
    (0, common_1.Controller)('api/lms/admin/courses/:courseId/lessons'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, course_ownership_guard_1.CourseOwnershipGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof lessons_service_1.LessonsService !== "undefined" && lessons_service_1.LessonsService) === "function" ? _a : Object])
], LessonsController);


/***/ }),
/* 208 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CourseOwnershipGuard = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let CourseOwnershipGuard = class CourseOwnershipGuard {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async canActivate(context) {
        const request = context.switchToHttp().getRequest();
        const user = request.user;
        if (!user) {
            throw new common_1.ForbiddenException('Authentication required');
        }
        if (user.role === 'ADMIN' || user.role === 'EDITOR') {
            return true;
        }
        const courseId = request.params.courseId || request.params.id;
        if (!courseId) {
            return true;
        }
        const course = await this.prisma.course.findUnique({
            where: { id: courseId },
            select: { instructorId: true },
        });
        if (!course) {
            throw new common_1.NotFoundException('Course not found');
        }
        if (course.instructorId !== user.id) {
            throw new common_1.ForbiddenException('You do not have permission to edit this course. Only the course instructor can make changes.');
        }
        request.isCourseOwner = true;
        return true;
    }
};
exports.CourseOwnershipGuard = CourseOwnershipGuard;
exports.CourseOwnershipGuard = CourseOwnershipGuard = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], CourseOwnershipGuard);


/***/ }),
/* 209 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UpdateProgressDto = exports.CreateVideoAssetDto = exports.ReorderLessonsDto = exports.UpdateLessonDto = exports.CreateLessonDto = exports.LessonType = void 0;
const class_validator_1 = __webpack_require__(59);
var LessonType;
(function (LessonType) {
    LessonType["VIDEO"] = "VIDEO";
    LessonType["ARTICLE"] = "ARTICLE";
    LessonType["QUIZ"] = "QUIZ";
    LessonType["ASSIGNMENT"] = "ASSIGNMENT";
})(LessonType || (exports.LessonType = LessonType = {}));
class CreateLessonDto {
}
exports.CreateLessonDto = CreateLessonDto;
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateLessonDto.prototype, "title", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateLessonDto.prototype, "content", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    __metadata("design:type", Number)
], CreateLessonDto.prototype, "orderIndex", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsEnum)(LessonType),
    __metadata("design:type", String)
], CreateLessonDto.prototype, "type", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsUUID)(),
    __metadata("design:type", String)
], CreateLessonDto.prototype, "videoAssetId", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsUUID)(),
    __metadata("design:type", String)
], CreateLessonDto.prototype, "moduleId", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    __metadata("design:type", Number)
], CreateLessonDto.prototype, "estimatedMinutes", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsBoolean)(),
    __metadata("design:type", Boolean)
], CreateLessonDto.prototype, "isPreview", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsBoolean)(),
    __metadata("design:type", Boolean)
], CreateLessonDto.prototype, "isRequired", void 0);
class UpdateLessonDto extends CreateLessonDto {
}
exports.UpdateLessonDto = UpdateLessonDto;
class ReorderLessonsDto {
}
exports.ReorderLessonsDto = ReorderLessonsDto;
__decorate([
    (0, class_validator_1.IsUUID)('4', { each: true }),
    __metadata("design:type", Array)
], ReorderLessonsDto.prototype, "lessonIds", void 0);
class CreateVideoAssetDto {
}
exports.CreateVideoAssetDto = CreateVideoAssetDto;
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsEnum)(['UPLOAD', 'HLS', 'YOUTUBE', 'VIMEO']),
    __metadata("design:type", String)
], CreateVideoAssetDto.prototype, "provider", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateVideoAssetDto.prototype, "url", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateVideoAssetDto.prototype, "playbackId", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateVideoAssetDto.prototype, "filePath", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], CreateVideoAssetDto.prototype, "durationSeconds", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsBoolean)(),
    __metadata("design:type", Boolean)
], CreateVideoAssetDto.prototype, "isProtected", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateVideoAssetDto.prototype, "thumbnailUrl", void 0);
class UpdateProgressDto {
}
exports.UpdateProgressDto = UpdateProgressDto;
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    __metadata("design:type", Number)
], UpdateProgressDto.prototype, "videoWatchedSeconds", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsBoolean)(),
    __metadata("design:type", Boolean)
], UpdateProgressDto.prototype, "lessonCompleted", void 0);


/***/ }),
/* 210 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ModulesController = void 0;
const common_1 = __webpack_require__(2);
const jwt_auth_guard_1 = __webpack_require__(61);
const course_ownership_guard_1 = __webpack_require__(208);
const modules_service_1 = __webpack_require__(200);
const module_dto_1 = __webpack_require__(211);
let ModulesController = class ModulesController {
    constructor(modulesService) {
        this.modulesService = modulesService;
    }
    async create(courseId, dto) {
        return this.modulesService.create(courseId, dto);
    }
    async findAll(courseId) {
        return this.modulesService.findByCourse(courseId);
    }
    async findOne(id) {
        return this.modulesService.findOne(id);
    }
    async update(id, dto) {
        return this.modulesService.update(id, dto);
    }
    async delete(id) {
        return this.modulesService.delete(id);
    }
    async reorder(courseId, dto) {
        return this.modulesService.reorder(courseId, dto.moduleIds);
    }
    async moveLesson(dto) {
        return this.modulesService.moveLessonToModule(dto.lessonId, dto.moduleId ?? null, dto.orderIndex);
    }
};
exports.ModulesController = ModulesController;
__decorate([
    (0, common_1.Post)(),
    __param(0, (0, common_1.Param)('courseId')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_b = typeof module_dto_1.CreateModuleDto !== "undefined" && module_dto_1.CreateModuleDto) === "function" ? _b : Object]),
    __metadata("design:returntype", Promise)
], ModulesController.prototype, "create", null);
__decorate([
    (0, common_1.Get)(),
    __param(0, (0, common_1.Param)('courseId')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], ModulesController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)(':id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], ModulesController.prototype, "findOne", null);
__decorate([
    (0, common_1.Put)(':id'),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_c = typeof module_dto_1.UpdateModuleDto !== "undefined" && module_dto_1.UpdateModuleDto) === "function" ? _c : Object]),
    __metadata("design:returntype", Promise)
], ModulesController.prototype, "update", null);
__decorate([
    (0, common_1.Delete)(':id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], ModulesController.prototype, "delete", null);
__decorate([
    (0, common_1.Put)('reorder'),
    __param(0, (0, common_1.Param)('courseId')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_d = typeof module_dto_1.ReorderModulesDto !== "undefined" && module_dto_1.ReorderModulesDto) === "function" ? _d : Object]),
    __metadata("design:returntype", Promise)
], ModulesController.prototype, "reorder", null);
__decorate([
    (0, common_1.Put)('lessons/move'),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_e = typeof module_dto_1.MoveLesonToModuleDto !== "undefined" && module_dto_1.MoveLesonToModuleDto) === "function" ? _e : Object]),
    __metadata("design:returntype", Promise)
], ModulesController.prototype, "moveLesson", null);
exports.ModulesController = ModulesController = __decorate([
    (0, common_1.Controller)('api/lms/admin/courses/:courseId/modules'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, course_ownership_guard_1.CourseOwnershipGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof modules_service_1.ModulesService !== "undefined" && modules_service_1.ModulesService) === "function" ? _a : Object])
], ModulesController);


/***/ }),
/* 211 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.BulkMoveLessonsDto = exports.MoveLesonToModuleDto = exports.ReorderModulesDto = exports.UpdateModuleDto = exports.CreateModuleDto = void 0;
const class_validator_1 = __webpack_require__(59);
class CreateModuleDto {
}
exports.CreateModuleDto = CreateModuleDto;
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateModuleDto.prototype, "title", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateModuleDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    __metadata("design:type", Number)
], CreateModuleDto.prototype, "orderIndex", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsBoolean)(),
    __metadata("design:type", Boolean)
], CreateModuleDto.prototype, "isPublished", void 0);
class UpdateModuleDto {
}
exports.UpdateModuleDto = UpdateModuleDto;
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], UpdateModuleDto.prototype, "title", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], UpdateModuleDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    __metadata("design:type", Number)
], UpdateModuleDto.prototype, "orderIndex", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsBoolean)(),
    __metadata("design:type", Boolean)
], UpdateModuleDto.prototype, "isPublished", void 0);
class ReorderModulesDto {
}
exports.ReorderModulesDto = ReorderModulesDto;
__decorate([
    (0, class_validator_1.IsUUID)('4', { each: true }),
    __metadata("design:type", Array)
], ReorderModulesDto.prototype, "moduleIds", void 0);
class MoveLesonToModuleDto {
}
exports.MoveLesonToModuleDto = MoveLesonToModuleDto;
__decorate([
    (0, class_validator_1.IsUUID)(),
    __metadata("design:type", String)
], MoveLesonToModuleDto.prototype, "lessonId", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsUUID)(),
    __metadata("design:type", String)
], MoveLesonToModuleDto.prototype, "moduleId", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    __metadata("design:type", Number)
], MoveLesonToModuleDto.prototype, "orderIndex", void 0);
class BulkMoveLessonsDto {
}
exports.BulkMoveLessonsDto = BulkMoveLessonsDto;
__decorate([
    (0, class_validator_1.IsUUID)('4', { each: true }),
    __metadata("design:type", Array)
], BulkMoveLessonsDto.prototype, "lessonIds", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsUUID)(),
    __metadata("design:type", String)
], BulkMoveLessonsDto.prototype, "moduleId", void 0);


/***/ }),
/* 212 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.QuizzesController = void 0;
const common_1 = __webpack_require__(2);
const jwt_auth_guard_1 = __webpack_require__(61);
const course_ownership_guard_1 = __webpack_require__(208);
const quizzes_service_1 = __webpack_require__(201);
const quiz_dto_1 = __webpack_require__(213);
let QuizzesController = class QuizzesController {
    constructor(quizzesService) {
        this.quizzesService = quizzesService;
    }
    async create(courseId, dto) {
        return this.quizzesService.create(courseId, dto);
    }
    async findByCourse(courseId) {
        return this.quizzesService.findByCourse(courseId);
    }
    async findOne(id) {
        return this.quizzesService.findOne(id);
    }
    async update(id, dto) {
        return this.quizzesService.update(id, dto);
    }
    async delete(id) {
        return this.quizzesService.delete(id);
    }
    async addQuestion(quizId, dto) {
        return this.quizzesService.addQuestion(quizId, dto);
    }
    async updateQuestion(questionId, dto) {
        return this.quizzesService.updateQuestion(questionId, dto);
    }
    async deleteQuestion(questionId) {
        return this.quizzesService.deleteQuestion(questionId);
    }
    async reorderQuestions(quizId, body) {
        return this.quizzesService.reorderQuestions(quizId, body.questionIds);
    }
};
exports.QuizzesController = QuizzesController;
__decorate([
    (0, common_1.Post)(),
    __param(0, (0, common_1.Param)('courseId')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_b = typeof quiz_dto_1.CreateQuizDto !== "undefined" && quiz_dto_1.CreateQuizDto) === "function" ? _b : Object]),
    __metadata("design:returntype", Promise)
], QuizzesController.prototype, "create", null);
__decorate([
    (0, common_1.Get)(),
    __param(0, (0, common_1.Param)('courseId')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], QuizzesController.prototype, "findByCourse", null);
__decorate([
    (0, common_1.Get)(':id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], QuizzesController.prototype, "findOne", null);
__decorate([
    (0, common_1.Put)(':id'),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_c = typeof quiz_dto_1.UpdateQuizDto !== "undefined" && quiz_dto_1.UpdateQuizDto) === "function" ? _c : Object]),
    __metadata("design:returntype", Promise)
], QuizzesController.prototype, "update", null);
__decorate([
    (0, common_1.Delete)(':id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], QuizzesController.prototype, "delete", null);
__decorate([
    (0, common_1.Post)(':quizId/questions'),
    __param(0, (0, common_1.Param)('quizId')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_d = typeof quiz_dto_1.CreateQuestionDto !== "undefined" && quiz_dto_1.CreateQuestionDto) === "function" ? _d : Object]),
    __metadata("design:returntype", Promise)
], QuizzesController.prototype, "addQuestion", null);
__decorate([
    (0, common_1.Put)('questions/:questionId'),
    __param(0, (0, common_1.Param)('questionId')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_e = typeof quiz_dto_1.UpdateQuestionDto !== "undefined" && quiz_dto_1.UpdateQuestionDto) === "function" ? _e : Object]),
    __metadata("design:returntype", Promise)
], QuizzesController.prototype, "updateQuestion", null);
__decorate([
    (0, common_1.Delete)('questions/:questionId'),
    __param(0, (0, common_1.Param)('questionId')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], QuizzesController.prototype, "deleteQuestion", null);
__decorate([
    (0, common_1.Put)(':quizId/questions/reorder'),
    __param(0, (0, common_1.Param)('quizId')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", Promise)
], QuizzesController.prototype, "reorderQuestions", null);
exports.QuizzesController = QuizzesController = __decorate([
    (0, common_1.Controller)('api/lms/admin/courses/:courseId/quizzes'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, course_ownership_guard_1.CourseOwnershipGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof quizzes_service_1.QuizzesService !== "undefined" && quizzes_service_1.QuizzesService) === "function" ? _a : Object])
], QuizzesController);


/***/ }),
/* 213 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.StartQuizDto = exports.SubmitQuizDto = exports.SubmitQuizAnswerDto = exports.UpdateQuizDto = exports.CreateQuizDto = exports.UpdateQuestionDto = exports.CreateQuestionDto = exports.QuestionType = void 0;
const class_validator_1 = __webpack_require__(59);
const class_transformer_1 = __webpack_require__(95);
var QuestionType;
(function (QuestionType) {
    QuestionType["MCQ"] = "MCQ";
    QuestionType["MCQ_MULTI"] = "MCQ_MULTI";
    QuestionType["TRUE_FALSE"] = "TRUE_FALSE";
    QuestionType["SHORT_ANSWER"] = "SHORT_ANSWER";
    QuestionType["ESSAY"] = "ESSAY";
})(QuestionType || (exports.QuestionType = QuestionType = {}));
class CreateQuestionDto {
}
exports.CreateQuestionDto = CreateQuestionDto;
__decorate([
    (0, class_validator_1.IsEnum)(QuestionType),
    __metadata("design:type", String)
], CreateQuestionDto.prototype, "type", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateQuestionDto.prototype, "prompt", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsArray)(),
    __metadata("design:type", Array)
], CreateQuestionDto.prototype, "optionsJson", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateQuestionDto.prototype, "explanation", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(1),
    __metadata("design:type", Number)
], CreateQuestionDto.prototype, "points", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    __metadata("design:type", Number)
], CreateQuestionDto.prototype, "orderIndex", void 0);
class UpdateQuestionDto extends CreateQuestionDto {
}
exports.UpdateQuestionDto = UpdateQuestionDto;
class CreateQuizDto {
}
exports.CreateQuizDto = CreateQuizDto;
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateQuizDto.prototype, "title", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateQuizDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsUUID)(),
    __metadata("design:type", String)
], CreateQuizDto.prototype, "lessonId", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    __metadata("design:type", Number)
], CreateQuizDto.prototype, "timeLimitSeconds", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(1),
    __metadata("design:type", Number)
], CreateQuizDto.prototype, "attemptsAllowed", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsBoolean)(),
    __metadata("design:type", Boolean)
], CreateQuizDto.prototype, "shuffleQuestions", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    (0, class_validator_1.Max)(100),
    __metadata("design:type", Number)
], CreateQuizDto.prototype, "passingScorePercent", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsBoolean)(),
    __metadata("design:type", Boolean)
], CreateQuizDto.prototype, "isRequired", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    __metadata("design:type", Number)
], CreateQuizDto.prototype, "orderIndex", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.ValidateNested)({ each: true }),
    (0, class_transformer_1.Type)(() => CreateQuestionDto),
    __metadata("design:type", Array)
], CreateQuizDto.prototype, "questions", void 0);
class UpdateQuizDto extends CreateQuizDto {
}
exports.UpdateQuizDto = UpdateQuizDto;
class SubmitQuizAnswerDto {
}
exports.SubmitQuizAnswerDto = SubmitQuizAnswerDto;
__decorate([
    (0, class_validator_1.IsUUID)(),
    __metadata("design:type", String)
], SubmitQuizAnswerDto.prototype, "questionId", void 0);
__decorate([
    (0, class_validator_1.IsDefined)(),
    (0, class_validator_1.Allow)(),
    __metadata("design:type", Object)
], SubmitQuizAnswerDto.prototype, "answer", void 0);
class SubmitQuizDto {
}
exports.SubmitQuizDto = SubmitQuizDto;
__decorate([
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.ValidateNested)({ each: true }),
    (0, class_transformer_1.Type)(() => SubmitQuizAnswerDto),
    __metadata("design:type", Array)
], SubmitQuizDto.prototype, "answers", void 0);
class StartQuizDto {
}
exports.StartQuizDto = StartQuizDto;


/***/ }),
/* 214 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.EnrollmentsController = void 0;
const common_1 = __webpack_require__(2);
const jwt_auth_guard_1 = __webpack_require__(61);
const enrollments_service_1 = __webpack_require__(202);
const enrollment_dto_1 = __webpack_require__(215);
let EnrollmentsController = class EnrollmentsController {
    constructor(enrollmentsService) {
        this.enrollmentsService = enrollmentsService;
    }
    async enroll(courseId, dto, req) {
        return this.enrollmentsService.enroll(courseId, req.user.id, dto);
    }
    async getMyEnrollments(req) {
        return this.enrollmentsService.findUserEnrollments(req.user.id);
    }
    async getMyEnrollment(courseId, req) {
        return this.enrollmentsService.findOne(courseId, req.user.id);
    }
    async cancelEnrollment(courseId, req) {
        return this.enrollmentsService.cancel(courseId, req.user.id);
    }
    async getCourseEnrollments(courseId) {
        return this.enrollmentsService.findCourseEnrollments(courseId);
    }
    async getEnrollmentStats(courseId) {
        return this.enrollmentsService.getEnrollmentStats(courseId);
    }
    async updateEnrollment(courseId, userId, dto) {
        return this.enrollmentsService.update(courseId, userId, dto);
    }
};
exports.EnrollmentsController = EnrollmentsController;
__decorate([
    (0, common_1.Post)('courses/:courseId/enroll'),
    __param(0, (0, common_1.Param)('courseId')),
    __param(1, (0, common_1.Body)()),
    __param(2, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_b = typeof enrollment_dto_1.EnrollCourseDto !== "undefined" && enrollment_dto_1.EnrollCourseDto) === "function" ? _b : Object, Object]),
    __metadata("design:returntype", Promise)
], EnrollmentsController.prototype, "enroll", null);
__decorate([
    (0, common_1.Get)('my-enrollments'),
    __param(0, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], EnrollmentsController.prototype, "getMyEnrollments", null);
__decorate([
    (0, common_1.Get)('courses/:courseId/enrollment'),
    __param(0, (0, common_1.Param)('courseId')),
    __param(1, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", Promise)
], EnrollmentsController.prototype, "getMyEnrollment", null);
__decorate([
    (0, common_1.Delete)('courses/:courseId/enrollment'),
    __param(0, (0, common_1.Param)('courseId')),
    __param(1, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", Promise)
], EnrollmentsController.prototype, "cancelEnrollment", null);
__decorate([
    (0, common_1.Get)('admin/courses/:courseId/enrollments'),
    __param(0, (0, common_1.Param)('courseId')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], EnrollmentsController.prototype, "getCourseEnrollments", null);
__decorate([
    (0, common_1.Get)('admin/courses/:courseId/enrollments/stats'),
    __param(0, (0, common_1.Param)('courseId')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], EnrollmentsController.prototype, "getEnrollmentStats", null);
__decorate([
    (0, common_1.Put)('admin/courses/:courseId/enrollments/:userId'),
    __param(0, (0, common_1.Param)('courseId')),
    __param(1, (0, common_1.Param)('userId')),
    __param(2, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, typeof (_c = typeof enrollment_dto_1.UpdateEnrollmentDto !== "undefined" && enrollment_dto_1.UpdateEnrollmentDto) === "function" ? _c : Object]),
    __metadata("design:returntype", Promise)
], EnrollmentsController.prototype, "updateEnrollment", null);
exports.EnrollmentsController = EnrollmentsController = __decorate([
    (0, common_1.Controller)('api/lms'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof enrollments_service_1.EnrollmentsService !== "undefined" && enrollments_service_1.EnrollmentsService) === "function" ? _a : Object])
], EnrollmentsController);


/***/ }),
/* 215 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.EnrollmentQueryDto = exports.UpdateEnrollmentDto = exports.EnrollCourseDto = exports.EnrollmentStatus = void 0;
const class_validator_1 = __webpack_require__(59);
var EnrollmentStatus;
(function (EnrollmentStatus) {
    EnrollmentStatus["ACTIVE"] = "ACTIVE";
    EnrollmentStatus["COMPLETED"] = "COMPLETED";
    EnrollmentStatus["CANCELLED"] = "CANCELLED";
    EnrollmentStatus["EXPIRED"] = "EXPIRED";
})(EnrollmentStatus || (exports.EnrollmentStatus = EnrollmentStatus = {}));
class EnrollCourseDto {
}
exports.EnrollCourseDto = EnrollCourseDto;
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], EnrollCourseDto.prototype, "paymentId", void 0);
class UpdateEnrollmentDto {
}
exports.UpdateEnrollmentDto = UpdateEnrollmentDto;
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsEnum)(EnrollmentStatus),
    __metadata("design:type", String)
], UpdateEnrollmentDto.prototype, "status", void 0);
class EnrollmentQueryDto {
}
exports.EnrollmentQueryDto = EnrollmentQueryDto;
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsUUID)(),
    __metadata("design:type", String)
], EnrollmentQueryDto.prototype, "courseId", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsUUID)(),
    __metadata("design:type", String)
], EnrollmentQueryDto.prototype, "userId", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsEnum)(EnrollmentStatus),
    __metadata("design:type", String)
], EnrollmentQueryDto.prototype, "status", void 0);


/***/ }),
/* 216 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.LearningController = void 0;
const common_1 = __webpack_require__(2);
const jwt_auth_guard_1 = __webpack_require__(61);
const optional_jwt_auth_guard_1 = __webpack_require__(76);
const prisma_service_1 = __webpack_require__(16);
const courses_service_1 = __webpack_require__(174);
const lessons_service_1 = __webpack_require__(199);
const quizzes_service_1 = __webpack_require__(201);
const progress_service_1 = __webpack_require__(176);
const certificates_service_1 = __webpack_require__(175);
const course_dto_1 = __webpack_require__(206);
const lesson_dto_1 = __webpack_require__(209);
const quiz_dto_1 = __webpack_require__(213);
let LearningController = class LearningController {
    constructor(prisma, coursesService, lessonsService, quizzesService, progressService, certificatesService) {
        this.prisma = prisma;
        this.coursesService = coursesService;
        this.lessonsService = lessonsService;
        this.quizzesService = quizzesService;
        this.progressService = progressService;
        this.certificatesService = certificatesService;
    }
    async getCourses(query) {
        return this.coursesService.findPublished(query);
    }
    async getCategories() {
        return this.coursesService.getCategories();
    }
    async getCourse(slug) {
        return this.coursesService.findBySlug(slug);
    }
    async getCourseForLearning(courseId, req) {
        const enrollment = await this.prisma.enrollment.findUnique({
            where: {
                courseId_userId: {
                    courseId,
                    userId: req.user.id,
                },
            },
        });
        if (!enrollment || !['ACTIVE', 'COMPLETED'].includes(enrollment.status)) {
            throw new common_1.ForbiddenException('You must be enrolled to access this course');
        }
        const [course, progress] = await Promise.all([
            this.coursesService.findOne(courseId),
            this.progressService.getCourseProgress(courseId, req.user.id),
        ]);
        return { course, progress, enrollment };
    }
    async getLesson(courseId, lessonId, req) {
        return this.lessonsService.getLessonForLearning(lessonId, req.user.id);
    }
    async updateProgress(courseId, lessonId, dto, req) {
        const progress = await this.progressService.updateProgress(lessonId, req.user.id, dto);
        await this.certificatesService.checkAndIssueCertificate(courseId, req.user.id);
        return progress;
    }
    async markLessonComplete(courseId, lessonId, req) {
        const progress = await this.progressService.markComplete(lessonId, req.user.id);
        await this.certificatesService.checkAndIssueCertificate(courseId, req.user.id);
        return progress;
    }
    async getQuiz(quizId, req) {
        return this.quizzesService.getQuizForStudent(quizId, req.user.id);
    }
    async startQuiz(courseId, quizId, req) {
        return this.quizzesService.startAttempt(quizId, req.user.id, courseId);
    }
    async submitQuiz(courseId, attemptId, dto, req) {
        const result = await this.quizzesService.submitAttempt(attemptId, dto, req.user.id);
        await this.certificatesService.checkAndIssueCertificate(courseId, req.user.id);
        return result;
    }
    async getDashboard(req) {
        return this.progressService.getUserDashboard(req.user.id);
    }
};
exports.LearningController = LearningController;
__decorate([
    (0, common_1.Get)('courses'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Query)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_g = typeof course_dto_1.CourseQueryDto !== "undefined" && course_dto_1.CourseQueryDto) === "function" ? _g : Object]),
    __metadata("design:returntype", Promise)
], LearningController.prototype, "getCourses", null);
__decorate([
    (0, common_1.Get)('courses/categories'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], LearningController.prototype, "getCategories", null);
__decorate([
    (0, common_1.Get)('courses/:slug'),
    (0, common_1.UseGuards)(optional_jwt_auth_guard_1.OptionalJwtAuthGuard),
    __param(0, (0, common_1.Param)('slug')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], LearningController.prototype, "getCourse", null);
__decorate([
    (0, common_1.Get)('learn/:courseId'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Param)('courseId')),
    __param(1, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", Promise)
], LearningController.prototype, "getCourseForLearning", null);
__decorate([
    (0, common_1.Get)('learn/:courseId/lessons/:lessonId'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Param)('courseId')),
    __param(1, (0, common_1.Param)('lessonId')),
    __param(2, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, Object]),
    __metadata("design:returntype", Promise)
], LearningController.prototype, "getLesson", null);
__decorate([
    (0, common_1.Put)('learn/:courseId/lessons/:lessonId/progress'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Param)('courseId')),
    __param(1, (0, common_1.Param)('lessonId')),
    __param(2, (0, common_1.Body)()),
    __param(3, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, typeof (_h = typeof lesson_dto_1.UpdateProgressDto !== "undefined" && lesson_dto_1.UpdateProgressDto) === "function" ? _h : Object, Object]),
    __metadata("design:returntype", Promise)
], LearningController.prototype, "updateProgress", null);
__decorate([
    (0, common_1.Post)('learn/:courseId/lessons/:lessonId/complete'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Param)('courseId')),
    __param(1, (0, common_1.Param)('lessonId')),
    __param(2, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, Object]),
    __metadata("design:returntype", Promise)
], LearningController.prototype, "markLessonComplete", null);
__decorate([
    (0, common_1.Get)('learn/:courseId/quizzes/:quizId'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Param)('quizId')),
    __param(1, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", Promise)
], LearningController.prototype, "getQuiz", null);
__decorate([
    (0, common_1.Post)('learn/:courseId/quizzes/:quizId/start'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Param)('courseId')),
    __param(1, (0, common_1.Param)('quizId')),
    __param(2, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, Object]),
    __metadata("design:returntype", Promise)
], LearningController.prototype, "startQuiz", null);
__decorate([
    (0, common_1.Post)('learn/:courseId/quizzes/:quizId/attempts/:attemptId/submit'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Param)('courseId')),
    __param(1, (0, common_1.Param)('attemptId')),
    __param(2, (0, common_1.Body)()),
    __param(3, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, typeof (_j = typeof quiz_dto_1.SubmitQuizDto !== "undefined" && quiz_dto_1.SubmitQuizDto) === "function" ? _j : Object, Object]),
    __metadata("design:returntype", Promise)
], LearningController.prototype, "submitQuiz", null);
__decorate([
    (0, common_1.Get)('dashboard'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], LearningController.prototype, "getDashboard", null);
exports.LearningController = LearningController = __decorate([
    (0, common_1.Controller)('api/lms'),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof courses_service_1.CoursesService !== "undefined" && courses_service_1.CoursesService) === "function" ? _b : Object, typeof (_c = typeof lessons_service_1.LessonsService !== "undefined" && lessons_service_1.LessonsService) === "function" ? _c : Object, typeof (_d = typeof quizzes_service_1.QuizzesService !== "undefined" && quizzes_service_1.QuizzesService) === "function" ? _d : Object, typeof (_e = typeof progress_service_1.ProgressService !== "undefined" && progress_service_1.ProgressService) === "function" ? _e : Object, typeof (_f = typeof certificates_service_1.CertificatesService !== "undefined" && certificates_service_1.CertificatesService) === "function" ? _f : Object])
], LearningController);


/***/ }),
/* 217 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CertificatesController = void 0;
const common_1 = __webpack_require__(2);
const jwt_auth_guard_1 = __webpack_require__(61);
const certificates_service_1 = __webpack_require__(175);
let CertificatesController = class CertificatesController {
    constructor(certificatesService) {
        this.certificatesService = certificatesService;
    }
    async verify(hash) {
        return this.certificatesService.verify(hash);
    }
    async getMyCertificates(req) {
        return this.certificatesService.findByUser(req.user.id);
    }
    async getCertificate(id) {
        return this.certificatesService.findOne(id);
    }
    async requestCertificate(courseId, req) {
        return this.certificatesService.issueCertificate(courseId, req.user.id);
    }
    async revokeCertificate(id, body) {
        return this.certificatesService.revoke(id, body.reason);
    }
};
exports.CertificatesController = CertificatesController;
__decorate([
    (0, common_1.Get)('certificates/verify/:hash'),
    __param(0, (0, common_1.Param)('hash')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], CertificatesController.prototype, "verify", null);
__decorate([
    (0, common_1.Get)('my-certificates'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], CertificatesController.prototype, "getMyCertificates", null);
__decorate([
    (0, common_1.Get)('certificates/:id'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], CertificatesController.prototype, "getCertificate", null);
__decorate([
    (0, common_1.Post)('courses/:courseId/certificate'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Param)('courseId')),
    __param(1, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", Promise)
], CertificatesController.prototype, "requestCertificate", null);
__decorate([
    (0, common_1.Put)('admin/certificates/:id/revoke'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", Promise)
], CertificatesController.prototype, "revokeCertificate", null);
exports.CertificatesController = CertificatesController = __decorate([
    (0, common_1.Controller)('api/lms'),
    __metadata("design:paramtypes", [typeof (_a = typeof certificates_service_1.CertificatesService !== "undefined" && certificates_service_1.CertificatesService) === "function" ? _a : Object])
], CertificatesController);


/***/ }),
/* 218 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 RecommendationsModule_1;
var _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.RecommendationsModule = void 0;
const common_1 = __webpack_require__(2);
const prisma_module_1 = __webpack_require__(15);
const recommendations_controller_1 = __webpack_require__(219);
const recommendations_admin_controller_1 = __webpack_require__(221);
const recommendations_service_1 = __webpack_require__(179);
const recommendation_engine_service_1 = __webpack_require__(180);
const recommendation_tracking_service_1 = __webpack_require__(181);
const recommendation_analytics_service_1 = __webpack_require__(222);
let RecommendationsModule = RecommendationsModule_1 = class RecommendationsModule {
    constructor(recommendationsService, trackingService) {
        this.recommendationsService = recommendationsService;
        this.trackingService = trackingService;
        this.logger = new common_1.Logger(RecommendationsModule_1.name);
        this.cleanupInterval = null;
        this.CLEANUP_INTERVAL_MS = 6 * 60 * 60 * 1000;
    }
    onModuleInit() {
        this.logger.log('Starting scheduled recommendation cleanup tasks');
        setTimeout(() => this.runCleanup(), 60 * 1000);
        this.cleanupInterval = setInterval(() => {
            this.runCleanup();
        }, this.CLEANUP_INTERVAL_MS);
    }
    onModuleDestroy() {
        if (this.cleanupInterval) {
            clearInterval(this.cleanupInterval);
            this.cleanupInterval = null;
        }
    }
    async runCleanup() {
        try {
            this.logger.log('Running scheduled recommendation cleanup...');
            const expiredCacheCount = await this.recommendationsService.clearExpiredCache();
            this.logger.log(`Cleared ${expiredCacheCount} expired cache entries`);
            const interactionCount = await this.trackingService.cleanupOldInteractions();
            this.logger.log(`Cleaned up ${interactionCount} old interaction records`);
            const clickCount = await this.trackingService.cleanupOldClicks();
            this.logger.log(`Cleaned up ${clickCount} old click records`);
        }
        catch (error) {
            this.logger.error(`Scheduled cleanup failed: ${error.message}`);
        }
    }
};
exports.RecommendationsModule = RecommendationsModule;
exports.RecommendationsModule = RecommendationsModule = RecommendationsModule_1 = __decorate([
    (0, common_1.Module)({
        imports: [prisma_module_1.PrismaModule],
        controllers: [recommendations_controller_1.RecommendationsController, recommendations_admin_controller_1.RecommendationsAdminController],
        providers: [
            recommendations_service_1.RecommendationsService,
            recommendation_engine_service_1.RecommendationEngineService,
            recommendation_tracking_service_1.RecommendationTrackingService,
            recommendation_analytics_service_1.RecommendationAnalyticsService,
        ],
        exports: [recommendations_service_1.RecommendationsService, recommendation_engine_service_1.RecommendationEngineService, recommendation_tracking_service_1.RecommendationTrackingService],
    }),
    __metadata("design:paramtypes", [typeof (_a = typeof recommendations_service_1.RecommendationsService !== "undefined" && recommendations_service_1.RecommendationsService) === "function" ? _a : Object, typeof (_b = typeof recommendation_tracking_service_1.RecommendationTrackingService !== "undefined" && recommendation_tracking_service_1.RecommendationTrackingService) === "function" ? _b : Object])
], RecommendationsModule);


/***/ }),
/* 219 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.RecommendationsController = void 0;
const common_1 = __webpack_require__(2);
const express_1 = __webpack_require__(57);
const recommendations_service_1 = __webpack_require__(179);
const recommendation_tracking_service_1 = __webpack_require__(181);
const dto_1 = __webpack_require__(220);
let RecommendationsController = class RecommendationsController {
    constructor(recommendationsService, trackingService) {
        this.recommendationsService = recommendationsService;
        this.trackingService = trackingService;
    }
    async getRelatedPosts(postId, query, req) {
        const userId = req.user?.id;
        return this.recommendationsService.getRelatedPosts(postId, query.limit || 6, userId);
    }
    async getRelatedPages(pageId, query) {
        return this.recommendationsService.getRelatedPages(pageId, query.limit || 6);
    }
    async getRelatedProducts(productId, query, req) {
        const userId = req.user?.id;
        return this.recommendationsService.getRelatedProducts(productId, query.limit || 6, userId);
    }
    async getRelatedCourses(courseId, query) {
        return this.recommendationsService.getRelatedCourses(courseId, query.limit || 6);
    }
    async getTrending(contentType, query, days) {
        const timeframeDays = days ? parseInt(days) : 7;
        return this.recommendationsService.getTrending(contentType, query.limit || 6, timeframeDays);
    }
    async getPopular(contentType, query) {
        return this.recommendationsService.getPopular(contentType, query.limit || 6);
    }
    async getPersonalized(contentType, query, req) {
        const userId = req.user?.id;
        if (!userId) {
            return this.recommendationsService.getPopular(contentType, query.limit || 6);
        }
        return this.recommendationsService.getPersonalized(userId, contentType, query.limit || 6);
    }
    async trackInteraction(dto, req) {
        const userId = req.user?.id || dto.userId;
        const sessionId = typeof dto.sessionId === 'string'
            ? dto.sessionId
            : typeof req.sessionID === 'string'
                ? req.sessionID
                : undefined;
        return this.trackingService.trackInteraction({
            ...dto,
            userId,
            sessionId,
        });
    }
    async trackClick(dto, req) {
        const userId = req.user?.id || dto.userId;
        const sessionId = typeof dto.sessionId === 'string'
            ? dto.sessionId
            : typeof req.sessionID === 'string'
                ? req.sessionID
                : undefined;
        return this.trackingService.trackRecommendationClick({
            ...dto,
            userId,
            sessionId,
        });
    }
    async getAlsoViewed(contentType, contentId, query) {
        return this.recommendationsService.getCollaborativeRecommendations(contentId, contentType, query.limit || 6);
    }
    async getFrequentlyBoughtTogether(productId, query) {
        return this.recommendationsService.getFrequentlyBoughtTogether(productId, query.limit || 4);
    }
    async getSimilarUsersRecommendations(contentType, query, req) {
        const userId = req.user?.id;
        if (!userId) {
            return this.recommendationsService.getPopular(contentType, query.limit || 6);
        }
        return this.recommendationsService.getSimilarUsersRecommendations(userId, contentType, query.limit || 6);
    }
};
exports.RecommendationsController = RecommendationsController;
__decorate([
    (0, common_1.Get)('posts/:postId'),
    __param(0, (0, common_1.Param)('postId')),
    __param(1, (0, common_1.Query)()),
    __param(2, (0, common_1.Req)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_c = typeof dto_1.GetRecommendationsDto !== "undefined" && dto_1.GetRecommendationsDto) === "function" ? _c : Object, typeof (_d = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _d : Object]),
    __metadata("design:returntype", Promise)
], RecommendationsController.prototype, "getRelatedPosts", null);
__decorate([
    (0, common_1.Get)('pages/:pageId'),
    __param(0, (0, common_1.Param)('pageId')),
    __param(1, (0, common_1.Query)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_e = typeof dto_1.GetRecommendationsDto !== "undefined" && dto_1.GetRecommendationsDto) === "function" ? _e : Object]),
    __metadata("design:returntype", Promise)
], RecommendationsController.prototype, "getRelatedPages", null);
__decorate([
    (0, common_1.Get)('products/:productId'),
    __param(0, (0, common_1.Param)('productId')),
    __param(1, (0, common_1.Query)()),
    __param(2, (0, common_1.Req)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_f = typeof dto_1.GetRecommendationsDto !== "undefined" && dto_1.GetRecommendationsDto) === "function" ? _f : Object, typeof (_g = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _g : Object]),
    __metadata("design:returntype", Promise)
], RecommendationsController.prototype, "getRelatedProducts", null);
__decorate([
    (0, common_1.Get)('courses/:courseId'),
    __param(0, (0, common_1.Param)('courseId')),
    __param(1, (0, common_1.Query)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_h = typeof dto_1.GetRecommendationsDto !== "undefined" && dto_1.GetRecommendationsDto) === "function" ? _h : Object]),
    __metadata("design:returntype", Promise)
], RecommendationsController.prototype, "getRelatedCourses", null);
__decorate([
    (0, common_1.Get)('trending/:contentType'),
    __param(0, (0, common_1.Param)('contentType')),
    __param(1, (0, common_1.Query)()),
    __param(2, (0, common_1.Query)('days')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_j = typeof dto_1.GetRecommendationsDto !== "undefined" && dto_1.GetRecommendationsDto) === "function" ? _j : Object, String]),
    __metadata("design:returntype", Promise)
], RecommendationsController.prototype, "getTrending", null);
__decorate([
    (0, common_1.Get)('popular/:contentType'),
    __param(0, (0, common_1.Param)('contentType')),
    __param(1, (0, common_1.Query)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_k = typeof dto_1.GetRecommendationsDto !== "undefined" && dto_1.GetRecommendationsDto) === "function" ? _k : Object]),
    __metadata("design:returntype", Promise)
], RecommendationsController.prototype, "getPopular", null);
__decorate([
    (0, common_1.Get)('personalized/:contentType'),
    __param(0, (0, common_1.Param)('contentType')),
    __param(1, (0, common_1.Query)()),
    __param(2, (0, common_1.Req)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_l = typeof dto_1.GetRecommendationsDto !== "undefined" && dto_1.GetRecommendationsDto) === "function" ? _l : Object, typeof (_m = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _m : Object]),
    __metadata("design:returntype", Promise)
], RecommendationsController.prototype, "getPersonalized", null);
__decorate([
    (0, common_1.Post)('track'),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, common_1.Req)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_o = typeof dto_1.TrackInteractionDto !== "undefined" && dto_1.TrackInteractionDto) === "function" ? _o : Object, typeof (_p = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _p : Object]),
    __metadata("design:returntype", Promise)
], RecommendationsController.prototype, "trackInteraction", null);
__decorate([
    (0, common_1.Post)('track-click'),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, common_1.Req)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_q = typeof dto_1.TrackRecommendationClickDto !== "undefined" && dto_1.TrackRecommendationClickDto) === "function" ? _q : Object, typeof (_r = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _r : Object]),
    __metadata("design:returntype", Promise)
], RecommendationsController.prototype, "trackClick", null);
__decorate([
    (0, common_1.Get)('also-viewed/:contentType/:contentId'),
    __param(0, (0, common_1.Param)('contentType')),
    __param(1, (0, common_1.Param)('contentId')),
    __param(2, (0, common_1.Query)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, typeof (_s = typeof dto_1.GetRecommendationsDto !== "undefined" && dto_1.GetRecommendationsDto) === "function" ? _s : Object]),
    __metadata("design:returntype", Promise)
], RecommendationsController.prototype, "getAlsoViewed", null);
__decorate([
    (0, common_1.Get)('bought-together/:productId'),
    __param(0, (0, common_1.Param)('productId')),
    __param(1, (0, common_1.Query)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_t = typeof dto_1.GetRecommendationsDto !== "undefined" && dto_1.GetRecommendationsDto) === "function" ? _t : Object]),
    __metadata("design:returntype", Promise)
], RecommendationsController.prototype, "getFrequentlyBoughtTogether", null);
__decorate([
    (0, common_1.Get)('similar-users/:contentType'),
    __param(0, (0, common_1.Param)('contentType')),
    __param(1, (0, common_1.Query)()),
    __param(2, (0, common_1.Req)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_u = typeof dto_1.GetRecommendationsDto !== "undefined" && dto_1.GetRecommendationsDto) === "function" ? _u : Object, typeof (_v = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _v : Object]),
    __metadata("design:returntype", Promise)
], RecommendationsController.prototype, "getSimilarUsersRecommendations", null);
exports.RecommendationsController = RecommendationsController = __decorate([
    (0, common_1.Controller)('api/recommendations'),
    __metadata("design:paramtypes", [typeof (_a = typeof recommendations_service_1.RecommendationsService !== "undefined" && recommendations_service_1.RecommendationsService) === "function" ? _a : Object, typeof (_b = typeof recommendation_tracking_service_1.RecommendationTrackingService !== "undefined" && recommendation_tracking_service_1.RecommendationTrackingService) === "function" ? _b : Object])
], RecommendationsController);


/***/ }),
/* 220 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b, _c;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UpdateRecommendationSettingsDto = exports.AddManualRecommendationDto = exports.UpdateRecommendationRuleDto = exports.CreateRecommendationRuleDto = exports.TrackRecommendationClickDto = exports.TrackInteractionDto = exports.GetRecommendationsDto = void 0;
const class_validator_1 = __webpack_require__(59);
class GetRecommendationsDto {
    constructor() {
        this.limit = 6;
    }
}
exports.GetRecommendationsDto = GetRecommendationsDto;
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(1),
    (0, class_validator_1.Max)(50),
    __metadata("design:type", Number)
], GetRecommendationsDto.prototype, "limit", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], GetRecommendationsDto.prototype, "algorithm", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], GetRecommendationsDto.prototype, "userId", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], GetRecommendationsDto.prototype, "sessionId", void 0);
class TrackInteractionDto {
}
exports.TrackInteractionDto = TrackInteractionDto;
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], TrackInteractionDto.prototype, "contentType", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], TrackInteractionDto.prototype, "contentId", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], TrackInteractionDto.prototype, "interactionType", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], TrackInteractionDto.prototype, "userId", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], TrackInteractionDto.prototype, "sessionId", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsObject)(),
    __metadata("design:type", typeof (_a = typeof Record !== "undefined" && Record) === "function" ? _a : Object)
], TrackInteractionDto.prototype, "metadata", void 0);
class TrackRecommendationClickDto {
}
exports.TrackRecommendationClickDto = TrackRecommendationClickDto;
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], TrackRecommendationClickDto.prototype, "sourceType", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], TrackRecommendationClickDto.prototype, "sourceId", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], TrackRecommendationClickDto.prototype, "recommendationType", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], TrackRecommendationClickDto.prototype, "clickedType", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], TrackRecommendationClickDto.prototype, "clickedId", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], TrackRecommendationClickDto.prototype, "position", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], TrackRecommendationClickDto.prototype, "userId", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], TrackRecommendationClickDto.prototype, "sessionId", void 0);
class CreateRecommendationRuleDto {
}
exports.CreateRecommendationRuleDto = CreateRecommendationRuleDto;
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateRecommendationRuleDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateRecommendationRuleDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateRecommendationRuleDto.prototype, "sourceType", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateRecommendationRuleDto.prototype, "sourceId", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateRecommendationRuleDto.prototype, "targetType", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateRecommendationRuleDto.prototype, "algorithm", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsObject)(),
    __metadata("design:type", typeof (_b = typeof Record !== "undefined" && Record) === "function" ? _b : Object)
], CreateRecommendationRuleDto.prototype, "settings", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], CreateRecommendationRuleDto.prototype, "priority", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsBoolean)(),
    __metadata("design:type", Boolean)
], CreateRecommendationRuleDto.prototype, "isActive", void 0);
class UpdateRecommendationRuleDto {
}
exports.UpdateRecommendationRuleDto = UpdateRecommendationRuleDto;
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], UpdateRecommendationRuleDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], UpdateRecommendationRuleDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], UpdateRecommendationRuleDto.prototype, "sourceType", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], UpdateRecommendationRuleDto.prototype, "sourceId", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], UpdateRecommendationRuleDto.prototype, "targetType", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], UpdateRecommendationRuleDto.prototype, "algorithm", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsObject)(),
    __metadata("design:type", typeof (_c = typeof Record !== "undefined" && Record) === "function" ? _c : Object)
], UpdateRecommendationRuleDto.prototype, "settings", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], UpdateRecommendationRuleDto.prototype, "priority", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsBoolean)(),
    __metadata("design:type", Boolean)
], UpdateRecommendationRuleDto.prototype, "isActive", void 0);
class AddManualRecommendationDto {
}
exports.AddManualRecommendationDto = AddManualRecommendationDto;
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], AddManualRecommendationDto.prototype, "contentType", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], AddManualRecommendationDto.prototype, "contentId", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], AddManualRecommendationDto.prototype, "position", void 0);
class UpdateRecommendationSettingsDto {
}
exports.UpdateRecommendationSettingsDto = UpdateRecommendationSettingsDto;
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsBoolean)(),
    __metadata("design:type", Boolean)
], UpdateRecommendationSettingsDto.prototype, "enablePersonalization", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsBoolean)(),
    __metadata("design:type", Boolean)
], UpdateRecommendationSettingsDto.prototype, "enableTrending", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsBoolean)(),
    __metadata("design:type", Boolean)
], UpdateRecommendationSettingsDto.prototype, "enableRelated", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsBoolean)(),
    __metadata("design:type", Boolean)
], UpdateRecommendationSettingsDto.prototype, "cacheEnabled", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], UpdateRecommendationSettingsDto.prototype, "cacheDuration", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], UpdateRecommendationSettingsDto.prototype, "maxRecommendations", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsNumber)(),
    __metadata("design:type", Number)
], UpdateRecommendationSettingsDto.prototype, "minScore", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.IsString)({ each: true }),
    __metadata("design:type", Array)
], UpdateRecommendationSettingsDto.prototype, "excludeCategories", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.IsString)({ each: true }),
    __metadata("design:type", Array)
], UpdateRecommendationSettingsDto.prototype, "excludeTags", void 0);


/***/ }),
/* 221 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e, _f, _g;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.RecommendationsAdminController = void 0;
const common_1 = __webpack_require__(2);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const client_1 = __webpack_require__(17);
const prisma_service_1 = __webpack_require__(16);
const recommendations_service_1 = __webpack_require__(179);
const recommendation_analytics_service_1 = __webpack_require__(222);
const dto_1 = __webpack_require__(220);
let RecommendationsAdminController = class RecommendationsAdminController {
    constructor(prisma, recommendationsService, analyticsService) {
        this.prisma = prisma;
        this.recommendationsService = recommendationsService;
        this.analyticsService = analyticsService;
    }
    async listRules(page, limit, isActive) {
        const pageNum = parseInt(page || '1');
        const limitNum = parseInt(limit || '20');
        const skip = (pageNum - 1) * limitNum;
        const where = {};
        if (isActive !== undefined) {
            where.isActive = isActive === 'true';
        }
        const [rules, total] = await Promise.all([
            this.prisma.recommendationRule.findMany({
                where,
                include: { manualItems: true },
                orderBy: { priority: 'desc' },
                skip,
                take: limitNum,
            }),
            this.prisma.recommendationRule.count({ where }),
        ]);
        return {
            rules,
            pagination: {
                page: pageNum,
                limit: limitNum,
                total,
                totalPages: Math.ceil(total / limitNum),
            },
        };
    }
    async getRule(id) {
        return this.prisma.recommendationRule.findUnique({
            where: { id },
            include: { manualItems: true },
        });
    }
    async createRule(dto) {
        return this.prisma.recommendationRule.create({
            data: {
                name: dto.name,
                description: dto.description,
                sourceType: dto.sourceType,
                sourceId: dto.sourceId,
                targetType: dto.targetType,
                algorithm: dto.algorithm,
                settings: dto.settings || {},
                priority: dto.priority || 0,
                isActive: dto.isActive ?? true,
            },
        });
    }
    async updateRule(id, dto) {
        return this.prisma.recommendationRule.update({
            where: { id },
            data: dto,
        });
    }
    async deleteRule(id) {
        await this.prisma.recommendationRule.delete({ where: { id } });
        return { success: true };
    }
    async addManualItem(ruleId, dto) {
        return this.prisma.manualRecommendation.create({
            data: {
                ruleId,
                contentType: dto.contentType,
                contentId: dto.contentId,
                position: dto.position || 0,
            },
        });
    }
    async removeManualItem(itemId) {
        await this.prisma.manualRecommendation.delete({ where: { id: itemId } });
        return { success: true };
    }
    async getSettings() {
        const settings = await this.prisma.recommendationSettings.findMany();
        const settingsMap = {};
        settings.forEach((s) => {
            settingsMap[s.key] = s.value;
        });
        return settingsMap;
    }
    async updateSettings(dto) {
        const updates = Object.entries(dto).filter(([_, v]) => v !== undefined);
        for (const [key, value] of updates) {
            await this.prisma.recommendationSettings.upsert({
                where: { key },
                update: { value: value },
                create: { key, value: value },
            });
        }
        return this.getSettings();
    }
    async getAnalytics(period, contentType) {
        return this.analyticsService.getAnalytics(period || 'week', contentType);
    }
    async getClickThroughRates(period) {
        return this.analyticsService.getClickThroughRates(period || 'week');
    }
    async getTopPerforming(period, limit) {
        return this.analyticsService.getTopPerforming(period || 'week', parseInt(limit || '10'));
    }
    async getDailyStats(period, contentType) {
        return this.analyticsService.getDailyStats(period || 'week', contentType);
    }
    async clearCache(sourceType, sourceId) {
        const count = await this.recommendationsService.clearCache(sourceType, sourceId);
        return { success: true, cleared: count };
    }
    async cleanupCache() {
        const count = await this.recommendationsService.clearExpiredCache();
        return { success: true, cleared: count };
    }
};
exports.RecommendationsAdminController = RecommendationsAdminController;
__decorate([
    (0, common_1.Get)('rules'),
    __param(0, (0, common_1.Query)('page')),
    __param(1, (0, common_1.Query)('limit')),
    __param(2, (0, common_1.Query)('isActive')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, String]),
    __metadata("design:returntype", Promise)
], RecommendationsAdminController.prototype, "listRules", null);
__decorate([
    (0, common_1.Get)('rules/:id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], RecommendationsAdminController.prototype, "getRule", null);
__decorate([
    (0, common_1.Post)('rules'),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_d = typeof dto_1.CreateRecommendationRuleDto !== "undefined" && dto_1.CreateRecommendationRuleDto) === "function" ? _d : Object]),
    __metadata("design:returntype", Promise)
], RecommendationsAdminController.prototype, "createRule", null);
__decorate([
    (0, common_1.Put)('rules/:id'),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_e = typeof dto_1.UpdateRecommendationRuleDto !== "undefined" && dto_1.UpdateRecommendationRuleDto) === "function" ? _e : Object]),
    __metadata("design:returntype", Promise)
], RecommendationsAdminController.prototype, "updateRule", null);
__decorate([
    (0, common_1.Delete)('rules/:id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], RecommendationsAdminController.prototype, "deleteRule", null);
__decorate([
    (0, common_1.Post)('rules/:ruleId/items'),
    __param(0, (0, common_1.Param)('ruleId')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_f = typeof dto_1.AddManualRecommendationDto !== "undefined" && dto_1.AddManualRecommendationDto) === "function" ? _f : Object]),
    __metadata("design:returntype", Promise)
], RecommendationsAdminController.prototype, "addManualItem", null);
__decorate([
    (0, common_1.Delete)('rules/:ruleId/items/:itemId'),
    __param(0, (0, common_1.Param)('itemId')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], RecommendationsAdminController.prototype, "removeManualItem", null);
__decorate([
    (0, common_1.Get)('settings'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], RecommendationsAdminController.prototype, "getSettings", null);
__decorate([
    (0, common_1.Put)('settings'),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_g = typeof dto_1.UpdateRecommendationSettingsDto !== "undefined" && dto_1.UpdateRecommendationSettingsDto) === "function" ? _g : Object]),
    __metadata("design:returntype", Promise)
], RecommendationsAdminController.prototype, "updateSettings", null);
__decorate([
    (0, common_1.Get)('analytics'),
    __param(0, (0, common_1.Query)('period')),
    __param(1, (0, common_1.Query)('contentType')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", Promise)
], RecommendationsAdminController.prototype, "getAnalytics", null);
__decorate([
    (0, common_1.Get)('analytics/ctr'),
    __param(0, (0, common_1.Query)('period')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], RecommendationsAdminController.prototype, "getClickThroughRates", null);
__decorate([
    (0, common_1.Get)('analytics/top'),
    __param(0, (0, common_1.Query)('period')),
    __param(1, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", Promise)
], RecommendationsAdminController.prototype, "getTopPerforming", null);
__decorate([
    (0, common_1.Get)('analytics/daily'),
    __param(0, (0, common_1.Query)('period')),
    __param(1, (0, common_1.Query)('contentType')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", Promise)
], RecommendationsAdminController.prototype, "getDailyStats", null);
__decorate([
    (0, common_1.Post)('cache/clear'),
    __param(0, (0, common_1.Query)('sourceType')),
    __param(1, (0, common_1.Query)('sourceId')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", Promise)
], RecommendationsAdminController.prototype, "clearCache", null);
__decorate([
    (0, common_1.Post)('cache/cleanup'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], RecommendationsAdminController.prototype, "cleanupCache", null);
exports.RecommendationsAdminController = RecommendationsAdminController = __decorate([
    (0, common_1.Controller)('api/admin/recommendations'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof recommendations_service_1.RecommendationsService !== "undefined" && recommendations_service_1.RecommendationsService) === "function" ? _b : Object, typeof (_c = typeof recommendation_analytics_service_1.RecommendationAnalyticsService !== "undefined" && recommendation_analytics_service_1.RecommendationAnalyticsService) === "function" ? _c : Object])
], RecommendationsAdminController);


/***/ }),
/* 222 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 RecommendationAnalyticsService_1;
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.RecommendationAnalyticsService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let RecommendationAnalyticsService = RecommendationAnalyticsService_1 = class RecommendationAnalyticsService {
    constructor(prisma) {
        this.prisma = prisma;
        this.logger = new common_1.Logger(RecommendationAnalyticsService_1.name);
    }
    async getAnalytics(period, contentType) {
        const startDate = this.getStartDate(period);
        const where = { createdAt: { gte: startDate } };
        if (contentType) {
            where.clickedType = contentType;
        }
        const totalClicks = await this.prisma.recommendationClick.count({ where });
        const clicksByType = await this.prisma.recommendationClick.groupBy({
            by: ['recommendationType'],
            where,
            _count: { id: true },
        });
        const clicksByContent = await this.prisma.recommendationClick.groupBy({
            by: ['clickedType'],
            where,
            _count: { id: true },
        });
        const interactionWhere = { createdAt: { gte: startDate } };
        if (contentType) {
            interactionWhere.contentType = contentType;
        }
        const totalInteractions = await this.prisma.userInteraction.count({
            where: interactionWhere,
        });
        const interactionsByType = await this.prisma.userInteraction.groupBy({
            by: ['interactionType'],
            where: interactionWhere,
            _count: { id: true },
        });
        return {
            period,
            startDate,
            totalClicks,
            totalInteractions,
            clicksByRecommendationType: clicksByType.reduce((acc, item) => {
                acc[item.recommendationType] = item._count.id;
                return acc;
            }, {}),
            clicksByContentType: clicksByContent.reduce((acc, item) => {
                acc[item.clickedType] = item._count.id;
                return acc;
            }, {}),
            interactionsByType: interactionsByType.reduce((acc, item) => {
                acc[item.interactionType] = item._count.id;
                return acc;
            }, {}),
        };
    }
    async getClickThroughRates(period) {
        const startDate = this.getStartDate(period);
        const impressions = await this.prisma.userInteraction.count({
            where: {
                createdAt: { gte: startDate },
                interactionType: 'view',
            },
        });
        const clicks = await this.prisma.recommendationClick.count({
            where: { createdAt: { gte: startDate } },
        });
        const clicksByType = await this.prisma.recommendationClick.groupBy({
            by: ['recommendationType'],
            where: { createdAt: { gte: startDate } },
            _count: { id: true },
        });
        return {
            period,
            totalImpressions: impressions,
            totalClicks: clicks,
            overallCTR: impressions > 0 ? (clicks / impressions) * 100 : 0,
            ctrByType: clicksByType.reduce((acc, item) => {
                acc[item.recommendationType] = item._count.id;
                return acc;
            }, {}),
        };
    }
    async getTopPerforming(period, limit) {
        const startDate = this.getStartDate(period);
        const topClicked = await this.prisma.recommendationClick.groupBy({
            by: ['clickedType', 'clickedId'],
            where: { createdAt: { gte: startDate } },
            _count: { id: true },
            orderBy: { _count: { id: 'desc' } },
            take: limit,
        });
        const enriched = await Promise.all(topClicked.map(async (item) => {
            const contentDetails = await this.getContentDetails(item.clickedType, item.clickedId);
            return {
                contentType: item.clickedType,
                contentId: item.clickedId,
                clicks: item._count.id,
                ...contentDetails,
            };
        }));
        return {
            period,
            topPerforming: enriched,
        };
    }
    async getContentDetails(contentType, contentId) {
        try {
            switch (contentType) {
                case 'post':
                    const post = await this.prisma.post.findUnique({
                        where: { id: contentId },
                        select: { title: true, slug: true },
                    });
                    return post ? { title: post.title, slug: post.slug } : {};
                case 'product':
                    const product = await this.prisma.product.findUnique({
                        where: { id: contentId },
                        select: { name: true, slug: true },
                    });
                    return product ? { title: product.name, slug: product.slug } : {};
                case 'course':
                    const course = await this.prisma.course.findUnique({
                        where: { id: contentId },
                        select: { title: true, slug: true },
                    });
                    return course ? { title: course.title, slug: course.slug } : {};
                default:
                    return {};
            }
        }
        catch {
            return {};
        }
    }
    async getDailyStats(period, contentType) {
        const startDate = this.getStartDate(period);
        const clickWhere = {
            createdAt: { gte: startDate },
        };
        if (contentType) {
            clickWhere.clickedType = contentType;
        }
        const interactionWhere = {
            createdAt: { gte: startDate },
        };
        if (contentType) {
            interactionWhere.contentType = contentType;
        }
        const clicks = await this.prisma.recommendationClick.findMany({
            where: clickWhere,
            select: { createdAt: true },
            orderBy: { createdAt: 'asc' },
        });
        const interactions = await this.prisma.userInteraction.findMany({
            where: interactionWhere,
            select: { createdAt: true },
            orderBy: { createdAt: 'asc' },
        });
        const clicksByDate = this.aggregateByDate(clicks);
        const interactionsByDate = this.aggregateByDate(interactions);
        return {
            period,
            startDate,
            clickStats: clicksByDate,
            interactionStats: interactionsByDate,
        };
    }
    aggregateByDate(records) {
        const dateMap = new Map();
        for (const record of records) {
            const dateStr = record.createdAt.toISOString().split('T')[0];
            dateMap.set(dateStr, (dateMap.get(dateStr) || 0) + 1);
        }
        return Array.from(dateMap.entries())
            .map(([date, count]) => ({ date, count }))
            .sort((a, b) => a.date.localeCompare(b.date));
    }
    async getConversionMetrics(period) {
        const startDate = this.getStartDate(period);
        const recommendationPurchases = await this.prisma.userInteraction.count({
            where: {
                createdAt: { gte: startDate },
                interactionType: 'purchase',
                metadata: {
                    path: ['fromRecommendation'],
                    equals: true,
                },
            },
        });
        const totalPurchases = await this.prisma.userInteraction.count({
            where: {
                createdAt: { gte: startDate },
                interactionType: 'purchase',
            },
        });
        const recommendationClicks = await this.prisma.recommendationClick.count({
            where: { createdAt: { gte: startDate } },
        });
        return {
            period,
            recommendationPurchases,
            totalPurchases,
            recommendationClicks,
            conversionRate: recommendationClicks > 0 ? (recommendationPurchases / recommendationClicks) * 100 : 0,
            recommendationContribution: totalPurchases > 0 ? (recommendationPurchases / totalPurchases) * 100 : 0,
        };
    }
    getStartDate(period) {
        const now = new Date();
        switch (period) {
            case 'day':
                now.setDate(now.getDate() - 1);
                break;
            case 'week':
                now.setDate(now.getDate() - 7);
                break;
            case 'month':
                now.setMonth(now.getMonth() - 1);
                break;
            case 'quarter':
                now.setMonth(now.getMonth() - 3);
                break;
            case 'year':
                now.setFullYear(now.getFullYear() - 1);
                break;
            default:
                now.setDate(now.getDate() - 7);
        }
        return now;
    }
};
exports.RecommendationAnalyticsService = RecommendationAnalyticsService;
exports.RecommendationAnalyticsService = RecommendationAnalyticsService = RecommendationAnalyticsService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], RecommendationAnalyticsService);


/***/ }),
/* 223 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.MarketplaceModule = void 0;
const common_1 = __webpack_require__(2);
const config_1 = __webpack_require__(13);
const prisma_module_1 = __webpack_require__(15);
const notifications_module_1 = __webpack_require__(224);
const controllers_1 = __webpack_require__(227);
const services_1 = __webpack_require__(240);
let MarketplaceModule = class MarketplaceModule {
};
exports.MarketplaceModule = MarketplaceModule;
exports.MarketplaceModule = MarketplaceModule = __decorate([
    (0, common_1.Module)({
        imports: [prisma_module_1.PrismaModule, config_1.ConfigModule, notifications_module_1.NotificationsModule],
        controllers: [
            controllers_1.DevelopersController,
            controllers_1.HiringRequestsController,
            controllers_1.ProjectsController,
            controllers_1.PaymentsController,
        ],
        providers: [
            services_1.DevelopersService,
            services_1.HiringRequestsService,
            services_1.ProjectsService,
            services_1.MarketplacePaymentsService,
        ],
        exports: [services_1.DevelopersService, services_1.HiringRequestsService, services_1.ProjectsService, services_1.MarketplacePaymentsService],
    })
], MarketplaceModule);


/***/ }),
/* 224 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.NotificationsModule = void 0;
const common_1 = __webpack_require__(2);
const notifications_controller_1 = __webpack_require__(225);
const notifications_service_1 = __webpack_require__(226);
const prisma_module_1 = __webpack_require__(15);
let NotificationsModule = class NotificationsModule {
};
exports.NotificationsModule = NotificationsModule;
exports.NotificationsModule = NotificationsModule = __decorate([
    (0, common_1.Global)(),
    (0, common_1.Module)({
        imports: [prisma_module_1.PrismaModule],
        controllers: [notifications_controller_1.NotificationsController],
        providers: [notifications_service_1.NotificationsService],
        exports: [notifications_service_1.NotificationsService],
    })
], NotificationsModule);


/***/ }),
/* 225 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.NotificationsController = void 0;
const common_1 = __webpack_require__(2);
const notifications_service_1 = __webpack_require__(226);
const jwt_auth_guard_1 = __webpack_require__(61);
const client_1 = __webpack_require__(17);
let NotificationsController = class NotificationsController {
    constructor(notificationsService) {
        this.notificationsService = notificationsService;
    }
    async findAll(req, page, limit, unreadOnly, type) {
        const query = {
            page: page ? parseInt(page) : 1,
            limit: limit ? parseInt(limit) : 20,
            unreadOnly: unreadOnly === 'true',
            type,
        };
        return this.notificationsService.findAll(req.user.id, query);
    }
    async getUnreadCount(req) {
        const count = await this.notificationsService.getUnreadCount(req.user.id);
        return { count };
    }
    async markAsRead(id, req) {
        await this.notificationsService.markAsRead(id, req.user.id);
        return { success: true };
    }
    async markAllAsRead(req) {
        await this.notificationsService.markAllAsRead(req.user.id);
        return { success: true };
    }
    async delete(id, req) {
        await this.notificationsService.delete(id, req.user.id);
        return { success: true };
    }
    async deleteAllRead(req) {
        await this.notificationsService.deleteAllRead(req.user.id);
        return { success: true };
    }
    async clearAll(req) {
        await this.notificationsService.clearAll(req.user.id);
        return { success: true };
    }
};
exports.NotificationsController = NotificationsController;
__decorate([
    (0, common_1.Get)(),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Query)('page')),
    __param(2, (0, common_1.Query)('limit')),
    __param(3, (0, common_1.Query)('unreadOnly')),
    __param(4, (0, common_1.Query)('type')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, String, String, typeof (_b = typeof client_1.NotificationType !== "undefined" && client_1.NotificationType) === "function" ? _b : Object]),
    __metadata("design:returntype", Promise)
], NotificationsController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)('unread-count'),
    __param(0, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], NotificationsController.prototype, "getUnreadCount", null);
__decorate([
    (0, common_1.Post)(':id/read'),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", Promise)
], NotificationsController.prototype, "markAsRead", null);
__decorate([
    (0, common_1.Post)('read-all'),
    __param(0, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], NotificationsController.prototype, "markAllAsRead", null);
__decorate([
    (0, common_1.Delete)(':id'),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", Promise)
], NotificationsController.prototype, "delete", null);
__decorate([
    (0, common_1.Delete)('clear/read'),
    __param(0, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], NotificationsController.prototype, "deleteAllRead", null);
__decorate([
    (0, common_1.Delete)('clear/all'),
    __param(0, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], NotificationsController.prototype, "clearAll", null);
exports.NotificationsController = NotificationsController = __decorate([
    (0, common_1.Controller)('api/notifications'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof notifications_service_1.NotificationsService !== "undefined" && notifications_service_1.NotificationsService) === "function" ? _a : Object])
], NotificationsController);


/***/ }),
/* 226 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.NotificationsService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let NotificationsService = class NotificationsService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async create(dto) {
        return this.prisma.notification.create({
            data: {
                userId: dto.userId,
                type: dto.type || 'INFO',
                title: dto.title,
                message: dto.message,
                link: dto.link,
                icon: dto.icon,
                iconColor: dto.iconColor,
                metadata: dto.metadata,
            },
        });
    }
    async createBulk(userIds, notification) {
        return this.prisma.notification.createMany({
            data: userIds.map((userId) => ({
                userId,
                type: notification.type || 'INFO',
                title: notification.title,
                message: notification.message,
                link: notification.link,
                icon: notification.icon,
                iconColor: notification.iconColor,
                metadata: notification.metadata,
            })),
        });
    }
    async notifyAdmins(notification) {
        const admins = await this.prisma.user.findMany({
            where: { role: 'ADMIN' },
            select: { id: true },
        });
        return this.createBulk(admins.map((a) => a.id), notification);
    }
    async findAll(userId, query = {}) {
        const { page = 1, limit = 20, unreadOnly = false, type } = query;
        const skip = (page - 1) * limit;
        const where = { userId };
        if (unreadOnly)
            where.isRead = false;
        if (type)
            where.type = type;
        const [notifications, total, unreadCount] = await Promise.all([
            this.prisma.notification.findMany({
                where,
                orderBy: { createdAt: 'desc' },
                skip,
                take: limit,
            }),
            this.prisma.notification.count({ where }),
            this.prisma.notification.count({ where: { userId, isRead: false } }),
        ]);
        return {
            data: notifications,
            meta: {
                total,
                unreadCount,
                page,
                limit,
                totalPages: Math.ceil(total / limit),
            },
        };
    }
    async getUnreadCount(userId) {
        return this.prisma.notification.count({
            where: { userId, isRead: false },
        });
    }
    async markAsRead(id, userId) {
        return this.prisma.notification.updateMany({
            where: { id, userId },
            data: { isRead: true, readAt: new Date() },
        });
    }
    async markAllAsRead(userId) {
        return this.prisma.notification.updateMany({
            where: { userId, isRead: false },
            data: { isRead: true, readAt: new Date() },
        });
    }
    async delete(id, userId) {
        return this.prisma.notification.deleteMany({
            where: { id, userId },
        });
    }
    async deleteAllRead(userId) {
        return this.prisma.notification.deleteMany({
            where: { userId, isRead: true },
        });
    }
    async clearAll(userId) {
        return this.prisma.notification.deleteMany({
            where: { userId },
        });
    }
};
exports.NotificationsService = NotificationsService;
exports.NotificationsService = NotificationsService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], NotificationsService);


/***/ }),
/* 227 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
__exportStar(__webpack_require__(228), exports);
__exportStar(__webpack_require__(234), exports);
__exportStar(__webpack_require__(237), exports);
__exportStar(__webpack_require__(239), exports);


/***/ }),
/* 228 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e, _f, _g;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.DevelopersController = void 0;
const common_1 = __webpack_require__(2);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const developers_service_1 = __webpack_require__(182);
const dto_1 = __webpack_require__(229);
let DevelopersController = class DevelopersController {
    constructor(developersService) {
        this.developersService = developersService;
    }
    async create(req, dto) {
        return this.developersService.create(req.user.id, dto);
    }
    async getMyProfile(req) {
        return this.developersService.findByUserId(req.user.id);
    }
    async updateMyProfile(req, dto) {
        const developer = await this.developersService.findByUserId(req.user.id);
        if (!developer) {
            return { error: 'Developer profile not found' };
        }
        return this.developersService.update(developer.id, req.user.id, dto);
    }
    async findAll(category, skills, minRate, maxRate, minRating, availability, search, sortBy, page, limit) {
        return this.developersService.findAll({
            status: dto_1.DeveloperStatus.ACTIVE,
            category,
            skills: skills ? skills.split(',') : undefined,
            minRate: minRate ? parseFloat(minRate) : undefined,
            maxRate: maxRate ? parseFloat(maxRate) : undefined,
            minRating: minRating ? parseFloat(minRating) : undefined,
            availability,
            search,
            sortBy,
            page: page ? parseInt(page) : 1,
            limit: limit ? parseInt(limit) : 12,
        });
    }
    async getBySlug(slug) {
        return this.developersService.findBySlug(slug);
    }
    async matchDevelopers(requirements) {
        return this.developersService.matchDevelopers(requirements);
    }
    async adminFindAll(status, category, search, page, limit) {
        return this.developersService.findAll({
            status,
            category,
            search,
            page: page ? parseInt(page) : 1,
            limit: limit ? parseInt(limit) : 20,
        });
    }
    async getStatistics() {
        return this.developersService.getStatistics();
    }
    async approve(id) {
        return this.developersService.approve(id);
    }
    async findById(id) {
        return this.developersService.findById(id);
    }
    async reject(id, reason) {
        return this.developersService.reject(id, reason);
    }
    async suspend(id, reason) {
        return this.developersService.suspend(id, reason);
    }
    async reactivate(id) {
        return this.developersService.reactivate(id);
    }
    async setFeatured(id, body) {
        return this.developersService.setFeatured(id, body.featured, body.days);
    }
    async update(id, req, dto) {
        return this.developersService.update(id, req.user.id, dto, true);
    }
};
exports.DevelopersController = DevelopersController;
__decorate([
    (0, common_1.Post)(),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, typeof (_b = typeof dto_1.CreateDeveloperDto !== "undefined" && dto_1.CreateDeveloperDto) === "function" ? _b : Object]),
    __metadata("design:returntype", Promise)
], DevelopersController.prototype, "create", null);
__decorate([
    (0, common_1.Get)('me'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], DevelopersController.prototype, "getMyProfile", null);
__decorate([
    (0, common_1.Put)('me'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, typeof (_c = typeof dto_1.UpdateDeveloperDto !== "undefined" && dto_1.UpdateDeveloperDto) === "function" ? _c : Object]),
    __metadata("design:returntype", Promise)
], DevelopersController.prototype, "updateMyProfile", null);
__decorate([
    (0, common_1.Get)(),
    __param(0, (0, common_1.Query)('category')),
    __param(1, (0, common_1.Query)('skills')),
    __param(2, (0, common_1.Query)('minRate')),
    __param(3, (0, common_1.Query)('maxRate')),
    __param(4, (0, common_1.Query)('minRating')),
    __param(5, (0, common_1.Query)('availability')),
    __param(6, (0, common_1.Query)('search')),
    __param(7, (0, common_1.Query)('sortBy')),
    __param(8, (0, common_1.Query)('page')),
    __param(9, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_d = typeof dto_1.DeveloperCategory !== "undefined" && dto_1.DeveloperCategory) === "function" ? _d : Object, String, String, String, String, String, String, String, String, String]),
    __metadata("design:returntype", Promise)
], DevelopersController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)('profile/:slug'),
    __param(0, (0, common_1.Param)('slug')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], DevelopersController.prototype, "getBySlug", null);
__decorate([
    (0, common_1.Post)('match'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], DevelopersController.prototype, "matchDevelopers", null);
__decorate([
    (0, common_1.Get)('admin/all'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)('ADMIN'),
    __param(0, (0, common_1.Query)('status')),
    __param(1, (0, common_1.Query)('category')),
    __param(2, (0, common_1.Query)('search')),
    __param(3, (0, common_1.Query)('page')),
    __param(4, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_e = typeof dto_1.DeveloperStatus !== "undefined" && dto_1.DeveloperStatus) === "function" ? _e : Object, typeof (_f = typeof dto_1.DeveloperCategory !== "undefined" && dto_1.DeveloperCategory) === "function" ? _f : Object, String, String, String]),
    __metadata("design:returntype", Promise)
], DevelopersController.prototype, "adminFindAll", null);
__decorate([
    (0, common_1.Get)('admin/statistics'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)('ADMIN'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], DevelopersController.prototype, "getStatistics", null);
__decorate([
    (0, common_1.Patch)(':id/approve'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)('ADMIN'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], DevelopersController.prototype, "approve", null);
__decorate([
    (0, common_1.Get)(':id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], DevelopersController.prototype, "findById", null);
__decorate([
    (0, common_1.Patch)(':id/reject'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)('ADMIN'),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)('reason')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", Promise)
], DevelopersController.prototype, "reject", null);
__decorate([
    (0, common_1.Patch)(':id/suspend'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)('ADMIN'),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)('reason')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", Promise)
], DevelopersController.prototype, "suspend", null);
__decorate([
    (0, common_1.Patch)(':id/reactivate'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)('ADMIN'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], DevelopersController.prototype, "reactivate", null);
__decorate([
    (0, common_1.Patch)(':id/featured'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)('ADMIN'),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", Promise)
], DevelopersController.prototype, "setFeatured", null);
__decorate([
    (0, common_1.Put)(':id'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)('ADMIN'),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Request)()),
    __param(2, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object, typeof (_g = typeof dto_1.UpdateDeveloperDto !== "undefined" && dto_1.UpdateDeveloperDto) === "function" ? _g : Object]),
    __metadata("design:returntype", Promise)
], DevelopersController.prototype, "update", null);
exports.DevelopersController = DevelopersController = __decorate([
    (0, common_1.Controller)('api/marketplace/developers'),
    __metadata("design:paramtypes", [typeof (_a = typeof developers_service_1.DevelopersService !== "undefined" && developers_service_1.DevelopersService) === "function" ? _a : Object])
], DevelopersController);


/***/ }),
/* 229 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
__exportStar(__webpack_require__(230), exports);
__exportStar(__webpack_require__(231), exports);
__exportStar(__webpack_require__(232), exports);
__exportStar(__webpack_require__(233), exports);


/***/ }),
/* 230 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UpdateDeveloperDto = exports.CreateDeveloperDto = exports.DeveloperCategory = exports.DeveloperStatus = void 0;
const class_validator_1 = __webpack_require__(59);
const class_transformer_1 = __webpack_require__(95);
var DeveloperStatus;
(function (DeveloperStatus) {
    DeveloperStatus["PENDING"] = "PENDING";
    DeveloperStatus["ACTIVE"] = "ACTIVE";
    DeveloperStatus["INACTIVE"] = "INACTIVE";
    DeveloperStatus["SUSPENDED"] = "SUSPENDED";
    DeveloperStatus["REJECTED"] = "REJECTED";
})(DeveloperStatus || (exports.DeveloperStatus = DeveloperStatus = {}));
var DeveloperCategory;
(function (DeveloperCategory) {
    DeveloperCategory["FRONTEND"] = "FRONTEND";
    DeveloperCategory["BACKEND"] = "BACKEND";
    DeveloperCategory["FULLSTACK"] = "FULLSTACK";
    DeveloperCategory["WORDPRESS"] = "WORDPRESS";
    DeveloperCategory["MOBILE"] = "MOBILE";
    DeveloperCategory["DEVOPS"] = "DEVOPS";
    DeveloperCategory["DESIGN"] = "DESIGN";
    DeveloperCategory["DATABASE"] = "DATABASE";
    DeveloperCategory["SECURITY"] = "SECURITY";
    DeveloperCategory["OTHER"] = "OTHER";
})(DeveloperCategory || (exports.DeveloperCategory = DeveloperCategory = {}));
class CreateDeveloperDto {
}
exports.CreateDeveloperDto = CreateDeveloperDto;
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateDeveloperDto.prototype, "displayName", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateDeveloperDto.prototype, "headline", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateDeveloperDto.prototype, "bio", void 0);
__decorate([
    (0, class_validator_1.IsEnum)(DeveloperCategory),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateDeveloperDto.prototype, "category", void 0);
__decorate([
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.IsString)({ each: true }),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], CreateDeveloperDto.prototype, "skills", void 0);
__decorate([
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.IsString)({ each: true }),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], CreateDeveloperDto.prototype, "languages", void 0);
__decorate([
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.IsString)({ each: true }),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], CreateDeveloperDto.prototype, "frameworks", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], CreateDeveloperDto.prototype, "hourlyRate", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    (0, class_validator_1.IsOptional)(),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], CreateDeveloperDto.prototype, "minimumBudget", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    (0, class_validator_1.Max)(50),
    (0, class_validator_1.IsOptional)(),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], CreateDeveloperDto.prototype, "yearsOfExperience", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateDeveloperDto.prototype, "applicationNote", void 0);
__decorate([
    (0, class_validator_1.IsUrl)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateDeveloperDto.prototype, "websiteUrl", void 0);
__decorate([
    (0, class_validator_1.IsUrl)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateDeveloperDto.prototype, "githubUrl", void 0);
__decorate([
    (0, class_validator_1.IsUrl)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateDeveloperDto.prototype, "linkedinUrl", void 0);
class UpdateDeveloperDto {
}
exports.UpdateDeveloperDto = UpdateDeveloperDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateDeveloperDto.prototype, "displayName", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateDeveloperDto.prototype, "headline", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateDeveloperDto.prototype, "bio", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateDeveloperDto.prototype, "profileImage", void 0);
__decorate([
    (0, class_validator_1.IsEnum)(DeveloperCategory),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateDeveloperDto.prototype, "category", void 0);
__decorate([
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.IsString)({ each: true }),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], UpdateDeveloperDto.prototype, "skills", void 0);
__decorate([
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.IsString)({ each: true }),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], UpdateDeveloperDto.prototype, "languages", void 0);
__decorate([
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.IsString)({ each: true }),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], UpdateDeveloperDto.prototype, "frameworks", void 0);
__decorate([
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.IsString)({ each: true }),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], UpdateDeveloperDto.prototype, "tools", void 0);
__decorate([
    (0, class_validator_1.IsArray)(),
    (0, class_validator_1.IsString)({ each: true }),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], UpdateDeveloperDto.prototype, "spokenLanguages", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    (0, class_validator_1.IsOptional)(),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], UpdateDeveloperDto.prototype, "hourlyRate", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    (0, class_validator_1.IsOptional)(),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], UpdateDeveloperDto.prototype, "minimumBudget", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    (0, class_validator_1.IsOptional)(),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], UpdateDeveloperDto.prototype, "yearsOfExperience", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], UpdateDeveloperDto.prototype, "portfolio", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], UpdateDeveloperDto.prototype, "education", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], UpdateDeveloperDto.prototype, "certifications", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateDeveloperDto.prototype, "availability", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    (0, class_validator_1.Max)(168),
    (0, class_validator_1.IsOptional)(),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], UpdateDeveloperDto.prototype, "availableHours", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateDeveloperDto.prototype, "timezone", void 0);


/***/ }),
/* 231 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.HiringRequestFiltersDto = exports.UpdateHiringRequestStatusDto = exports.CreateHiringRequestDto = exports.HiringRequestStatus = void 0;
const class_validator_1 = __webpack_require__(59);
const class_transformer_1 = __webpack_require__(95);
var HiringRequestStatus;
(function (HiringRequestStatus) {
    HiringRequestStatus["PENDING"] = "PENDING";
    HiringRequestStatus["ACCEPTED"] = "ACCEPTED";
    HiringRequestStatus["REJECTED"] = "REJECTED";
    HiringRequestStatus["CANCELLED"] = "CANCELLED";
    HiringRequestStatus["IN_PROGRESS"] = "IN_PROGRESS";
    HiringRequestStatus["COMPLETED"] = "COMPLETED";
    HiringRequestStatus["DISPUTED"] = "DISPUTED";
})(HiringRequestStatus || (exports.HiringRequestStatus = HiringRequestStatus = {}));
class CreateHiringRequestDto {
}
exports.CreateHiringRequestDto = CreateHiringRequestDto;
__decorate([
    (0, class_validator_1.IsUUID)(),
    __metadata("design:type", String)
], CreateHiringRequestDto.prototype, "developerId", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateHiringRequestDto.prototype, "title", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateHiringRequestDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateHiringRequestDto.prototype, "requirements", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateHiringRequestDto.prototype, "budgetType", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(1),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], CreateHiringRequestDto.prototype, "budgetAmount", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], CreateHiringRequestDto.prototype, "estimatedHours", void 0);
__decorate([
    (0, class_validator_1.IsDateString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateHiringRequestDto.prototype, "deadline", void 0);
class UpdateHiringRequestStatusDto {
}
exports.UpdateHiringRequestStatusDto = UpdateHiringRequestStatusDto;
__decorate([
    (0, class_validator_1.IsEnum)(HiringRequestStatus),
    __metadata("design:type", String)
], UpdateHiringRequestStatusDto.prototype, "status", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateHiringRequestStatusDto.prototype, "responseMessage", void 0);
class HiringRequestFiltersDto {
}
exports.HiringRequestFiltersDto = HiringRequestFiltersDto;
__decorate([
    (0, class_validator_1.IsEnum)(HiringRequestStatus),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], HiringRequestFiltersDto.prototype, "status", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], HiringRequestFiltersDto.prototype, "page", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], HiringRequestFiltersDto.prototype, "limit", void 0);


/***/ }),
/* 232 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ProjectFiltersDto = exports.CreateProjectReviewDto = exports.LogHoursDto = exports.UpdateProjectDto = exports.CreateProjectDto = exports.ProjectStatus = void 0;
const class_validator_1 = __webpack_require__(59);
const class_transformer_1 = __webpack_require__(95);
var ProjectStatus;
(function (ProjectStatus) {
    ProjectStatus["DRAFT"] = "DRAFT";
    ProjectStatus["ACTIVE"] = "ACTIVE";
    ProjectStatus["ON_HOLD"] = "ON_HOLD";
    ProjectStatus["COMPLETED"] = "COMPLETED";
    ProjectStatus["CANCELLED"] = "CANCELLED";
})(ProjectStatus || (exports.ProjectStatus = ProjectStatus = {}));
class CreateProjectDto {
}
exports.CreateProjectDto = CreateProjectDto;
__decorate([
    (0, class_validator_1.IsUUID)(),
    __metadata("design:type", String)
], CreateProjectDto.prototype, "developerId", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateProjectDto.prototype, "title", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateProjectDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateProjectDto.prototype, "requirements", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateProjectDto.prototype, "budgetType", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(1),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], CreateProjectDto.prototype, "totalBudget", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], CreateProjectDto.prototype, "hourlyRate", void 0);
__decorate([
    (0, class_validator_1.IsDateString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateProjectDto.prototype, "deadline", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], CreateProjectDto.prototype, "milestones", void 0);
class UpdateProjectDto {
}
exports.UpdateProjectDto = UpdateProjectDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateProjectDto.prototype, "title", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateProjectDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateProjectDto.prototype, "requirements", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    (0, class_validator_1.Max)(100),
    (0, class_validator_1.IsOptional)(),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], UpdateProjectDto.prototype, "progress", void 0);
__decorate([
    (0, class_validator_1.IsEnum)(ProjectStatus),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], UpdateProjectDto.prototype, "status", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], UpdateProjectDto.prototype, "milestones", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], UpdateProjectDto.prototype, "deliverables", void 0);
class LogHoursDto {
}
exports.LogHoursDto = LogHoursDto;
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0.25),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], LogHoursDto.prototype, "hours", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], LogHoursDto.prototype, "description", void 0);
class CreateProjectReviewDto {
}
exports.CreateProjectReviewDto = CreateProjectReviewDto;
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(1),
    (0, class_validator_1.Max)(5),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], CreateProjectReviewDto.prototype, "rating", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateProjectReviewDto.prototype, "review", void 0);
class ProjectFiltersDto {
}
exports.ProjectFiltersDto = ProjectFiltersDto;
__decorate([
    (0, class_validator_1.IsEnum)(ProjectStatus),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], ProjectFiltersDto.prototype, "status", void 0);
__decorate([
    (0, class_validator_1.IsUUID)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], ProjectFiltersDto.prototype, "developerId", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], ProjectFiltersDto.prototype, "page", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], ProjectFiltersDto.prototype, "limit", void 0);


/***/ }),
/* 233 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.TransactionFiltersDto = exports.ResolveDisputeDto = exports.CreateDisputeDto = exports.RequestPayoutDto = exports.ReleaseEscrowDto = exports.CreateEscrowDepositDto = exports.DisputeStatus = exports.PayoutStatus = exports.MarketplaceTransactionStatus = exports.MarketplaceTransactionType = void 0;
const class_validator_1 = __webpack_require__(59);
const class_transformer_1 = __webpack_require__(95);
var MarketplaceTransactionType;
(function (MarketplaceTransactionType) {
    MarketplaceTransactionType["ESCROW_DEPOSIT"] = "ESCROW_DEPOSIT";
    MarketplaceTransactionType["ESCROW_RELEASE"] = "ESCROW_RELEASE";
    MarketplaceTransactionType["ESCROW_REFUND"] = "ESCROW_REFUND";
    MarketplaceTransactionType["PLATFORM_FEE"] = "PLATFORM_FEE";
    MarketplaceTransactionType["DEVELOPER_PAYOUT"] = "DEVELOPER_PAYOUT";
    MarketplaceTransactionType["DISPUTE_RESOLUTION"] = "DISPUTE_RESOLUTION";
})(MarketplaceTransactionType || (exports.MarketplaceTransactionType = MarketplaceTransactionType = {}));
var MarketplaceTransactionStatus;
(function (MarketplaceTransactionStatus) {
    MarketplaceTransactionStatus["PENDING"] = "PENDING";
    MarketplaceTransactionStatus["PROCESSING"] = "PROCESSING";
    MarketplaceTransactionStatus["COMPLETED"] = "COMPLETED";
    MarketplaceTransactionStatus["FAILED"] = "FAILED";
    MarketplaceTransactionStatus["REFUNDED"] = "REFUNDED";
    MarketplaceTransactionStatus["CANCELLED"] = "CANCELLED";
})(MarketplaceTransactionStatus || (exports.MarketplaceTransactionStatus = MarketplaceTransactionStatus = {}));
var PayoutStatus;
(function (PayoutStatus) {
    PayoutStatus["PENDING"] = "PENDING";
    PayoutStatus["PROCESSING"] = "PROCESSING";
    PayoutStatus["COMPLETED"] = "COMPLETED";
    PayoutStatus["FAILED"] = "FAILED";
})(PayoutStatus || (exports.PayoutStatus = PayoutStatus = {}));
var DisputeStatus;
(function (DisputeStatus) {
    DisputeStatus["OPEN"] = "OPEN";
    DisputeStatus["UNDER_REVIEW"] = "UNDER_REVIEW";
    DisputeStatus["RESOLVED_CLIENT"] = "RESOLVED_CLIENT";
    DisputeStatus["RESOLVED_DEVELOPER"] = "RESOLVED_DEVELOPER";
    DisputeStatus["CLOSED"] = "CLOSED";
})(DisputeStatus || (exports.DisputeStatus = DisputeStatus = {}));
class CreateEscrowDepositDto {
}
exports.CreateEscrowDepositDto = CreateEscrowDepositDto;
__decorate([
    (0, class_validator_1.IsUUID)(),
    __metadata("design:type", String)
], CreateEscrowDepositDto.prototype, "projectId", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(1),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], CreateEscrowDepositDto.prototype, "amount", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], CreateEscrowDepositDto.prototype, "paymentMethodId", void 0);
class ReleaseEscrowDto {
}
exports.ReleaseEscrowDto = ReleaseEscrowDto;
__decorate([
    (0, class_validator_1.IsUUID)(),
    __metadata("design:type", String)
], ReleaseEscrowDto.prototype, "projectId", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], ReleaseEscrowDto.prototype, "amount", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], ReleaseEscrowDto.prototype, "description", void 0);
class RequestPayoutDto {
}
exports.RequestPayoutDto = RequestPayoutDto;
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(10),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], RequestPayoutDto.prototype, "amount", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], RequestPayoutDto.prototype, "payoutMethod", void 0);
class CreateDisputeDto {
}
exports.CreateDisputeDto = CreateDisputeDto;
__decorate([
    (0, class_validator_1.IsUUID)(),
    __metadata("design:type", String)
], CreateDisputeDto.prototype, "projectId", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateDisputeDto.prototype, "reason", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], CreateDisputeDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Array)
], CreateDisputeDto.prototype, "evidence", void 0);
class ResolveDisputeDto {
}
exports.ResolveDisputeDto = ResolveDisputeDto;
__decorate([
    (0, class_validator_1.IsEnum)(DisputeStatus),
    __metadata("design:type", String)
], ResolveDisputeDto.prototype, "resolution", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    __metadata("design:type", String)
], ResolveDisputeDto.prototype, "resolutionNotes", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.Min)(0),
    (0, class_validator_1.IsOptional)(),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], ResolveDisputeDto.prototype, "refundAmount", void 0);
class TransactionFiltersDto {
}
exports.TransactionFiltersDto = TransactionFiltersDto;
__decorate([
    (0, class_validator_1.IsEnum)(MarketplaceTransactionType),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], TransactionFiltersDto.prototype, "type", void 0);
__decorate([
    (0, class_validator_1.IsEnum)(MarketplaceTransactionStatus),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], TransactionFiltersDto.prototype, "status", void 0);
__decorate([
    (0, class_validator_1.IsUUID)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], TransactionFiltersDto.prototype, "projectId", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], TransactionFiltersDto.prototype, "page", void 0);
__decorate([
    (0, class_validator_1.IsNumber)(),
    (0, class_validator_1.IsOptional)(),
    (0, class_transformer_1.Type)(() => Number),
    __metadata("design:type", Number)
], TransactionFiltersDto.prototype, "limit", void 0);


/***/ }),
/* 234 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e, _f, _g;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.HiringRequestsController = void 0;
const common_1 = __webpack_require__(2);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const hiring_requests_service_1 = __webpack_require__(235);
const projects_service_1 = __webpack_require__(236);
const dto_1 = __webpack_require__(229);
let HiringRequestsController = class HiringRequestsController {
    constructor(hiringRequestsService, projectsService) {
        this.hiringRequestsService = hiringRequestsService;
        this.projectsService = projectsService;
    }
    async create(req, dto) {
        return this.hiringRequestsService.create(req.user.id, dto);
    }
    async getMyClientRequests(req, status, page, limit) {
        return this.hiringRequestsService.findForUser(req.user.id, 'client', {
            status,
            page: page ? parseInt(page) : 1,
            limit: limit ? parseInt(limit) : 10,
        });
    }
    async getMyDeveloperRequests(req, status, page, limit) {
        return this.hiringRequestsService.findForUser(req.user.id, 'developer', {
            status,
            page: page ? parseInt(page) : 1,
            limit: limit ? parseInt(limit) : 10,
        });
    }
    async adminFindAll(status, page, limit) {
        return this.hiringRequestsService.findForUser('', 'client', {
            status,
            page: page ? parseInt(page) : 1,
            limit: limit ? parseInt(limit) : 20,
        });
    }
    async findById(req, id) {
        return this.hiringRequestsService.findById(id, req.user.id, req.user.role === 'ADMIN');
    }
    async updateStatus(req, id, dto) {
        return this.hiringRequestsService.updateStatus(id, req.user.id, dto, req.user.role === 'ADMIN');
    }
    async accept(req, id, message) {
        return this.hiringRequestsService.updateStatus(id, req.user.id, {
            status: dto_1.HiringRequestStatus.ACCEPTED,
            responseMessage: message,
        });
    }
    async reject(req, id, message) {
        return this.hiringRequestsService.updateStatus(id, req.user.id, {
            status: dto_1.HiringRequestStatus.REJECTED,
            responseMessage: message,
        });
    }
    async cancel(req, id) {
        return this.hiringRequestsService.updateStatus(id, req.user.id, {
            status: dto_1.HiringRequestStatus.CANCELLED,
        });
    }
    async createProject(req, id) {
        const request = await this.hiringRequestsService.findById(id, req.user.id, req.user.role === 'ADMIN');
        if (request.clientId !== req.user.id && req.user.role !== 'ADMIN') {
            return { error: 'Only the client can create a project' };
        }
        return this.projectsService.createFromHiringRequest(id);
    }
};
exports.HiringRequestsController = HiringRequestsController;
__decorate([
    (0, common_1.Post)(),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, typeof (_c = typeof dto_1.CreateHiringRequestDto !== "undefined" && dto_1.CreateHiringRequestDto) === "function" ? _c : Object]),
    __metadata("design:returntype", Promise)
], HiringRequestsController.prototype, "create", null);
__decorate([
    (0, common_1.Get)('my/client'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Query)('status')),
    __param(2, (0, common_1.Query)('page')),
    __param(3, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, typeof (_d = typeof dto_1.HiringRequestStatus !== "undefined" && dto_1.HiringRequestStatus) === "function" ? _d : Object, String, String]),
    __metadata("design:returntype", Promise)
], HiringRequestsController.prototype, "getMyClientRequests", null);
__decorate([
    (0, common_1.Get)('my/developer'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Query)('status')),
    __param(2, (0, common_1.Query)('page')),
    __param(3, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, typeof (_e = typeof dto_1.HiringRequestStatus !== "undefined" && dto_1.HiringRequestStatus) === "function" ? _e : Object, String, String]),
    __metadata("design:returntype", Promise)
], HiringRequestsController.prototype, "getMyDeveloperRequests", null);
__decorate([
    (0, common_1.Get)('admin/all'),
    (0, common_1.UseGuards)(roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)('ADMIN'),
    __param(0, (0, common_1.Query)('status')),
    __param(1, (0, common_1.Query)('page')),
    __param(2, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_f = typeof dto_1.HiringRequestStatus !== "undefined" && dto_1.HiringRequestStatus) === "function" ? _f : Object, String, String]),
    __metadata("design:returntype", Promise)
], HiringRequestsController.prototype, "adminFindAll", null);
__decorate([
    (0, common_1.Get)(':id'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String]),
    __metadata("design:returntype", Promise)
], HiringRequestsController.prototype, "findById", null);
__decorate([
    (0, common_1.Patch)(':id/status'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __param(2, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, typeof (_g = typeof dto_1.UpdateHiringRequestStatusDto !== "undefined" && dto_1.UpdateHiringRequestStatusDto) === "function" ? _g : Object]),
    __metadata("design:returntype", Promise)
], HiringRequestsController.prototype, "updateStatus", null);
__decorate([
    (0, common_1.Post)(':id/accept'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __param(2, (0, common_1.Body)('message')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, String]),
    __metadata("design:returntype", Promise)
], HiringRequestsController.prototype, "accept", null);
__decorate([
    (0, common_1.Post)(':id/reject'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __param(2, (0, common_1.Body)('message')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, String]),
    __metadata("design:returntype", Promise)
], HiringRequestsController.prototype, "reject", null);
__decorate([
    (0, common_1.Post)(':id/cancel'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String]),
    __metadata("design:returntype", Promise)
], HiringRequestsController.prototype, "cancel", null);
__decorate([
    (0, common_1.Post)(':id/create-project'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String]),
    __metadata("design:returntype", Promise)
], HiringRequestsController.prototype, "createProject", null);
exports.HiringRequestsController = HiringRequestsController = __decorate([
    (0, common_1.Controller)('api/marketplace/hiring-requests'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof hiring_requests_service_1.HiringRequestsService !== "undefined" && hiring_requests_service_1.HiringRequestsService) === "function" ? _a : Object, typeof (_b = typeof projects_service_1.ProjectsService !== "undefined" && projects_service_1.ProjectsService) === "function" ? _b : Object])
], HiringRequestsController);


/***/ }),
/* 235 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.HiringRequestsService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const notifications_service_1 = __webpack_require__(226);
let HiringRequestsService = class HiringRequestsService {
    constructor(prisma, notificationsService) {
        this.prisma = prisma;
        this.notificationsService = notificationsService;
    }
    async create(clientId, dto) {
        const developer = await this.prisma.developer.findUnique({
            where: { id: dto.developerId },
            include: { user: true },
        });
        if (!developer)
            throw new common_1.NotFoundException('Developer not found');
        if (developer.status !== 'ACTIVE')
            throw new common_1.BadRequestException('Developer is not available');
        if (developer.userId === clientId)
            throw new common_1.BadRequestException('Cannot hire yourself');
        const request = await this.prisma.hiringRequest.create({
            data: {
                clientId,
                developerId: dto.developerId,
                title: dto.title,
                description: dto.description,
                requirements: dto.requirements,
                budgetType: dto.budgetType || 'fixed',
                budgetAmount: dto.budgetAmount,
                estimatedHours: dto.estimatedHours,
                deadline: dto.deadline ? new Date(dto.deadline) : null,
                status: 'PENDING',
            },
            include: {
                client: { select: { id: true, name: true, email: true, avatar: true } },
                developer: { include: { user: { select: { id: true, name: true } } } },
            },
        });
        await this.notificationsService.create({
            userId: developer.userId,
            type: 'MARKETPLACE',
            title: 'New Hiring Request',
            message: `You have a new hiring request: "${dto.title}"`,
            link: `/admin/marketplace/requests/${request.id}`,
        });
        return request;
    }
    async findById(id, userId, isAdmin = false) {
        const request = await this.prisma.hiringRequest.findUnique({
            where: { id },
            include: {
                client: { select: { id: true, name: true, email: true, avatar: true } },
                developer: {
                    include: { user: { select: { id: true, name: true, email: true, avatar: true } } },
                },
                project: true,
            },
        });
        if (!request)
            throw new common_1.NotFoundException('Hiring request not found');
        if (!isAdmin && request.clientId !== userId && request.developer.userId !== userId) {
            throw new common_1.ForbiddenException('Not authorized to view this request');
        }
        return request;
    }
    async findForUser(userId, role, filters) {
        const { status, page = 1, limit = 10 } = filters;
        const where = {};
        if (role === 'client') {
            where.clientId = userId;
        }
        else {
            where.developer = { userId };
        }
        if (status)
            where.status = status;
        const [requests, total] = await Promise.all([
            this.prisma.hiringRequest.findMany({
                where,
                orderBy: { createdAt: 'desc' },
                skip: (page - 1) * limit,
                take: limit,
                include: {
                    client: { select: { id: true, name: true, avatar: true } },
                    developer: { include: { user: { select: { id: true, name: true, avatar: true } } } },
                },
            }),
            this.prisma.hiringRequest.count({ where }),
        ]);
        return { requests, pagination: { page, limit, total, pages: Math.ceil(total / limit) } };
    }
    async updateStatus(id, userId, dto, isAdmin = false) {
        const request = await this.prisma.hiringRequest.findUnique({
            where: { id },
            include: { developer: true, client: true },
        });
        if (!request)
            throw new common_1.NotFoundException('Hiring request not found');
        const isDeveloper = request.developer.userId === userId;
        const isClient = request.clientId === userId;
        if (!isAdmin && !isDeveloper && !isClient) {
            throw new common_1.ForbiddenException('Not authorized');
        }
        const validTransitions = this.getValidTransitions(request.status, isDeveloper);
        if (!validTransitions.includes(dto.status)) {
            throw new common_1.BadRequestException(`Invalid status transition from ${request.status} to ${dto.status}`);
        }
        const updated = await this.prisma.hiringRequest.update({
            where: { id },
            data: {
                status: dto.status,
                responseMessage: dto.responseMessage,
                respondedAt: ['ACCEPTED', 'REJECTED'].includes(dto.status) ? new Date() : undefined,
            },
            include: {
                client: { select: { id: true, name: true, email: true } },
                developer: { include: { user: { select: { id: true, name: true } } } },
            },
        });
        const notifyUserId = isDeveloper ? request.clientId : request.developer.userId;
        await this.notificationsService.create({
            userId: notifyUserId,
            type: 'MARKETPLACE',
            title: `Hiring Request ${dto.status}`,
            message: `Your hiring request "${request.title}" has been ${dto.status.toLowerCase()}`,
            link: `/admin/marketplace/requests/${id}`,
        });
        return updated;
    }
    getValidTransitions(current, isDeveloper) {
        const transitions = {
            PENDING: isDeveloper ? ['ACCEPTED', 'REJECTED'] : ['CANCELLED'],
            ACCEPTED: ['IN_PROGRESS', 'CANCELLED'],
            REJECTED: [],
            CANCELLED: [],
            IN_PROGRESS: ['COMPLETED', 'DISPUTED'],
            COMPLETED: [],
            DISPUTED: [],
        };
        return transitions[current] || [];
    }
};
exports.HiringRequestsService = HiringRequestsService;
exports.HiringRequestsService = HiringRequestsService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof notifications_service_1.NotificationsService !== "undefined" && notifications_service_1.NotificationsService) === "function" ? _b : Object])
], HiringRequestsService);


/***/ }),
/* 236 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b, _c, _d;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ProjectsService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const notifications_service_1 = __webpack_require__(226);
const system_config_service_1 = __webpack_require__(52);
const developers_service_1 = __webpack_require__(182);
let ProjectsService = class ProjectsService {
    constructor(prisma, notificationsService, developersService, systemConfig) {
        this.prisma = prisma;
        this.notificationsService = notificationsService;
        this.developersService = developersService;
        this.systemConfig = systemConfig;
    }
    async create(clientId, dto) {
        const developer = await this.prisma.developer.findUnique({ where: { id: dto.developerId } });
        if (!developer)
            throw new common_1.NotFoundException('Developer not found');
        if (developer.status !== 'ACTIVE')
            throw new common_1.BadRequestException('Developer is not active');
        const platformFeePercent = await this.systemConfig.getPlatformFeePercent();
        const platformFee = dto.totalBudget * (platformFeePercent / 100);
        const project = await this.prisma.project.create({
            data: {
                clientId,
                developerId: dto.developerId,
                title: dto.title,
                description: dto.description,
                requirements: dto.requirements,
                budgetType: dto.budgetType || 'fixed',
                totalBudget: dto.totalBudget,
                hourlyRate: dto.hourlyRate,
                deadline: dto.deadline ? new Date(dto.deadline) : null,
                milestones: dto.milestones || [],
                platformFeePercent,
                platformFee,
                status: 'DRAFT',
            },
            include: {
                client: { select: { id: true, name: true, email: true, avatar: true } },
                developer: { include: { user: { select: { id: true, name: true, avatar: true } } } },
            },
        });
        await this.notificationsService.create({
            userId: developer.userId,
            type: 'MARKETPLACE',
            title: 'New Project Created',
            message: `A new project "${dto.title}" has been created with you`,
            link: `/admin/marketplace/projects/${project.id}`,
        });
        return project;
    }
    async createFromHiringRequest(hiringRequestId) {
        const request = await this.prisma.hiringRequest.findUnique({
            where: { id: hiringRequestId },
            include: { developer: true },
        });
        if (!request)
            throw new common_1.NotFoundException('Hiring request not found');
        if (request.status !== 'ACCEPTED')
            throw new common_1.BadRequestException('Request must be accepted first');
        if (request.projectId)
            throw new common_1.BadRequestException('Project already created');
        const platformFeePercent = await this.systemConfig.getPlatformFeePercent();
        const platformFee = Number(request.budgetAmount) * (platformFeePercent / 100);
        const project = await this.prisma.project.create({
            data: {
                clientId: request.clientId,
                developerId: request.developerId,
                title: request.title,
                description: request.description,
                requirements: request.requirements,
                budgetType: request.budgetType,
                totalBudget: request.budgetAmount,
                hourlyRate: request.budgetType === 'hourly' ? request.budgetAmount : null,
                deadline: request.deadline,
                platformFeePercent,
                platformFee,
                status: 'ACTIVE',
                startDate: new Date(),
            },
        });
        await this.prisma.hiringRequest.update({
            where: { id: hiringRequestId },
            data: { projectId: project.id, status: 'IN_PROGRESS' },
        });
        return project;
    }
    async findById(id, userId, isAdmin = false) {
        const project = await this.prisma.project.findUnique({
            where: { id },
            include: {
                client: { select: { id: true, name: true, email: true, avatar: true } },
                developer: {
                    include: { user: { select: { id: true, name: true, email: true, avatar: true } } },
                },
                transactions: { orderBy: { createdAt: 'desc' } },
                messages: { orderBy: { createdAt: 'desc' }, take: 50 },
            },
        });
        if (!project)
            throw new common_1.NotFoundException('Project not found');
        if (!isAdmin && project.clientId !== userId && project.developer.userId !== userId) {
            throw new common_1.ForbiddenException('Not authorized');
        }
        return project;
    }
    async update(id, userId, dto, isAdmin = false) {
        const project = await this.prisma.project.findUnique({
            where: { id },
            include: { developer: true },
        });
        if (!project)
            throw new common_1.NotFoundException('Project not found');
        const isClient = project.clientId === userId;
        const isDeveloper = project.developer.userId === userId;
        if (!isAdmin && !isClient && !isDeveloper)
            throw new common_1.ForbiddenException('Not authorized');
        return this.prisma.project.update({
            where: { id },
            data: {
                title: dto.title,
                description: dto.description,
                requirements: dto.requirements,
                progress: dto.progress,
                status: dto.status,
                milestones: dto.milestones,
                deliverables: dto.deliverables,
            },
        });
    }
    async logHours(projectId, userId, dto) {
        const project = await this.prisma.project.findUnique({
            where: { id: projectId },
            include: { developer: true },
        });
        if (!project)
            throw new common_1.NotFoundException('Project not found');
        if (project.developer.userId !== userId)
            throw new common_1.ForbiddenException('Only developer can log hours');
        if (project.budgetType !== 'hourly')
            throw new common_1.BadRequestException('Not an hourly project');
        return this.prisma.project.update({
            where: { id: projectId },
            data: { hoursLogged: { increment: dto.hours } },
        });
    }
    async complete(projectId, userId, isAdmin = false) {
        const project = await this.prisma.project.findUnique({
            where: { id: projectId },
            include: { developer: true },
        });
        if (!project)
            throw new common_1.NotFoundException('Project not found');
        if (!isAdmin && project.clientId !== userId)
            throw new common_1.ForbiddenException('Only client can complete');
        if (project.status !== 'ACTIVE')
            throw new common_1.BadRequestException('Project is not active');
        return this.prisma.project.update({
            where: { id: projectId },
            data: { status: 'COMPLETED', completedAt: new Date(), progress: 100 },
        });
    }
    async addReview(projectId, userId, dto) {
        const project = await this.prisma.project.findUnique({
            where: { id: projectId },
            include: { developer: true },
        });
        if (!project)
            throw new common_1.NotFoundException('Project not found');
        if (project.status !== 'COMPLETED')
            throw new common_1.BadRequestException('Project must be completed');
        const isClient = project.clientId === userId;
        const isDeveloper = project.developer.userId === userId;
        if (!isClient && !isDeveloper)
            throw new common_1.ForbiddenException('Not authorized');
        const updateData = {};
        if (isClient) {
            updateData.clientRating = dto.rating;
            updateData.clientReview = dto.review;
            await this.developersService.updateStats(project.developerId, dto.rating, Number(project.amountPaid));
            await this.prisma.developerReview.create({
                data: {
                    developerId: project.developerId,
                    reviewerId: userId,
                    projectId,
                    overallRating: dto.rating,
                    content: dto.review,
                    isVerified: true,
                },
            });
        }
        else {
            updateData.developerRating = dto.rating;
            updateData.developerReview = dto.review;
        }
        return this.prisma.project.update({ where: { id: projectId }, data: updateData });
    }
    async findForUser(userId, role, filters) {
        const { status, page = 1, limit = 10 } = filters;
        const where = {};
        if (role === 'client')
            where.clientId = userId;
        else
            where.developer = { userId };
        if (status)
            where.status = status;
        const [projects, total] = await Promise.all([
            this.prisma.project.findMany({
                where,
                orderBy: { createdAt: 'desc' },
                skip: (page - 1) * limit,
                take: limit,
                include: {
                    client: { select: { id: true, name: true, avatar: true } },
                    developer: { include: { user: { select: { id: true, name: true, avatar: true } } } },
                },
            }),
            this.prisma.project.count({ where }),
        ]);
        return { projects, pagination: { page, limit, total, pages: Math.ceil(total / limit) } };
    }
    async sendMessage(projectId, senderId, content, attachments) {
        const project = await this.prisma.project.findUnique({
            where: { id: projectId },
            include: { developer: true },
        });
        if (!project)
            throw new common_1.NotFoundException('Project not found');
        const isClient = project.clientId === senderId;
        const isDeveloper = project.developer.userId === senderId;
        if (!isClient && !isDeveloper)
            throw new common_1.ForbiddenException('Not authorized');
        const message = await this.prisma.projectMessage.create({
            data: { projectId, senderId, content, attachments: attachments || [] },
        });
        const recipientId = isClient ? project.developer.userId : project.clientId;
        await this.notificationsService.create({
            userId: recipientId,
            type: 'MARKETPLACE',
            title: 'New Project Message',
            message: `New message in project "${project.title}"`,
            link: `/admin/marketplace/projects/${projectId}`,
        });
        return message;
    }
    async getStatistics() {
        const [total, active, completed, totalValue, avgValue] = await Promise.all([
            this.prisma.project.count(),
            this.prisma.project.count({ where: { status: 'ACTIVE' } }),
            this.prisma.project.count({ where: { status: 'COMPLETED' } }),
            this.prisma.project.aggregate({ _sum: { totalBudget: true } }),
            this.prisma.project.aggregate({ _avg: { totalBudget: true } }),
        ]);
        return {
            total,
            active,
            completed,
            totalValue: totalValue._sum.totalBudget || 0,
            avgValue: avgValue._avg.totalBudget || 0,
        };
    }
};
exports.ProjectsService = ProjectsService;
exports.ProjectsService = ProjectsService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof notifications_service_1.NotificationsService !== "undefined" && notifications_service_1.NotificationsService) === "function" ? _b : Object, typeof (_c = typeof developers_service_1.DevelopersService !== "undefined" && developers_service_1.DevelopersService) === "function" ? _c : Object, typeof (_d = typeof system_config_service_1.SystemConfigService !== "undefined" && system_config_service_1.SystemConfigService) === "function" ? _d : Object])
], ProjectsService);


/***/ }),
/* 237 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e, _f, _g, _h;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ProjectsController = void 0;
const common_1 = __webpack_require__(2);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const projects_service_1 = __webpack_require__(236);
const marketplace_payments_service_1 = __webpack_require__(238);
const dto_1 = __webpack_require__(229);
let ProjectsController = class ProjectsController {
    constructor(projectsService, paymentsService) {
        this.projectsService = projectsService;
        this.paymentsService = paymentsService;
    }
    async create(req, dto) {
        return this.projectsService.create(req.user.id, dto);
    }
    async getMyClientProjects(req, status, page, limit) {
        return this.projectsService.findForUser(req.user.id, 'client', {
            status,
            page: page ? parseInt(page) : 1,
            limit: limit ? parseInt(limit) : 10,
        });
    }
    async getMyDeveloperProjects(req, status, page, limit) {
        return this.projectsService.findForUser(req.user.id, 'developer', {
            status,
            page: page ? parseInt(page) : 1,
            limit: limit ? parseInt(limit) : 10,
        });
    }
    async getStatistics() {
        return this.projectsService.getStatistics();
    }
    async findById(req, id) {
        return this.projectsService.findById(id, req.user.id, req.user.role === 'ADMIN');
    }
    async update(req, id, dto) {
        return this.projectsService.update(id, req.user.id, dto, req.user.role === 'ADMIN');
    }
    async logHours(req, id, dto) {
        return this.projectsService.logHours(id, req.user.id, dto);
    }
    async complete(req, id) {
        return this.projectsService.complete(id, req.user.id, req.user.role === 'ADMIN');
    }
    async addReview(req, id, dto) {
        return this.projectsService.addReview(id, req.user.id, dto);
    }
    async sendMessage(req, id, body) {
        return this.projectsService.sendMessage(id, req.user.id, body.content, body.attachments);
    }
    async depositEscrow(req, id, body) {
        return this.paymentsService.createEscrowDeposit(id, req.user.id, body.amount, body.paymentMethodId);
    }
    async getTransactions(req, id) {
        await this.projectsService.findById(id, req.user.id, req.user.role === 'ADMIN');
        return this.paymentsService.getProjectTransactions(id);
    }
    async createDispute(req, id, body) {
        const project = await this.projectsService.findById(id, req.user.id, false);
        const initiatorType = project.clientId === req.user.id ? 'client' : 'developer';
        return this.paymentsService.createDispute(id, req.user.id, initiatorType, body.reason, body.description);
    }
    async releaseEscrow(req, id, amount) {
        return this.paymentsService.releaseEscrow(id, amount, req.user.id);
    }
};
exports.ProjectsController = ProjectsController;
__decorate([
    (0, common_1.Post)(),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, typeof (_c = typeof dto_1.CreateProjectDto !== "undefined" && dto_1.CreateProjectDto) === "function" ? _c : Object]),
    __metadata("design:returntype", Promise)
], ProjectsController.prototype, "create", null);
__decorate([
    (0, common_1.Get)('my/client'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Query)('status')),
    __param(2, (0, common_1.Query)('page')),
    __param(3, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, typeof (_d = typeof dto_1.ProjectStatus !== "undefined" && dto_1.ProjectStatus) === "function" ? _d : Object, String, String]),
    __metadata("design:returntype", Promise)
], ProjectsController.prototype, "getMyClientProjects", null);
__decorate([
    (0, common_1.Get)('my/developer'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Query)('status')),
    __param(2, (0, common_1.Query)('page')),
    __param(3, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, typeof (_e = typeof dto_1.ProjectStatus !== "undefined" && dto_1.ProjectStatus) === "function" ? _e : Object, String, String]),
    __metadata("design:returntype", Promise)
], ProjectsController.prototype, "getMyDeveloperProjects", null);
__decorate([
    (0, common_1.Get)('admin/statistics'),
    (0, common_1.UseGuards)(roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)('ADMIN'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], ProjectsController.prototype, "getStatistics", null);
__decorate([
    (0, common_1.Get)(':id'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String]),
    __metadata("design:returntype", Promise)
], ProjectsController.prototype, "findById", null);
__decorate([
    (0, common_1.Put)(':id'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __param(2, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, typeof (_f = typeof dto_1.UpdateProjectDto !== "undefined" && dto_1.UpdateProjectDto) === "function" ? _f : Object]),
    __metadata("design:returntype", Promise)
], ProjectsController.prototype, "update", null);
__decorate([
    (0, common_1.Post)(':id/log-hours'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __param(2, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, typeof (_g = typeof dto_1.LogHoursDto !== "undefined" && dto_1.LogHoursDto) === "function" ? _g : Object]),
    __metadata("design:returntype", Promise)
], ProjectsController.prototype, "logHours", null);
__decorate([
    (0, common_1.Post)(':id/complete'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String]),
    __metadata("design:returntype", Promise)
], ProjectsController.prototype, "complete", null);
__decorate([
    (0, common_1.Post)(':id/review'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __param(2, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, typeof (_h = typeof dto_1.CreateProjectReviewDto !== "undefined" && dto_1.CreateProjectReviewDto) === "function" ? _h : Object]),
    __metadata("design:returntype", Promise)
], ProjectsController.prototype, "addReview", null);
__decorate([
    (0, common_1.Post)(':id/messages'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __param(2, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, Object]),
    __metadata("design:returntype", Promise)
], ProjectsController.prototype, "sendMessage", null);
__decorate([
    (0, common_1.Post)(':id/escrow/deposit'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __param(2, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, Object]),
    __metadata("design:returntype", Promise)
], ProjectsController.prototype, "depositEscrow", null);
__decorate([
    (0, common_1.Get)(':id/transactions'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String]),
    __metadata("design:returntype", Promise)
], ProjectsController.prototype, "getTransactions", null);
__decorate([
    (0, common_1.Post)(':id/dispute'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __param(2, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, Object]),
    __metadata("design:returntype", Promise)
], ProjectsController.prototype, "createDispute", null);
__decorate([
    (0, common_1.Post)(':id/escrow/release'),
    (0, common_1.UseGuards)(roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)('ADMIN'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __param(2, (0, common_1.Body)('amount')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, Number]),
    __metadata("design:returntype", Promise)
], ProjectsController.prototype, "releaseEscrow", null);
exports.ProjectsController = ProjectsController = __decorate([
    (0, common_1.Controller)('api/marketplace/projects'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof projects_service_1.ProjectsService !== "undefined" && projects_service_1.ProjectsService) === "function" ? _a : Object, typeof (_b = typeof marketplace_payments_service_1.MarketplacePaymentsService !== "undefined" && marketplace_payments_service_1.MarketplacePaymentsService) === "function" ? _b : Object])
], ProjectsController);


/***/ }),
/* 238 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b, _c;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.MarketplacePaymentsService = void 0;
const common_1 = __webpack_require__(2);
const config_1 = __webpack_require__(13);
const prisma_service_1 = __webpack_require__(16);
const notifications_service_1 = __webpack_require__(226);
const stripe_1 = __webpack_require__(82);
let MarketplacePaymentsService = class MarketplacePaymentsService {
    constructor(prisma, configService, notificationsService) {
        this.prisma = prisma;
        this.configService = configService;
        this.notificationsService = notificationsService;
        const stripeKey = this.configService.get('STRIPE_SECRET_KEY');
        if (stripeKey) {
            this.stripe = new stripe_1.default(stripeKey);
        }
    }
    async createEscrowDeposit(projectId, clientId, amount, paymentMethodId) {
        const project = await this.prisma.project.findUnique({
            where: { id: projectId },
            include: { developer: true },
        });
        if (!project)
            throw new common_1.NotFoundException('Project not found');
        if (project.clientId !== clientId)
            throw new common_1.BadRequestException('Not authorized');
        let stripePaymentIntentId;
        if (this.stripe && paymentMethodId) {
            const paymentIntent = await this.stripe.paymentIntents.create({
                amount: Math.round(amount * 100),
                currency: 'usd',
                payment_method: paymentMethodId,
                confirm: true,
                metadata: { projectId, type: 'escrow_deposit' },
                automatic_payment_methods: { enabled: true, allow_redirects: 'never' },
            });
            stripePaymentIntentId = paymentIntent.id;
        }
        const transaction = await this.prisma.marketplaceTransaction.create({
            data: {
                projectId,
                type: 'ESCROW_DEPOSIT',
                amount,
                status: stripePaymentIntentId ? 'COMPLETED' : 'PENDING',
                stripePaymentIntentId,
                fromUserId: clientId,
                processedAt: stripePaymentIntentId ? new Date() : null,
            },
        });
        await this.prisma.project.update({
            where: { id: projectId },
            data: { amountInEscrow: { increment: amount } },
        });
        await this.notificationsService.create({
            userId: project.developer.userId,
            type: 'MARKETPLACE',
            title: 'Escrow Deposit Received',
            message: `$${amount} has been deposited to escrow for "${project.title}"`,
            link: `/admin/marketplace/projects/${projectId}`,
        });
        return transaction;
    }
    async releaseEscrow(projectId, amount, _adminId) {
        const project = await this.prisma.project.findUnique({
            where: { id: projectId },
            include: { developer: true },
        });
        if (!project)
            throw new common_1.NotFoundException('Project not found');
        if (Number(project.amountInEscrow) < amount) {
            throw new common_1.BadRequestException('Insufficient escrow balance');
        }
        const platformFee = amount * (project.platformFeePercent / 100);
        const developerAmount = amount - platformFee;
        const transaction = await this.prisma.marketplaceTransaction.create({
            data: {
                projectId,
                type: 'ESCROW_RELEASE',
                amount: developerAmount,
                status: 'COMPLETED',
                toUserId: project.developer.userId,
                processedAt: new Date(),
                metadata: { platformFee, originalAmount: amount },
            },
        });
        await this.prisma.marketplaceTransaction.create({
            data: {
                projectId,
                type: 'PLATFORM_FEE',
                amount: platformFee,
                status: 'COMPLETED',
                processedAt: new Date(),
            },
        });
        await this.prisma.project.update({
            where: { id: projectId },
            data: {
                amountInEscrow: { decrement: amount },
                amountPaid: { increment: developerAmount },
            },
        });
        await this.prisma.developer.update({
            where: { id: project.developerId },
            data: { totalEarnings: { increment: developerAmount } },
        });
        await this.notificationsService.create({
            userId: project.developer.userId,
            type: 'MARKETPLACE',
            title: 'Payment Released',
            message: `$${developerAmount.toFixed(2)} has been released to your account`,
            link: `/admin/marketplace/projects/${projectId}`,
        });
        return transaction;
    }
    async requestPayout(developerId, amount) {
        const developer = await this.prisma.developer.findUnique({ where: { id: developerId } });
        if (!developer)
            throw new common_1.NotFoundException('Developer not found');
        if (Number(developer.totalEarnings) < amount) {
            throw new common_1.BadRequestException('Insufficient balance');
        }
        const payout = await this.prisma.developerPayout.create({
            data: { developerId, amount, status: 'PENDING' },
        });
        return payout;
    }
    async processPayout(payoutId) {
        const payout = await this.prisma.developerPayout.findUnique({
            where: { id: payoutId },
            include: { developer: true },
        });
        if (!payout)
            throw new common_1.NotFoundException('Payout not found');
        if (payout.status !== 'PENDING')
            throw new common_1.BadRequestException('Payout already processed');
        let stripePayoutId;
        if (this.stripe && payout.developer.stripeConnectId) {
            try {
                const transfer = await this.stripe.transfers.create({
                    amount: Math.round(Number(payout.amount) * 100),
                    currency: 'usd',
                    destination: payout.developer.stripeConnectId,
                });
                stripePayoutId = transfer.id;
            }
            catch (error) {
                await this.prisma.developerPayout.update({
                    where: { id: payoutId },
                    data: { status: 'FAILED', failureReason: error.message },
                });
                throw error;
            }
        }
        await this.prisma.developerPayout.update({
            where: { id: payoutId },
            data: { status: 'COMPLETED', stripePayoutId, processedAt: new Date() },
        });
        await this.prisma.developer.update({
            where: { id: payout.developerId },
            data: { totalEarnings: { decrement: payout.amount } },
        });
        return payout;
    }
    async createDispute(projectId, initiatorId, initiatorType, reason, description) {
        const project = await this.prisma.project.findUnique({ where: { id: projectId } });
        if (!project)
            throw new common_1.NotFoundException('Project not found');
        const dispute = await this.prisma.projectDispute.create({
            data: { projectId, initiatorId, initiatorType, reason, description, status: 'OPEN' },
        });
        await this.prisma.project.update({
            where: { id: projectId },
            data: { status: 'ON_HOLD' },
        });
        return dispute;
    }
    async resolveDispute(disputeId, adminId, resolution, notes, refundAmount) {
        const dispute = await this.prisma.projectDispute.findUnique({
            where: { id: disputeId },
            include: { project: { include: { developer: true } } },
        });
        if (!dispute)
            throw new common_1.NotFoundException('Dispute not found');
        if (refundAmount && refundAmount > 0) {
            await this.prisma.marketplaceTransaction.create({
                data: {
                    projectId: dispute.projectId,
                    type: 'DISPUTE_RESOLUTION',
                    amount: refundAmount,
                    status: 'COMPLETED',
                    toUserId: resolution === 'RESOLVED_CLIENT'
                        ? dispute.project.clientId
                        : dispute.project.developer.userId,
                    processedAt: new Date(),
                },
            });
        }
        return this.prisma.projectDispute.update({
            where: { id: disputeId },
            data: {
                status: resolution,
                resolution: notes,
                resolvedById: adminId,
                resolvedAt: new Date(),
                refundAmount,
            },
        });
    }
    async getProjectTransactions(projectId) {
        return this.prisma.marketplaceTransaction.findMany({
            where: { projectId },
            orderBy: { createdAt: 'desc' },
        });
    }
    async getDeveloperPayouts(developerId) {
        return this.prisma.developerPayout.findMany({
            where: { developerId },
            orderBy: { createdAt: 'desc' },
        });
    }
    async getFinancialStatistics() {
        const [totalTransactions, totalEscrow, totalPaid, totalFees, pendingPayouts] = await Promise.all([
            this.prisma.marketplaceTransaction.count(),
            this.prisma.project.aggregate({ _sum: { amountInEscrow: true } }),
            this.prisma.project.aggregate({ _sum: { amountPaid: true } }),
            this.prisma.marketplaceTransaction.aggregate({
                where: { type: 'PLATFORM_FEE' },
                _sum: { amount: true },
            }),
            this.prisma.developerPayout.aggregate({
                where: { status: 'PENDING' },
                _sum: { amount: true },
                _count: true,
            }),
        ]);
        return {
            totalTransactions,
            totalEscrow: totalEscrow._sum.amountInEscrow || 0,
            totalPaid: totalPaid._sum.amountPaid || 0,
            totalFees: totalFees._sum.amount || 0,
            pendingPayouts: {
                count: pendingPayouts._count,
                amount: pendingPayouts._sum.amount || 0,
            },
        };
    }
};
exports.MarketplacePaymentsService = MarketplacePaymentsService;
exports.MarketplacePaymentsService = MarketplacePaymentsService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof config_1.ConfigService !== "undefined" && config_1.ConfigService) === "function" ? _b : Object, typeof (_c = typeof notifications_service_1.NotificationsService !== "undefined" && notifications_service_1.NotificationsService) === "function" ? _c : Object])
], MarketplacePaymentsService);


/***/ }),
/* 239 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PaymentsController = void 0;
const common_1 = __webpack_require__(2);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const marketplace_payments_service_1 = __webpack_require__(238);
const developers_service_1 = __webpack_require__(182);
const dto_1 = __webpack_require__(229);
let PaymentsController = class PaymentsController {
    constructor(paymentsService, developersService) {
        this.paymentsService = paymentsService;
        this.developersService = developersService;
    }
    async requestPayout(req, dto) {
        const developer = await this.developersService.findByUserId(req.user.id);
        if (!developer) {
            return { error: 'Developer profile not found' };
        }
        return this.paymentsService.requestPayout(developer.id, dto.amount);
    }
    async getMyPayouts(req) {
        const developer = await this.developersService.findByUserId(req.user.id);
        if (!developer) {
            return { payouts: [] };
        }
        return this.paymentsService.getDeveloperPayouts(developer.id);
    }
    async getFinancialStatistics() {
        return this.paymentsService.getFinancialStatistics();
    }
    async processPayout(id) {
        return this.paymentsService.processPayout(id);
    }
    async resolveDispute(req, id, dto) {
        return this.paymentsService.resolveDispute(id, req.user.id, dto.resolution, dto.resolutionNotes, dto.refundAmount);
    }
};
exports.PaymentsController = PaymentsController;
__decorate([
    (0, common_1.Post)('payout/request'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, typeof (_c = typeof dto_1.RequestPayoutDto !== "undefined" && dto_1.RequestPayoutDto) === "function" ? _c : Object]),
    __metadata("design:returntype", Promise)
], PaymentsController.prototype, "requestPayout", null);
__decorate([
    (0, common_1.Get)('payout/my'),
    __param(0, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], PaymentsController.prototype, "getMyPayouts", null);
__decorate([
    (0, common_1.Get)('admin/statistics'),
    (0, common_1.UseGuards)(roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)('ADMIN'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], PaymentsController.prototype, "getFinancialStatistics", null);
__decorate([
    (0, common_1.Post)('payout/:id/process'),
    (0, common_1.UseGuards)(roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)('ADMIN'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], PaymentsController.prototype, "processPayout", null);
__decorate([
    (0, common_1.Patch)('dispute/:id/resolve'),
    (0, common_1.UseGuards)(roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)('ADMIN'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __param(2, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, typeof (_d = typeof dto_1.ResolveDisputeDto !== "undefined" && dto_1.ResolveDisputeDto) === "function" ? _d : Object]),
    __metadata("design:returntype", Promise)
], PaymentsController.prototype, "resolveDispute", null);
exports.PaymentsController = PaymentsController = __decorate([
    (0, common_1.Controller)('api/marketplace/payments'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof marketplace_payments_service_1.MarketplacePaymentsService !== "undefined" && marketplace_payments_service_1.MarketplacePaymentsService) === "function" ? _a : Object, typeof (_b = typeof developers_service_1.DevelopersService !== "undefined" && developers_service_1.DevelopersService) === "function" ? _b : Object])
], PaymentsController);


/***/ }),
/* 240 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
__exportStar(__webpack_require__(182), exports);
__exportStar(__webpack_require__(235), exports);
__exportStar(__webpack_require__(236), exports);
__exportStar(__webpack_require__(238), exports);


/***/ }),
/* 241 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SecurityModule = void 0;
const common_1 = __webpack_require__(2);
const prisma_module_1 = __webpack_require__(15);
const users_module_1 = __webpack_require__(68);
const security_controller_1 = __webpack_require__(242);
const security_events_service_1 = __webpack_require__(243);
const ip_block_service_1 = __webpack_require__(244);
const two_factor_service_1 = __webpack_require__(245);
const file_integrity_service_1 = __webpack_require__(247);
const security_check_service_1 = __webpack_require__(248);
const rate_limit_service_1 = __webpack_require__(249);
const session_service_1 = __webpack_require__(250);
const password_policy_service_1 = __webpack_require__(251);
const ip_block_middleware_1 = __webpack_require__(254);
const rate_limit_middleware_1 = __webpack_require__(255);
let SecurityModule = class SecurityModule {
    configure(consumer) {
        consumer.apply(ip_block_middleware_1.IpBlockMiddleware).forRoutes('api/*');
        consumer.apply(rate_limit_middleware_1.RateLimitMiddleware).forRoutes('api/*');
    }
};
exports.SecurityModule = SecurityModule;
exports.SecurityModule = SecurityModule = __decorate([
    (0, common_1.Module)({
        imports: [prisma_module_1.PrismaModule, users_module_1.UsersModule],
        controllers: [security_controller_1.SecurityController],
        providers: [
            security_events_service_1.SecurityEventsService,
            ip_block_service_1.IpBlockService,
            two_factor_service_1.TwoFactorService,
            file_integrity_service_1.FileIntegrityService,
            security_check_service_1.SecurityCheckService,
            rate_limit_service_1.RateLimitService,
            session_service_1.SessionService,
            password_policy_service_1.PasswordPolicyService,
        ],
        exports: [
            security_events_service_1.SecurityEventsService,
            ip_block_service_1.IpBlockService,
            two_factor_service_1.TwoFactorService,
            rate_limit_service_1.RateLimitService,
            session_service_1.SessionService,
            password_policy_service_1.PasswordPolicyService,
        ],
    })
], SecurityModule);


/***/ }),
/* 242 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SecurityController = void 0;
const common_1 = __webpack_require__(2);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const current_user_decorator_1 = __webpack_require__(63);
const client_1 = __webpack_require__(17);
const express_1 = __webpack_require__(57);
const security_events_service_1 = __webpack_require__(243);
const ip_block_service_1 = __webpack_require__(244);
const two_factor_service_1 = __webpack_require__(245);
const file_integrity_service_1 = __webpack_require__(247);
const security_check_service_1 = __webpack_require__(248);
const rate_limit_service_1 = __webpack_require__(249);
const session_service_1 = __webpack_require__(250);
const password_policy_service_1 = __webpack_require__(251);
const security_dto_1 = __webpack_require__(253);
let SecurityController = class SecurityController {
    constructor(securityEvents, ipBlock, twoFactor, fileIntegrity, securityCheck, rateLimit, session, passwordPolicy) {
        this.securityEvents = securityEvents;
        this.ipBlock = ipBlock;
        this.twoFactor = twoFactor;
        this.fileIntegrity = fileIntegrity;
        this.securityCheck = securityCheck;
        this.rateLimit = rateLimit;
        this.session = session;
        this.passwordPolicy = passwordPolicy;
    }
    async getDashboard(user, req) {
        const isHttps = req.protocol === 'https';
        const [overview, securityStatus] = await Promise.all([
            this.securityCheck.getDashboardOverview(user.id),
            this.securityCheck.runSecurityChecks(user.id, isHttps),
        ]);
        return {
            ...overview,
            securityStatus,
        };
    }
    async runSecurityCheck(user, req) {
        const isHttps = req.protocol === 'https';
        return this.securityCheck.runSecurityChecks(user.id, isHttps);
    }
    async getEvents(filters) {
        const parsedFilters = {
            ...filters,
            startDate: filters.startDate ? new Date(filters.startDate) : undefined,
            endDate: filters.endDate ? new Date(filters.endDate) : undefined,
            limit: filters.limit ? Number(filters.limit) : undefined,
            offset: filters.offset ? Number(filters.offset) : undefined,
        };
        return this.securityEvents.getEvents(parsedFilters);
    }
    async getBlockedIps() {
        return this.ipBlock.getBlockedIps();
    }
    async blockIp(dto, user) {
        return this.ipBlock.blockIp(dto, user.id);
    }
    async unblockIp(ip, user) {
        return this.ipBlock.unblockIp(ip, user.id);
    }
    async generate2FASecret(user) {
        return this.twoFactor.generateSecret(user.id);
    }
    async enable2FA(dto, user, req) {
        const ip = req.ip;
        return this.twoFactor.enable2FA(user.id, dto.secret, dto.token, ip);
    }
    async disable2FA(dto, user, req) {
        const ip = req.ip;
        return this.twoFactor.disable2FA(user.id, dto.password, ip);
    }
    async verify2FA(dto, user) {
        const isValid = await this.twoFactor.verifyToken(user.id, dto.token);
        return { valid: isValid };
    }
    async generateBaseline(user) {
        const hashes = await this.fileIntegrity.generateBaseline(user.id);
        return {
            success: true,
            fileCount: hashes.length,
            message: 'Baseline generated successfully',
        };
    }
    async scanIntegrity(user) {
        return this.fileIntegrity.scanForChanges(user.id);
    }
    async getRateLimits() {
        return this.rateLimit.getAllConfigs();
    }
    async upsertRateLimit(data) {
        return this.rateLimit.upsertConfig(data);
    }
    async deleteRateLimit(endpoint) {
        return this.rateLimit.deleteConfig(decodeURIComponent(endpoint));
    }
    async getRateLimitViolations(limit) {
        return this.rateLimit.getViolations(limit ? parseInt(limit) : 100);
    }
    async getAllSessions(userId) {
        return this.session.getAllSessions(userId);
    }
    async getMySession(user) {
        return this.session.getUserSessions(user.id);
    }
    async forceLogout(sessionId, user) {
        return this.session.forceLogout(sessionId, user.id);
    }
    async forceLogoutAll(userId, user) {
        return this.session.forceLogoutAll(userId, user.id);
    }
    async cleanupSessions() {
        return this.session.cleanupExpiredSessions();
    }
    async getPasswordPolicy() {
        return this.passwordPolicy.getPolicy();
    }
    async updatePasswordPolicy(config) {
        return this.passwordPolicy.updatePolicy(config);
    }
    async validatePassword(data) {
        return this.passwordPolicy.validatePassword(data.password, data.userId);
    }
    async checkPasswordExpired(userId) {
        const expired = await this.passwordPolicy.isPasswordExpired(userId);
        return { expired };
    }
};
exports.SecurityController = SecurityController;
__decorate([
    (0, common_1.Get)('dashboard'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, current_user_decorator_1.CurrentUser)()),
    __param(1, (0, common_1.Req)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, typeof (_j = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _j : Object]),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "getDashboard", null);
__decorate([
    (0, common_1.Post)('check'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, current_user_decorator_1.CurrentUser)()),
    __param(1, (0, common_1.Req)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, typeof (_k = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _k : Object]),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "runSecurityCheck", null);
__decorate([
    (0, common_1.Get)('events'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Query)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_l = typeof security_dto_1.SecurityEventFiltersDto !== "undefined" && security_dto_1.SecurityEventFiltersDto) === "function" ? _l : Object]),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "getEvents", null);
__decorate([
    (0, common_1.Get)('blocked-ips'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "getBlockedIps", null);
__decorate([
    (0, common_1.Post)('blocked-ips'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, current_user_decorator_1.CurrentUser)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_m = typeof security_dto_1.BlockIpDto !== "undefined" && security_dto_1.BlockIpDto) === "function" ? _m : Object, Object]),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "blockIp", null);
__decorate([
    (0, common_1.Delete)('blocked-ips/:ip'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('ip')),
    __param(1, (0, current_user_decorator_1.CurrentUser)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "unblockIp", null);
__decorate([
    (0, common_1.Post)('2fa/generate'),
    __param(0, (0, current_user_decorator_1.CurrentUser)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "generate2FASecret", null);
__decorate([
    (0, common_1.Post)('2fa/enable'),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, current_user_decorator_1.CurrentUser)()),
    __param(2, (0, common_1.Req)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_o = typeof security_dto_1.Enable2FADto !== "undefined" && security_dto_1.Enable2FADto) === "function" ? _o : Object, Object, typeof (_p = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _p : Object]),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "enable2FA", null);
__decorate([
    (0, common_1.Post)('2fa/disable'),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, current_user_decorator_1.CurrentUser)()),
    __param(2, (0, common_1.Req)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_q = typeof security_dto_1.Disable2FADto !== "undefined" && security_dto_1.Disable2FADto) === "function" ? _q : Object, Object, typeof (_r = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _r : Object]),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "disable2FA", null);
__decorate([
    (0, common_1.Post)('2fa/verify'),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, current_user_decorator_1.CurrentUser)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_s = typeof security_dto_1.Verify2FADto !== "undefined" && security_dto_1.Verify2FADto) === "function" ? _s : Object, Object]),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "verify2FA", null);
__decorate([
    (0, common_1.Post)('integrity/baseline'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, current_user_decorator_1.CurrentUser)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "generateBaseline", null);
__decorate([
    (0, common_1.Post)('integrity/scan'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, current_user_decorator_1.CurrentUser)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "scanIntegrity", null);
__decorate([
    (0, common_1.Get)('rate-limits'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "getRateLimits", null);
__decorate([
    (0, common_1.Post)('rate-limits'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "upsertRateLimit", null);
__decorate([
    (0, common_1.Delete)('rate-limits/:endpoint'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('endpoint')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "deleteRateLimit", null);
__decorate([
    (0, common_1.Get)('rate-limits/violations'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "getRateLimitViolations", null);
__decorate([
    (0, common_1.Get)('sessions'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Query)('userId')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "getAllSessions", null);
__decorate([
    (0, common_1.Get)('sessions/me'),
    __param(0, (0, current_user_decorator_1.CurrentUser)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "getMySession", null);
__decorate([
    (0, common_1.Delete)('sessions/:sessionId'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('sessionId')),
    __param(1, (0, current_user_decorator_1.CurrentUser)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "forceLogout", null);
__decorate([
    (0, common_1.Delete)('sessions/user/:userId'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('userId')),
    __param(1, (0, current_user_decorator_1.CurrentUser)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "forceLogoutAll", null);
__decorate([
    (0, common_1.Post)('sessions/cleanup'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "cleanupSessions", null);
__decorate([
    (0, common_1.Get)('password-policy'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "getPasswordPolicy", null);
__decorate([
    (0, common_1.Post)('password-policy'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "updatePasswordPolicy", null);
__decorate([
    (0, common_1.Post)('password-policy/validate'),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "validatePassword", null);
__decorate([
    (0, common_1.Get)('password-policy/expired/:userId'),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('userId')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], SecurityController.prototype, "checkPasswordExpired", null);
exports.SecurityController = SecurityController = __decorate([
    (0, common_1.Controller)('api/security'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof security_events_service_1.SecurityEventsService !== "undefined" && security_events_service_1.SecurityEventsService) === "function" ? _a : Object, typeof (_b = typeof ip_block_service_1.IpBlockService !== "undefined" && ip_block_service_1.IpBlockService) === "function" ? _b : Object, typeof (_c = typeof two_factor_service_1.TwoFactorService !== "undefined" && two_factor_service_1.TwoFactorService) === "function" ? _c : Object, typeof (_d = typeof file_integrity_service_1.FileIntegrityService !== "undefined" && file_integrity_service_1.FileIntegrityService) === "function" ? _d : Object, typeof (_e = typeof security_check_service_1.SecurityCheckService !== "undefined" && security_check_service_1.SecurityCheckService) === "function" ? _e : Object, typeof (_f = typeof rate_limit_service_1.RateLimitService !== "undefined" && rate_limit_service_1.RateLimitService) === "function" ? _f : Object, typeof (_g = typeof session_service_1.SessionService !== "undefined" && session_service_1.SessionService) === "function" ? _g : Object, typeof (_h = typeof password_policy_service_1.PasswordPolicyService !== "undefined" && password_policy_service_1.PasswordPolicyService) === "function" ? _h : Object])
], SecurityController);


/***/ }),
/* 243 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SecurityEventsService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const client_1 = __webpack_require__(17);
let SecurityEventsService = class SecurityEventsService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async createEvent(data) {
        return this.prisma.securityEvent.create({
            data: {
                userId: data.userId,
                type: data.type,
                ip: data.ip,
                userAgent: data.userAgent,
                metadata: data.metadata || {},
            },
            include: {
                user: {
                    select: {
                        id: true,
                        email: true,
                        name: true,
                    },
                },
            },
        });
    }
    async getEvents(filters = {}) {
        const where = {};
        if (filters.userId)
            where.userId = filters.userId;
        if (filters.type)
            where.type = filters.type;
        if (filters.ip)
            where.ip = filters.ip;
        if (filters.startDate || filters.endDate) {
            where.createdAt = {};
            if (filters.startDate)
                where.createdAt.gte = filters.startDate;
            if (filters.endDate)
                where.createdAt.lte = filters.endDate;
        }
        const [events, total] = await Promise.all([
            this.prisma.securityEvent.findMany({
                where,
                include: {
                    user: {
                        select: {
                            id: true,
                            email: true,
                            name: true,
                        },
                    },
                },
                orderBy: { createdAt: 'desc' },
                take: filters.limit || 50,
                skip: filters.offset || 0,
            }),
            this.prisma.securityEvent.count({ where }),
        ]);
        return { events, total };
    }
    async getRecentFailedLogins(email, minutes = 15) {
        const user = await this.prisma.user.findUnique({ where: { email } });
        if (!user)
            return 0;
        const since = new Date(Date.now() - minutes * 60 * 1000);
        return this.prisma.securityEvent.count({
            where: {
                userId: user.id,
                type: client_1.SecurityEventType.FAILED_LOGIN,
                createdAt: { gte: since },
            },
        });
    }
    async getRecentFailedLoginsByIp(ip, minutes = 15) {
        const since = new Date(Date.now() - minutes * 60 * 1000);
        return this.prisma.securityEvent.count({
            where: {
                ip,
                type: client_1.SecurityEventType.FAILED_LOGIN,
                createdAt: { gte: since },
            },
        });
    }
    async getStatistics(hours = 24) {
        const since = new Date(Date.now() - hours * 60 * 60 * 1000);
        const [failedLogins, lockedAccounts, blockedRequests] = await Promise.all([
            this.prisma.securityEvent.count({
                where: {
                    type: client_1.SecurityEventType.FAILED_LOGIN,
                    createdAt: { gte: since },
                },
            }),
            this.prisma.user.count({
                where: {
                    accountLockedUntil: { gt: new Date() },
                },
            }),
            this.prisma.securityEvent.count({
                where: {
                    type: client_1.SecurityEventType.BLOCKED_REQUEST,
                    createdAt: { gte: since },
                },
            }),
        ]);
        return {
            failedLogins,
            lockedAccounts,
            blockedRequests,
        };
    }
};
exports.SecurityEventsService = SecurityEventsService;
exports.SecurityEventsService = SecurityEventsService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], SecurityEventsService);


/***/ }),
/* 244 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.IpBlockService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const security_events_service_1 = __webpack_require__(243);
const client_1 = __webpack_require__(17);
let IpBlockService = class IpBlockService {
    constructor(prisma, securityEvents) {
        this.prisma = prisma;
        this.securityEvents = securityEvents;
    }
    async isBlocked(ip) {
        const block = await this.prisma.blockedIP.findUnique({
            where: { ip },
        });
        if (!block)
            return false;
        if (block.expiresAt && block.expiresAt < new Date()) {
            await this.unblockIp(ip);
            return false;
        }
        return true;
    }
    async blockIp(data, userId) {
        const expiresAt = data.expiresAt ? new Date(data.expiresAt) : null;
        const blocked = await this.prisma.blockedIP.upsert({
            where: { ip: data.ip },
            create: {
                ip: data.ip,
                reason: data.reason,
                expiresAt,
            },
            update: {
                reason: data.reason,
                expiresAt,
            },
        });
        await this.securityEvents.createEvent({
            userId,
            type: client_1.SecurityEventType.IP_BLOCKED,
            ip: data.ip,
            metadata: {
                reason: data.reason,
                expiresAt: data.expiresAt,
            },
        });
        return blocked;
    }
    async unblockIp(ip, userId) {
        const deleted = await this.prisma.blockedIP.delete({
            where: { ip },
        });
        await this.securityEvents.createEvent({
            userId,
            type: client_1.SecurityEventType.IP_UNBLOCKED,
            ip,
        });
        return deleted;
    }
    async getBlockedIps() {
        const blocks = await this.prisma.blockedIP.findMany({
            orderBy: { createdAt: 'desc' },
        });
        const now = new Date();
        return blocks.filter((block) => !block.expiresAt || block.expiresAt > now);
    }
    async cleanupExpiredBlocks() {
        const deleted = await this.prisma.blockedIP.deleteMany({
            where: {
                expiresAt: {
                    lte: new Date(),
                },
            },
        });
        return deleted.count;
    }
};
exports.IpBlockService = IpBlockService;
exports.IpBlockService = IpBlockService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof security_events_service_1.SecurityEventsService !== "undefined" && security_events_service_1.SecurityEventsService) === "function" ? _b : Object])
], IpBlockService);


/***/ }),
/* 245 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.TwoFactorService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const security_events_service_1 = __webpack_require__(243);
const client_1 = __webpack_require__(17);
const speakeasy = __webpack_require__(47);
const QRCode = __webpack_require__(246);
const bcrypt = __webpack_require__(46);
const crypto = __webpack_require__(48);
let TwoFactorService = class TwoFactorService {
    constructor(prisma, securityEvents) {
        this.prisma = prisma;
        this.securityEvents = securityEvents;
    }
    async generateSecret(userId) {
        const user = await this.prisma.user.findUnique({
            where: { id: userId },
            select: { email: true, name: true },
        });
        if (!user) {
            throw new Error('User not found');
        }
        const secret = speakeasy.generateSecret({
            name: `WordPress Node (${user.email})`,
            issuer: 'WordPress Node CMS',
        });
        const qrCodeUrl = await QRCode.toDataURL(secret.otpauth_url);
        return {
            secret: secret.base32,
            qrCode: qrCodeUrl,
        };
    }
    async enable2FA(userId, secret, token, ip) {
        const isValid = speakeasy.totp.verify({
            secret,
            encoding: 'base32',
            token,
            window: 2,
        });
        if (!isValid) {
            throw new Error('Invalid verification code');
        }
        const recoveryCodes = this.generateRecoveryCodes(8);
        const hashedCodes = await Promise.all(recoveryCodes.map((code) => bcrypt.hash(code, 10)));
        await this.prisma.user.update({
            where: { id: userId },
            data: {
                twoFactorEnabled: true,
                twoFactorSecret: secret,
                recoveryCodes: hashedCodes,
            },
        });
        await this.securityEvents.createEvent({
            userId,
            type: client_1.SecurityEventType.TWO_FA_ENABLED,
            ip,
        });
        return { recoveryCodes };
    }
    async disable2FA(userId, password, ip) {
        const user = await this.prisma.user.findUnique({
            where: { id: userId },
        });
        if (!user) {
            throw new Error('User not found');
        }
        const isPasswordValid = await bcrypt.compare(password, user.password);
        if (!isPasswordValid) {
            throw new Error('Invalid password');
        }
        await this.prisma.user.update({
            where: { id: userId },
            data: {
                twoFactorEnabled: false,
                twoFactorSecret: null,
                recoveryCodes: null,
            },
        });
        await this.securityEvents.createEvent({
            userId,
            type: client_1.SecurityEventType.TWO_FA_DISABLED,
            ip,
        });
        return { success: true };
    }
    async verifyToken(userId, token) {
        const user = await this.prisma.user.findUnique({
            where: { id: userId },
            select: { twoFactorSecret: true, recoveryCodes: true },
        });
        if (!user || !user.twoFactorSecret) {
            return false;
        }
        const isValid = speakeasy.totp.verify({
            secret: user.twoFactorSecret,
            encoding: 'base32',
            token,
            window: 2,
        });
        if (isValid)
            return true;
        if (user.recoveryCodes && Array.isArray(user.recoveryCodes)) {
            for (const hashedCode of user.recoveryCodes) {
                const matches = await bcrypt.compare(token, hashedCode);
                if (matches) {
                    const updatedCodes = user.recoveryCodes.filter((code) => code !== hashedCode);
                    await this.prisma.user.update({
                        where: { id: userId },
                        data: { recoveryCodes: updatedCodes },
                    });
                    return true;
                }
            }
        }
        return false;
    }
    generateRecoveryCodes(count) {
        const codes = [];
        for (let i = 0; i < count; i++) {
            const code = crypto.randomBytes(4).toString('hex').toUpperCase();
            codes.push(code.match(/.{1,4}/g).join('-'));
        }
        return codes;
    }
};
exports.TwoFactorService = TwoFactorService;
exports.TwoFactorService = TwoFactorService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof security_events_service_1.SecurityEventsService !== "undefined" && security_events_service_1.SecurityEventsService) === "function" ? _b : Object])
], TwoFactorService);


/***/ }),
/* 246 */
/***/ ((module) => {

module.exports = require("qrcode");

/***/ }),
/* 247 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.FileIntegrityService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const security_events_service_1 = __webpack_require__(243);
const client_1 = __webpack_require__(17);
const crypto = __webpack_require__(48);
const fs = __webpack_require__(24);
const path = __webpack_require__(3);
let FileIntegrityService = class FileIntegrityService {
    constructor(prisma, securityEvents) {
        this.prisma = prisma;
        this.securityEvents = securityEvents;
        this.BASELINE_KEY = 'file_integrity_baseline';
        this.MONITORED_DIRS = ['src', 'prisma/schema.prisma'];
    }
    async hashFile(filePath) {
        const content = await fs.readFile(filePath);
        return crypto.createHash('sha256').update(content).digest('hex');
    }
    async scanDirectory(dirPath, baseDir = dirPath) {
        const hashes = [];
        try {
            const entries = await fs.readdir(dirPath, { withFileTypes: true });
            for (const entry of entries) {
                const fullPath = path.join(dirPath, entry.name);
                if (entry.name === 'node_modules' ||
                    entry.name === 'dist' ||
                    entry.name === 'uploads' ||
                    entry.name === '.git' ||
                    entry.name.startsWith('.')) {
                    continue;
                }
                if (entry.isDirectory()) {
                    const subHashes = await this.scanDirectory(fullPath, baseDir);
                    hashes.push(...subHashes);
                }
                else if (entry.isFile()) {
                    const hash = await this.hashFile(fullPath);
                    const relativePath = path.relative(baseDir, fullPath);
                    hashes.push({ path: relativePath, hash });
                }
            }
        }
        catch (error) {
            console.error(`Error scanning directory ${dirPath}:`, error);
        }
        return hashes;
    }
    async generateBaseline(userId) {
        const allHashes = [];
        for (const dir of this.MONITORED_DIRS) {
            const dirPath = path.join(process.cwd(), dir);
            try {
                const stats = await fs.stat(dirPath);
                if (stats.isDirectory()) {
                    const hashes = await this.scanDirectory(dirPath);
                    allHashes.push(...hashes);
                }
                else if (stats.isFile()) {
                    const hash = await this.hashFile(dirPath);
                    allHashes.push({ path: dir, hash });
                }
            }
            catch (error) {
                console.error(`Error processing ${dir}:`, error);
            }
        }
        await this.prisma.setting.upsert({
            where: { key: this.BASELINE_KEY },
            create: {
                key: this.BASELINE_KEY,
                value: allHashes,
                type: 'json',
                group: 'security',
            },
            update: {
                value: allHashes,
            },
        });
        if (userId) {
            await this.securityEvents.createEvent({
                userId,
                type: client_1.SecurityEventType.INTEGRITY_SCAN,
                metadata: {
                    action: 'baseline_generated',
                    fileCount: allHashes.length,
                },
            });
        }
        return allHashes;
    }
    async scanForChanges(userId) {
        const baselineSetting = await this.prisma.setting.findUnique({
            where: { key: this.BASELINE_KEY },
        });
        if (!baselineSetting) {
            throw new Error('No baseline found. Please generate a baseline first.');
        }
        const baseline = baselineSetting.value;
        const baselineMap = new Map(baseline.map((f) => [f.path, f.hash]));
        const current = await this.generateCurrentHashes();
        const currentMap = new Map(current.map((f) => [f.path, f.hash]));
        const result = {
            new: [],
            modified: [],
            deleted: [],
            scannedAt: new Date(),
        };
        for (const [filePath, hash] of currentMap) {
            if (!baselineMap.has(filePath)) {
                result.new.push(filePath);
            }
            else if (baselineMap.get(filePath) !== hash) {
                result.modified.push(filePath);
            }
        }
        for (const filePath of baselineMap.keys()) {
            if (!currentMap.has(filePath)) {
                result.deleted.push(filePath);
            }
        }
        if (userId) {
            await this.securityEvents.createEvent({
                userId,
                type: client_1.SecurityEventType.INTEGRITY_SCAN,
                metadata: {
                    action: 'scan_completed',
                    new: result.new.length,
                    modified: result.modified.length,
                    deleted: result.deleted.length,
                },
            });
        }
        return result;
    }
    async generateCurrentHashes() {
        const allHashes = [];
        for (const dir of this.MONITORED_DIRS) {
            const dirPath = path.join(process.cwd(), dir);
            try {
                const stats = await fs.stat(dirPath);
                if (stats.isDirectory()) {
                    const hashes = await this.scanDirectory(dirPath);
                    allHashes.push(...hashes);
                }
                else if (stats.isFile()) {
                    const hash = await this.hashFile(dirPath);
                    allHashes.push({ path: dir, hash });
                }
            }
            catch (_error) {
            }
        }
        return allHashes;
    }
};
exports.FileIntegrityService = FileIntegrityService;
exports.FileIntegrityService = FileIntegrityService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof security_events_service_1.SecurityEventsService !== "undefined" && security_events_service_1.SecurityEventsService) === "function" ? _b : Object])
], FileIntegrityService);


/***/ }),
/* 248 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SecurityCheckService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const security_events_service_1 = __webpack_require__(243);
const client_1 = __webpack_require__(17);
let SecurityCheckService = class SecurityCheckService {
    constructor(prisma, securityEvents) {
        this.prisma = prisma;
        this.securityEvents = securityEvents;
    }
    async runSecurityChecks(userId, isHttps = false) {
        const checks = [];
        checks.push({
            name: 'HTTPS',
            status: isHttps ? 'pass' : 'fail',
            message: isHttps ? 'HTTPS is enabled' : 'HTTPS is not enabled',
            details: isHttps
                ? 'Your site is using secure HTTPS connections'
                : 'Enable HTTPS to encrypt data in transit',
        });
        const admins = await this.prisma.user.findMany({
            where: { role: client_1.UserRole.ADMIN },
            select: { id: true, twoFactorEnabled: true },
        });
        const adminsWithout2FA = admins.filter((a) => !a.twoFactorEnabled).length;
        const all2FAEnabled = adminsWithout2FA === 0 && admins.length > 0;
        checks.push({
            name: '2FA for Admins',
            status: all2FAEnabled ? 'pass' : adminsWithout2FA === admins.length ? 'fail' : 'warning',
            message: all2FAEnabled
                ? 'All admin accounts have 2FA enabled'
                : `${adminsWithout2FA} of ${admins.length} admin accounts don't have 2FA`,
            details: 'Two-factor authentication adds an extra layer of security',
        });
        const defaultAdmin = await this.prisma.user.findFirst({
            where: {
                email: 'admin@example.com',
                role: client_1.UserRole.ADMIN,
            },
        });
        checks.push({
            name: 'Default Admin Account',
            status: defaultAdmin ? 'fail' : 'pass',
            message: defaultAdmin
                ? 'Default admin account still exists'
                : 'No default admin account found',
            details: defaultAdmin
                ? 'Change the default admin email to something unique'
                : 'Good! Default credentials have been changed',
        });
        const recentFailedLogins = await this.securityEvents.getStatistics(24);
        checks.push({
            name: 'Failed Login Attempts',
            status: recentFailedLogins.failedLogins > 50 ? 'warning' : 'pass',
            message: `${recentFailedLogins.failedLogins} failed login attempts in the last 24 hours`,
            details: recentFailedLogins.failedLogins > 50
                ? 'High number of failed logins detected. Monitor for brute force attacks.'
                : 'Normal level of failed login attempts',
        });
        checks.push({
            name: 'Locked Accounts',
            status: recentFailedLogins.lockedAccounts > 0 ? 'warning' : 'pass',
            message: `${recentFailedLogins.lockedAccounts} accounts currently locked`,
            details: recentFailedLogins.lockedAccounts > 0
                ? 'Some accounts are locked due to failed login attempts'
                : 'No accounts are currently locked',
        });
        checks.push({
            name: 'Security Headers',
            status: 'pass',
            message: 'Helmet middleware is configured',
            details: 'Basic security headers are being set by Helmet',
        });
        const failCount = checks.filter((c) => c.status === 'fail').length;
        const warningCount = checks.filter((c) => c.status === 'warning').length;
        let riskLevel;
        if (failCount >= 2) {
            riskLevel = 'high';
        }
        else if (failCount === 1 || warningCount >= 2) {
            riskLevel = 'medium';
        }
        else {
            riskLevel = 'low';
        }
        if (userId) {
            await this.securityEvents.createEvent({
                userId,
                type: client_1.SecurityEventType.SECURITY_CHECK,
                metadata: {
                    riskLevel,
                    failCount,
                    warningCount,
                },
            });
        }
        return {
            riskLevel,
            checks,
            summary: {
                twoFactorEnabled: all2FAEnabled,
                httpsEnabled: isHttps,
                securityHeadersOk: true,
                defaultAdminExists: !!defaultAdmin,
            },
        };
    }
    async getDashboardOverview(userId) {
        const [stats24h, stats7d, blockedIps, lastLogin] = await Promise.all([
            this.securityEvents.getStatistics(24),
            this.securityEvents.getStatistics(24 * 7),
            this.prisma.blockedIP.count(),
            userId ? this.getLastLogin(userId) : null,
        ]);
        return {
            failedLogins24h: stats24h.failedLogins,
            failedLogins7d: stats7d.failedLogins,
            lockedAccounts: stats24h.lockedAccounts,
            blockedIps,
            lastLogin,
        };
    }
    async getLastLogin(userId) {
        const lastLogin = await this.prisma.securityEvent.findFirst({
            where: {
                userId,
                type: client_1.SecurityEventType.SUCCESS_LOGIN,
            },
            orderBy: { createdAt: 'desc' },
            select: {
                createdAt: true,
                ip: true,
            },
        });
        return lastLogin;
    }
};
exports.SecurityCheckService = SecurityCheckService;
exports.SecurityCheckService = SecurityCheckService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof security_events_service_1.SecurityEventsService !== "undefined" && security_events_service_1.SecurityEventsService) === "function" ? _b : Object])
], SecurityCheckService);


/***/ }),
/* 249 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var RateLimitService_1;
var _a, _b, _c, _d;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.RateLimitService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const security_events_service_1 = __webpack_require__(243);
const ip_block_service_1 = __webpack_require__(244);
const redis_service_1 = __webpack_require__(19);
let RateLimitService = RateLimitService_1 = class RateLimitService {
    constructor(prisma, securityEvents, ipBlock, redis) {
        this.prisma = prisma;
        this.securityEvents = securityEvents;
        this.ipBlock = ipBlock;
        this.redis = redis;
        this.logger = new common_1.Logger(RateLimitService_1.name);
        this.requestStore = new Map();
        this.cleanupInterval = setInterval(() => this.cleanupOldRequests(), 60000);
    }
    async checkRateLimit(ip, endpoint) {
        const config = await this.getConfig(endpoint);
        if (!config || !config.enabled) {
            return { allowed: true };
        }
        if (this.redis?.isAvailable()) {
            return this.checkRateLimitRedis(ip, endpoint, config);
        }
        return this.checkRateLimitMemory(ip, endpoint, config);
    }
    async checkRateLimitRedis(ip, endpoint, config) {
        const key = `ratelimit:${ip}:${endpoint}`;
        const windowSeconds = Math.ceil(config.windowMs / 1000);
        try {
            const count = await this.redis.incr(key);
            if (count === 1) {
                await this.redis.expire(key, windowSeconds);
            }
            if (count > config.maxRequests) {
                await this.logViolation(ip, endpoint, count, config.maxRequests);
                if (config.blockDuration) {
                    const blockData = {
                        ip,
                        reason: `Rate limit exceeded on ${endpoint}`,
                        expiresAt: new Date(Date.now() + config.blockDuration * 60000).toISOString(),
                    };
                    await this.ipBlock.blockIp(blockData);
                }
                const ttl = await this.redis.ttl(key);
                return { allowed: false, retryAfter: ttl > 0 ? ttl : windowSeconds };
            }
            return { allowed: true };
        }
        catch (error) {
            this.logger.warn(`Redis rate limit check failed, falling back to memory: ${error.message}`);
            return this.checkRateLimitMemory(ip, endpoint, config);
        }
    }
    async checkRateLimitMemory(ip, endpoint, config) {
        if (!this.requestStore.has(ip)) {
            this.requestStore.set(ip, new Map());
        }
        const ipStore = this.requestStore.get(ip);
        if (!ipStore.has(endpoint)) {
            ipStore.set(endpoint, []);
        }
        const requests = ipStore.get(endpoint);
        const now = Date.now();
        requests.push(now);
        const windowStart = now - config.windowMs;
        const recentRequests = requests.filter((time) => time > windowStart);
        ipStore.set(endpoint, recentRequests);
        if (recentRequests.length > config.maxRequests) {
            await this.logViolation(ip, endpoint, recentRequests.length, config.maxRequests);
            if (config.blockDuration) {
                const blockData = {
                    ip,
                    reason: `Rate limit exceeded on ${endpoint}`,
                    expiresAt: new Date(Date.now() + config.blockDuration * 60000).toISOString(),
                };
                await this.ipBlock.blockIp(blockData);
            }
            const retryAfter = Math.ceil(config.windowMs / 1000);
            return { allowed: false, retryAfter };
        }
        return { allowed: true };
    }
    async getConfig(endpoint) {
        let config = await this.prisma.rateLimitConfig.findUnique({
            where: { endpoint },
        });
        if (!config) {
            config = await this.prisma.rateLimitConfig.findUnique({
                where: { endpoint: 'global' },
            });
        }
        return config;
    }
    async getAllConfigs() {
        return this.prisma.rateLimitConfig.findMany({
            orderBy: { endpoint: 'asc' },
        });
    }
    async upsertConfig(data) {
        return this.prisma.rateLimitConfig.upsert({
            where: { endpoint: data.endpoint },
            create: data,
            update: data,
        });
    }
    async deleteConfig(endpoint) {
        return this.prisma.rateLimitConfig.delete({
            where: { endpoint },
        });
    }
    async getViolations(limit = 100) {
        return this.prisma.rateLimitViolation.findMany({
            take: limit,
            orderBy: { createdAt: 'desc' },
        });
    }
    async logViolation(ip, endpoint, requests, limit) {
        await this.prisma.rateLimitViolation.create({
            data: {
                ip,
                endpoint,
                requests,
                limit,
            },
        });
    }
    cleanupOldRequests() {
        const now = Date.now();
        const maxAge = 3600000;
        for (const [ip, ipStore] of this.requestStore.entries()) {
            for (const [endpoint, requests] of ipStore.entries()) {
                const recentRequests = requests.filter((time) => now - time < maxAge);
                if (recentRequests.length === 0) {
                    ipStore.delete(endpoint);
                }
                else {
                    ipStore.set(endpoint, recentRequests);
                }
            }
            if (ipStore.size === 0) {
                this.requestStore.delete(ip);
            }
        }
    }
};
exports.RateLimitService = RateLimitService;
exports.RateLimitService = RateLimitService = RateLimitService_1 = __decorate([
    (0, common_1.Injectable)(),
    __param(3, (0, common_1.Optional)()),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof security_events_service_1.SecurityEventsService !== "undefined" && security_events_service_1.SecurityEventsService) === "function" ? _b : Object, typeof (_c = typeof ip_block_service_1.IpBlockService !== "undefined" && ip_block_service_1.IpBlockService) === "function" ? _c : Object, typeof (_d = typeof redis_service_1.RedisService !== "undefined" && redis_service_1.RedisService) === "function" ? _d : Object])
], RateLimitService);


/***/ }),
/* 250 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SessionService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const security_events_service_1 = __webpack_require__(243);
const client_1 = __webpack_require__(17);
let SessionService = class SessionService {
    constructor(prisma, securityEvents) {
        this.prisma = prisma;
        this.securityEvents = securityEvents;
    }
    async getAllSessions(userId) {
        const where = userId ? { userId } : {};
        const sessions = await this.prisma.session.findMany({
            where: {
                ...where,
                expiresAt: {
                    gt: new Date(),
                },
            },
            include: {
                user: {
                    select: {
                        id: true,
                        email: true,
                        name: true,
                        role: true,
                    },
                },
            },
            orderBy: {
                lastActivity: 'desc',
            },
        });
        return sessions.map((session) => ({
            id: session.id,
            userId: session.userId,
            user: session.user,
            ip: session.ip,
            userAgent: session.userAgent,
            lastActivity: session.lastActivity,
            createdAt: session.createdAt,
            expiresAt: session.expiresAt,
        }));
    }
    async getUserSessions(userId) {
        return this.getAllSessions(userId);
    }
    async forceLogout(sessionId, adminUserId) {
        const session = await this.prisma.session.findUnique({
            where: { id: sessionId },
            include: { user: true },
        });
        if (!session) {
            throw new Error('Session not found');
        }
        await this.prisma.session.delete({
            where: { id: sessionId },
        });
        await this.securityEvents.createEvent({
            userId: session.userId,
            type: client_1.SecurityEventType.LOGOUT,
            ip: session.ip || undefined,
            metadata: {
                sessionId,
                forcedBy: adminUserId,
                reason: 'Force logout by administrator',
            },
        });
        return { success: true, message: 'Session terminated' };
    }
    async forceLogoutAll(userId, adminUserId) {
        const sessions = await this.prisma.session.findMany({
            where: { userId },
        });
        await this.prisma.session.deleteMany({
            where: { userId },
        });
        await this.securityEvents.createEvent({
            userId,
            type: client_1.SecurityEventType.LOGOUT,
            metadata: {
                forcedBy: adminUserId,
                reason: 'Force logout all sessions by administrator',
                sessionCount: sessions.length,
            },
        });
        return {
            success: true,
            message: `${sessions.length} session(s) terminated`,
            count: sessions.length,
        };
    }
    async updateActivity(sessionId, ip, userAgent) {
        return this.prisma.session.update({
            where: { id: sessionId },
            data: {
                lastActivity: new Date(),
                ip: ip || undefined,
                userAgent: userAgent || undefined,
            },
        });
    }
    async cleanupExpiredSessions() {
        const result = await this.prisma.session.deleteMany({
            where: {
                expiresAt: {
                    lt: new Date(),
                },
            },
        });
        return { deleted: result.count };
    }
};
exports.SessionService = SessionService;
exports.SessionService = SessionService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof security_events_service_1.SecurityEventsService !== "undefined" && security_events_service_1.SecurityEventsService) === "function" ? _b : Object])
], SessionService);


/***/ }),
/* 251 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PasswordPolicyService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const bcrypt = __webpack_require__(46);
const crypto = __webpack_require__(48);
const https = __webpack_require__(252);
let PasswordPolicyService = class PasswordPolicyService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async getPolicy() {
        const policy = await this.prisma.passwordPolicy.findFirst({
            orderBy: { createdAt: 'desc' },
        });
        return policy
            ? {
                minLength: policy.minLength,
                requireUppercase: policy.requireUppercase,
                requireLowercase: policy.requireLowercase,
                requireNumbers: policy.requireNumbers,
                requireSpecialChars: policy.requireSpecialChars,
                expirationDays: policy.expirationDays,
                preventReuse: policy.preventReuse,
                checkBreachedPasswords: policy.checkBreachedPasswords,
                enabled: policy.enabled,
            }
            : null;
    }
    async updatePolicy(config) {
        await this.prisma.passwordPolicy.deleteMany({});
        const policy = await this.prisma.passwordPolicy.create({
            data: {
                minLength: config.minLength ?? 8,
                requireUppercase: config.requireUppercase ?? true,
                requireLowercase: config.requireLowercase ?? true,
                requireNumbers: config.requireNumbers ?? true,
                requireSpecialChars: config.requireSpecialChars ?? true,
                expirationDays: config.expirationDays ?? null,
                preventReuse: config.preventReuse ?? 5,
                checkBreachedPasswords: config.checkBreachedPasswords ?? false,
                enabled: config.enabled ?? true,
            },
        });
        return {
            minLength: policy.minLength,
            requireUppercase: policy.requireUppercase,
            requireLowercase: policy.requireLowercase,
            requireNumbers: policy.requireNumbers,
            requireSpecialChars: policy.requireSpecialChars,
            expirationDays: policy.expirationDays,
            preventReuse: policy.preventReuse,
            checkBreachedPasswords: policy.checkBreachedPasswords,
            enabled: policy.enabled,
        };
    }
    async validatePassword(password, userId) {
        const policy = await this.getPolicy();
        const errors = [];
        if (!policy || !policy.enabled) {
            return { valid: true, errors: [] };
        }
        if (password.length < policy.minLength) {
            errors.push(`Password must be at least ${policy.minLength} characters long`);
        }
        if (policy.requireUppercase && !/[A-Z]/.test(password)) {
            errors.push('Password must contain at least one uppercase letter');
        }
        if (policy.requireLowercase && !/[a-z]/.test(password)) {
            errors.push('Password must contain at least one lowercase letter');
        }
        if (policy.requireNumbers && !/[0-9]/.test(password)) {
            errors.push('Password must contain at least one number');
        }
        if (policy.requireSpecialChars && !/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(password)) {
            errors.push('Password must contain at least one special character');
        }
        if (userId && policy.preventReuse > 0) {
            const isReused = await this.checkPasswordReuse(userId, password, policy.preventReuse);
            if (isReused) {
                errors.push(`Password cannot be one of your last ${policy.preventReuse} passwords`);
            }
        }
        if (policy.checkBreachedPasswords) {
            const isBreached = await this.checkBreachedPassword(password);
            if (isBreached) {
                errors.push('This password has been found in a data breach. Please choose a different password');
            }
        }
        return {
            valid: errors.length === 0,
            errors,
        };
    }
    async checkPasswordReuse(userId, password, count) {
        const history = await this.prisma.passwordHistory.findMany({
            where: { userId },
            orderBy: { createdAt: 'desc' },
            take: count,
        });
        for (const entry of history) {
            const matches = await bcrypt.compare(password, entry.password);
            if (matches) {
                return true;
            }
        }
        return false;
    }
    async checkBreachedPassword(password) {
        try {
            const sha1 = crypto.createHash('sha1').update(password).digest('hex').toUpperCase();
            const prefix = sha1.substring(0, 5);
            const suffix = sha1.substring(5);
            return new Promise((resolve) => {
                const req = https.get(`https://api.pwnedpasswords.com/range/${prefix}`, {
                    timeout: 5000,
                }, (res) => {
                    let data = '';
                    res.on('data', (chunk) => {
                        data += chunk;
                    });
                    res.on('end', () => {
                        const hashes = data.split('\n');
                        for (const hash of hashes) {
                            const [hashSuffix] = hash.split(':');
                            if (hashSuffix === suffix) {
                                resolve(true);
                                return;
                            }
                        }
                        resolve(false);
                    });
                });
                req.on('error', () => {
                    resolve(false);
                });
                req.on('timeout', () => {
                    req.destroy();
                    resolve(false);
                });
            });
        }
        catch (error) {
            console.error('Failed to check breached passwords:', error);
            return false;
        }
    }
    async addToHistory(userId, hashedPassword) {
        await this.prisma.passwordHistory.create({
            data: {
                userId,
                password: hashedPassword,
            },
        });
        const policy = await this.getPolicy();
        if (policy && policy.preventReuse > 0) {
            const allHistory = await this.prisma.passwordHistory.findMany({
                where: { userId },
                orderBy: { createdAt: 'desc' },
            });
            const toDelete = allHistory.slice(policy.preventReuse);
            if (toDelete.length > 0) {
                await this.prisma.passwordHistory.deleteMany({
                    where: {
                        id: { in: toDelete.map((h) => h.id) },
                    },
                });
            }
        }
    }
    async isPasswordExpired(userId) {
        const policy = await this.getPolicy();
        if (!policy || !policy.enabled || !policy.expirationDays) {
            return false;
        }
        const latestPassword = await this.prisma.passwordHistory.findFirst({
            where: { userId },
            orderBy: { createdAt: 'desc' },
        });
        if (!latestPassword) {
            return false;
        }
        const expirationDate = new Date(latestPassword.createdAt);
        expirationDate.setDate(expirationDate.getDate() + policy.expirationDays);
        return new Date() > expirationDate;
    }
};
exports.PasswordPolicyService = PasswordPolicyService;
exports.PasswordPolicyService = PasswordPolicyService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], PasswordPolicyService);


/***/ }),
/* 252 */
/***/ ((module) => {

module.exports = require("https");

/***/ }),
/* 253 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SecurityEventFiltersDto = exports.Disable2FADto = exports.Verify2FADto = exports.Enable2FADto = exports.UnblockIpDto = exports.BlockIpDto = void 0;
const class_validator_1 = __webpack_require__(59);
const client_1 = __webpack_require__(17);
class BlockIpDto {
}
exports.BlockIpDto = BlockIpDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], BlockIpDto.prototype, "ip", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], BlockIpDto.prototype, "reason", void 0);
__decorate([
    (0, class_validator_1.IsDateString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], BlockIpDto.prototype, "expiresAt", void 0);
class UnblockIpDto {
}
exports.UnblockIpDto = UnblockIpDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], UnblockIpDto.prototype, "ip", void 0);
class Enable2FADto {
}
exports.Enable2FADto = Enable2FADto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], Enable2FADto.prototype, "secret", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], Enable2FADto.prototype, "token", void 0);
class Verify2FADto {
}
exports.Verify2FADto = Verify2FADto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], Verify2FADto.prototype, "token", void 0);
class Disable2FADto {
}
exports.Disable2FADto = Disable2FADto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsNotEmpty)(),
    __metadata("design:type", String)
], Disable2FADto.prototype, "password", void 0);
class SecurityEventFiltersDto {
}
exports.SecurityEventFiltersDto = SecurityEventFiltersDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], SecurityEventFiltersDto.prototype, "userId", void 0);
__decorate([
    (0, class_validator_1.IsEnum)(client_1.SecurityEventType),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", typeof (_a = typeof client_1.SecurityEventType !== "undefined" && client_1.SecurityEventType) === "function" ? _a : Object)
], SecurityEventFiltersDto.prototype, "type", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], SecurityEventFiltersDto.prototype, "ip", void 0);
__decorate([
    (0, class_validator_1.IsDateString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], SecurityEventFiltersDto.prototype, "startDate", void 0);
__decorate([
    (0, class_validator_1.IsDateString)(),
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", String)
], SecurityEventFiltersDto.prototype, "endDate", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Number)
], SecurityEventFiltersDto.prototype, "limit", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    __metadata("design:type", Number)
], SecurityEventFiltersDto.prototype, "offset", void 0);


/***/ }),
/* 254 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.IpBlockMiddleware = void 0;
const common_1 = __webpack_require__(2);
const ip_block_service_1 = __webpack_require__(244);
const security_events_service_1 = __webpack_require__(243);
const client_1 = __webpack_require__(17);
let IpBlockMiddleware = class IpBlockMiddleware {
    constructor(ipBlockService, securityEvents) {
        this.ipBlockService = ipBlockService;
        this.securityEvents = securityEvents;
    }
    async use(req, res, next) {
        const ip = this.getClientIp(req);
        if (!ip) {
            return next();
        }
        const isBlocked = await this.ipBlockService.isBlocked(ip);
        if (isBlocked) {
            await this.securityEvents.createEvent({
                type: client_1.SecurityEventType.BLOCKED_REQUEST,
                ip,
                userAgent: req.headers['user-agent'],
                metadata: {
                    path: req.path,
                    method: req.method,
                },
            });
            throw new common_1.ForbiddenException('Access denied. Your IP address has been blocked.');
        }
        next();
    }
    getClientIp(req) {
        const forwarded = req.headers['x-forwarded-for'];
        if (forwarded) {
            const ips = forwarded.split(',');
            return ips[0].trim();
        }
        const realIp = req.headers['x-real-ip'];
        if (realIp) {
            return realIp;
        }
        return req.ip;
    }
};
exports.IpBlockMiddleware = IpBlockMiddleware;
exports.IpBlockMiddleware = IpBlockMiddleware = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof ip_block_service_1.IpBlockService !== "undefined" && ip_block_service_1.IpBlockService) === "function" ? _a : Object, typeof (_b = typeof security_events_service_1.SecurityEventsService !== "undefined" && security_events_service_1.SecurityEventsService) === "function" ? _b : Object])
], IpBlockMiddleware);


/***/ }),
/* 255 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.RateLimitMiddleware = void 0;
const common_1 = __webpack_require__(2);
const rate_limit_service_1 = __webpack_require__(249);
let RateLimitMiddleware = class RateLimitMiddleware {
    constructor(rateLimitService) {
        this.rateLimitService = rateLimitService;
    }
    async use(req, res, next) {
        const ip = req.headers['x-forwarded-for']?.split(',')[0]?.trim() ||
            req.headers['x-real-ip'] ||
            req.ip ||
            'unknown';
        const endpoint = req.path;
        const result = await this.rateLimitService.checkRateLimit(ip, endpoint);
        if (!result.allowed) {
            res.setHeader('X-RateLimit-Limit', '0');
            res.setHeader('X-RateLimit-Remaining', '0');
            if (result.retryAfter) {
                res.setHeader('Retry-After', result.retryAfter.toString());
            }
            throw new common_1.HttpException({
                statusCode: common_1.HttpStatus.TOO_MANY_REQUESTS,
                message: 'Too many requests, please try again later',
                retryAfter: result.retryAfter,
            }, common_1.HttpStatus.TOO_MANY_REQUESTS);
        }
        next();
    }
};
exports.RateLimitMiddleware = RateLimitMiddleware;
exports.RateLimitMiddleware = RateLimitMiddleware = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof rate_limit_service_1.RateLimitService !== "undefined" && rate_limit_service_1.RateLimitService) === "function" ? _a : Object])
], RateLimitMiddleware);


/***/ }),
/* 256 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.GroupsModule = void 0;
const common_1 = __webpack_require__(2);
const jwt_1 = __webpack_require__(43);
const config_1 = __webpack_require__(13);
const groups_controller_1 = __webpack_require__(257);
const groups_service_1 = __webpack_require__(258);
const groups_gateway_1 = __webpack_require__(263);
const prisma_module_1 = __webpack_require__(15);
const group_member_guard_1 = __webpack_require__(261);
const group_owner_guard_1 = __webpack_require__(262);
let GroupsModule = class GroupsModule {
};
exports.GroupsModule = GroupsModule;
exports.GroupsModule = GroupsModule = __decorate([
    (0, common_1.Module)({
        imports: [
            prisma_module_1.PrismaModule,
            jwt_1.JwtModule.registerAsync({
                imports: [config_1.ConfigModule],
                useFactory: async (configService) => ({
                    secret: configService.get('JWT_SECRET') || 'default-secret-change-in-production',
                    signOptions: {
                        expiresIn: 604800,
                    },
                }),
                inject: [config_1.ConfigService],
            }),
        ],
        controllers: [groups_controller_1.GroupsController],
        providers: [groups_service_1.GroupsService, groups_gateway_1.GroupsGateway, group_member_guard_1.GroupMemberGuard, group_owner_guard_1.GroupOwnerGuard],
        exports: [groups_service_1.GroupsService],
    })
], GroupsModule);


/***/ }),
/* 257 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.GroupsController = void 0;
const common_1 = __webpack_require__(2);
const groups_service_1 = __webpack_require__(258);
const create_group_dto_1 = __webpack_require__(259);
const update_group_dto_1 = __webpack_require__(260);
const jwt_auth_guard_1 = __webpack_require__(61);
const group_member_guard_1 = __webpack_require__(261);
const group_owner_guard_1 = __webpack_require__(262);
const client_1 = __webpack_require__(17);
let GroupsController = class GroupsController {
    constructor(groupsService) {
        this.groupsService = groupsService;
    }
    async findAll(req, visibility, search, page, limit) {
        return this.groupsService.findAll(req.user.id, {
            visibility,
            search,
            page: page ? parseInt(page) : undefined,
            limit: limit ? parseInt(limit) : undefined,
        });
    }
    async create(req, createGroupDto) {
        return this.groupsService.create(createGroupDto, req.user.id);
    }
    async findOne(req, id) {
        return this.groupsService.findOne(id, req.user.id);
    }
    async update(req, id, updateGroupDto) {
        return this.groupsService.update(id, updateGroupDto, req.user.id, req.user.role);
    }
    async remove(req, id) {
        return this.groupsService.remove(id, req.user.id, req.user.role);
    }
    async join(req, id) {
        return this.groupsService.join(id, req.user.id);
    }
    async leave(req, id) {
        return this.groupsService.leave(id, req.user.id);
    }
    async getMessages(id, limit, before) {
        return this.groupsService.getMessages(id, {
            limit: limit ? parseInt(limit) : undefined,
            before,
        });
    }
    async getMembers(id) {
        return this.groupsService.getMembers(id);
    }
    async removeMember(req, id, userId) {
        return this.groupsService.removeMember(id, userId, req.user.id, req.user.role);
    }
    async banUser(req, id, userId) {
        return this.groupsService.banUser(id, userId, req.user.id, req.user.role);
    }
    async deleteMessage(req, id, messageId) {
        return this.groupsService.deleteMessage(id, messageId, req.user.id, req.user.role);
    }
};
exports.GroupsController = GroupsController;
__decorate([
    (0, common_1.Get)(),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Query)('visibility')),
    __param(2, (0, common_1.Query)('search')),
    __param(3, (0, common_1.Query)('page')),
    __param(4, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, typeof (_b = typeof client_1.GroupVisibility !== "undefined" && client_1.GroupVisibility) === "function" ? _b : Object, String, String, String]),
    __metadata("design:returntype", Promise)
], GroupsController.prototype, "findAll", null);
__decorate([
    (0, common_1.Post)(),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, typeof (_c = typeof create_group_dto_1.CreateGroupDto !== "undefined" && create_group_dto_1.CreateGroupDto) === "function" ? _c : Object]),
    __metadata("design:returntype", Promise)
], GroupsController.prototype, "create", null);
__decorate([
    (0, common_1.Get)(':id'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String]),
    __metadata("design:returntype", Promise)
], GroupsController.prototype, "findOne", null);
__decorate([
    (0, common_1.Patch)(':id'),
    (0, common_1.UseGuards)(group_owner_guard_1.GroupOwnerGuard),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __param(2, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, typeof (_d = typeof update_group_dto_1.UpdateGroupDto !== "undefined" && update_group_dto_1.UpdateGroupDto) === "function" ? _d : Object]),
    __metadata("design:returntype", Promise)
], GroupsController.prototype, "update", null);
__decorate([
    (0, common_1.Delete)(':id'),
    (0, common_1.UseGuards)(group_owner_guard_1.GroupOwnerGuard),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String]),
    __metadata("design:returntype", Promise)
], GroupsController.prototype, "remove", null);
__decorate([
    (0, common_1.Post)(':id/join'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String]),
    __metadata("design:returntype", Promise)
], GroupsController.prototype, "join", null);
__decorate([
    (0, common_1.Post)(':id/leave'),
    (0, common_1.UseGuards)(group_member_guard_1.GroupMemberGuard),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String]),
    __metadata("design:returntype", Promise)
], GroupsController.prototype, "leave", null);
__decorate([
    (0, common_1.Get)(':id/messages'),
    (0, common_1.UseGuards)(group_member_guard_1.GroupMemberGuard),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Query)('limit')),
    __param(2, (0, common_1.Query)('before')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, String]),
    __metadata("design:returntype", Promise)
], GroupsController.prototype, "getMessages", null);
__decorate([
    (0, common_1.Get)(':id/members'),
    (0, common_1.UseGuards)(group_member_guard_1.GroupMemberGuard),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], GroupsController.prototype, "getMembers", null);
__decorate([
    (0, common_1.Delete)(':id/members/:userId'),
    (0, common_1.UseGuards)(group_member_guard_1.GroupMemberGuard),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __param(2, (0, common_1.Param)('userId')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, String]),
    __metadata("design:returntype", Promise)
], GroupsController.prototype, "removeMember", null);
__decorate([
    (0, common_1.Post)(':id/ban/:userId'),
    (0, common_1.UseGuards)(group_owner_guard_1.GroupOwnerGuard),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __param(2, (0, common_1.Param)('userId')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, String]),
    __metadata("design:returntype", Promise)
], GroupsController.prototype, "banUser", null);
__decorate([
    (0, common_1.Delete)(':id/messages/:messageId'),
    (0, common_1.UseGuards)(group_member_guard_1.GroupMemberGuard),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __param(2, (0, common_1.Param)('messageId')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, String]),
    __metadata("design:returntype", Promise)
], GroupsController.prototype, "deleteMessage", null);
exports.GroupsController = GroupsController = __decorate([
    (0, common_1.Controller)('api/groups'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof groups_service_1.GroupsService !== "undefined" && groups_service_1.GroupsService) === "function" ? _a : Object])
], GroupsController);


/***/ }),
/* 258 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.GroupsService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const client_1 = __webpack_require__(17);
let GroupsService = class GroupsService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async findAll(userId, params) {
        const page = params?.page || 1;
        const limit = params?.limit || 20;
        const skip = (page - 1) * limit;
        const where = {
            OR: [
                { visibility: client_1.GroupVisibility.PUBLIC },
                {
                    members: {
                        some: {
                            userId,
                        },
                    },
                },
            ],
        };
        if (params?.visibility) {
            where.visibility = params.visibility;
        }
        if (params?.search) {
            where.AND = [
                {
                    OR: [
                        { name: { contains: params.search, mode: 'insensitive' } },
                        { description: { contains: params.search, mode: 'insensitive' } },
                    ],
                },
            ];
        }
        const [groups, total] = await Promise.all([
            this.prisma.group.findMany({
                where,
                skip,
                take: limit,
                include: {
                    owner: {
                        select: {
                            id: true,
                            name: true,
                            email: true,
                            avatar: true,
                        },
                    },
                    members: {
                        where: { userId },
                        select: { userId: true, role: true },
                    },
                    _count: {
                        select: {
                            members: true,
                        },
                    },
                },
                orderBy: {
                    createdAt: 'desc',
                },
            }),
            this.prisma.group.count({ where }),
        ]);
        const groupsWithMembership = groups.map((group) => ({
            ...group,
            isMember: group.members.length > 0,
            memberRole: group.members[0]?.role || null,
            members: undefined,
        }));
        return {
            groups: groupsWithMembership,
            pagination: {
                page,
                limit,
                total,
                totalPages: Math.ceil(total / limit),
            },
        };
    }
    async findOne(id, userId) {
        const group = await this.prisma.group.findUnique({
            where: { id },
            include: {
                owner: {
                    select: {
                        id: true,
                        name: true,
                        email: true,
                        avatar: true,
                    },
                },
                _count: {
                    select: {
                        members: true,
                        messages: true,
                    },
                },
            },
        });
        if (!group) {
            throw new common_1.NotFoundException('Group not found');
        }
        const membership = await this.prisma.groupMember.findUnique({
            where: {
                groupId_userId: {
                    groupId: id,
                    userId,
                },
            },
        });
        if (group.visibility === client_1.GroupVisibility.PRIVATE && !membership) {
            throw new common_1.ForbiddenException('This group is private');
        }
        return {
            ...group,
            isMember: !!membership,
            memberRole: membership?.role,
            isBanned: membership?.isBanned,
        };
    }
    async create(createGroupDto, userId) {
        let slug = createGroupDto.slug;
        let counter = 1;
        while (await this.prisma.group.findUnique({ where: { slug } })) {
            slug = `${createGroupDto.slug}-${counter}`;
            counter++;
        }
        const group = await this.prisma.group.create({
            data: {
                ...createGroupDto,
                slug,
                ownerId: userId,
                members: {
                    create: {
                        userId,
                        role: client_1.GroupMemberRole.OWNER,
                    },
                },
            },
            include: {
                owner: {
                    select: {
                        id: true,
                        name: true,
                        email: true,
                        avatar: true,
                    },
                },
            },
        });
        return group;
    }
    async update(id, updateGroupDto, userId, userRole) {
        const group = await this.prisma.group.findUnique({
            where: { id },
        });
        if (!group) {
            throw new common_1.NotFoundException('Group not found');
        }
        if (group.ownerId !== userId && userRole !== client_1.UserRole.ADMIN) {
            throw new common_1.ForbiddenException('Only the group owner can update this group');
        }
        return this.prisma.group.update({
            where: { id },
            data: updateGroupDto,
            include: {
                owner: {
                    select: {
                        id: true,
                        name: true,
                        email: true,
                        avatar: true,
                    },
                },
            },
        });
    }
    async remove(id, userId, userRole) {
        const group = await this.prisma.group.findUnique({
            where: { id },
        });
        if (!group) {
            throw new common_1.NotFoundException('Group not found');
        }
        if (group.ownerId !== userId && userRole !== client_1.UserRole.ADMIN) {
            throw new common_1.ForbiddenException('Only the group owner can delete this group');
        }
        return this.prisma.group.delete({
            where: { id },
        });
    }
    async join(groupId, userId) {
        const group = await this.prisma.group.findUnique({
            where: { id: groupId },
        });
        if (!group) {
            throw new common_1.NotFoundException('Group not found');
        }
        const existing = await this.prisma.groupMember.findUnique({
            where: {
                groupId_userId: {
                    groupId,
                    userId,
                },
            },
        });
        if (existing) {
            if (existing.isBanned) {
                throw new common_1.ForbiddenException('You are banned from this group');
            }
            throw new common_1.BadRequestException('You are already a member of this group');
        }
        if (group.visibility === client_1.GroupVisibility.PRIVATE) {
            throw new common_1.ForbiddenException('This group is private. You need an invitation to join.');
        }
        return this.prisma.groupMember.create({
            data: {
                groupId,
                userId,
                role: client_1.GroupMemberRole.MEMBER,
            },
            include: {
                user: {
                    select: {
                        id: true,
                        name: true,
                        email: true,
                        avatar: true,
                    },
                },
            },
        });
    }
    async leave(groupId, userId) {
        const group = await this.prisma.group.findUnique({
            where: { id: groupId },
        });
        if (!group) {
            throw new common_1.NotFoundException('Group not found');
        }
        if (group.ownerId === userId) {
            throw new common_1.BadRequestException('Group owner cannot leave the group. Transfer ownership or delete the group instead.');
        }
        const membership = await this.prisma.groupMember.findUnique({
            where: {
                groupId_userId: {
                    groupId,
                    userId,
                },
            },
        });
        if (!membership) {
            throw new common_1.BadRequestException('You are not a member of this group');
        }
        return this.prisma.groupMember.delete({
            where: {
                groupId_userId: {
                    groupId,
                    userId,
                },
            },
        });
    }
    async getMessages(groupId, params) {
        const limit = params?.limit || 50;
        const where = { groupId };
        if (params?.before) {
            where.id = { lt: params.before };
        }
        const messages = await this.prisma.groupMessage.findMany({
            where,
            take: limit,
            orderBy: {
                createdAt: 'desc',
            },
            include: {
                sender: {
                    select: {
                        id: true,
                        name: true,
                        email: true,
                        avatar: true,
                    },
                },
            },
        });
        return messages.reverse();
    }
    async getMembers(groupId) {
        return this.prisma.groupMember.findMany({
            where: { groupId },
            include: {
                user: {
                    select: {
                        id: true,
                        name: true,
                        email: true,
                        avatar: true,
                    },
                },
            },
            orderBy: {
                joinedAt: 'asc',
            },
        });
    }
    async removeMember(groupId, userId, requesterId, requesterRole) {
        const group = await this.prisma.group.findUnique({
            where: { id: groupId },
        });
        if (!group) {
            throw new common_1.NotFoundException('Group not found');
        }
        const requesterMembership = await this.prisma.groupMember.findUnique({
            where: {
                groupId_userId: {
                    groupId,
                    userId: requesterId,
                },
            },
        });
        const canRemove = requesterRole === client_1.UserRole.ADMIN ||
            group.ownerId === requesterId ||
            (requesterMembership && requesterMembership.role === client_1.GroupMemberRole.MODERATOR);
        if (!canRemove) {
            throw new common_1.ForbiddenException('You do not have permission to remove members');
        }
        if (group.ownerId === userId) {
            throw new common_1.BadRequestException('Cannot remove the group owner');
        }
        return this.prisma.groupMember.delete({
            where: {
                groupId_userId: {
                    groupId,
                    userId,
                },
            },
        });
    }
    async banUser(groupId, userId, requesterId, requesterRole) {
        const group = await this.prisma.group.findUnique({
            where: { id: groupId },
        });
        if (!group) {
            throw new common_1.NotFoundException('Group not found');
        }
        if (group.ownerId !== requesterId && requesterRole !== client_1.UserRole.ADMIN) {
            throw new common_1.ForbiddenException('Only the group owner can ban users');
        }
        if (group.ownerId === userId) {
            throw new common_1.BadRequestException('Cannot ban the group owner');
        }
        return this.prisma.groupMember.update({
            where: {
                groupId_userId: {
                    groupId,
                    userId,
                },
            },
            data: {
                isBanned: true,
            },
        });
    }
    async deleteMessage(groupId, messageId, userId, userRole) {
        const message = await this.prisma.groupMessage.findUnique({
            where: { id: messageId },
            include: {
                group: true,
            },
        });
        if (!message || message.groupId !== groupId) {
            throw new common_1.NotFoundException('Message not found');
        }
        const canDelete = userRole === client_1.UserRole.ADMIN ||
            message.group.ownerId === userId ||
            (message.senderId === userId && Date.now() - message.createdAt.getTime() < 5 * 60 * 1000);
        if (!canDelete) {
            throw new common_1.ForbiddenException('You do not have permission to delete this message');
        }
        return this.prisma.groupMessage.delete({
            where: { id: messageId },
        });
    }
};
exports.GroupsService = GroupsService;
exports.GroupsService = GroupsService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], GroupsService);


/***/ }),
/* 259 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CreateGroupDto = void 0;
const class_validator_1 = __webpack_require__(59);
const client_1 = __webpack_require__(17);
class CreateGroupDto {
}
exports.CreateGroupDto = CreateGroupDto;
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.MinLength)(3),
    (0, class_validator_1.MaxLength)(100),
    __metadata("design:type", String)
], CreateGroupDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.MinLength)(3),
    (0, class_validator_1.MaxLength)(100),
    (0, class_validator_1.Matches)(/^[a-z0-9-]+$/, {
        message: 'Slug must contain only lowercase letters, numbers, and hyphens',
    }),
    __metadata("design:type", String)
], CreateGroupDto.prototype, "slug", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.MaxLength)(500),
    __metadata("design:type", String)
], CreateGroupDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsEnum)(client_1.GroupVisibility),
    __metadata("design:type", typeof (_a = typeof client_1.GroupVisibility !== "undefined" && client_1.GroupVisibility) === "function" ? _a : Object)
], CreateGroupDto.prototype, "visibility", void 0);


/***/ }),
/* 260 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UpdateGroupDto = void 0;
const class_validator_1 = __webpack_require__(59);
const client_1 = __webpack_require__(17);
class UpdateGroupDto {
}
exports.UpdateGroupDto = UpdateGroupDto;
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.MinLength)(3),
    (0, class_validator_1.MaxLength)(100),
    __metadata("design:type", String)
], UpdateGroupDto.prototype, "name", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsString)(),
    (0, class_validator_1.MaxLength)(500),
    __metadata("design:type", String)
], UpdateGroupDto.prototype, "description", void 0);
__decorate([
    (0, class_validator_1.IsOptional)(),
    (0, class_validator_1.IsEnum)(client_1.GroupVisibility),
    __metadata("design:type", typeof (_a = typeof client_1.GroupVisibility !== "undefined" && client_1.GroupVisibility) === "function" ? _a : Object)
], UpdateGroupDto.prototype, "visibility", void 0);


/***/ }),
/* 261 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.GroupMemberGuard = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let GroupMemberGuard = class GroupMemberGuard {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async canActivate(context) {
        const request = context.switchToHttp().getRequest();
        const user = request.user;
        const groupId = request.params.id || request.params.groupId;
        if (!user || !groupId) {
            throw new common_1.ForbiddenException('Access denied');
        }
        const membership = await this.prisma.groupMember.findUnique({
            where: {
                groupId_userId: {
                    groupId,
                    userId: user.id,
                },
            },
        });
        if (!membership || membership.isBanned) {
            throw new common_1.ForbiddenException('You are not a member of this group');
        }
        request.groupMembership = membership;
        return true;
    }
};
exports.GroupMemberGuard = GroupMemberGuard;
exports.GroupMemberGuard = GroupMemberGuard = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], GroupMemberGuard);


/***/ }),
/* 262 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.GroupOwnerGuard = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const client_1 = __webpack_require__(17);
let GroupOwnerGuard = class GroupOwnerGuard {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async canActivate(context) {
        const request = context.switchToHttp().getRequest();
        const user = request.user;
        const groupId = request.params.id || request.params.groupId;
        if (!user || !groupId) {
            throw new common_1.ForbiddenException('Access denied');
        }
        if (user.role === client_1.UserRole.ADMIN) {
            return true;
        }
        const group = await this.prisma.group.findUnique({
            where: { id: groupId },
            select: { ownerId: true },
        });
        if (!group || group.ownerId !== user.id) {
            throw new common_1.ForbiddenException('Only the group owner can perform this action');
        }
        return true;
    }
};
exports.GroupOwnerGuard = GroupOwnerGuard;
exports.GroupOwnerGuard = GroupOwnerGuard = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], GroupOwnerGuard);


/***/ }),
/* 263 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.GroupsGateway = void 0;
const websockets_1 = __webpack_require__(264);
const socket_io_1 = __webpack_require__(265);
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const jwt_1 = __webpack_require__(43);
let GroupsGateway = class GroupsGateway {
    constructor(prisma, jwtService) {
        this.prisma = prisma;
        this.jwtService = jwtService;
        this.onlineUsers = new Map();
        this.userSockets = new Map();
        this.socketUsers = new Map();
    }
    async handleConnection(client) {
        try {
            const token = client.handshake.auth.token || client.handshake.headers.authorization?.split(' ')[1];
            if (!token) {
                throw new common_1.UnauthorizedException('No token provided');
            }
            const payload = this.jwtService.verify(token);
            const user = await this.prisma.user.findUnique({
                where: { id: payload.sub },
                select: {
                    id: true,
                    name: true,
                    email: true,
                    avatar: true,
                },
            });
            if (!user) {
                throw new common_1.UnauthorizedException('User not found');
            }
            this.socketUsers.set(client.id, user);
            if (!this.userSockets.has(user.id)) {
                this.userSockets.set(user.id, new Set());
            }
            this.userSockets.get(user.id).add(client.id);
            const onlineUserIds = Array.from(this.userSockets.keys());
            client.emit('users:online:list', { users: onlineUserIds });
            this.server.emit('user:online', { userId: user.id });
            console.log(`User ${user.name} connected to groups gateway (${onlineUserIds.length} users online, ${this.userSockets.get(user.id).size} devices)`);
        }
        catch (error) {
            console.error('WebSocket authentication failed:', error.message);
            client.disconnect();
        }
    }
    async handleDisconnect(client) {
        const user = this.socketUsers.get(client.id);
        if (user) {
            this.socketUsers.delete(client.id);
            const userSocketSet = this.userSockets.get(user.id);
            if (userSocketSet) {
                userSocketSet.delete(client.id);
                if (userSocketSet.size === 0) {
                    this.onlineUsers.forEach((users, groupId) => {
                        if (users.has(user.id)) {
                            users.delete(user.id);
                            this.server.to(`group:${groupId}`).emit('group:user:offline', {
                                userId: user.id,
                                userName: user.name,
                            });
                        }
                    });
                    this.userSockets.delete(user.id);
                    this.server.emit('user:offline', { userId: user.id });
                    console.log(`User ${user.name} disconnected from groups gateway (now offline)`);
                }
                else {
                    console.log(`User ${user.name} disconnected one device from groups (${userSocketSet.size} devices still connected)`);
                }
            }
        }
    }
    async handleJoinGroup(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user) {
            return { error: 'Unauthorized' };
        }
        const { groupId } = data;
        const membership = await this.prisma.groupMember.findUnique({
            where: {
                groupId_userId: {
                    groupId,
                    userId: user.id,
                },
            },
        });
        if (!membership || membership.isBanned) {
            return { error: 'You are not a member of this group' };
        }
        client.join(`group:${groupId}`);
        if (!this.onlineUsers.has(groupId)) {
            this.onlineUsers.set(groupId, new Set());
        }
        this.onlineUsers.get(groupId).add(user.id);
        this.server.to(`group:${groupId}`).emit('group:user:online', {
            userId: user.id,
            userName: user.name,
            userAvatar: user.avatar,
        });
        const onlineUserIds = Array.from(this.onlineUsers.get(groupId) || []);
        return { success: true, onlineUsers: onlineUserIds };
    }
    async handleLeaveGroup(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user) {
            return { error: 'Unauthorized' };
        }
        const { groupId } = data;
        client.leave(`group:${groupId}`);
        if (this.onlineUsers.has(groupId)) {
            this.onlineUsers.get(groupId).delete(user.id);
        }
        this.server.to(`group:${groupId}`).emit('group:user:offline', {
            userId: user.id,
            userName: user.name,
        });
        return { success: true };
    }
    async handleSendMessage(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user) {
            return { error: 'Unauthorized' };
        }
        const { groupId, content, media } = data;
        try {
            const membership = await this.prisma.groupMember.findUnique({
                where: {
                    groupId_userId: {
                        groupId,
                        userId: user.id,
                    },
                },
            });
            if (!membership || membership.isBanned) {
                return { error: 'You are not allowed to send messages in this group' };
            }
            const message = await this.prisma.groupMessage.create({
                data: {
                    groupId,
                    senderId: user.id,
                    content,
                    media: media && media.length > 0 ? media : [],
                },
                include: {
                    sender: {
                        select: {
                            id: true,
                            name: true,
                            email: true,
                            avatar: true,
                        },
                    },
                },
            });
            this.server.to(`group:${groupId}`).emit('group:message:new', message);
            return { success: true, message };
        }
        catch (error) {
            console.error('Error sending group message:', error);
            return { error: error.message || 'Failed to send message' };
        }
    }
    async handleTypingStart(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user) {
            return;
        }
        const { groupId } = data;
        client.to(`group:${groupId}`).emit('group:typing', {
            userId: user.id,
            userName: user.name,
            isTyping: true,
        });
    }
    async handleTypingStop(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user) {
            return;
        }
        const { groupId } = data;
        client.to(`group:${groupId}`).emit('group:typing', {
            userId: user.id,
            userName: user.name,
            isTyping: false,
        });
    }
    async handleDeleteMessage(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user) {
            return { error: 'Unauthorized' };
        }
        const { groupId, messageId } = data;
        const message = await this.prisma.groupMessage.findUnique({
            where: { id: messageId },
            include: { group: true },
        });
        if (!message) {
            return { error: 'Message not found' };
        }
        const membership = await this.prisma.groupMember.findUnique({
            where: { groupId_userId: { groupId, userId: user.id } },
        });
        const canDelete = message.senderId === user.id ||
            message.group.ownerId === user.id ||
            membership?.role === 'MODERATOR';
        if (!canDelete) {
            return { error: 'You cannot delete this message' };
        }
        await this.prisma.groupMessage.delete({ where: { id: messageId } });
        this.server.to(`group:${groupId}`).emit('group:message:deleted', { messageId, groupId });
        return { success: true };
    }
    emitMemberJoined(groupId, member) {
        this.server.to(`group:${groupId}`).emit('group:member:joined', member);
    }
    emitMemberLeft(groupId, userId) {
        this.server.to(`group:${groupId}`).emit('group:member:left', { userId });
    }
    async handleVideoStart(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return;
        this.server.to(`group:${data.groupId}`).emit('group:video:started', {
            groupId: data.groupId,
            roomUrl: data.roomUrl,
            startedBy: {
                id: user.id,
                name: user.name,
            },
        });
        return { success: true };
    }
    async handleVideoEnd(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return;
        this.server.to(`group:${data.groupId}`).emit('group:video:ended', {
            groupId: data.groupId,
            endedBy: user.id,
        });
        return { success: true };
    }
    emitToUser(userId, event, data) {
        const socketIds = this.userSockets.get(userId);
        if (socketIds) {
            socketIds.forEach((socketId) => {
                this.server.to(socketId).emit(event, data);
            });
        }
    }
    async handleCallInitiate(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return { error: 'Unauthorized' };
        this.emitToUser(data.targetUserId, 'call:incoming', {
            callerId: user.id,
            callerName: user.name,
            callerAvatar: user.avatar,
            conversationId: data.conversationId || `direct-${user.id}-${data.targetUserId}`,
        });
        return { success: true };
    }
    async handleCallAccept(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return { error: 'Unauthorized' };
        this.emitToUser(data.targetUserId, 'call:accepted', {
            accepterId: user.id,
        });
        return { success: true };
    }
    async handleCallReject(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return { error: 'Unauthorized' };
        this.emitToUser(data.targetUserId, 'call:rejected', {
            rejecterId: user.id,
        });
        return { success: true };
    }
    async handleCallOffer(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return { error: 'Unauthorized' };
        this.emitToUser(data.targetUserId, 'call:offer', {
            callerId: user.id,
            offer: data.offer,
        });
        return { success: true };
    }
    async handleCallAnswer(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return { error: 'Unauthorized' };
        this.emitToUser(data.targetUserId, 'call:answer', {
            answererId: user.id,
            answer: data.answer,
        });
        return { success: true };
    }
    async handleIceCandidate(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return { error: 'Unauthorized' };
        this.emitToUser(data.targetUserId, 'call:ice-candidate', {
            senderId: user.id,
            candidate: data.candidate,
        });
        return { success: true };
    }
    async handleCallEnd(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return { error: 'Unauthorized' };
        this.emitToUser(data.targetUserId, 'call:ended', {
            enderId: user.id,
        });
        return { success: true };
    }
};
exports.GroupsGateway = GroupsGateway;
__decorate([
    (0, websockets_1.WebSocketServer)(),
    __metadata("design:type", typeof (_c = typeof socket_io_1.Server !== "undefined" && socket_io_1.Server) === "function" ? _c : Object)
], GroupsGateway.prototype, "server", void 0);
__decorate([
    (0, websockets_1.SubscribeMessage)('group:join'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_d = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _d : Object, Object]),
    __metadata("design:returntype", Promise)
], GroupsGateway.prototype, "handleJoinGroup", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('group:leave'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_e = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _e : Object, Object]),
    __metadata("design:returntype", Promise)
], GroupsGateway.prototype, "handleLeaveGroup", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('group:message:send'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_f = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _f : Object, Object]),
    __metadata("design:returntype", Promise)
], GroupsGateway.prototype, "handleSendMessage", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('group:typing:start'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_g = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _g : Object, Object]),
    __metadata("design:returntype", Promise)
], GroupsGateway.prototype, "handleTypingStart", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('group:typing:stop'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_h = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _h : Object, Object]),
    __metadata("design:returntype", Promise)
], GroupsGateway.prototype, "handleTypingStop", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('group:message:delete'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_j = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _j : Object, Object]),
    __metadata("design:returntype", Promise)
], GroupsGateway.prototype, "handleDeleteMessage", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('group:video:start'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_k = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _k : Object, Object]),
    __metadata("design:returntype", Promise)
], GroupsGateway.prototype, "handleVideoStart", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('group:video:end'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_l = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _l : Object, Object]),
    __metadata("design:returntype", Promise)
], GroupsGateway.prototype, "handleVideoEnd", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('call:initiate'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_m = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _m : Object, Object]),
    __metadata("design:returntype", Promise)
], GroupsGateway.prototype, "handleCallInitiate", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('call:accept'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_o = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _o : Object, Object]),
    __metadata("design:returntype", Promise)
], GroupsGateway.prototype, "handleCallAccept", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('call:reject'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_p = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _p : Object, Object]),
    __metadata("design:returntype", Promise)
], GroupsGateway.prototype, "handleCallReject", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('call:offer'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_q = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _q : Object, Object]),
    __metadata("design:returntype", Promise)
], GroupsGateway.prototype, "handleCallOffer", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('call:answer'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_r = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _r : Object, Object]),
    __metadata("design:returntype", Promise)
], GroupsGateway.prototype, "handleCallAnswer", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('call:ice-candidate'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_s = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _s : Object, Object]),
    __metadata("design:returntype", Promise)
], GroupsGateway.prototype, "handleIceCandidate", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('call:end'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_t = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _t : Object, Object]),
    __metadata("design:returntype", Promise)
], GroupsGateway.prototype, "handleCallEnd", null);
exports.GroupsGateway = GroupsGateway = __decorate([
    (0, websockets_1.WebSocketGateway)({
        cors: {
            origin: '*',
            credentials: true,
        },
        namespace: '/groups',
    }),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof jwt_1.JwtService !== "undefined" && jwt_1.JwtService) === "function" ? _b : Object])
], GroupsGateway);


/***/ }),
/* 264 */
/***/ ((module) => {

module.exports = require("@nestjs/websockets");

/***/ }),
/* 265 */
/***/ ((module) => {

module.exports = require("socket.io");

/***/ }),
/* 266 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.AnalyticsModule = void 0;
const common_1 = __webpack_require__(2);
const analytics_controller_1 = __webpack_require__(267);
const analytics_service_1 = __webpack_require__(268);
const prisma_module_1 = __webpack_require__(15);
const feature_guard_1 = __webpack_require__(162);
let AnalyticsModule = class AnalyticsModule {
};
exports.AnalyticsModule = AnalyticsModule;
exports.AnalyticsModule = AnalyticsModule = __decorate([
    (0, common_1.Module)({
        imports: [prisma_module_1.PrismaModule],
        controllers: [analytics_controller_1.AnalyticsController],
        providers: [analytics_service_1.AnalyticsService, feature_guard_1.FeatureGuard],
        exports: [analytics_service_1.AnalyticsService],
    })
], AnalyticsModule);


/***/ }),
/* 267 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.AnalyticsController = void 0;
const common_1 = __webpack_require__(2);
const analytics_service_1 = __webpack_require__(268);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const feature_guard_1 = __webpack_require__(162);
const roles_decorator_1 = __webpack_require__(73);
const subscription_decorator_1 = __webpack_require__(161);
const client_1 = __webpack_require__(17);
const express_1 = __webpack_require__(57);
const prisma_service_1 = __webpack_require__(16);
let AnalyticsController = class AnalyticsController {
    constructor(analyticsService, prisma) {
        this.analyticsService = analyticsService;
        this.prisma = prisma;
    }
    getDashboardStats(period) {
        return this.analyticsService.getDashboardStats(period || 'week');
    }
    getPageViewsOverTime(period) {
        return this.analyticsService.getPageViewsOverTime(period || 'week');
    }
    getTopPages(period, limit) {
        return this.analyticsService.getTopPages(period || 'week', parseInt(limit || '10'));
    }
    getTrafficSources(period, limit) {
        return this.analyticsService.getTrafficSources(period || 'week', parseInt(limit || '10'));
    }
    getDeviceBreakdown(period) {
        return this.analyticsService.getDeviceBreakdown(period || 'week');
    }
    getBrowserBreakdown(period) {
        return this.analyticsService.getBrowserBreakdown(period || 'week');
    }
    getRealTimeStats() {
        return this.analyticsService.getRealTimeStats();
    }
    async trackPageView(req, body) {
        const userAgent = req.headers['user-agent'] || '';
        const referer = req.headers['referer'] || null;
        const ip = this.anonymizeIp(req.ip || req.socket.remoteAddress || '');
        const { device, browser, os } = this.parseUserAgent(userAgent);
        const sessionId = typeof body.sessionId === 'string' ? body.sessionId : null;
        return this.prisma.pageView.create({
            data: {
                path: body.path,
                sessionId,
                ipAddress: ip,
                userAgent,
                referer,
                device,
                browser,
                os,
            },
        });
    }
    async trackEvent(req, body) {
        const ip = this.anonymizeIp(req.ip || req.socket.remoteAddress || '');
        const sessionId = typeof body.sessionId === 'string' ? body.sessionId : null;
        return this.prisma.analyticsEvent.create({
            data: {
                category: body.category,
                action: body.action,
                label: body.label,
                value: body.value,
                path: body.path,
                sessionId,
                ipAddress: ip,
            },
        });
    }
    async trackSession(req, body) {
        const userAgent = req.headers['user-agent'] || '';
        const referer = req.headers['referer'] || null;
        const ip = this.anonymizeIp(req.ip || req.socket.remoteAddress || '');
        const { device, browser, os } = this.parseUserAgent(userAgent);
        const session = await this.prisma.analyticsSession.create({
            data: {
                ipAddress: ip,
                userAgent,
                device,
                browser,
                os,
                referer,
                landingPage: body.path,
            },
        });
        return { sessionId: session.id };
    }
    anonymizeIp(ip) {
        if (!ip)
            return '';
        if (ip.includes('.')) {
            const parts = ip.split('.');
            if (parts.length === 4) {
                parts[3] = '0';
                return parts.join('.');
            }
        }
        if (ip.includes(':')) {
            const parts = ip.split(':');
            if (parts.length >= 5) {
                return parts.slice(0, 3).join(':') + ':0:0:0:0:0';
            }
        }
        return ip;
    }
    parseUserAgent(ua) {
        const uaLower = ua.toLowerCase();
        let device = 'desktop';
        if (/mobile|android|iphone|ipad|ipod|blackberry|windows phone/i.test(ua)) {
            device = /ipad|tablet/i.test(ua) ? 'tablet' : 'mobile';
        }
        let browser = 'unknown';
        if (uaLower.includes('firefox'))
            browser = 'Firefox';
        else if (uaLower.includes('edg'))
            browser = 'Edge';
        else if (uaLower.includes('chrome'))
            browser = 'Chrome';
        else if (uaLower.includes('safari'))
            browser = 'Safari';
        else if (uaLower.includes('opera') || uaLower.includes('opr'))
            browser = 'Opera';
        let os = 'unknown';
        if (uaLower.includes('windows'))
            os = 'Windows';
        else if (uaLower.includes('mac'))
            os = 'macOS';
        else if (uaLower.includes('linux'))
            os = 'Linux';
        else if (uaLower.includes('android'))
            os = 'Android';
        else if (uaLower.includes('iphone') || uaLower.includes('ipad'))
            os = 'iOS';
        return { device, browser, os };
    }
};
exports.AnalyticsController = AnalyticsController;
__decorate([
    (0, common_1.Get)('dashboard'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard, feature_guard_1.FeatureGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    (0, subscription_decorator_1.RequiresFeature)(subscription_decorator_1.SUBSCRIPTION_FEATURES.ANALYTICS),
    __param(0, (0, common_1.Query)('period')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], AnalyticsController.prototype, "getDashboardStats", null);
__decorate([
    (0, common_1.Get)('pageviews'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard, feature_guard_1.FeatureGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    (0, subscription_decorator_1.RequiresFeature)(subscription_decorator_1.SUBSCRIPTION_FEATURES.ANALYTICS),
    __param(0, (0, common_1.Query)('period')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], AnalyticsController.prototype, "getPageViewsOverTime", null);
__decorate([
    (0, common_1.Get)('top-pages'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard, feature_guard_1.FeatureGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    (0, subscription_decorator_1.RequiresFeature)(subscription_decorator_1.SUBSCRIPTION_FEATURES.ANALYTICS),
    __param(0, (0, common_1.Query)('period')),
    __param(1, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", void 0)
], AnalyticsController.prototype, "getTopPages", null);
__decorate([
    (0, common_1.Get)('traffic-sources'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard, feature_guard_1.FeatureGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    (0, subscription_decorator_1.RequiresFeature)(subscription_decorator_1.SUBSCRIPTION_FEATURES.ANALYTICS),
    __param(0, (0, common_1.Query)('period')),
    __param(1, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", void 0)
], AnalyticsController.prototype, "getTrafficSources", null);
__decorate([
    (0, common_1.Get)('devices'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard, feature_guard_1.FeatureGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    (0, subscription_decorator_1.RequiresFeature)(subscription_decorator_1.SUBSCRIPTION_FEATURES.ANALYTICS),
    __param(0, (0, common_1.Query)('period')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], AnalyticsController.prototype, "getDeviceBreakdown", null);
__decorate([
    (0, common_1.Get)('browsers'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard, feature_guard_1.FeatureGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    (0, subscription_decorator_1.RequiresFeature)(subscription_decorator_1.SUBSCRIPTION_FEATURES.ANALYTICS),
    __param(0, (0, common_1.Query)('period')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], AnalyticsController.prototype, "getBrowserBreakdown", null);
__decorate([
    (0, common_1.Get)('realtime'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard, feature_guard_1.FeatureGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    (0, subscription_decorator_1.RequiresFeature)(subscription_decorator_1.SUBSCRIPTION_FEATURES.ANALYTICS),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], AnalyticsController.prototype, "getRealTimeStats", null);
__decorate([
    (0, common_1.Post)('track/pageview'),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_c = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _c : Object, Object]),
    __metadata("design:returntype", Promise)
], AnalyticsController.prototype, "trackPageView", null);
__decorate([
    (0, common_1.Post)('track/event'),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_d = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _d : Object, Object]),
    __metadata("design:returntype", Promise)
], AnalyticsController.prototype, "trackEvent", null);
__decorate([
    (0, common_1.Post)('track/session'),
    __param(0, (0, common_1.Req)()),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_e = typeof express_1.Request !== "undefined" && express_1.Request) === "function" ? _e : Object, Object]),
    __metadata("design:returntype", Promise)
], AnalyticsController.prototype, "trackSession", null);
exports.AnalyticsController = AnalyticsController = __decorate([
    (0, common_1.Controller)('api/analytics'),
    __metadata("design:paramtypes", [typeof (_a = typeof analytics_service_1.AnalyticsService !== "undefined" && analytics_service_1.AnalyticsService) === "function" ? _a : Object, typeof (_b = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _b : Object])
], AnalyticsController);


/***/ }),
/* 268 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.AnalyticsService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let AnalyticsService = class AnalyticsService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    getDateFilter(period) {
        const now = new Date();
        let startDate;
        switch (period) {
            case 'today':
                startDate = new Date(now.getFullYear(), now.getMonth(), now.getDate());
                break;
            case 'yesterday':
                startDate = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1);
                break;
            case 'week':
                startDate = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
                break;
            case 'month':
                startDate = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
                break;
            case 'year':
                startDate = new Date(now.getTime() - 365 * 24 * 60 * 60 * 1000);
                break;
            default:
                startDate = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
        }
        return { gte: startDate };
    }
    async getDashboardStats(period = 'week') {
        const dateFilter = this.getDateFilter(period);
        const [totalPageViews, uniqueVisitors, totalSessions, avgSessionDuration] = await Promise.all([
            this.prisma.pageView.count({ where: { createdAt: dateFilter } }),
            this.prisma.pageView.groupBy({ by: ['ipAddress'], where: { createdAt: dateFilter } }),
            this.prisma.analyticsSession.count({ where: { startedAt: dateFilter } }),
            this.prisma.analyticsSession.aggregate({
                where: { startedAt: dateFilter, duration: { gt: 0 } },
                _avg: { duration: true },
            }),
        ]);
        const bounceRate = totalSessions > 0
            ? await this.prisma.analyticsSession
                .count({ where: { startedAt: dateFilter, pageCount: 1 } })
                .then((bounces) => Math.round((bounces / totalSessions) * 100))
            : 0;
        return {
            pageViews: totalPageViews,
            uniqueVisitors: uniqueVisitors.length,
            sessions: totalSessions,
            avgDuration: Math.round(avgSessionDuration._avg?.duration || 0),
            bounceRate,
        };
    }
    async getPageViewsOverTime(period = 'week') {
        const dateFilter = this.getDateFilter(period);
        const pageViews = await this.prisma.pageView.findMany({
            where: { createdAt: dateFilter },
            select: { createdAt: true },
            orderBy: { createdAt: 'asc' },
        });
        const grouped = {};
        pageViews.forEach((pv) => {
            const date = pv.createdAt.toISOString().split('T')[0];
            grouped[date] = (grouped[date] || 0) + 1;
        });
        return Object.entries(grouped).map(([date, views]) => ({ date, views }));
    }
    async getTopPages(period = 'week', limit = 10) {
        const dateFilter = this.getDateFilter(period);
        const pages = await this.prisma.pageView.groupBy({
            by: ['path'],
            where: { createdAt: dateFilter },
            _count: { path: true },
            _avg: { duration: true },
            orderBy: { _count: { path: 'desc' } },
            take: limit,
        });
        return pages.map((p) => ({
            path: p.path,
            views: p._count.path,
            avgDuration: Math.round(p._avg?.duration || 0),
        }));
    }
    async getTrafficSources(period = 'week', limit = 10) {
        const dateFilter = this.getDateFilter(period);
        const sources = await this.prisma.pageView.groupBy({
            by: ['referer'],
            where: { createdAt: dateFilter, referer: { not: null } },
            _count: { referer: true },
            orderBy: { _count: { referer: 'desc' } },
            take: limit,
        });
        return sources.map((s) => ({ source: s.referer || 'Direct', visits: s._count.referer }));
    }
    async getDeviceBreakdown(period = 'week') {
        const dateFilter = this.getDateFilter(period);
        const devices = await this.prisma.pageView.groupBy({
            by: ['device'],
            where: { createdAt: dateFilter, device: { not: null } },
            _count: { device: true },
        });
        const total = devices.reduce((sum, d) => sum + d._count.device, 0);
        return devices.map((d) => ({
            device: d.device || 'Unknown',
            count: d._count.device,
            percentage: total > 0 ? Math.round((d._count.device / total) * 100) : 0,
        }));
    }
    async getBrowserBreakdown(period = 'week') {
        const dateFilter = this.getDateFilter(period);
        const browsers = await this.prisma.pageView.groupBy({
            by: ['browser'],
            where: { createdAt: dateFilter, browser: { not: null } },
            _count: { browser: true },
            orderBy: { _count: { browser: 'desc' } },
            take: 5,
        });
        const total = browsers.reduce((sum, b) => sum + b._count.browser, 0);
        return browsers.map((b) => ({
            browser: b.browser || 'Unknown',
            count: b._count.browser,
            percentage: total > 0 ? Math.round((b._count.browser / total) * 100) : 0,
        }));
    }
    async getRealTimeStats() {
        const fiveMinutesAgo = new Date(Date.now() - 5 * 60 * 1000);
        const [activeVisitors, recentPages] = await Promise.all([
            this.prisma.analyticsSession.count({
                where: { isActive: true, startedAt: { gte: fiveMinutesAgo } },
            }),
            this.prisma.pageView.findMany({
                where: { createdAt: { gte: fiveMinutesAgo } },
                select: { path: true, createdAt: true },
                orderBy: { createdAt: 'desc' },
                take: 10,
            }),
        ]);
        return { activeVisitors, recentPages };
    }
};
exports.AnalyticsService = AnalyticsService;
exports.AnalyticsService = AnalyticsService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], AnalyticsService);


/***/ }),
/* 269 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SeoModule = void 0;
const common_1 = __webpack_require__(2);
const seo_controller_1 = __webpack_require__(270);
const seo_service_1 = __webpack_require__(271);
const prisma_module_1 = __webpack_require__(15);
let SeoModule = class SeoModule {
};
exports.SeoModule = SeoModule;
exports.SeoModule = SeoModule = __decorate([
    (0, common_1.Module)({
        imports: [prisma_module_1.PrismaModule],
        controllers: [seo_controller_1.SeoController],
        providers: [seo_service_1.SeoService],
        exports: [seo_service_1.SeoService],
    })
], SeoModule);


/***/ }),
/* 270 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SeoController = void 0;
const common_1 = __webpack_require__(2);
const express_1 = __webpack_require__(57);
const seo_service_1 = __webpack_require__(271);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const client_1 = __webpack_require__(17);
let SeoController = class SeoController {
    constructor(seoService) {
        this.seoService = seoService;
    }
    getRedirects() {
        return this.seoService.getRedirects();
    }
    createRedirect(body) {
        return this.seoService.createRedirect(body);
    }
    updateRedirect(id, body) {
        return this.seoService.updateRedirect(id, body);
    }
    deleteRedirect(id) {
        return this.seoService.deleteRedirect(id);
    }
    getSitemapEntries() {
        return this.seoService.getSitemapEntries();
    }
    createSitemapEntry(body) {
        return this.seoService.createSitemapEntry(body);
    }
    updateSitemapEntry(id, body) {
        return this.seoService.updateSitemapEntry(id, body);
    }
    deleteSitemapEntry(id) {
        return this.seoService.deleteSitemapEntry(id);
    }
    async getSitemap(res) {
        const baseUrl = process.env.SITE_URL || 'http://localhost:3000';
        const xml = await this.seoService.generateSitemap(baseUrl);
        res.send(xml);
    }
    getSchemaMarkups(scope) {
        return this.seoService.getSchemaMarkups(scope);
    }
    createSchemaMarkup(body) {
        return this.seoService.createSchemaMarkup(body);
    }
    updateSchemaMarkup(id, body) {
        return this.seoService.updateSchemaMarkup(id, body);
    }
    deleteSchemaMarkup(id) {
        return this.seoService.deleteSchemaMarkup(id);
    }
    async getSchemaForPage(scope, scopeId) {
        const schemas = await this.seoService.getSchemaMarkups(scope);
        const filtered = scopeId
            ? schemas.filter((s) => !s.scopeId || s.scopeId === scopeId)
            : schemas;
        return filtered.map((s) => s.content);
    }
    analyzeContent(contentType, contentId) {
        return this.seoService.analyzeContent(contentType, contentId);
    }
    getSeoSettings() {
        return this.seoService.getSeoSettings();
    }
    updateSeoSettings(body) {
        return this.seoService.updateSeoSettings(body);
    }
    async getRobotsTxt(res) {
        const baseUrl = process.env.SITE_URL || 'http://localhost:3000';
        const robotsTxt = await this.seoService.generateRobotsTxt(baseUrl);
        res.send(robotsTxt);
    }
    async getGlobalMeta() {
        const baseUrl = process.env.SITE_URL || 'http://localhost:3000';
        return this.seoService.getGlobalMetaTags(baseUrl);
    }
    async getOrganizationSchema() {
        const baseUrl = process.env.SITE_URL || 'http://localhost:3000';
        return this.seoService.generateOrganizationSchema(baseUrl);
    }
    async getWebsiteSchema() {
        const baseUrl = process.env.SITE_URL || 'http://localhost:3000';
        return this.seoService.generateWebsiteSchema(baseUrl);
    }
};
exports.SeoController = SeoController;
__decorate([
    (0, common_1.Get)('redirects'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], SeoController.prototype, "getRedirects", null);
__decorate([
    (0, common_1.Post)('redirects'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], SeoController.prototype, "createRedirect", null);
__decorate([
    (0, common_1.Put)('redirects/:id'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", void 0)
], SeoController.prototype, "updateRedirect", null);
__decorate([
    (0, common_1.Delete)('redirects/:id'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], SeoController.prototype, "deleteRedirect", null);
__decorate([
    (0, common_1.Get)('sitemap/entries'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], SeoController.prototype, "getSitemapEntries", null);
__decorate([
    (0, common_1.Post)('sitemap/entries'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], SeoController.prototype, "createSitemapEntry", null);
__decorate([
    (0, common_1.Put)('sitemap/entries/:id'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", void 0)
], SeoController.prototype, "updateSitemapEntry", null);
__decorate([
    (0, common_1.Delete)('sitemap/entries/:id'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], SeoController.prototype, "deleteSitemapEntry", null);
__decorate([
    (0, common_1.Get)('sitemap.xml'),
    (0, common_1.Header)('Content-Type', 'application/xml'),
    __param(0, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_b = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _b : Object]),
    __metadata("design:returntype", Promise)
], SeoController.prototype, "getSitemap", null);
__decorate([
    (0, common_1.Get)('schema'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Query)('scope')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], SeoController.prototype, "getSchemaMarkups", null);
__decorate([
    (0, common_1.Post)('schema'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], SeoController.prototype, "createSchemaMarkup", null);
__decorate([
    (0, common_1.Put)('schema/:id'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", void 0)
], SeoController.prototype, "updateSchemaMarkup", null);
__decorate([
    (0, common_1.Delete)('schema/:id'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], SeoController.prototype, "deleteSchemaMarkup", null);
__decorate([
    (0, common_1.Get)('schema/render'),
    __param(0, (0, common_1.Query)('scope')),
    __param(1, (0, common_1.Query)('scopeId')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", Promise)
], SeoController.prototype, "getSchemaForPage", null);
__decorate([
    (0, common_1.Get)('analyze/:contentType/:contentId'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Param)('contentType')),
    __param(1, (0, common_1.Param)('contentId')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", void 0)
], SeoController.prototype, "analyzeContent", null);
__decorate([
    (0, common_1.Get)('settings'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], SeoController.prototype, "getSeoSettings", null);
__decorate([
    (0, common_1.Put)('settings'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_c = typeof Record !== "undefined" && Record) === "function" ? _c : Object]),
    __metadata("design:returntype", void 0)
], SeoController.prototype, "updateSeoSettings", null);
__decorate([
    (0, common_1.Get)('robots.txt'),
    (0, common_1.Header)('Content-Type', 'text/plain'),
    __param(0, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_d = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _d : Object]),
    __metadata("design:returntype", Promise)
], SeoController.prototype, "getRobotsTxt", null);
__decorate([
    (0, common_1.Get)('meta'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SeoController.prototype, "getGlobalMeta", null);
__decorate([
    (0, common_1.Get)('schema/organization'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SeoController.prototype, "getOrganizationSchema", null);
__decorate([
    (0, common_1.Get)('schema/website'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SeoController.prototype, "getWebsiteSchema", null);
exports.SeoController = SeoController = __decorate([
    (0, common_1.Controller)('api/seo'),
    __metadata("design:paramtypes", [typeof (_a = typeof seo_service_1.SeoService !== "undefined" && seo_service_1.SeoService) === "function" ? _a : Object])
], SeoController);


/***/ }),
/* 271 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 SeoService_1;
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SeoService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let SeoService = SeoService_1 = class SeoService {
    constructor(prisma) {
        this.prisma = prisma;
        this.logger = new common_1.Logger(SeoService_1.name);
    }
    async onModuleInit() {
        await this.initializeDefaultSeoSettings();
    }
    async initializeDefaultSeoSettings() {
        const seoSettings = [
            { key: 'seo_site_title', value: 'My Website', type: 'string', group: 'seo' },
            { key: 'seo_site_description', value: 'Welcome to my website - your destination for quality content and services.', type: 'string', group: 'seo' },
            { key: 'seo_site_keywords', value: 'website, blog, services, products', type: 'string', group: 'seo' },
            { key: 'seo_og_image', value: '/images/og-default.jpg', type: 'string', group: 'seo' },
            { key: 'seo_twitter_handle', value: '', type: 'string', group: 'seo' },
            { key: 'seo_google_site_verification', value: '', type: 'string', group: 'seo' },
            { key: 'seo_bing_site_verification', value: '', type: 'string', group: 'seo' },
            { key: 'seo_robots_txt_custom', value: '', type: 'string', group: 'seo' },
            { key: 'seo_organization_name', value: '', type: 'string', group: 'seo' },
            { key: 'seo_organization_logo', value: '', type: 'string', group: 'seo' },
            { key: 'seo_organization_address', value: '', type: 'string', group: 'seo' },
            { key: 'seo_organization_phone', value: '', type: 'string', group: 'seo' },
            { key: 'seo_organization_email', value: '', type: 'string', group: 'seo' },
            { key: 'seo_social_facebook', value: '', type: 'string', group: 'seo' },
            { key: 'seo_social_twitter', value: '', type: 'string', group: 'seo' },
            { key: 'seo_social_instagram', value: '', type: 'string', group: 'seo' },
            { key: 'seo_social_linkedin', value: '', type: 'string', group: 'seo' },
            { key: 'seo_social_youtube', value: '', type: 'string', group: 'seo' },
        ];
        for (const setting of seoSettings) {
            await this.prisma.setting.upsert({
                where: { key: setting.key },
                update: {},
                create: setting,
            });
        }
        this.logger.log('SEO settings initialized');
    }
    async getRedirects() {
        return this.prisma.seoRedirect.findMany({ orderBy: { createdAt: 'desc' } });
    }
    async createRedirect(data) {
        return this.prisma.seoRedirect.create({
            data: { fromPath: data.fromPath, toPath: data.toPath, type: data.type || 301 },
        });
    }
    async updateRedirect(id, data) {
        return this.prisma.seoRedirect.update({ where: { id }, data });
    }
    async deleteRedirect(id) {
        return this.prisma.seoRedirect.delete({ where: { id } });
    }
    async checkRedirect(path) {
        const redirect = await this.prisma.seoRedirect.findUnique({
            where: { fromPath: path, isActive: true },
        });
        if (redirect) {
            await this.prisma.seoRedirect.update({
                where: { id: redirect.id },
                data: { hitCount: { increment: 1 }, lastHitAt: new Date() },
            });
        }
        return redirect;
    }
    async getSitemapEntries() {
        return this.prisma.seoSitemapEntry.findMany({
            where: { isActive: true },
            orderBy: { priority: 'desc' },
        });
    }
    async createSitemapEntry(data) {
        return this.prisma.seoSitemapEntry.create({ data });
    }
    async updateSitemapEntry(id, data) {
        return this.prisma.seoSitemapEntry.update({ where: { id }, data });
    }
    async deleteSitemapEntry(id) {
        return this.prisma.seoSitemapEntry.delete({ where: { id } });
    }
    async generateSitemap(baseUrl) {
        const [posts, pages, products, courses, customEntries] = await Promise.all([
            this.prisma.post.findMany({
                where: { status: 'PUBLISHED' },
                select: { slug: true, updatedAt: true },
            }),
            this.prisma.page.findMany({
                where: { status: 'PUBLISHED' },
                select: { slug: true, updatedAt: true },
            }),
            this.prisma.product.findMany({
                where: { status: 'ACTIVE' },
                select: { slug: true, updatedAt: true },
            }),
            this.prisma.course.findMany({
                where: { status: 'PUBLISHED' },
                select: { slug: true, updatedAt: true },
            }),
            this.getSitemapEntries(),
        ]);
        const urls = [
            { loc: baseUrl, priority: 1.0, changefreq: 'daily' },
            ...posts.map((p) => ({
                loc: `${baseUrl}/blog/${p.slug}`,
                lastmod: p.updatedAt.toISOString(),
                priority: 0.8,
                changefreq: 'weekly',
            })),
            ...pages.map((p) => ({
                loc: `${baseUrl}/${p.slug}`,
                lastmod: p.updatedAt.toISOString(),
                priority: 0.7,
                changefreq: 'monthly',
            })),
            ...products.map((p) => ({
                loc: `${baseUrl}/shop/${p.slug}`,
                lastmod: p.updatedAt.toISOString(),
                priority: 0.8,
                changefreq: 'weekly',
            })),
            ...courses.map((c) => ({
                loc: `${baseUrl}/lms/course/${c.slug}`,
                lastmod: c.updatedAt.toISOString(),
                priority: 0.8,
                changefreq: 'weekly',
            })),
            ...customEntries.map((e) => ({
                loc: e.url.startsWith('http') ? e.url : `${baseUrl}${e.url}`,
                lastmod: e.lastmod.toISOString(),
                priority: e.priority,
                changefreq: e.changefreq,
            })),
        ];
        return this.buildSitemapXml(urls);
    }
    buildSitemapXml(urls) {
        const urlEntries = urls
            .map((u) => `  <url>
    <loc>${u.loc}</loc>
    ${u.lastmod ? `<lastmod>${u.lastmod}</lastmod>` : ''}
    ${u.changefreq ? `<changefreq>${u.changefreq}</changefreq>` : ''}
    ${u.priority ? `<priority>${u.priority}</priority>` : ''}
  </url>`)
            .join('\n');
        return `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urlEntries}
</urlset>`;
    }
    async getSchemaMarkups(scope) {
        const where = scope ? { scope, isActive: true } : { isActive: true };
        return this.prisma.seoSchemaMarkup.findMany({ where, orderBy: { createdAt: 'desc' } });
    }
    async createSchemaMarkup(data) {
        return this.prisma.seoSchemaMarkup.create({ data });
    }
    async updateSchemaMarkup(id, data) {
        return this.prisma.seoSchemaMarkup.update({ where: { id }, data });
    }
    async deleteSchemaMarkup(id) {
        return this.prisma.seoSchemaMarkup.delete({ where: { id } });
    }
    async analyzeContent(contentType, contentId) {
        let content;
        switch (contentType) {
            case 'post':
                content = await this.prisma.post.findUnique({ where: { id: contentId } });
                break;
            case 'page':
                content = await this.prisma.page.findUnique({ where: { id: contentId } });
                break;
            case 'product':
                content = await this.prisma.product.findUnique({ where: { id: contentId } });
                break;
            default:
                throw new Error(`Unknown content type: ${contentType}`);
        }
        if (!content)
            throw new Error('Content not found');
        return this.performSeoAnalysis(content, contentType);
    }
    performSeoAnalysis(content, _contentType) {
        const issues = [];
        const suggestions = [];
        let score = 100;
        if (!content.metaTitle) {
            issues.push('Missing meta title');
            score -= 15;
        }
        else if (content.metaTitle.length < 30) {
            issues.push('Meta title too short (<30 chars)');
            score -= 5;
        }
        else if (content.metaTitle.length > 60) {
            issues.push('Meta title too long (>60 chars)');
            score -= 5;
        }
        if (!content.metaDescription) {
            issues.push('Missing meta description');
            score -= 15;
        }
        else if (content.metaDescription.length < 70) {
            issues.push('Meta description too short (<70 chars)');
            score -= 5;
        }
        else if (content.metaDescription.length > 160) {
            issues.push('Meta description too long (>160 chars)');
            score -= 5;
        }
        const plainContent = (content.content || content.description || '').replace(/<[^>]*>/g, '');
        if (plainContent.length < 300) {
            issues.push('Content too short (<300 chars)');
            score -= 10;
            suggestions.push('Add more detailed content for better SEO');
        }
        if (content.slug && content.slug.includes('_')) {
            issues.push('Slug contains underscores instead of hyphens');
            score -= 5;
        }
        return { score: Math.max(0, score), issues, suggestions, analyzed: new Date().toISOString() };
    }
    async getSeoSettings() {
        const settings = await this.prisma.setting.findMany({
            where: { group: 'seo' },
        });
        const result = {};
        for (const s of settings) {
            result[s.key.replace('seo_', '')] = s.value;
        }
        return result;
    }
    async updateSeoSettings(data) {
        for (const [key, value] of Object.entries(data)) {
            await this.prisma.setting.upsert({
                where: { key: `seo_${key}` },
                update: { value },
                create: { key: `seo_${key}`, value, type: 'string', group: 'seo' },
            });
        }
        return this.getSeoSettings();
    }
    async generateRobotsTxt(baseUrl) {
        const customRobots = await this.prisma.setting.findUnique({
            where: { key: 'seo_robots_txt_custom' },
        });
        if (customRobots?.value && customRobots.value.trim()) {
            return customRobots.value;
        }
        return `# Robots.txt generated by WordPress Node CMS
User-agent: *
Allow: /

# Disallow admin and API paths
Disallow: /admin/
Disallow: /api/
Disallow: /checkout/
Disallow: /login
Disallow: /register
Disallow: /forgot-password
Disallow: /reset-password

# Allow specific API endpoints for crawlers
Allow: /api/seo/sitemap.xml

# Crawl-delay for polite crawling
Crawl-delay: 1

# Sitemap location
Sitemap: ${baseUrl}/api/seo/sitemap.xml
`;
    }
    async generateOrganizationSchema(baseUrl) {
        const settings = await this.getSeoSettings();
        const schema = {
            '@context': 'https://schema.org',
            '@type': 'Organization',
            name: settings.organization_name || settings.site_title || 'Organization',
            url: baseUrl,
        };
        if (settings.site_description) {
            schema.description = settings.site_description;
        }
        if (settings.organization_logo) {
            schema.logo = settings.organization_logo.startsWith('http')
                ? settings.organization_logo
                : `${baseUrl}${settings.organization_logo}`;
        }
        if (settings.organization_email) {
            schema.email = settings.organization_email;
        }
        if (settings.organization_phone) {
            schema.telephone = settings.organization_phone;
        }
        if (settings.organization_address) {
            schema.address = {
                '@type': 'PostalAddress',
                streetAddress: settings.organization_address,
            };
        }
        const sameAs = [];
        if (settings.social_facebook)
            sameAs.push(settings.social_facebook);
        if (settings.social_twitter)
            sameAs.push(settings.social_twitter);
        if (settings.social_instagram)
            sameAs.push(settings.social_instagram);
        if (settings.social_linkedin)
            sameAs.push(settings.social_linkedin);
        if (settings.social_youtube)
            sameAs.push(settings.social_youtube);
        if (sameAs.length > 0) {
            schema.sameAs = sameAs;
        }
        return schema;
    }
    async generateWebsiteSchema(baseUrl) {
        const settings = await this.getSeoSettings();
        return {
            '@context': 'https://schema.org',
            '@type': 'WebSite',
            name: settings.site_title || 'Website',
            description: settings.site_description || '',
            url: baseUrl,
            potentialAction: {
                '@type': 'SearchAction',
                target: {
                    '@type': 'EntryPoint',
                    urlTemplate: `${baseUrl}/search?q={search_term_string}`,
                },
                'query-input': 'required name=search_term_string',
            },
        };
    }
    generateBreadcrumbSchema(baseUrl, items) {
        return {
            '@context': 'https://schema.org',
            '@type': 'BreadcrumbList',
            itemListElement: items.map((item, index) => ({
                '@type': 'ListItem',
                position: index + 1,
                name: item.name,
                item: item.url.startsWith('http') ? item.url : `${baseUrl}${item.url}`,
            })),
        };
    }
    async generateArticleSchema(baseUrl, article) {
        const settings = await this.getSeoSettings();
        return {
            '@context': 'https://schema.org',
            '@type': 'Article',
            headline: article.title,
            description: article.description,
            url: `${baseUrl}/blog/${article.slug}`,
            datePublished: article.publishedAt.toISOString(),
            dateModified: article.updatedAt.toISOString(),
            author: {
                '@type': 'Person',
                name: article.authorName,
            },
            publisher: {
                '@type': 'Organization',
                name: settings.organization_name || settings.site_title || 'Publisher',
                logo: settings.organization_logo ? {
                    '@type': 'ImageObject',
                    url: settings.organization_logo.startsWith('http')
                        ? settings.organization_logo
                        : `${baseUrl}${settings.organization_logo}`,
                } : undefined,
            },
            image: article.image ? (article.image.startsWith('http') ? article.image : `${baseUrl}${article.image}`) : undefined,
        };
    }
    generateProductSchema(baseUrl, product) {
        return {
            '@context': 'https://schema.org',
            '@type': 'Product',
            name: product.name,
            description: product.description,
            url: `${baseUrl}/shop/${product.slug}`,
            sku: product.sku || product.slug,
            image: product.image ? (product.image.startsWith('http') ? product.image : `${baseUrl}${product.image}`) : undefined,
            offers: {
                '@type': 'Offer',
                price: product.price,
                priceCurrency: product.currency || 'USD',
                availability: product.inStock !== false
                    ? 'https://schema.org/InStock'
                    : 'https://schema.org/OutOfStock',
                url: `${baseUrl}/shop/${product.slug}`,
            },
        };
    }
    generateCourseSchema(baseUrl, course) {
        return {
            '@context': 'https://schema.org',
            '@type': 'Course',
            name: course.name,
            description: course.description,
            url: `${baseUrl}/courses/${course.slug}`,
            provider: {
                '@type': 'Organization',
                name: course.instructorName,
            },
            image: course.image ? (course.image.startsWith('http') ? course.image : `${baseUrl}${course.image}`) : undefined,
            offers: course.price ? {
                '@type': 'Offer',
                price: course.price,
                priceCurrency: course.currency || 'USD',
            } : undefined,
        };
    }
    async getGlobalMetaTags(baseUrl) {
        const settings = await this.getSeoSettings();
        return {
            title: settings.site_title || 'Website',
            description: settings.site_description || '',
            keywords: settings.site_keywords || '',
            ogImage: settings.og_image ? (settings.og_image.startsWith('http') ? settings.og_image : `${baseUrl}${settings.og_image}`) : '',
            twitterHandle: settings.twitter_handle || '',
            googleVerification: settings.google_site_verification || '',
            bingVerification: settings.bing_site_verification || '',
        };
    }
};
exports.SeoService = SeoService;
exports.SeoService = SeoService = SeoService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], SeoService);


/***/ }),
/* 272 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.MessagesModule = void 0;
const common_1 = __webpack_require__(2);
const jwt_1 = __webpack_require__(43);
const prisma_module_1 = __webpack_require__(15);
const messages_service_1 = __webpack_require__(273);
const messages_controller_1 = __webpack_require__(274);
const messages_gateway_1 = __webpack_require__(275);
let MessagesModule = class MessagesModule {
};
exports.MessagesModule = MessagesModule;
exports.MessagesModule = MessagesModule = __decorate([
    (0, common_1.Module)({
        imports: [
            prisma_module_1.PrismaModule,
            jwt_1.JwtModule.register({
                secret: process.env.JWT_SECRET || 'your-secret-key',
                signOptions: { expiresIn: '7d' },
            }),
        ],
        controllers: [messages_controller_1.MessagesController],
        providers: [messages_service_1.MessagesService, messages_gateway_1.MessagesGateway],
        exports: [messages_service_1.MessagesService, messages_gateway_1.MessagesGateway],
    })
], MessagesModule);


/***/ }),
/* 273 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.MessagesService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
let MessagesService = class MessagesService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async getOrCreateConversation(userId1, userId2) {
        if (userId1 === userId2) {
            throw new common_1.BadRequestException('Cannot create conversation with yourself');
        }
        const [p1, p2] = [userId1, userId2].sort();
        let conversation = await this.prisma.conversation.findFirst({
            where: {
                OR: [
                    { participant1Id: p1, participant2Id: p2 },
                    { participant1Id: p2, participant2Id: p1 },
                ],
            },
            include: {
                participant1: { select: { id: true, name: true, email: true, avatar: true } },
                participant2: { select: { id: true, name: true, email: true, avatar: true } },
            },
        });
        if (!conversation) {
            conversation = await this.prisma.conversation.create({
                data: { participant1Id: p1, participant2Id: p2 },
                include: {
                    participant1: { select: { id: true, name: true, email: true, avatar: true } },
                    participant2: { select: { id: true, name: true, email: true, avatar: true } },
                },
            });
        }
        return conversation;
    }
    async getConversations(userId) {
        const conversations = await this.prisma.conversation.findMany({
            where: {
                OR: [{ participant1Id: userId }, { participant2Id: userId }],
            },
            include: {
                participant1: { select: { id: true, name: true, email: true, avatar: true } },
                participant2: { select: { id: true, name: true, email: true, avatar: true } },
                messages: {
                    orderBy: { createdAt: 'desc' },
                    take: 1,
                    include: { sender: { select: { id: true, name: true } } },
                },
            },
            orderBy: { lastMessageAt: 'desc' },
        });
        const conversationsWithUnread = await Promise.all(conversations.map(async (conv) => {
            const unreadCount = await this.prisma.directMessage.count({
                where: { conversationId: conv.id, senderId: { not: userId }, isRead: false },
            });
            const otherUser = conv.participant1Id === userId ? conv.participant2 : conv.participant1;
            return {
                ...conv,
                otherUser,
                unreadCount,
                lastMessage: conv.messages[0] || null,
            };
        }));
        return conversationsWithUnread;
    }
    async getMessages(conversationId, userId, cursor, limit = 50) {
        const conversation = await this.prisma.conversation.findFirst({
            where: {
                id: conversationId,
                OR: [{ participant1Id: userId }, { participant2Id: userId }],
            },
        });
        if (!conversation) {
            throw new common_1.NotFoundException('Conversation not found');
        }
        const messages = await this.prisma.directMessage.findMany({
            where: { conversationId },
            include: { sender: { select: { id: true, name: true, email: true, avatar: true } } },
            orderBy: { createdAt: 'desc' },
            take: limit,
            ...(cursor ? { cursor: { id: cursor }, skip: 1 } : {}),
        });
        return messages.reverse();
    }
    async sendMessage(conversationId, senderId, content, media) {
        const conversation = await this.prisma.conversation.findFirst({
            where: {
                id: conversationId,
                OR: [{ participant1Id: senderId }, { participant2Id: senderId }],
            },
        });
        if (!conversation) {
            throw new common_1.NotFoundException('Conversation not found');
        }
        const message = await this.prisma.directMessage.create({
            data: {
                conversationId,
                senderId,
                content,
                media: media && media.length > 0 ? media : [],
            },
            include: { sender: { select: { id: true, name: true, email: true, avatar: true } } },
        });
        await this.prisma.conversation.update({
            where: { id: conversationId },
            data: { lastMessageAt: new Date() },
        });
        return message;
    }
    async markAsRead(conversationId, userId) {
        await this.prisma.directMessage.updateMany({
            where: { conversationId, senderId: { not: userId }, isRead: false },
            data: { isRead: true, readAt: new Date() },
        });
    }
    async getUnreadCount(userId) {
        const conversations = await this.prisma.conversation.findMany({
            where: { OR: [{ participant1Id: userId }, { participant2Id: userId }] },
            select: { id: true },
        });
        return this.prisma.directMessage.count({
            where: {
                conversationId: { in: conversations.map((c) => c.id) },
                senderId: { not: userId },
                isRead: false,
            },
        });
    }
    async deleteMessage(conversationId, messageId, userId) {
        const conversation = await this.prisma.conversation.findFirst({
            where: {
                id: conversationId,
                OR: [{ participant1Id: userId }, { participant2Id: userId }],
            },
        });
        if (!conversation) {
            throw new common_1.NotFoundException('Conversation not found');
        }
        const message = await this.prisma.directMessage.findUnique({
            where: { id: messageId },
        });
        if (!message) {
            throw new common_1.NotFoundException('Message not found');
        }
        if (message.senderId !== userId) {
            throw new common_1.ForbiddenException('You can only delete your own messages');
        }
        await this.prisma.directMessage.delete({ where: { id: messageId } });
        return { success: true, messageId };
    }
    async deleteConversation(conversationId, userId) {
        console.log(`Deleting conversation ${conversationId} for user ${userId}`);
        const conversation = await this.prisma.conversation.findFirst({
            where: {
                id: conversationId,
                OR: [{ participant1Id: userId }, { participant2Id: userId }],
            },
        });
        if (!conversation) {
            console.log(`Conversation ${conversationId} not found for user ${userId}`);
            throw new common_1.NotFoundException('Conversation not found');
        }
        console.log(`Found conversation, deleting messages...`);
        const deletedMessages = await this.prisma.directMessage.deleteMany({
            where: { conversationId },
        });
        console.log(`Deleted ${deletedMessages.count} messages`);
        await this.prisma.conversation.delete({
            where: { id: conversationId },
        });
        console.log(`Conversation ${conversationId} deleted successfully`);
        return { success: true, conversationId };
    }
};
exports.MessagesService = MessagesService;
exports.MessagesService = MessagesService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], MessagesService);


/***/ }),
/* 274 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.MessagesController = void 0;
const common_1 = __webpack_require__(2);
const platform_express_1 = __webpack_require__(124);
const multer_1 = __webpack_require__(125);
const path_1 = __webpack_require__(3);
const uuid_1 = __webpack_require__(25);
const messages_service_1 = __webpack_require__(273);
const messages_gateway_1 = __webpack_require__(275);
const jwt_auth_guard_1 = __webpack_require__(61);
const messageMediaStorage = (0, multer_1.diskStorage)({
    destination: (0, path_1.join)(process.cwd(), 'uploads', 'messages'),
    filename: (req, file, cb) => {
        const uniqueName = `${(0, uuid_1.v4)()}${(0, path_1.extname)(file.originalname)}`;
        cb(null, uniqueName);
    },
});
const mediaFileFilter = (req, file, cb) => {
    const allowedMimes = [
        'image/jpeg',
        'image/png',
        'image/gif',
        'image/webp',
        'video/mp4',
        'video/webm',
        'video/quicktime',
    ];
    if (allowedMimes.includes(file.mimetype)) {
        cb(null, true);
    }
    else {
        cb(new Error('Invalid file type. Only images and videos are allowed.'), false);
    }
};
let MessagesController = class MessagesController {
    constructor(messagesService, messagesGateway) {
        this.messagesService = messagesService;
        this.messagesGateway = messagesGateway;
    }
    async getConversations(req) {
        return this.messagesService.getConversations(req.user.id);
    }
    async startConversation(req, body) {
        return this.messagesService.getOrCreateConversation(req.user.id, body.userId);
    }
    async getMessages(req, conversationId, cursor, limit) {
        return this.messagesService.getMessages(conversationId, req.user.id, cursor, limit ? parseInt(limit, 10) : 50);
    }
    async sendMessage(req, conversationId, body) {
        return this.messagesService.sendMessage(conversationId, req.user.id, body.content, body.media);
    }
    async uploadMedia(files) {
        const media = files.map((file) => ({
            url: `/uploads/messages/${file.filename}`,
            type: file.mimetype.startsWith('video/') ? 'video' : 'image',
            filename: file.originalname,
            size: file.size,
            mimeType: file.mimetype,
        }));
        return { media };
    }
    async markAsRead(req, conversationId) {
        await this.messagesService.markAsRead(conversationId, req.user.id);
        return { success: true };
    }
    async getUnreadCount(req) {
        const count = await this.messagesService.getUnreadCount(req.user.id);
        return { count };
    }
    async getOnlineUsers() {
        return { users: this.messagesGateway.getOnlineUsers() };
    }
    async deleteConversation(req, conversationId) {
        return this.messagesService.deleteConversation(conversationId, req.user.id);
    }
    async deleteMessage(req, conversationId, messageId) {
        return this.messagesService.deleteMessage(conversationId, messageId, req.user.id);
    }
};
exports.MessagesController = MessagesController;
__decorate([
    (0, common_1.Get)('conversations'),
    __param(0, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], MessagesController.prototype, "getConversations", null);
__decorate([
    (0, common_1.Post)('conversations'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Object]),
    __metadata("design:returntype", Promise)
], MessagesController.prototype, "startConversation", null);
__decorate([
    (0, common_1.Get)('conversations/:id/messages'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __param(2, (0, common_1.Query)('cursor')),
    __param(3, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, String, String]),
    __metadata("design:returntype", Promise)
], MessagesController.prototype, "getMessages", null);
__decorate([
    (0, common_1.Post)('conversations/:id/messages'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __param(2, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, Object]),
    __metadata("design:returntype", Promise)
], MessagesController.prototype, "sendMessage", null);
__decorate([
    (0, common_1.Post)('upload'),
    (0, common_1.UseInterceptors)((0, platform_express_1.FilesInterceptor)('files', 10, {
        storage: messageMediaStorage,
        fileFilter: mediaFileFilter,
        limits: { fileSize: 50 * 1024 * 1024 },
    })),
    __param(0, (0, common_1.UploadedFiles)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Array]),
    __metadata("design:returntype", Promise)
], MessagesController.prototype, "uploadMedia", null);
__decorate([
    (0, common_1.Post)('conversations/:id/read'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String]),
    __metadata("design:returntype", Promise)
], MessagesController.prototype, "markAsRead", null);
__decorate([
    (0, common_1.Get)('unread-count'),
    __param(0, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], MessagesController.prototype, "getUnreadCount", null);
__decorate([
    (0, common_1.Get)('online-users'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], MessagesController.prototype, "getOnlineUsers", null);
__decorate([
    (0, common_1.Delete)('conversations/:conversationId'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('conversationId')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String]),
    __metadata("design:returntype", Promise)
], MessagesController.prototype, "deleteConversation", null);
__decorate([
    (0, common_1.Delete)('conversations/:conversationId/messages/:messageId'),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('conversationId')),
    __param(2, (0, common_1.Param)('messageId')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, String]),
    __metadata("design:returntype", Promise)
], MessagesController.prototype, "deleteMessage", null);
exports.MessagesController = MessagesController = __decorate([
    (0, common_1.Controller)('api/messages'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
    __metadata("design:paramtypes", [typeof (_a = typeof messages_service_1.MessagesService !== "undefined" && messages_service_1.MessagesService) === "function" ? _a : Object, typeof (_b = typeof messages_gateway_1.MessagesGateway !== "undefined" && messages_gateway_1.MessagesGateway) === "function" ? _b : Object])
], MessagesController);


/***/ }),
/* 275 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.MessagesGateway = void 0;
const websockets_1 = __webpack_require__(264);
const socket_io_1 = __webpack_require__(265);
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const jwt_1 = __webpack_require__(43);
const messages_service_1 = __webpack_require__(273);
let MessagesGateway = class MessagesGateway {
    constructor(prisma, jwtService, messagesService) {
        this.prisma = prisma;
        this.jwtService = jwtService;
        this.messagesService = messagesService;
        this.userSockets = new Map();
        this.socketUsers = new Map();
    }
    async handleConnection(client) {
        try {
            const token = client.handshake.auth.token || client.handshake.headers.authorization?.split(' ')[1];
            if (!token)
                throw new common_1.UnauthorizedException('No token provided');
            const payload = this.jwtService.verify(token);
            const user = await this.prisma.user.findUnique({
                where: { id: payload.sub },
                select: { id: true, name: true, email: true, avatar: true },
            });
            if (!user)
                throw new common_1.UnauthorizedException('User not found');
            this.socketUsers.set(client.id, user);
            if (!this.userSockets.has(user.id)) {
                this.userSockets.set(user.id, new Set());
            }
            this.userSockets.get(user.id).add(client.id);
            const onlineUserIds = Array.from(this.userSockets.keys());
            client.emit('users:online:list', { users: onlineUserIds });
            this.server.emit('user:online', { userId: user.id });
            console.log(`User ${user.name} connected to messages gateway (${onlineUserIds.length} users online, ${this.userSockets.get(user.id).size} devices)`);
        }
        catch (error) {
            console.error('WebSocket authentication failed:', error.message);
            client.disconnect();
        }
    }
    async handleDisconnect(client) {
        const user = this.socketUsers.get(client.id);
        if (user) {
            this.socketUsers.delete(client.id);
            const userSocketSet = this.userSockets.get(user.id);
            if (userSocketSet) {
                userSocketSet.delete(client.id);
                if (userSocketSet.size === 0) {
                    this.userSockets.delete(user.id);
                    this.server.emit('user:offline', { userId: user.id });
                    console.log(`User ${user.name} disconnected from messages gateway (now offline)`);
                }
                else {
                    console.log(`User ${user.name} disconnected one device (${userSocketSet.size} devices still connected)`);
                }
            }
        }
    }
    async handleSendMessage(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return { error: 'Unauthorized' };
        try {
            const message = await this.messagesService.sendMessage(data.conversationId, user.id, data.content, data.media);
            const conversation = await this.prisma.conversation.findUnique({
                where: { id: data.conversationId },
            });
            if (conversation) {
                const recipientId = conversation.participant1Id === user.id
                    ? conversation.participant2Id
                    : conversation.participant1Id;
                client.emit('dm:message:new', message);
                this.emitToUser(recipientId, 'dm:message:new', message);
            }
            return { success: true, message };
        }
        catch (error) {
            console.error('Error sending message:', error);
            return { error: error.message || 'Failed to send message' };
        }
    }
    async handleTypingStart(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return;
        const conversation = await this.prisma.conversation.findUnique({
            where: { id: data.conversationId },
        });
        if (!conversation)
            return;
        const recipientId = conversation.participant1Id === user.id
            ? conversation.participant2Id
            : conversation.participant1Id;
        this.emitToUser(recipientId, 'dm:typing', {
            conversationId: data.conversationId,
            userId: user.id,
            userName: user.name,
            isTyping: true,
        });
    }
    async handleTypingStop(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return;
        const conversation = await this.prisma.conversation.findUnique({
            where: { id: data.conversationId },
        });
        if (!conversation)
            return;
        const recipientId = conversation.participant1Id === user.id
            ? conversation.participant2Id
            : conversation.participant1Id;
        this.emitToUser(recipientId, 'dm:typing', {
            conversationId: data.conversationId,
            userId: user.id,
            userName: user.name,
            isTyping: false,
        });
    }
    async handleMarkRead(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return;
        await this.messagesService.markAsRead(data.conversationId, user.id);
        const conversation = await this.prisma.conversation.findUnique({
            where: { id: data.conversationId },
        });
        if (conversation) {
            const recipientId = conversation.participant1Id === user.id
                ? conversation.participant2Id
                : conversation.participant1Id;
            this.emitToUser(recipientId, 'dm:read', {
                conversationId: data.conversationId,
                readBy: user.id,
            });
        }
    }
    async handleDeleteMessage(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return { error: 'Unauthorized' };
        const message = await this.prisma.directMessage.findUnique({
            where: { id: data.messageId },
        });
        if (!message || message.senderId !== user.id) {
            return { error: 'Cannot delete this message' };
        }
        await this.prisma.directMessage.delete({ where: { id: data.messageId } });
        client.emit('dm:message:deleted', {
            messageId: data.messageId,
            conversationId: data.conversationId,
        });
        const conversation = await this.prisma.conversation.findUnique({
            where: { id: data.conversationId },
        });
        if (conversation) {
            const recipientId = conversation.participant1Id === user.id
                ? conversation.participant2Id
                : conversation.participant1Id;
            this.emitToUser(recipientId, 'dm:message:deleted', {
                messageId: data.messageId,
                conversationId: data.conversationId,
            });
        }
        return { success: true };
    }
    async handleCallInitiate(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return { error: 'Unauthorized' };
        if (!this.isUserOnline(data.targetUserId)) {
            client.emit('call:error', { message: 'User is offline' });
            return { error: 'User is offline' };
        }
        this.emitToUser(data.targetUserId, 'call:incoming', {
            callerId: user.id,
            callerName: user.name,
            callerAvatar: user.avatar,
            conversationId: data.conversationId,
        });
        return { success: true };
    }
    async handleCallAccept(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return { error: 'Unauthorized' };
        this.emitToUser(data.callerId, 'call:accepted', {
            acceptedBy: user.id,
            acceptedByName: user.name,
            conversationId: data.conversationId,
        });
        return { success: true };
    }
    async handleCallReject(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return { error: 'Unauthorized' };
        this.emitToUser(data.callerId, 'call:rejected', {
            rejectedBy: user.id,
            reason: data.reason || 'Call declined',
        });
        return { success: true };
    }
    async handleCallEnd(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return { error: 'Unauthorized' };
        this.emitToUser(data.targetUserId, 'call:ended', {
            endedBy: user.id,
        });
        return { success: true };
    }
    async handleCallOffer(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return { error: 'Unauthorized' };
        this.emitToUser(data.targetUserId, 'call:offer', {
            callerId: user.id,
            offer: data.offer,
        });
        return { success: true };
    }
    async handleCallAnswer(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return { error: 'Unauthorized' };
        this.emitToUser(data.targetUserId, 'call:answer', {
            answererId: user.id,
            answer: data.answer,
        });
        return { success: true };
    }
    async handleIceCandidate(client, data) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return { error: 'Unauthorized' };
        this.emitToUser(data.targetUserId, 'call:ice-candidate', {
            fromUserId: user.id,
            candidate: data.candidate,
        });
        return { success: true };
    }
    handleRequestOnlineUsers(client) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return { error: 'Unauthorized' };
        const onlineUserIds = Array.from(this.userSockets.keys());
        client.emit('users:online:list', { users: onlineUserIds });
        console.log(`User ${user.name} requested online users list (${onlineUserIds.length} users online)`);
        return { success: true, count: onlineUserIds.length };
    }
    handlePing(client) {
        const user = this.socketUsers.get(client.id);
        if (!user)
            return { error: 'Unauthorized' };
        return { pong: true, timestamp: Date.now() };
    }
    getOnlineUsers() {
        return Array.from(this.userSockets.keys());
    }
    isUserOnline(userId) {
        return this.userSockets.has(userId);
    }
    emitToUser(userId, event, data) {
        const socketIds = this.userSockets.get(userId);
        if (socketIds) {
            socketIds.forEach((socketId) => {
                this.server.to(socketId).emit(event, data);
            });
        }
    }
};
exports.MessagesGateway = MessagesGateway;
__decorate([
    (0, websockets_1.WebSocketServer)(),
    __metadata("design:type", typeof (_d = typeof socket_io_1.Server !== "undefined" && socket_io_1.Server) === "function" ? _d : Object)
], MessagesGateway.prototype, "server", void 0);
__decorate([
    (0, websockets_1.SubscribeMessage)('dm:send'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_e = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _e : Object, Object]),
    __metadata("design:returntype", Promise)
], MessagesGateway.prototype, "handleSendMessage", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('dm:typing:start'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_f = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _f : Object, Object]),
    __metadata("design:returntype", Promise)
], MessagesGateway.prototype, "handleTypingStart", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('dm:typing:stop'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_g = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _g : Object, Object]),
    __metadata("design:returntype", Promise)
], MessagesGateway.prototype, "handleTypingStop", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('dm:read'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_h = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _h : Object, Object]),
    __metadata("design:returntype", Promise)
], MessagesGateway.prototype, "handleMarkRead", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('dm:delete'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_j = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _j : Object, Object]),
    __metadata("design:returntype", Promise)
], MessagesGateway.prototype, "handleDeleteMessage", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('call:initiate'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_k = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _k : Object, Object]),
    __metadata("design:returntype", Promise)
], MessagesGateway.prototype, "handleCallInitiate", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('call:accept'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_l = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _l : Object, Object]),
    __metadata("design:returntype", Promise)
], MessagesGateway.prototype, "handleCallAccept", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('call:reject'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_m = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _m : Object, Object]),
    __metadata("design:returntype", Promise)
], MessagesGateway.prototype, "handleCallReject", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('call:end'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_o = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _o : Object, Object]),
    __metadata("design:returntype", Promise)
], MessagesGateway.prototype, "handleCallEnd", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('call:offer'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_p = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _p : Object, Object]),
    __metadata("design:returntype", Promise)
], MessagesGateway.prototype, "handleCallOffer", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('call:answer'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_q = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _q : Object, Object]),
    __metadata("design:returntype", Promise)
], MessagesGateway.prototype, "handleCallAnswer", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('call:ice-candidate'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __param(1, (0, websockets_1.MessageBody)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_r = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _r : Object, Object]),
    __metadata("design:returntype", Promise)
], MessagesGateway.prototype, "handleIceCandidate", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('users:request:list'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_s = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _s : Object]),
    __metadata("design:returntype", void 0)
], MessagesGateway.prototype, "handleRequestOnlineUsers", null);
__decorate([
    (0, websockets_1.SubscribeMessage)('ping'),
    __param(0, (0, websockets_1.ConnectedSocket)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_t = typeof socket_io_1.Socket !== "undefined" && socket_io_1.Socket) === "function" ? _t : Object]),
    __metadata("design:returntype", void 0)
], MessagesGateway.prototype, "handlePing", null);
exports.MessagesGateway = MessagesGateway = __decorate([
    (0, websockets_1.WebSocketGateway)({
        cors: { origin: '*', credentials: true },
        namespace: '/messages',
    }),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof jwt_1.JwtService !== "undefined" && jwt_1.JwtService) === "function" ? _b : Object, typeof (_c = typeof messages_service_1.MessagesService !== "undefined" && messages_service_1.MessagesService) === "function" ? _c : Object])
], MessagesGateway);


/***/ }),
/* 276 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.BackupModule = void 0;
const common_1 = __webpack_require__(2);
const backup_controller_1 = __webpack_require__(277);
const backup_service_1 = __webpack_require__(278);
const prisma_module_1 = __webpack_require__(15);
let BackupModule = class BackupModule {
};
exports.BackupModule = BackupModule;
exports.BackupModule = BackupModule = __decorate([
    (0, common_1.Module)({
        imports: [prisma_module_1.PrismaModule],
        controllers: [backup_controller_1.BackupController],
        providers: [backup_service_1.BackupService],
        exports: [backup_service_1.BackupService],
    })
], BackupModule);


/***/ }),
/* 277 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b, _c, _d, _e;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.BackupController = void 0;
const common_1 = __webpack_require__(2);
const express_1 = __webpack_require__(57);
const backup_service_1 = __webpack_require__(278);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const client_1 = __webpack_require__(17);
let BackupController = class BackupController {
    constructor(backupService) {
        this.backupService = backupService;
    }
    async create(dto, req) {
        return this.backupService.create(dto, req.user.id);
    }
    async findAll(page, limit, status, type) {
        return this.backupService.findAll({
            page: page ? parseInt(page) : 1,
            limit: limit ? parseInt(limit) : 20,
            status,
            type,
        });
    }
    async getStats() {
        return this.backupService.getStats();
    }
    async findOne(id) {
        const backup = await this.backupService.findOne(id);
        if (!backup) {
            throw new common_1.NotFoundException('Backup not found');
        }
        return backup;
    }
    async download(id, res) {
        const backup = await this.backupService.findOne(id);
        if (!backup) {
            throw new common_1.NotFoundException('Backup not found');
        }
        if (!backup.filePath) {
            throw new common_1.NotFoundException('Backup file not available');
        }
        const filePath = this.backupService.getFilePath(backup.filePath);
        if (!filePath) {
            throw new common_1.NotFoundException('Backup file not found on disk');
        }
        res.download(filePath, backup.filePath);
    }
    async delete(id) {
        const backup = await this.backupService.findOne(id);
        if (!backup) {
            throw new common_1.NotFoundException('Backup not found');
        }
        await this.backupService.delete(id);
        return { success: true };
    }
    async quickBackup(req) {
        const name = `Quick Backup - ${new Date().toLocaleString()}`;
        return this.backupService.create({ name, type: 'FULL' }, req.user.id);
    }
    async databaseBackup(req) {
        const name = `Database Backup - ${new Date().toLocaleString()}`;
        return this.backupService.create({
            name,
            type: 'DATABASE',
            includesDatabase: true,
            includesMedia: false,
            includesThemes: false,
            includesPlugins: false,
        }, req.user.id);
    }
    async restore(id, options) {
        const backup = await this.backupService.findOne(id);
        if (!backup) {
            throw new common_1.NotFoundException('Backup not found');
        }
        if (backup.status !== 'COMPLETED') {
            throw new common_1.ForbiddenException('Cannot restore from incomplete backup');
        }
        return this.backupService.restore(id, options);
    }
};
exports.BackupController = BackupController;
__decorate([
    (0, common_1.Post)(),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_b = typeof backup_service_1.CreateBackupDto !== "undefined" && backup_service_1.CreateBackupDto) === "function" ? _b : Object, Object]),
    __metadata("design:returntype", Promise)
], BackupController.prototype, "create", null);
__decorate([
    (0, common_1.Get)(),
    __param(0, (0, common_1.Query)('page')),
    __param(1, (0, common_1.Query)('limit')),
    __param(2, (0, common_1.Query)('status')),
    __param(3, (0, common_1.Query)('type')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, typeof (_c = typeof client_1.BackupStatus !== "undefined" && client_1.BackupStatus) === "function" ? _c : Object, typeof (_d = typeof client_1.BackupType !== "undefined" && client_1.BackupType) === "function" ? _d : Object]),
    __metadata("design:returntype", Promise)
], BackupController.prototype, "findAll", null);
__decorate([
    (0, common_1.Get)('stats'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], BackupController.prototype, "getStats", null);
__decorate([
    (0, common_1.Get)(':id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], BackupController.prototype, "findOne", null);
__decorate([
    (0, common_1.Get)(':id/download'),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Res)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, typeof (_e = typeof express_1.Response !== "undefined" && express_1.Response) === "function" ? _e : Object]),
    __metadata("design:returntype", Promise)
], BackupController.prototype, "download", null);
__decorate([
    (0, common_1.Delete)(':id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], BackupController.prototype, "delete", null);
__decorate([
    (0, common_1.Post)('quick'),
    __param(0, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], BackupController.prototype, "quickBackup", null);
__decorate([
    (0, common_1.Post)('database'),
    __param(0, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], BackupController.prototype, "databaseBackup", null);
__decorate([
    (0, common_1.Post)(':id/restore'),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, Object]),
    __metadata("design:returntype", Promise)
], BackupController.prototype, "restore", null);
exports.BackupController = BackupController = __decorate([
    (0, common_1.Controller)('api/backups'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __metadata("design:paramtypes", [typeof (_a = typeof backup_service_1.BackupService !== "undefined" && backup_service_1.BackupService) === "function" ? _a : Object])
], BackupController);


/***/ }),
/* 278 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 BackupService_1;
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.BackupService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const fs = __webpack_require__(4);
const path = __webpack_require__(3);
const archiver = __webpack_require__(279);
const AdmZip = __webpack_require__(130);
const crypto_1 = __webpack_require__(48);
let BackupService = BackupService_1 = class BackupService {
    constructor(prisma) {
        this.prisma = prisma;
        this.logger = new common_1.Logger(BackupService_1.name);
        this.backupDir = path.join(process.cwd(), 'backups');
        if (!fs.existsSync(this.backupDir)) {
            fs.mkdirSync(this.backupDir, { recursive: true });
        }
    }
    async create(dto, userId) {
        const backup = await this.prisma.backup.create({
            data: {
                name: dto.name,
                description: dto.description,
                type: dto.type || 'FULL',
                status: 'PENDING',
                includesDatabase: dto.includesDatabase ?? true,
                includesMedia: dto.includesMedia ?? true,
                includesThemes: dto.includesThemes ?? true,
                includesPlugins: dto.includesPlugins ?? true,
                createdById: userId,
            },
        });
        this.runBackup(backup.id).catch((err) => {
            this.logger.error(`Backup ${backup.id} failed: ${err.message}`);
        });
        return backup;
    }
    async runBackup(backupId) {
        const backup = await this.prisma.backup.findUnique({ where: { id: backupId } });
        if (!backup)
            return;
        await this.prisma.backup.update({
            where: { id: backupId },
            data: { status: 'IN_PROGRESS', startedAt: new Date() },
        });
        try {
            const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
            const fileName = `backup-${backup.type.toLowerCase()}-${timestamp}.zip`;
            const filePath = path.join(this.backupDir, fileName);
            const archive = archiver('zip', { zlib: { level: 9 } });
            const output = fs.createWriteStream(filePath);
            let filesCount = 0;
            let recordsCount = 0;
            let tablesCount = 0;
            await new Promise((resolve, reject) => {
                output.on('close', resolve);
                archive.on('error', reject);
                archive.pipe(output);
                if (backup.includesDatabase) {
                    const dbData = this.exportDatabaseSync();
                    archive.append(JSON.stringify(dbData, null, 2), { name: 'database.json' });
                    tablesCount = Object.keys(dbData).length;
                    recordsCount = Object.values(dbData).reduce((sum, arr) => sum + arr.length, 0);
                }
                if (backup.includesMedia) {
                    const uploadsDir = path.join(process.cwd(), 'uploads');
                    if (fs.existsSync(uploadsDir)) {
                        archive.directory(uploadsDir, 'uploads');
                        filesCount += this.countFiles(uploadsDir);
                    }
                }
                if (backup.includesThemes) {
                    const themesDir = path.join(process.cwd(), 'themes');
                    if (fs.existsSync(themesDir)) {
                        archive.directory(themesDir, 'themes');
                        filesCount += this.countFiles(themesDir);
                    }
                }
                if (backup.includesPlugins) {
                    const pluginsDir = path.join(process.cwd(), 'plugins');
                    if (fs.existsSync(pluginsDir)) {
                        archive.directory(pluginsDir, 'plugins');
                        filesCount += this.countFiles(pluginsDir);
                    }
                }
                archive.finalize();
            });
            const stats = fs.statSync(filePath);
            const checksum = await this.calculateChecksum(filePath);
            await this.prisma.backup.update({
                where: { id: backupId },
                data: {
                    status: 'COMPLETED',
                    filePath: fileName,
                    fileSize: BigInt(stats.size),
                    checksum,
                    tablesCount,
                    recordsCount,
                    filesCount,
                    completedAt: new Date(),
                },
            });
            this.logger.log(`Backup ${backupId} completed: ${fileName}`);
        }
        catch (error) {
            await this.prisma.backup.update({
                where: { id: backupId },
                data: {
                    status: 'FAILED',
                    errorMessage: error.message,
                    completedAt: new Date(),
                },
            });
            throw error;
        }
    }
    exportDatabaseSync() {
        return {};
    }
    async exportDatabase() {
        const data = {};
        data.users = await this.prisma.user.findMany({
            select: { id: true, email: true, name: true, role: true, createdAt: true },
        });
        data.posts = await this.prisma.post.findMany();
        data.pages = await this.prisma.page.findMany();
        data.media = await this.prisma.media.findMany();
        data.menus = await this.prisma.menu.findMany({ include: { items: true } });
        data.settings = await this.prisma.setting.findMany();
        return data;
    }
    countFiles(dir) {
        let count = 0;
        try {
            const items = fs.readdirSync(dir);
            for (const item of items) {
                const fullPath = path.join(dir, item);
                const stat = fs.statSync(fullPath);
                if (stat.isDirectory()) {
                    count += this.countFiles(fullPath);
                }
                else {
                    count++;
                }
            }
        }
        catch {
        }
        return count;
    }
    async calculateChecksum(filePath) {
        return new Promise((resolve, reject) => {
            const hash = (0, crypto_1.createHash)('md5');
            const stream = fs.createReadStream(filePath);
            stream.on('data', (data) => hash.update(data));
            stream.on('end', () => resolve(hash.digest('hex')));
            stream.on('error', reject);
        });
    }
    async findAll(query = {}) {
        const { page = 1, limit = 20, status, type } = query;
        const skip = (page - 1) * limit;
        const where = {};
        if (status)
            where.status = status;
        if (type)
            where.type = type;
        const [backups, total] = await Promise.all([
            this.prisma.backup.findMany({
                where,
                orderBy: { createdAt: 'desc' },
                skip,
                take: limit,
                include: { createdBy: { select: { id: true, name: true, email: true } } },
            }),
            this.prisma.backup.count({ where }),
        ]);
        return {
            data: backups.map((b) => ({
                ...b,
                fileSize: b.fileSize ? Number(b.fileSize) : null,
            })),
            meta: { total, page, limit, totalPages: Math.ceil(total / limit) },
        };
    }
    async findOne(id) {
        const backup = await this.prisma.backup.findUnique({
            where: { id },
            include: { createdBy: { select: { id: true, name: true, email: true } } },
        });
        if (backup) {
            return { ...backup, fileSize: backup.fileSize ? Number(backup.fileSize) : null };
        }
        return null;
    }
    async delete(id) {
        const backup = await this.prisma.backup.findUnique({ where: { id } });
        if (backup?.filePath) {
            const fullPath = path.join(this.backupDir, backup.filePath);
            if (fs.existsSync(fullPath)) {
                fs.unlinkSync(fullPath);
            }
        }
        return this.prisma.backup.delete({ where: { id } });
    }
    getFilePath(fileName) {
        const fullPath = path.join(this.backupDir, fileName);
        if (fs.existsSync(fullPath)) {
            return fullPath;
        }
        return null;
    }
    async getStats() {
        const [total, completed, failed, inProgress, totalSize] = await Promise.all([
            this.prisma.backup.count(),
            this.prisma.backup.count({ where: { status: 'COMPLETED' } }),
            this.prisma.backup.count({ where: { status: 'FAILED' } }),
            this.prisma.backup.count({ where: { status: 'IN_PROGRESS' } }),
            this.prisma.backup.aggregate({ _sum: { fileSize: true } }),
        ]);
        return {
            total,
            completed,
            failed,
            inProgress,
            totalSize: totalSize._sum.fileSize ? Number(totalSize._sum.fileSize) : 0,
        };
    }
    async restore(id, options = {}) {
        const backup = await this.prisma.backup.findUnique({ where: { id } });
        if (!backup) {
            throw new common_1.BadRequestException('Backup not found');
        }
        if (backup.status !== 'COMPLETED') {
            throw new common_1.BadRequestException('Cannot restore from incomplete backup');
        }
        if (!backup.filePath) {
            throw new common_1.BadRequestException('Backup file not available');
        }
        const backupPath = path.join(this.backupDir, backup.filePath);
        if (!fs.existsSync(backupPath)) {
            throw new common_1.BadRequestException('Backup file not found on disk');
        }
        const restoreDatabase = options.restoreDatabase ?? backup.includesDatabase;
        const restoreMedia = options.restoreMedia ?? backup.includesMedia;
        const restoreThemes = options.restoreThemes ?? backup.includesThemes;
        const restorePlugins = options.restorePlugins ?? backup.includesPlugins;
        const results = {};
        try {
            const zip = new AdmZip(backupPath);
            const zipEntries = zip.getEntries();
            if (restoreDatabase) {
                const dbEntry = zipEntries.find((e) => e.entryName === 'database.json');
                if (dbEntry) {
                    const dbData = JSON.parse(dbEntry.getData().toString('utf8'));
                    results.database = await this.restoreDatabase(dbData);
                }
            }
            if (restoreMedia) {
                const mediaEntries = zipEntries.filter((e) => e.entryName.startsWith('uploads/'));
                if (mediaEntries.length > 0) {
                    const uploadsDir = path.join(process.cwd(), 'uploads');
                    if (!fs.existsSync(uploadsDir)) {
                        fs.mkdirSync(uploadsDir, { recursive: true });
                    }
                    for (const entry of mediaEntries) {
                        if (!entry.isDirectory) {
                            const targetPath = path.join(process.cwd(), entry.entryName);
                            const targetDir = path.dirname(targetPath);
                            if (!fs.existsSync(targetDir)) {
                                fs.mkdirSync(targetDir, { recursive: true });
                            }
                            fs.writeFileSync(targetPath, entry.getData());
                        }
                    }
                    results.media = { filesRestored: mediaEntries.filter((e) => !e.isDirectory).length };
                }
            }
            if (restoreThemes) {
                const themeEntries = zipEntries.filter((e) => e.entryName.startsWith('themes/'));
                if (themeEntries.length > 0) {
                    for (const entry of themeEntries) {
                        if (!entry.isDirectory) {
                            const targetPath = path.join(process.cwd(), entry.entryName);
                            const targetDir = path.dirname(targetPath);
                            if (!fs.existsSync(targetDir)) {
                                fs.mkdirSync(targetDir, { recursive: true });
                            }
                            fs.writeFileSync(targetPath, entry.getData());
                        }
                    }
                    results.themes = { filesRestored: themeEntries.filter((e) => !e.isDirectory).length };
                }
            }
            if (restorePlugins) {
                const pluginEntries = zipEntries.filter((e) => e.entryName.startsWith('plugins/'));
                if (pluginEntries.length > 0) {
                    for (const entry of pluginEntries) {
                        if (!entry.isDirectory) {
                            const targetPath = path.join(process.cwd(), entry.entryName);
                            const targetDir = path.dirname(targetPath);
                            if (!fs.existsSync(targetDir)) {
                                fs.mkdirSync(targetDir, { recursive: true });
                            }
                            fs.writeFileSync(targetPath, entry.getData());
                        }
                    }
                    results.plugins = { filesRestored: pluginEntries.filter((e) => !e.isDirectory).length };
                }
            }
            this.logger.log(`Backup ${id} restored successfully`);
            return { success: true, message: 'Backup restored successfully', results };
        }
        catch (error) {
            this.logger.error(`Restore failed: ${error.message}`);
            throw new common_1.BadRequestException(`Restore failed: ${error.message}`);
        }
    }
    async restoreDatabase(data) {
        const results = {};
        if (data.settings && Array.isArray(data.settings)) {
            for (const setting of data.settings) {
                await this.prisma.setting.upsert({
                    where: { key: setting.key },
                    create: setting,
                    update: setting,
                });
            }
            results.settings = data.settings.length;
        }
        if (data.posts && Array.isArray(data.posts)) {
            for (const post of data.posts) {
                try {
                    await this.prisma.post.upsert({
                        where: { id: post.id },
                        create: post,
                        update: post,
                    });
                }
                catch {
                }
            }
            results.posts = data.posts.length;
        }
        if (data.pages && Array.isArray(data.pages)) {
            for (const page of data.pages) {
                try {
                    await this.prisma.page.upsert({
                        where: { id: page.id },
                        create: page,
                        update: page,
                    });
                }
                catch {
                }
            }
            results.pages = data.pages.length;
        }
        if (data.menus && Array.isArray(data.menus)) {
            for (const menu of data.menus) {
                try {
                    const { items, ...menuData } = menu;
                    await this.prisma.menu.upsert({
                        where: { id: menu.id },
                        create: menuData,
                        update: menuData,
                    });
                    if (items && Array.isArray(items)) {
                        for (const item of items) {
                            await this.prisma.menuItem.upsert({
                                where: { id: item.id },
                                create: item,
                                update: item,
                            });
                        }
                    }
                }
                catch {
                }
            }
            results.menus = data.menus.length;
        }
        return results;
    }
};
exports.BackupService = BackupService;
exports.BackupService = BackupService = BackupService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], BackupService);


/***/ }),
/* 279 */
/***/ ((module) => {

module.exports = require("archiver");

/***/ }),
/* 280 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UpdatesModule = void 0;
const common_1 = __webpack_require__(2);
const updates_controller_1 = __webpack_require__(281);
const updates_service_1 = __webpack_require__(282);
const version_service_1 = __webpack_require__(283);
const migration_service_1 = __webpack_require__(284);
const prisma_service_1 = __webpack_require__(16);
const backup_module_1 = __webpack_require__(276);
let UpdatesModule = class UpdatesModule {
};
exports.UpdatesModule = UpdatesModule;
exports.UpdatesModule = UpdatesModule = __decorate([
    (0, common_1.Module)({
        imports: [backup_module_1.BackupModule],
        controllers: [updates_controller_1.UpdatesController],
        providers: [updates_service_1.UpdatesService, version_service_1.VersionService, migration_service_1.MigrationService, prisma_service_1.PrismaService],
        exports: [updates_service_1.UpdatesService, version_service_1.VersionService],
    })
], UpdatesModule);


/***/ }),
/* 281 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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); }
};
var _a, _b;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UpdatesController = void 0;
const common_1 = __webpack_require__(2);
const jwt_auth_guard_1 = __webpack_require__(61);
const roles_guard_1 = __webpack_require__(72);
const roles_decorator_1 = __webpack_require__(73);
const client_1 = __webpack_require__(17);
const updates_service_1 = __webpack_require__(282);
const version_service_1 = __webpack_require__(283);
let UpdatesController = class UpdatesController {
    constructor(updatesService, versionService) {
        this.updatesService = updatesService;
        this.versionService = versionService;
    }
    async getStatus() {
        return this.updatesService.getStatus();
    }
    async checkForUpdates() {
        return this.updatesService.checkForUpdates();
    }
    async getAvailableUpdates() {
        return this.versionService.getAvailableUpdates();
    }
    async getUpdateHistory(limit) {
        return this.updatesService.getUpdateHistory(limit ? parseInt(limit, 10) : 20);
    }
    async checkCompatibility(version) {
        return this.versionService.checkCompatibility(version);
    }
    async downloadUpdate(body) {
        return this.updatesService.downloadUpdate(body.version);
    }
    async applyUpdate(body, req) {
        return this.updatesService.applyUpdate(body.version, req.user?.id);
    }
    async rollback(id) {
        return this.updatesService.rollback(id);
    }
    async getVersionInfo() {
        const currentVersion = this.versionService.getCurrentVersion();
        const versionHistory = await this.versionService.getVersionHistory();
        return {
            currentVersion,
            versionHistory,
            nodeVersion: process.version,
            platform: process.platform,
            arch: process.arch,
        };
    }
    async pullLatest(req) {
        return this.updatesService.pullLatest(req.user?.id);
    }
};
exports.UpdatesController = UpdatesController;
__decorate([
    (0, common_1.Get)('status'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], UpdatesController.prototype, "getStatus", null);
__decorate([
    (0, common_1.Get)('check'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], UpdatesController.prototype, "checkForUpdates", null);
__decorate([
    (0, common_1.Get)('available'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], UpdatesController.prototype, "getAvailableUpdates", null);
__decorate([
    (0, common_1.Get)('history'),
    __param(0, (0, common_1.Query)('limit')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], UpdatesController.prototype, "getUpdateHistory", null);
__decorate([
    (0, common_1.Get)('compatibility/:version'),
    __param(0, (0, common_1.Param)('version')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], UpdatesController.prototype, "checkCompatibility", null);
__decorate([
    (0, common_1.Post)('download'),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], UpdatesController.prototype, "downloadUpdate", null);
__decorate([
    (0, common_1.Post)('apply'),
    __param(0, (0, common_1.Body)()),
    __param(1, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Object]),
    __metadata("design:returntype", Promise)
], UpdatesController.prototype, "applyUpdate", null);
__decorate([
    (0, common_1.Post)('rollback/:id'),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], UpdatesController.prototype, "rollback", null);
__decorate([
    (0, common_1.Get)('version'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], UpdatesController.prototype, "getVersionInfo", null);
__decorate([
    (0, common_1.Post)('pull-latest'),
    __param(0, (0, common_1.Request)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], UpdatesController.prototype, "pullLatest", null);
exports.UpdatesController = UpdatesController = __decorate([
    (0, common_1.Controller)('api/updates'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, roles_guard_1.RolesGuard),
    (0, roles_decorator_1.Roles)(client_1.UserRole.ADMIN),
    __metadata("design:paramtypes", [typeof (_a = typeof updates_service_1.UpdatesService !== "undefined" && updates_service_1.UpdatesService) === "function" ? _a : Object, typeof (_b = typeof version_service_1.VersionService !== "undefined" && version_service_1.VersionService) === "function" ? _b : Object])
], UpdatesController);


/***/ }),
/* 282 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 UpdatesService_1;
var _a, _b, _c, _d;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.UpdatesService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const version_service_1 = __webpack_require__(283);
const migration_service_1 = __webpack_require__(284);
const backup_service_1 = __webpack_require__(278);
const fs = __webpack_require__(4);
const path = __webpack_require__(3);
const https = __webpack_require__(252);
const http = __webpack_require__(287);
const AdmZip = __webpack_require__(130);
const crypto_1 = __webpack_require__(48);
const child_process_1 = __webpack_require__(285);
const util_1 = __webpack_require__(286);
const execAsync = (0, util_1.promisify)(child_process_1.exec);
let UpdatesService = UpdatesService_1 = class UpdatesService {
    constructor(prisma, versionService, migrationService, backupService) {
        this.prisma = prisma;
        this.versionService = versionService;
        this.migrationService = migrationService;
        this.backupService = backupService;
        this.logger = new common_1.Logger(UpdatesService_1.name);
        this.updatesDir = path.join(process.cwd(), 'updates');
        this.rollbackDir = path.join(process.cwd(), 'updates', 'rollback');
        this.updateInProgress = false;
        this.currentProgress = { stage: 'idle', progress: 0, message: '' };
        if (!fs.existsSync(this.updatesDir)) {
            fs.mkdirSync(this.updatesDir, { recursive: true });
        }
        if (!fs.existsSync(this.rollbackDir)) {
            fs.mkdirSync(this.rollbackDir, { recursive: true });
        }
    }
    async getStatus() {
        const updateCheck = await this.versionService.isUpdateAvailable();
        const pendingMigrations = await this.migrationService.getPendingMigrations();
        return {
            currentVersion: updateCheck.currentVersion,
            latestVersion: updateCheck.latestVersion,
            updateAvailable: updateCheck.available,
            versionInfo: updateCheck.versionInfo,
            pendingMigrations,
            updateInProgress: this.updateInProgress,
            currentProgress: this.currentProgress,
        };
    }
    async checkForUpdates() {
        const updateCheck = await this.versionService.isUpdateAvailable();
        const availableUpdates = await this.versionService.getAvailableUpdates();
        if (updateCheck.available && updateCheck.versionInfo) {
            await this.prisma.setting.upsert({
                where: { key: 'latest_available_version' },
                create: {
                    key: 'latest_available_version',
                    value: JSON.stringify(updateCheck.versionInfo),
                    type: 'JSON',
                },
                update: { value: JSON.stringify(updateCheck.versionInfo) },
            });
        }
        return {
            ...updateCheck,
            availableUpdates,
            checkedAt: new Date().toISOString(),
        };
    }
    async downloadUpdate(version) {
        const manifest = await this.versionService.fetchUpdateManifest();
        const versionInfo = manifest?.versions.find((v) => v.version === version);
        if (!versionInfo) {
            throw new common_1.BadRequestException(`Version ${version} not found`);
        }
        if (!versionInfo.downloadUrl) {
            throw new common_1.BadRequestException('No download URL available for this version');
        }
        const fileName = `wordpress-node-${version}.zip`;
        const filePath = path.join(this.updatesDir, fileName);
        const updateHistory = await this.prisma.updateHistory.create({
            data: {
                fromVersion: this.versionService.getCurrentVersion(),
                toVersion: version,
                status: 'DOWNLOADING',
                downloadUrl: versionInfo.downloadUrl,
                checksum: versionInfo.checksum,
                fileSize: BigInt(versionInfo.fileSize || 0),
                changelog: versionInfo.changelog,
                releaseNotes: versionInfo.releaseNotes,
            },
        });
        try {
            this.setProgress('downloading', 0, `Downloading version ${version}...`);
            await this.downloadFile(versionInfo.downloadUrl, filePath, (progress) => {
                this.setProgress('downloading', progress, `Downloading: ${progress}%`);
            });
            if (versionInfo.checksum) {
                const fileChecksum = await this.calculateChecksum(filePath);
                if (fileChecksum !== versionInfo.checksum) {
                    fs.unlinkSync(filePath);
                    throw new Error('Checksum verification failed');
                }
            }
            await this.prisma.updateHistory.update({
                where: { id: updateHistory.id },
                data: { status: 'DOWNLOADED' },
            });
            this.setProgress('downloaded', 100, 'Download complete');
            return { success: true, filePath };
        }
        catch (error) {
            await this.prisma.updateHistory.update({
                where: { id: updateHistory.id },
                data: { status: 'FAILED', errorMessage: error.message },
            });
            throw error;
        }
    }
    setProgress(stage, progress, message) {
        this.currentProgress = { stage, progress, message };
        this.logger.log(`[${stage}] ${progress}% - ${message}`);
    }
    async applyUpdate(version, userId) {
        if (this.updateInProgress) {
            throw new common_1.BadRequestException('An update is already in progress');
        }
        this.updateInProgress = true;
        const currentVersion = this.versionService.getCurrentVersion();
        let updateHistory = await this.prisma.updateHistory.findFirst({
            where: { toVersion: version, status: 'DOWNLOADED' },
            orderBy: { createdAt: 'desc' },
        });
        if (!updateHistory) {
            const downloadResult = await this.downloadUpdate(version);
            if (!downloadResult.success) {
                this.updateInProgress = false;
                throw new common_1.BadRequestException('Failed to download update');
            }
            updateHistory = await this.prisma.updateHistory.findFirst({
                where: { toVersion: version, status: 'DOWNLOADED' },
                orderBy: { createdAt: 'desc' },
            });
        }
        try {
            this.setProgress('backing_up', 10, 'Creating pre-update backup...');
            await this.prisma.updateHistory.update({
                where: { id: updateHistory.id },
                data: { status: 'BACKING_UP', initiatedBy: userId },
            });
            const backup = await this.backupService.create({
                name: `Pre-Update Backup v${version}`,
                description: `Auto backup before updating to ${version}`,
                type: 'FULL',
                includesDatabase: true,
                includesMedia: true,
                includesThemes: true,
                includesPlugins: true,
            }, userId || 'system');
            await this.prisma.updateHistory.update({
                where: { id: updateHistory.id },
                data: { backupId: backup.id },
            });
            this.setProgress('preparing', 20, 'Creating rollback point...');
            await this.createRollbackPoint(currentVersion);
            this.setProgress('applying', 40, 'Extracting update package...');
            await this.prisma.updateHistory.update({
                where: { id: updateHistory.id },
                data: { status: 'APPLYING' },
            });
            const updateFile = path.join(this.updatesDir, `wordpress-node-${version}.zip`);
            await this.extractUpdate(updateFile);
            this.setProgress('migrating', 60, 'Running database migrations...');
            await this.prisma.updateHistory.update({
                where: { id: updateHistory.id },
                data: { status: 'MIGRATING' },
            });
            const migrationResult = await this.migrationService.runMigrations();
            await this.prisma.updateHistory.update({
                where: { id: updateHistory.id },
                data: { migrationsRun: migrationResult.migrationsRun, migrationLogs: migrationResult.logs },
            });
            if (!migrationResult.success) {
                throw new Error(`Migration failed: ${migrationResult.error}`);
            }
            this.setProgress('installing', 75, 'Installing dependencies...');
            await execAsync('npm install --production --quiet --no-progress', {
                cwd: process.cwd(),
                timeout: 300000,
                maxBuffer: 1024 * 1024 * 10,
            });
            this.setProgress('building', 85, 'Building application...');
            await execAsync('npm run build', {
                cwd: process.cwd(),
                timeout: 300000,
                maxBuffer: 1024 * 1024 * 10,
            });
            this.setProgress('verifying', 95, 'Verifying update...');
            await this.prisma.updateHistory.update({
                where: { id: updateHistory.id },
                data: { status: 'VERIFYING' },
            });
            const schemaValid = await this.migrationService.validateSchema();
            if (!schemaValid.valid) {
                throw new Error(`Schema validation failed`);
            }
            this.setProgress('completed', 100, 'Update completed successfully!');
            await this.prisma.updateHistory.update({
                where: { id: updateHistory.id },
                data: { status: 'COMPLETED', completedAt: new Date() },
            });
            await this.versionService.recordCurrentVersion();
            this.updateInProgress = false;
            return { success: true, message: `Updated to ${version}. Please restart the server.` };
        }
        catch (error) {
            this.logger.error('Update failed', error);
            await this.prisma.updateHistory.update({
                where: { id: updateHistory.id },
                data: { status: 'FAILED', errorMessage: error.message, errorStack: error.stack },
            });
            this.setProgress('failed', 0, `Update failed: ${error.message}`);
            this.updateInProgress = false;
            throw error;
        }
    }
    async rollback(updateHistoryId) {
        const updateHistory = await this.prisma.updateHistory.findUnique({
            where: { id: updateHistoryId },
            include: { backup: true },
        });
        if (!updateHistory) {
            throw new common_1.BadRequestException('Update history not found');
        }
        try {
            this.setProgress('rolling_back', 10, 'Initiating rollback...');
            const rollbackPath = path.join(this.rollbackDir, updateHistory.fromVersion);
            if (fs.existsSync(rollbackPath)) {
                this.setProgress('rolling_back', 30, 'Restoring files...');
                await this.restoreFromRollback(rollbackPath);
            }
            if (updateHistory.backup) {
                this.setProgress('rolling_back', 60, 'Restoring database...');
                await this.backupService.restore(updateHistory.backup.id, { restoreDatabase: true });
            }
            this.setProgress('rolling_back', 80, 'Reinstalling dependencies...');
            await execAsync('npm install --production --quiet --no-progress', {
                cwd: process.cwd(),
                timeout: 300000,
                maxBuffer: 1024 * 1024 * 10,
            });
            this.setProgress('rolling_back', 90, 'Rebuilding...');
            await execAsync('npm run build', {
                cwd: process.cwd(),
                timeout: 300000,
                maxBuffer: 1024 * 1024 * 10,
            });
            await this.prisma.updateHistory.update({
                where: { id: updateHistoryId },
                data: { rolledBack: true, rollbackAt: new Date(), status: 'ROLLED_BACK' },
            });
            this.setProgress('completed', 100, 'Rollback completed');
            return {
                success: true,
                message: `Rolled back to ${updateHistory.fromVersion}. Restart server.`,
            };
        }
        catch (error) {
            this.setProgress('failed', 0, `Rollback failed: ${error.message}`);
            throw error;
        }
    }
    async getUpdateHistory(limit = 20) {
        return this.prisma.updateHistory.findMany({
            take: limit,
            orderBy: { startedAt: 'desc' },
            include: { backup: true, initiatedByUser: { select: { id: true, name: true, email: true } } },
        });
    }
    async downloadFile(url, dest, onProgress) {
        return new Promise((resolve, reject) => {
            const file = fs.createWriteStream(dest);
            const protocol = url.startsWith('https') ? https : http;
            protocol
                .get(url, { headers: { 'User-Agent': 'WordPress-Node-CMS' } }, (response) => {
                if (response.statusCode === 302 || response.statusCode === 301) {
                    file.close();
                    fs.unlinkSync(dest);
                    return this.downloadFile(response.headers.location, dest, onProgress)
                        .then(resolve)
                        .catch(reject);
                }
                const totalSize = parseInt(response.headers['content-length'] || '0', 10);
                let downloaded = 0;
                response.on('data', (chunk) => {
                    downloaded += chunk.length;
                    if (totalSize && onProgress)
                        onProgress(Math.round((downloaded / totalSize) * 100));
                });
                response.pipe(file);
                file.on('finish', () => {
                    file.close();
                    resolve();
                });
            })
                .on('error', (err) => {
                fs.unlink(dest, () => { });
                reject(err);
            });
        });
    }
    async calculateChecksum(filePath) {
        return new Promise((resolve, reject) => {
            const hash = (0, crypto_1.createHash)('sha256');
            const stream = fs.createReadStream(filePath);
            stream.on('data', (data) => hash.update(data));
            stream.on('end', () => resolve(hash.digest('hex')));
            stream.on('error', reject);
        });
    }
    async createRollbackPoint(version) {
        const rollbackPath = path.join(this.rollbackDir, version);
        if (!fs.existsSync(rollbackPath))
            fs.mkdirSync(rollbackPath, { recursive: true });
        const files = ['package.json', 'package-lock.json', 'prisma/schema.prisma'];
        for (const file of files) {
            const src = path.join(process.cwd(), file);
            const dest = path.join(rollbackPath, file);
            if (fs.existsSync(src)) {
                fs.mkdirSync(path.dirname(dest), { recursive: true });
                fs.copyFileSync(src, dest);
            }
        }
    }
    async extractUpdate(zipPath) {
        const zip = new AdmZip(zipPath);
        const extractPath = path.join(this.updatesDir, 'extracted');
        zip.extractAllTo(extractPath, true);
        const exclude = ['node_modules', '.git', 'uploads', 'backups', 'updates', '.env'];
        await this.copyDirectory(extractPath, process.cwd(), exclude);
    }
    async copyDirectory(src, dest, exclude) {
        if (!fs.existsSync(src)) {
            this.logger.warn(`Source directory does not exist: ${src}`);
            return;
        }
        if (!fs.existsSync(dest)) {
            fs.mkdirSync(dest, { recursive: true });
        }
        const entries = fs.readdirSync(src, { withFileTypes: true });
        for (const entry of entries) {
            if (exclude.includes(entry.name))
                continue;
            const srcPath = path.join(src, entry.name);
            const destPath = path.join(dest, entry.name);
            try {
                if (entry.isDirectory()) {
                    fs.mkdirSync(destPath, { recursive: true });
                    await this.copyDirectory(srcPath, destPath, exclude);
                }
                else {
                    if (!fs.existsSync(srcPath)) {
                        this.logger.warn(`Skipping missing file: ${srcPath}`);
                        continue;
                    }
                    const parentDir = path.dirname(destPath);
                    if (!fs.existsSync(parentDir)) {
                        fs.mkdirSync(parentDir, { recursive: true });
                    }
                    fs.copyFileSync(srcPath, destPath);
                }
            }
            catch (err) {
                this.logger.warn(`Failed to copy ${srcPath}: ${err.message}`);
            }
        }
    }
    async restoreFromRollback(rollbackPath) {
        const files = fs.readdirSync(rollbackPath, { withFileTypes: true });
        for (const file of files) {
            const src = path.join(rollbackPath, file.name);
            const dest = path.join(process.cwd(), file.name);
            if (file.isDirectory())
                await this.copyDirectory(src, dest, []);
            else
                fs.copyFileSync(src, dest);
        }
    }
    async pullLatest(userId) {
        if (this.updateInProgress) {
            throw new common_1.BadRequestException('An update is already in progress');
        }
        this.updateInProgress = true;
        const logs = [];
        const currentVersion = this.versionService.getCurrentVersion();
        let newVersion = currentVersion;
        const updateHistory = await this.prisma.updateHistory.create({
            data: {
                fromVersion: currentVersion,
                toVersion: 'latest',
                status: 'DOWNLOADING',
                changelog: 'Pull latest from main branch',
                initiatedBy: userId,
            },
        });
        try {
            this.setProgress('backing_up', 5, 'Creating pre-update backup...');
            logs.push('Creating backup before update...');
            const backupDir = path.join(process.cwd(), 'backups', `pre-update-${Date.now()}`);
            fs.mkdirSync(backupDir, { recursive: true });
            const distPath = path.join(process.cwd(), 'dist');
            const adminDistPath = path.join(process.cwd(), 'admin', 'dist');
            const envPath = path.join(process.cwd(), '.env');
            if (fs.existsSync(distPath)) {
                await this.copyDirectory(distPath, path.join(backupDir, 'dist'), []);
            }
            if (fs.existsSync(adminDistPath)) {
                await this.copyDirectory(adminDistPath, path.join(backupDir, 'admin-dist'), []);
            }
            if (fs.existsSync(envPath)) {
                fs.copyFileSync(envPath, path.join(backupDir, '.env'));
            }
            fs.copyFileSync(path.join(process.cwd(), 'package.json'), path.join(backupDir, 'package.json'));
            logs.push(`✓ Backup created at: ${backupDir}`);
            this.setProgress('downloading', 15, 'Pulling latest changes from GitHub...');
            logs.push('Pulling latest changes from GitHub...');
            await this.prisma.updateHistory.update({
                where: { id: updateHistory.id },
                data: { status: 'DOWNLOADING' },
            });
            try {
                await execAsync('git stash', { cwd: process.cwd(), timeout: 30000 });
                logs.push('✓ Stashed local changes');
            }
            catch {
            }
            try {
                await execAsync('git checkout scripts/', { cwd: process.cwd(), timeout: 30000 });
                logs.push('✓ Reset scripts folder');
            }
            catch {
            }
            const pullResult = await execAsync('git pull origin main', {
                cwd: process.cwd(),
                timeout: 120000,
            });
            logs.push('✓ Code updated');
            logs.push(pullResult.stdout.trim());
            try {
                const pkgJson = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf8'));
                newVersion = pkgJson.version || currentVersion;
                logs.push(`New version: ${newVersion}`);
            }
            catch {
                newVersion = 'unknown';
            }
            await this.prisma.updateHistory.update({
                where: { id: updateHistory.id },
                data: { toVersion: newVersion, status: 'APPLYING' },
            });
            this.setProgress('installing', 30, 'Installing backend dependencies...');
            logs.push('Installing backend dependencies...');
            await execAsync('npm install --production=false --quiet --no-progress', {
                cwd: process.cwd(),
                timeout: 300000,
                maxBuffer: 1024 * 1024 * 10,
            });
            logs.push('✓ Backend dependencies installed');
            this.setProgress('installing', 45, 'Installing admin dependencies...');
            logs.push('Installing admin dependencies...');
            const adminDir = path.join(process.cwd(), 'admin');
            const nodeModulesPath = path.join(adminDir, 'node_modules');
            const packageLockPath = path.join(adminDir, 'package-lock.json');
            if (fs.existsSync(nodeModulesPath)) {
                await execAsync('rm -rf node_modules', { cwd: adminDir, timeout: 60000 });
                logs.push('✓ Cleaned old node_modules');
            }
            if (fs.existsSync(packageLockPath)) {
                fs.unlinkSync(packageLockPath);
                logs.push('✓ Removed package-lock.json');
            }
            await execAsync('npm install --include=dev --quiet --no-progress', {
                cwd: adminDir,
                timeout: 300000,
                maxBuffer: 1024 * 1024 * 10,
                env: { ...process.env, NODE_ENV: 'development' },
            });
            logs.push('✓ Admin dependencies installed');
            const viteCheck = path.join(adminDir, 'node_modules', 'vite');
            if (!fs.existsSync(viteCheck)) {
                logs.push('⚠ Vite not found, installing explicitly...');
                await execAsync('npm install vite @vitejs/plugin-react --save-dev --quiet', {
                    cwd: adminDir,
                    timeout: 120000,
                    maxBuffer: 1024 * 1024 * 10,
                    env: { ...process.env, NODE_ENV: 'development' },
                });
                logs.push('✓ Vite installed');
            }
            this.setProgress('building', 60, 'Building admin panel...');
            logs.push('Building admin panel...');
            await this.prisma.updateHistory.update({
                where: { id: updateHistory.id },
                data: { status: 'APPLYING' },
            });
            await execAsync('npm run build', {
                cwd: adminDir,
                timeout: 300000,
                maxBuffer: 1024 * 1024 * 10,
            });
            if (!fs.existsSync(path.join(adminDir, 'dist', 'index.html'))) {
                throw new Error('Admin panel build failed - dist/index.html not found');
            }
            logs.push('✓ Admin panel built');
            this.setProgress('building', 75, 'Building backend...');
            logs.push('Building backend...');
            await execAsync('npm run build', {
                cwd: process.cwd(),
                timeout: 300000,
                maxBuffer: 1024 * 1024 * 10,
            });
            if (!fs.existsSync(path.join(process.cwd(), 'dist', 'main.js'))) {
                throw new Error('Backend build failed - dist/main.js not found');
            }
            logs.push('✓ Backend built');
            this.setProgress('migrating', 85, 'Applying database migrations...');
            logs.push('Applying database migrations...');
            await this.prisma.updateHistory.update({
                where: { id: updateHistory.id },
                data: { status: 'MIGRATING' },
            });
            try {
                await execAsync('npx prisma generate', { cwd: process.cwd(), timeout: 120000 });
                await execAsync('npx prisma db push --accept-data-loss', {
                    cwd: process.cwd(),
                    timeout: 300000,
                });
                logs.push('✓ Database schema updated');
            }
            catch (migErr) {
                logs.push(`Warning: Migration had issues: ${migErr.message}`);
                try {
                    await execAsync('npx prisma db push', { cwd: process.cwd(), timeout: 300000 });
                    logs.push('✓ Database schema updated (retry)');
                }
                catch {
                    logs.push('Warning: Could not auto-migrate, manual migration may be needed');
                }
            }
            this.setProgress('verifying', 95, 'Verifying update...');
            logs.push('Verifying update...');
            await this.prisma.updateHistory.update({
                where: { id: updateHistory.id },
                data: { status: 'VERIFYING' },
            });
            this.setProgress('completed', 100, 'Update completed successfully!');
            logs.push('');
            logs.push('═══════════════════════════════════════════');
            logs.push('           Update Complete!');
            logs.push('═══════════════════════════════════════════');
            logs.push(`Updated from ${currentVersion} to ${newVersion}`);
            logs.push('Restart the server to apply changes');
            await this.prisma.updateHistory.update({
                where: { id: updateHistory.id },
                data: {
                    status: 'COMPLETED',
                    completedAt: new Date(),
                    migrationLogs: logs.join('\n'),
                },
            });
            await this.versionService.recordCurrentVersion();
            this.updateInProgress = false;
            return {
                success: true,
                message: `Updated from ${currentVersion} to ${newVersion}. Please restart the server.`,
                fromVersion: currentVersion,
                toVersion: newVersion,
                logs,
            };
        }
        catch (error) {
            this.logger.error('Pull latest failed', error);
            logs.push(`✗ Error: ${error.message}`);
            await this.prisma.updateHistory.update({
                where: { id: updateHistory.id },
                data: {
                    status: 'FAILED',
                    errorMessage: error.message,
                    errorStack: error.stack,
                    migrationLogs: logs.join('\n'),
                },
            });
            this.setProgress('failed', 0, `Update failed: ${error.message}`);
            this.updateInProgress = false;
            throw new common_1.BadRequestException({
                message: `Update failed: ${error.message}`,
                logs,
            });
        }
    }
};
exports.UpdatesService = UpdatesService;
exports.UpdatesService = UpdatesService = UpdatesService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object, typeof (_b = typeof version_service_1.VersionService !== "undefined" && version_service_1.VersionService) === "function" ? _b : Object, typeof (_c = typeof migration_service_1.MigrationService !== "undefined" && migration_service_1.MigrationService) === "function" ? _c : Object, typeof (_d = typeof backup_service_1.BackupService !== "undefined" && backup_service_1.BackupService) === "function" ? _d : Object])
], UpdatesService);


/***/ }),
/* 283 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 VersionService_1;
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.VersionService = void 0;
const common_1 = __webpack_require__(2);
const prisma_service_1 = __webpack_require__(16);
const fs = __webpack_require__(4);
const path = __webpack_require__(3);
const https = __webpack_require__(252);
let VersionService = VersionService_1 = class VersionService {
    constructor(prisma) {
        this.prisma = prisma;
        this.logger = new common_1.Logger(VersionService_1.name);
        this.DEFAULT_UPDATE_SERVER = 'https://api.github.com/repos/syntex82/WordPress-Node/releases';
        this.MANIFEST_CACHE_DURATION = 3600000;
        this.manifestCache = null;
        this.manifestCacheTime = 0;
    }
    getCurrentVersion() {
        try {
            const packagePath = path.join(process.cwd(), 'package.json');
            const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf-8'));
            return packageJson.version || '1.0.0';
        }
        catch (error) {
            this.logger.error('Failed to read current version', error);
            return '1.0.0';
        }
    }
    compareVersions(v1, v2) {
        const parts1 = v1
            .replace(/[^0-9.]/g, '')
            .split('.')
            .map(Number);
        const parts2 = v2
            .replace(/[^0-9.]/g, '')
            .split('.')
            .map(Number);
        for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
            const p1 = parts1[i] || 0;
            const p2 = parts2[i] || 0;
            if (p1 < p2)
                return -1;
            if (p1 > p2)
                return 1;
        }
        return 0;
    }
    async isUpdateAvailable() {
        const currentVersion = this.getCurrentVersion();
        const manifest = await this.fetchUpdateManifest();
        if (!manifest) {
            return { available: false, currentVersion, latestVersion: currentVersion };
        }
        const latestVersion = manifest.latestStable || manifest.latestVersion;
        const available = this.compareVersions(currentVersion, latestVersion) < 0;
        const versionInfo = manifest.versions.find((v) => v.version === latestVersion);
        return { available, currentVersion, latestVersion, versionInfo };
    }
    async getAvailableUpdates() {
        const currentVersion = this.getCurrentVersion();
        const manifest = await this.fetchUpdateManifest();
        if (!manifest)
            return [];
        return manifest.versions
            .filter((v) => this.compareVersions(currentVersion, v.version) < 0)
            .sort((a, b) => this.compareVersions(b.version, a.version));
    }
    async fetchUpdateManifest() {
        if (this.manifestCache && Date.now() - this.manifestCacheTime < this.MANIFEST_CACHE_DURATION) {
            return this.manifestCache;
        }
        try {
            const updateServerSetting = await this.prisma.setting.findUnique({
                where: { key: 'update_server_url' },
            });
            const updateServerUrl = updateServerSetting?.value || this.DEFAULT_UPDATE_SERVER;
            const manifest = await this.fetchFromGitHub(updateServerUrl);
            if (manifest) {
                this.manifestCache = manifest;
                this.manifestCacheTime = Date.now();
            }
            return manifest;
        }
        catch (error) {
            this.logger.error('Failed to fetch update manifest', error);
            return null;
        }
    }
    async fetchFromGitHub(url) {
        return new Promise((resolve) => {
            const options = {
                headers: {
                    'User-Agent': 'WordPress-Node-CMS',
                    Accept: 'application/vnd.github.v3+json',
                },
            };
            https
                .get(url, options, (res) => {
                let data = '';
                res.on('data', (chunk) => (data += chunk));
                res.on('end', () => {
                    try {
                        const releases = JSON.parse(data);
                        if (!Array.isArray(releases)) {
                            resolve(null);
                            return;
                        }
                        resolve(this.parseGitHubReleases(releases));
                    }
                    catch {
                        resolve(null);
                    }
                });
            })
                .on('error', () => resolve(null));
        });
    }
    parseGitHubReleases(releases) {
        const versions = releases
            .filter((r) => !r.draft)
            .map((release) => {
            const tarAsset = release.assets?.find((a) => a.name.endsWith('.tar.gz') && !a.name.endsWith('.sha256'));
            const zipAsset = release.assets?.find((a) => a.name.endsWith('.zip') && !a.name.endsWith('.sha256'));
            const checksumAsset = release.assets?.find((a) => a.name.endsWith('.tar.gz.sha256') || a.name.endsWith('.zip.sha256'));
            const asset = tarAsset || zipAsset;
            return {
                version: release.tag_name?.replace(/^v/, '') || release.name,
                releaseDate: release.published_at || release.created_at,
                changelog: release.body || '',
                releaseNotes: release.body || '',
                downloadUrl: asset?.browser_download_url || release.zipball_url || '',
                checksum: checksumAsset?.browser_download_url || '',
                fileSize: asset?.size || 0,
                minNodeVersion: '18.0.0',
                minNpmVersion: '8.0.0',
                breakingChanges: release.body?.toLowerCase().includes('breaking') || false,
                requiresManualSteps: release.body?.toLowerCase().includes('manual') || false,
                manualStepsDescription: undefined,
            };
        });
        const stableVersions = versions.filter((v) => !v.version.includes('-'));
        return {
            latestVersion: versions[0]?.version || '1.0.0',
            latestStable: stableVersions[0]?.version || versions[0]?.version || '1.0.0',
            versions,
            updateServerUrl: this.DEFAULT_UPDATE_SERVER,
        };
    }
    async recordCurrentVersion() {
        const currentVersion = this.getCurrentVersion();
        await this.prisma.systemVersion.updateMany({
            where: { isCurrentVersion: true },
            data: { isCurrentVersion: false },
        });
        await this.prisma.systemVersion.upsert({
            where: { version: currentVersion },
            create: {
                version: currentVersion,
                isCurrentVersion: true,
                installedAt: new Date(),
            },
            update: {
                isCurrentVersion: true,
                installedAt: new Date(),
            },
        });
    }
    async getVersionHistory() {
        return this.prisma.systemVersion.findMany({
            orderBy: { installedAt: 'desc' },
        });
    }
    async checkCompatibility(targetVersion) {
        const issues = [];
        const warnings = [];
        const nodeVersion = process.version.replace('v', '');
        const manifest = await this.fetchUpdateManifest();
        const versionInfo = manifest?.versions.find((v) => v.version === targetVersion);
        if (versionInfo?.minNodeVersion) {
            if (this.compareVersions(nodeVersion, versionInfo.minNodeVersion) < 0) {
                issues.push(`Node.js ${versionInfo.minNodeVersion}+ required. Current: ${nodeVersion}`);
            }
        }
        try {
            const stats = fs.statfsSync(process.cwd());
            const freeSpaceGB = (stats.bavail * stats.bsize) / (1024 * 1024 * 1024);
            if (freeSpaceGB < 0.5) {
                issues.push(`Insufficient disk space. At least 500MB required.`);
            }
        }
        catch {
        }
        if (versionInfo?.breakingChanges) {
            warnings.push('This version contains breaking changes.');
        }
        if (versionInfo?.requiresManualSteps) {
            warnings.push('This update requires manual steps.');
        }
        return { compatible: issues.length === 0, issues, warnings };
    }
};
exports.VersionService = VersionService;
exports.VersionService = VersionService = VersionService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [typeof (_a = typeof prisma_service_1.PrismaService !== "undefined" && prisma_service_1.PrismaService) === "function" ? _a : Object])
], VersionService);


/***/ }),
/* 284 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 MigrationService_1;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.MigrationService = void 0;
const common_1 = __webpack_require__(2);
const child_process_1 = __webpack_require__(285);
const util_1 = __webpack_require__(286);
const fs = __webpack_require__(4);
const path = __webpack_require__(3);
const execAsync = (0, util_1.promisify)(child_process_1.exec);
let MigrationService = MigrationService_1 = class MigrationService {
    constructor() {
        this.logger = new common_1.Logger(MigrationService_1.name);
    }
    async runMigrations() {
        const logs = [];
        const migrationsRun = [];
        try {
            this.logger.log('Starting database migrations...');
            logs.push('Starting database migrations...');
            this.logger.log('Generating Prisma client...');
            logs.push('Generating Prisma client...');
            const generateResult = await execAsync('npx prisma generate', {
                cwd: process.cwd(),
                timeout: 120000,
            });
            logs.push(generateResult.stdout);
            this.logger.log('Deploying migrations...');
            logs.push('Deploying migrations...');
            const migrateResult = await execAsync('npx prisma migrate deploy', {
                cwd: process.cwd(),
                timeout: 300000,
            });
            logs.push(migrateResult.stdout);
            const migrationMatches = migrateResult.stdout.match(/Applied migration `([^`]+)`/g);
            if (migrationMatches) {
                migrationMatches.forEach((match) => {
                    const name = match.match(/`([^`]+)`/)?.[1];
                    if (name)
                        migrationsRun.push(name);
                });
            }
            this.logger.log(`Migrations completed. Applied: ${migrationsRun.length}`);
            logs.push(`Migrations completed successfully. Applied ${migrationsRun.length} migration(s).`);
            return {
                success: true,
                migrationsRun,
                logs: logs.join('\n'),
            };
        }
        catch (error) {
            this.logger.error('Migration failed', error);
            logs.push(`Migration failed: ${error.message}`);
            return {
                success: false,
                migrationsRun,
                logs: logs.join('\n'),
                error: error.message,
            };
        }
    }
    async getPendingMigrations() {
        try {
            const result = await execAsync('npx prisma migrate status', {
                cwd: process.cwd(),
                timeout: 60000,
            });
            const pending = [];
            const lines = result.stdout.split('\n');
            for (const line of lines) {
                if (line.includes('Not yet applied')) {
                    const match = line.match(/(\d{14}_\w+)/);
                    if (match)
                        pending.push(match[1]);
                }
            }
            return pending;
        }
        catch (error) {
            this.logger.error('Failed to check pending migrations', error);
            return [];
        }
    }
    async backupDatabase() {
        try {
            const backupDir = path.join(process.cwd(), 'backups', 'migrations');
            if (!fs.existsSync(backupDir)) {
                fs.mkdirSync(backupDir, { recursive: true });
            }
            const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
            const backupPath = path.join(backupDir, `pre-migration-${timestamp}.sql`);
            const databaseUrl = process.env.DATABASE_URL || '';
            if (databaseUrl.includes('postgresql')) {
                try {
                    await execAsync(`pg_dump "${databaseUrl}" > "${backupPath}"`, {
                        timeout: 300000,
                    });
                    return { success: true, backupPath };
                }
                catch {
                    this.logger.warn('pg_dump not available, skipping SQL backup');
                }
            }
            return { success: true };
        }
        catch (error) {
            return { success: false, error: error.message };
        }
    }
    async validateSchema() {
        try {
            await execAsync('npx prisma validate', {
                cwd: process.cwd(),
                timeout: 60000,
            });
            return { valid: true, issues: [] };
        }
        catch (error) {
            return {
                valid: false,
                issues: [error.message],
            };
        }
    }
};
exports.MigrationService = MigrationService;
exports.MigrationService = MigrationService = MigrationService_1 = __decorate([
    (0, common_1.Injectable)()
], MigrationService);


/***/ }),
/* 285 */
/***/ ((module) => {

module.exports = require("child_process");

/***/ }),
/* 286 */
/***/ ((module) => {

module.exports = require("util");

/***/ }),
/* 287 */
/***/ ((module) => {

module.exports = require("http");

/***/ }),
/* 288 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.VideoModule = void 0;
const common_1 = __webpack_require__(2);
const video_controller_1 = __webpack_require__(289);
const video_service_1 = __webpack_require__(290);
const prisma_module_1 = __webpack_require__(15);
const feature_guard_1 = __webpack_require__(162);
let VideoModule = class VideoModule {
};
exports.VideoModule = VideoModule;
exports.VideoModule = VideoModule = __decorate([
    (0, common_1.Module)({
        imports: [prisma_module_1.PrismaModule],
        controllers: [video_controller_1.VideoController],
        providers: [video_service_1.VideoService, feature_guard_1.FeatureGuard],
        exports: [video_service_1.VideoService],
    })
], VideoModule);


/***/ }),
/* 289 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.VideoController = void 0;
const common_1 = __webpack_require__(2);
const video_service_1 = __webpack_require__(290);
const jwt_auth_guard_1 = __webpack_require__(61);
const feature_guard_1 = __webpack_require__(162);
const subscription_decorator_1 = __webpack_require__(161);
let VideoController = class VideoController {
    constructor(videoService) {
        this.videoService = videoService;
    }
    async getIceServers() {
        const iceServers = await this.videoService.getIceServers();
        return {
            success: true,
            iceServers,
            info: 'Video calls are 1-on-1 only. Select a user to call.',
        };
    }
    async startCall() {
        const iceServers = await this.videoService.getIceServers();
        return {
            success: true,
            iceServers,
            type: 'one-on-one',
            message: 'Video calls connect you directly with one other person.',
        };
    }
};
exports.VideoController = VideoController;
__decorate([
    (0, common_1.Get)('ice-servers'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], VideoController.prototype, "getIceServers", null);
__decorate([
    (0, common_1.Post)('call'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], VideoController.prototype, "startCall", null);
exports.VideoController = VideoController = __decorate([
    (0, common_1.Controller)('api/video'),
    (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard, feature_guard_1.FeatureGuard),
    (0, subscription_decorator_1.RequiresFeature)(subscription_decorator_1.SUBSCRIPTION_FEATURES.VIDEO_CALLS),
    __metadata("design:paramtypes", [typeof (_a = typeof video_service_1.VideoService !== "undefined" && video_service_1.VideoService) === "function" ? _a : Object])
], VideoController);


/***/ }),
/* 290 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


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 VideoService_1;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.VideoService = void 0;
const common_1 = __webpack_require__(2);
let VideoService = VideoService_1 = class VideoService {
    constructor() {
        this.logger = new common_1.Logger(VideoService_1.name);
        this.logger.log('Video Service initialized (1-on-1 WebRTC only)');
    }
    async getIceServers() {
        return [
            { urls: 'stun:stun.l.google.com:19302' },
            { urls: 'stun:stun1.l.google.com:19302' },
            { urls: 'stun:stun2.l.google.com:19302' },
            { urls: 'stun:stun3.l.google.com:19302' },
            { urls: 'stun:stun4.l.google.com:19302' },
        ];
    }
};
exports.VideoService = VideoService;
exports.VideoService = VideoService = VideoService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [])
], VideoService);


/***/ })
/******/ 	]);
/************************************************************************/
/******/ 	// The module cache
/******/ 	var __webpack_module_cache__ = {};
/******/ 	
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/ 		// Check if module is in cache
/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
/******/ 		if (cachedModule !== undefined) {
/******/ 			return cachedModule.exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			// no module.id needed
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/ 	
/******/ 		// Execute the module function
/******/ 		__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ 	
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/ 	
/************************************************************************/
var __webpack_exports__ = {};
// This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
(() => {
var exports = __webpack_exports__;

Object.defineProperty(exports, "__esModule", ({ value: true }));
const core_1 = __webpack_require__(1);
const common_1 = __webpack_require__(2);
const path_1 = __webpack_require__(3);
const fs_1 = __webpack_require__(4);
const cookieParser = __webpack_require__(5);
const session = __webpack_require__(6);
const connectRedis = __webpack_require__(7);
const ioredis_1 = __webpack_require__(8);
const RedisStore = connectRedis.default || connectRedis;
const jwt = __webpack_require__(9);
const compression = __webpack_require__(10);
const helmet_1 = __webpack_require__(11);
const app_module_1 = __webpack_require__(12);
function validateEnvironment(logger) {
    const isProduction = process.env.NODE_ENV === 'production';
    const requiredVars = ['DATABASE_URL'];
    const missingRequired = [];
    for (const envVar of requiredVars) {
        if (!process.env[envVar]) {
            missingRequired.push(envVar);
        }
    }
    if (missingRequired.length > 0) {
        logger.error(`Missing required environment variables: ${missingRequired.join(', ')}`);
        logger.error('Please configure these variables in your .env file or environment');
        process.exit(1);
    }
    if (isProduction) {
        const productionRequired = ['JWT_SECRET', 'ENCRYPTION_KEY', 'SESSION_SECRET'];
        const missingProduction = [];
        for (const envVar of productionRequired) {
            if (!process.env[envVar] ||
                process.env[envVar] === 'default-secret' ||
                process.env[envVar] === 'default-secret-change-in-production') {
                missingProduction.push(envVar);
            }
        }
        if (missingProduction.length > 0) {
            logger.error(`Production requires secure values for: ${missingProduction.join(', ')}`);
            logger.error("Generate secure secrets with: node -e \"console.log(require('crypto').randomBytes(32).toString('hex'))\"");
            process.exit(1);
        }
    }
    const recommendedVars = [
        { name: 'JWT_SECRET', default: 'your-super-secret-jwt-key' },
        { name: 'ENCRYPTION_KEY', default: 'default-encryption-key-32chars!!' },
        { name: 'SESSION_SECRET', default: 'default-secret-change-in-production' },
    ];
    for (const { name, default: defaultVal } of recommendedVars) {
        if (!process.env[name] || process.env[name] === defaultVal) {
            logger.warn(`⚠️ ${name} is using default value - configure a secure value for production`);
        }
    }
    if (!process.env.SMTP_HOST || !process.env.SMTP_USER) {
        logger.warn('⚠️ SMTP not configured in .env - email features will be limited until configured via admin panel');
    }
}
async function bootstrap() {
    const logger = new common_1.Logger('Bootstrap');
    validateEnvironment(logger);
    const isProduction = process.env.NODE_ENV === 'production';
    const instanceId = process.env.INSTANCE_ID || `instance-${process.pid}`;
    const app = await core_1.NestFactory.create(app_module_1.AppModule, {
        logger: isProduction ? ['error', 'warn', 'log'] : ['error', 'warn', 'log', 'debug'],
    });
    app.set('trust proxy', process.env.TRUST_PROXY === 'true' || 1);
    if (process.env.ENABLE_COMPRESSION !== 'false') {
        app.use(compression({
            threshold: 1024,
            level: 6,
            filter: (req, res) => {
                if (req.headers['x-no-compression'])
                    return false;
                return compression.filter(req, res);
            },
        }));
    }
    app.use((0, helmet_1.default)({
        contentSecurityPolicy: isProduction
            ? {
                directives: {
                    defaultSrc: ["'self'"],
                    styleSrc: ["'self'", "'unsafe-inline'", 'https://fonts.googleapis.com'],
                    fontSrc: ["'self'", 'https://fonts.gstatic.com'],
                    imgSrc: ["'self'", 'data:', 'https:', 'blob:'],
                    scriptSrc: ["'self'", "'unsafe-inline'", "'unsafe-eval'", 'https://js.stripe.com'],
                    connectSrc: [
                        "'self'",
                        'https://api.stripe.com',
                        'https://fonts.googleapis.com',
                        'https://fonts.gstatic.com',
                        'https://js.stripe.com',
                        'wss:',
                        'ws:',
                    ],
                    frameSrc: [
                        "'self'",
                        'https://js.stripe.com',
                        'https://www.youtube.com',
                        'https://youtube.com',
                        'https://www.youtube-nocookie.com',
                        'https://player.vimeo.com',
                        'https://www.openstreetmap.org',
                        'https://maps.google.com',
                        'https://www.google.com',
                    ],
                    mediaSrc: ["'self'", 'https:', 'blob:'],
                },
            }
            : false,
        frameguard: false,
        hsts: isProduction ? { maxAge: 31536000, includeSubDomains: true } : false,
    }));
    app.use((req, res, next) => {
        res.setHeader('Permissions-Policy', 'camera=(self), microphone=(self), geolocation=(self), fullscreen=(self)');
        next();
    });
    const jwtSecret = process.env.JWT_SECRET || 'default-secret';
    app.use((req, res, next) => {
        const previewToken = req.query._preview_token;
        if (previewToken) {
            try {
                const decoded = jwt.verify(previewToken, jwtSecret);
                if (decoded && decoded.preview === true) {
                    const allowedOrigins = [
                        'http://localhost:5173',
                        'http://localhost:3000',
                        process.env.APP_URL,
                    ].filter(Boolean);
                    res.setHeader('Content-Security-Policy', `frame-ancestors 'self' ${allowedOrigins.join(' ')}`);
                    return next();
                }
            }
            catch (_e) {
            }
        }
        res.setHeader('X-Frame-Options', 'SAMEORIGIN');
        next();
    });
    app.use((req, res, next) => {
        res.setHeader('X-Instance-ID', instanceId);
        next();
    });
    app.use(cookieParser());
    const sessionConfig = {
        secret: process.env.SESSION_SECRET || 'default-secret-change-in-production',
        resave: false,
        saveUninitialized: false,
        name: 'wpnode.sid',
        cookie: {
            maxAge: 1000 * 60 * 60 * 24 * 7,
            httpOnly: true,
            secure: isProduction,
            sameSite: 'lax',
        },
    };
    if (process.env.REDIS_HOST) {
        try {
            const redisClient = new ioredis_1.default({
                host: process.env.REDIS_HOST,
                port: parseInt(process.env.REDIS_PORT || '6379', 10),
                password: process.env.REDIS_PASSWORD || undefined,
                db: parseInt(process.env.REDIS_DB || '0', 10),
                maxRetriesPerRequest: null,
                enableReadyCheck: true,
            });
            await redisClient.ping();
            logger.log('🔴 Redis session store connected successfully');
            sessionConfig.store = new RedisStore({
                client: redisClient,
                prefix: 'wpnode:session:',
                ttl: 60 * 60 * 24 * 7,
            });
        }
        catch (error) {
            logger.warn('⚠️  Redis connection failed, falling back to MemoryStore');
            logger.warn('   For production use, please configure Redis properly');
            logger.warn(`   Error: ${error.message}`);
        }
    }
    else {
        logger.warn('⚠️  REDIS_HOST not configured, using MemoryStore for sessions');
        logger.warn('   This is not recommended for production or multi-instance deployments');
        logger.warn('   Please configure Redis in your .env file');
    }
    app.use(session(sessionConfig));
    app.useGlobalPipes(new common_1.ValidationPipe({
        whitelist: true,
        forbidNonWhitelisted: true,
        transform: true,
        transformOptions: {
            enableImplicitConversion: true,
        },
    }));
    const corsOrigins = process.env.CORS_ORIGIN?.split(',') || ['http://localhost:5173'];
    app.enableCors({
        origin: corsOrigins,
        credentials: true,
        methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
        allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],
    });
    const requiredDirs = [
        (0, path_1.join)(process.cwd(), 'uploads'),
        (0, path_1.join)(process.cwd(), 'uploads', 'messages'),
        (0, path_1.join)(process.cwd(), 'uploads', 'media'),
        (0, path_1.join)(process.cwd(), 'uploads', 'groups'),
        (0, path_1.join)(process.cwd(), 'public'),
    ];
    for (const dir of requiredDirs) {
        if (!(0, fs_1.existsSync)(dir)) {
            (0, fs_1.mkdirSync)(dir, { recursive: true });
            logger.log(`📁 Created directory: ${dir}`);
        }
    }
    const staticOptions = isProduction ? { maxAge: '1y', etag: true, lastModified: true } : {};
    app.useStaticAssets((0, path_1.join)(process.cwd(), 'public'), {
        ...staticOptions,
        maxAge: '1d',
    });
    app.useStaticAssets((0, path_1.join)(process.cwd(), 'uploads'), {
        prefix: '/uploads/',
        ...staticOptions,
    });
    app.useStaticAssets((0, path_1.join)(process.cwd(), 'admin', 'dist'), {
        prefix: '/admin/',
        ...staticOptions,
        index: false,
    });
    app.useStaticAssets((0, path_1.join)(process.cwd(), 'themes'), {
        prefix: '/themes/',
        ...staticOptions,
    });
    app.useStaticAssets((0, path_1.join)(process.cwd(), 'plugins'), {
        prefix: '/api/plugins/',
        ...staticOptions,
    });
    app.setBaseViewsDir((0, path_1.join)(process.cwd(), 'themes'));
    app.setViewEngine('hbs');
    try {
        const { PluginLoaderService } = await Promise.resolve().then(() => __webpack_require__(167));
        const pluginLoader = app.get(PluginLoaderService);
        pluginLoader.setExpressApp(app.getHttpAdapter().getInstance());
        logger.log('✅ Plugin routes registered with Express');
    }
    catch (error) {
        logger.warn('⚠️ Could not register plugin routes:', error);
    }
    const expressApp = app.getHttpAdapter().getInstance();
    const generateManifest = (_req) => ({
        id: '/',
        name: 'Learn Online',
        short_name: 'LearnOnline',
        description: 'Online learning platform with courses, quizzes, certificates, and real-time messaging',
        start_url: '/',
        scope: '/',
        display: 'standalone',
        orientation: 'any',
        theme_color: '#4f46e5',
        background_color: '#0f172a',
        categories: ['education', 'productivity'],
        icons: [
            {
                src: '/api/pwa/icons/icon-192.svg',
                sizes: '192x192',
                type: 'image/svg+xml',
                purpose: 'any',
            },
            {
                src: '/api/pwa/icons/icon-192-maskable.svg',
                sizes: '192x192',
                type: 'image/svg+xml',
                purpose: 'maskable',
            },
            {
                src: '/api/pwa/icons/icon-512.svg',
                sizes: '512x512',
                type: 'image/svg+xml',
                purpose: 'any',
            },
            {
                src: '/api/pwa/icons/icon-512-maskable.svg',
                sizes: '512x512',
                type: 'image/svg+xml',
                purpose: 'maskable',
            },
        ],
        prefer_related_applications: false,
        shortcuts: [
            {
                name: 'Courses',
                short_name: 'Courses',
                url: '/courses',
                icons: [{ src: '/api/pwa/icons/icon-96.svg', sizes: '96x96' }],
            },
            {
                name: 'Messages',
                short_name: 'Messages',
                url: '/admin/messages',
                icons: [{ src: '/api/pwa/icons/icon-96.svg', sizes: '96x96' }],
            },
        ],
    });
    const generateServiceWorker = () => `
const CACHE = 'wp-node-v4';

self.addEventListener('install', () => self.skipWaiting());

self.addEventListener('activate', e => {
  e.waitUntil(caches.keys().then(keys => Promise.all(keys.map(k => caches.delete(k)))).then(() => self.clients.claim()));
});

self.addEventListener('fetch', e => {
  if (e.request.method !== 'GET') return;
  const url = new URL(e.request.url);
  if (e.request.mode === 'navigate') return;
  if (url.pathname.startsWith('/admin')) return;
  if (url.pathname.startsWith('/api/')) return;
  if (url.pathname.includes('/socket.io')) return;
  if (url.pathname.includes('/messages')) return;
  if (url.pathname.includes('/lms')) return;
  if (url.pathname.includes('/courses')) return;
  if (url.pathname.includes('/shop')) return;
  if (url.origin !== self.location.origin) return;
  const isStatic = url.pathname.match(/\\.(js|css|png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|ico)$/);
  if (!isStatic) return;
  e.respondWith(fetch(e.request).then(r => { if (r.status === 200) { const c = r.clone(); caches.open(CACHE).then(cache => cache.put(e.request, c)); } return r; }).catch(() => caches.match(e.request)));
});
`;
    const generateOfflinePage = () => `<!DOCTYPE html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Offline</title><style>body{min-height:100vh;display:flex;align-items:center;justify-content:center;background:#1e293b;font-family:system-ui;color:#f1f5f9;text-align:center}h1{margin-bottom:1rem}button{background:#4f46e5;color:white;border:none;padding:.75rem 1.5rem;border-radius:8px;cursor:pointer}</style></head><body><div><h1>You're Offline</h1><p>Check your connection and try again.</p><br><button onclick="location.reload()">Retry</button></div></body></html>`;
    expressApp.get('/api/pwa/manifest.json', (req, res) => {
        res.setHeader('Content-Type', 'application/manifest+json');
        res.json(generateManifest(req));
    });
    expressApp.get('/api/pwa/sw.js', (req, res) => {
        res.setHeader('Content-Type', 'application/javascript');
        res.setHeader('Service-Worker-Allowed', '/');
        res.send(generateServiceWorker());
    });
    expressApp.get('/api/pwa/offline', (req, res) => {
        res.setHeader('Content-Type', 'text/html');
        res.send(generateOfflinePage());
    });
    expressApp.get('/manifest.json', (req, res) => {
        res.setHeader('Content-Type', 'application/manifest+json');
        res.json(generateManifest(req));
    });
    expressApp.get('/sw.js', (req, res) => {
        res.setHeader('Content-Type', 'application/javascript');
        res.setHeader('Service-Worker-Allowed', '/');
        res.send(generateServiceWorker());
    });
    expressApp.get('/offline', (req, res) => {
        res.setHeader('Content-Type', 'text/html');
        res.send(generateOfflinePage());
    });
    expressApp.get('/api/pwa/icons/:filename', (req, res) => {
        const filename = req.params.filename;
        const iconPath = (0, path_1.join)(process.cwd(), 'public', 'pwa', 'icons', filename);
        if ((0, fs_1.existsSync)(iconPath)) {
            res.setHeader('Content-Type', 'image/svg+xml');
            res.setHeader('Cache-Control', 'public, max-age=86400');
            res.sendFile(iconPath);
        }
        else {
            const match = filename.match(/(\d+)/);
            const size = match ? parseInt(match[1]) : 192;
            res.setHeader('Content-Type', 'image/svg+xml');
            res.send(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${size} ${size}"><rect width="${size}" height="${size}" fill="#1a2332" rx="${Math.round(size * 0.15)}"/><polygon points="${size / 2},${size * 0.15} ${size * 0.78},${size * 0.3} ${size * 0.78},${size * 0.7} ${size / 2},${size * 0.85} ${size * 0.22},${size * 0.7} ${size * 0.22},${size * 0.3}" fill="none" stroke="#2dd4bf" stroke-width="${Math.round(size * 0.02)}"/><text x="50%" y="45%" dominant-baseline="central" text-anchor="middle" fill="white" font-family="Arial" font-weight="bold" font-size="${Math.round(size * 0.15)}">WP</text><text x="50%" y="62%" dominant-baseline="central" text-anchor="middle" fill="#2dd4bf" font-family="Arial" font-weight="bold" font-size="${Math.round(size * 0.1)}">NODE</text></svg>`);
        }
    });
    expressApp.get('/api/pwa/favicon.svg', (req, res) => {
        const faviconPath = (0, path_1.join)(process.cwd(), 'public', 'favicon.svg');
        if ((0, fs_1.existsSync)(faviconPath)) {
            res.setHeader('Content-Type', 'image/svg+xml');
            res.setHeader('Cache-Control', 'public, max-age=86400');
            res.sendFile(faviconPath);
        }
        else {
            res.setHeader('Content-Type', 'image/svg+xml');
            res.send(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><rect width="32" height="32" rx="6" fill="#1a2332"/><polygon points="16,5 26,10 26,22 16,27 6,22 6,10" fill="none" stroke="#2dd4bf" stroke-width="1.5"/><text x="16" y="18" font-family="Arial" font-size="8" font-weight="bold" fill="#fff" text-anchor="middle">WP</text></svg>`);
        }
    });
    expressApp.get('/pwa/icons/:filename', (req, res) => {
        const filename = req.params.filename;
        const iconPath = (0, path_1.join)(process.cwd(), 'public', 'pwa', 'icons', filename);
        if ((0, fs_1.existsSync)(iconPath)) {
            res.setHeader('Content-Type', 'image/svg+xml');
            res.sendFile(iconPath);
        }
        else {
            const match = filename.match(/(\d+)/);
            const size = match ? parseInt(match[1]) : 192;
            res.setHeader('Content-Type', 'image/svg+xml');
            res.send(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${size} ${size}"><rect width="${size}" height="${size}" fill="#1a2332" rx="${Math.round(size * 0.15)}"/><text x="50%" y="50%" dominant-baseline="central" text-anchor="middle" fill="#2dd4bf" font-family="Arial" font-weight="bold" font-size="${Math.round(size * 0.3)}">WP</text></svg>`);
        }
    });
    logger.log('✅ Built-in PWA routes registered');
    let seoService = null;
    try {
        const { SeoService } = await Promise.resolve().then(() => __webpack_require__(271));
        seoService = app.get(SeoService);
        logger.log('✅ SeoService loaded for root SEO routes');
    }
    catch (e) {
        logger.warn('⚠️ SeoService not available for root SEO routes');
    }
    expressApp.get('/robots.txt', async (req, res) => {
        const baseUrl = process.env.SITE_URL || `http://localhost:${port}`;
        res.setHeader('Content-Type', 'text/plain');
        res.setHeader('Cache-Control', 'public, max-age=86400');
        if (seoService) {
            try {
                const robotsTxt = await seoService.generateRobotsTxt(baseUrl);
                return res.send(robotsTxt);
            }
            catch (e) {
                logger.warn('robots.txt generation failed:', e);
            }
        }
        res.send(`User-agent: *
Allow: /
Disallow: /admin/
Disallow: /api/
Sitemap: ${baseUrl}/sitemap.xml`);
    });
    expressApp.get('/sitemap.xml', async (req, res) => {
        const baseUrl = process.env.SITE_URL || `http://localhost:${port}`;
        res.setHeader('Content-Type', 'application/xml');
        res.setHeader('Cache-Control', 'public, max-age=3600');
        if (seoService) {
            try {
                const sitemapXml = await seoService.generateSitemap(baseUrl);
                return res.send(sitemapXml);
            }
            catch (error) {
                logger.warn('Sitemap generation failed:', error);
            }
        }
        res.send(`<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url><loc>${baseUrl}</loc><priority>1.0</priority></url>
</urlset>`);
    });
    logger.log('✅ SEO routes registered (robots.txt, sitemap.xml)');
    const shutdown = async (signal) => {
        logger.log(`Received ${signal}, starting graceful shutdown...`);
        await app.close();
        logger.log('Application closed gracefully');
        process.exit(0);
    };
    process.on('SIGTERM', () => shutdown('SIGTERM'));
    process.on('SIGINT', () => shutdown('SIGINT'));
    const port = process.env.PORT || 3000;
    const host = process.env.HOST || '0.0.0.0';
    await app.listen(port, host);
    logger.log(`
    🚀 WordPress Node CMS is running!

    📍 Application: http://localhost:${port}
    📍 Admin Panel: http://localhost:${port}/admin
    📍 API: http://localhost:${port}/api
    📍 Health: http://localhost:${port}/health

    🏷️  Instance: ${instanceId}
    🌍 Environment: ${process.env.NODE_ENV || 'development'}
    💾 Storage: ${process.env.STORAGE_PROVIDER || 'local'}
    📦 Compression: ${process.env.ENABLE_COMPRESSION !== 'false' ? 'enabled' : 'disabled'}
  `);
}
bootstrap();

})();

/******/ })()
;